source: branches/eraser6/Util/File.cs @ 293

Revision 293, 31.1 KB checked in by lowjoel, 6 years ago (diff)

When calling File.GetFileDescription? or File.GetFileIcon?, the path provided must end with a trailing \ if the path is a directory or volume.

Line 
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5using System.Runtime.InteropServices;
6using System.Windows.Forms;
7using System.Drawing;
8using System.IO;
9using Microsoft.Win32.SafeHandles;
10
11namespace Eraser.Util
12{
13    using HICON = IntPtr;
14    using HIMAGELIST = IntPtr;
15
16    public static class File
17    {
18        /// <summary>
19        /// Gets the list of ADSes of the given file.
20        /// </summary>
21        /// <param name="info">The FileInfo object with the file path etc.</param>
22        /// <returns>A list containing the names of the ADSes of each file. The
23        /// list will be empty if no ADSes exist.</returns>
24        public static List<string> GetADSes(FileInfo info)
25        {
26            List<string> result = new List<string>();
27            using (FileStream stream = info.OpenRead())
28            {
29                SafeFileHandle streamHandle = stream.SafeFileHandle;
30
31                //Allocate the structures
32                WIN32_STREAM_ID streamID = new WIN32_STREAM_ID();
33                IntPtr context = IntPtr.Zero;
34                uint bytesRead = 0;
35
36                //Read the header of the WIN32_STREAM_ID
37                BackupRead(streamHandle, ref streamID, (uint)Marshal.SizeOf(streamID),
38                    ref bytesRead, false, false, ref context);
39
40                while (bytesRead == Marshal.SizeOf(streamID))
41                {
42                    if (streamID.dwStreamId == BACKUP_ALTERNATE_DATA)
43                    {
44                        //Allocate memory to copy the stream name into, then copy the name
45                        IntPtr pName = Marshal.AllocHGlobal((IntPtr)streamID.dwStreamNameSize);
46                        uint nameLength = streamID.dwStreamNameSize / sizeof(char);
47                        char[] name = new char[nameLength];
48                        BackupRead(streamHandle, pName, streamID.dwStreamNameSize, ref bytesRead,
49                            false, false, ref context);
50                        Marshal.Copy(pName, name, 0, (int)nameLength);
51
52                        //Get the name of the stream. The raw value is :NAME:$DATA
53                        string streamName = new string(name);
54                        result.Add(streamName.Substring(1, streamName.LastIndexOf(':') - 1));
55                    }
56
57                    //Skip the file contents. Jump to the next header.
58                    uint seekLow = 0, seekHigh = 0;
59                    BackupSeek(streamHandle, (uint)(streamID.Size & uint.MaxValue),
60                        (uint)(streamID.Size >> (sizeof(uint) * 8)), out seekLow,
61                        out seekHigh, ref context);
62
63                    //And try to read the header
64                    BackupRead(streamHandle, ref streamID, (uint)Marshal.SizeOf(streamID),
65                        ref bytesRead, false, false, ref context);
66                }
67
68                //Free the context
69                BackupRead(streamHandle, IntPtr.Zero, 0, ref bytesRead, true, false, ref context);
70            }
71
72            return result;
73        }
74
75        /// <summary>
76        /// Uses SHGetFileInfo to retrieve the description for the given file,
77        /// folder or drive.
78        /// </summary>
79        /// <param name="path">A string that contains the path and file name for
80        /// the file in question. Both absolute and relative paths are valid.
81        /// Directories and volumes must contain the trailing \</param>
82        /// <returns>A string containing the description</returns>
83        public static string GetFileDescription(string path)
84        {
85            SHFILEINFO shfi = new SHFILEINFO();
86            SHGetFileInfo(path, 0, ref shfi, Marshal.SizeOf(shfi),
87                SHGetFileInfoFlags.SHGFI_DISPLAYNAME);
88            return shfi.szDisplayName;
89        }
90
91        /// <summary>
92        /// Uses SHGetFileInfo to retrieve the icon for the given file, folder or
93        /// drive.
94        /// </summary>
95        /// <param name="path">A string that contains the path and file name for
96        /// the file in question. Both absolute and relative paths are valid.
97        /// Directories and volumes must contain the trailing \</param>
98        /// <returns>An Icon object containing the bitmap</returns>
99        public static Icon GetFileIcon(string path)
100        {
101            SHFILEINFO shfi = new SHFILEINFO();
102            SHGetFileInfo(path, 0, ref shfi, Marshal.SizeOf(shfi),
103                SHGetFileInfoFlags.SHGFI_SMALLICON | SHGetFileInfoFlags.SHGFI_ICON);
104            return Icon.FromHandle(shfi.hIcon);
105        }
106
107        /// <summary>
108        /// Compacts the file path, fitting in the given width.
109        /// </summary>
110        /// <param name="longPath">The long file path.</param>
111        /// <param name="newWidth">The target width of the text.</param>
112        /// <param name="drawFont">The font used for drawing the text.</param>
113        /// <returns>The compacted file path.</returns>
114        public static string GetCompactPath(string longPath, int newWidth, Font drawFont)
115        {
116            using (Control ctrl = new Control())
117            {
118                //First check if the source string is too long.
119                Graphics g = ctrl.CreateGraphics();
120                int width = g.MeasureString(longPath, drawFont).ToSize().Width;
121                if (width <= newWidth)
122                    return longPath;
123
124                //It is, shorten it.
125                int aveCharWidth = width / longPath.Length;
126                int charCount = newWidth / aveCharWidth;
127                StringBuilder builder = new StringBuilder();
128                builder.Append(longPath);
129                builder.EnsureCapacity(charCount);
130
131                while (g.MeasureString(builder.ToString(), drawFont).Width > newWidth)
132                {
133                    if (!PathCompactPathEx(builder, longPath, (uint)charCount--, 0))
134                    {
135                        return string.Empty;
136                    }
137                }
138
139                return builder.ToString();
140            }
141        }
142
143        /// <summary>
144        /// Determines if a given file is protected by SFC.
145        /// </summary>
146        /// <param name="filePath">The path to check</param>
147        /// <returns>True if the file is protected.</returns>
148        public static bool IsProtectedSystemFile(string filePath)
149        {
150            if (SfcIsFileProtected(IntPtr.Zero, filePath))
151                return true;
152            else if (Marshal.GetLastWin32Error() == 2) //ERROR_FILE_NOT_FOUND
153                return false;
154
155            throw new Exception("Unknown SfcIsFileProtected error.");
156        }
157
158        /// <summary>
159        /// Checks whether the path given is compressed.
160        /// </summary>
161        /// <param name="filePath">The path to the file or folder</param>
162        /// <returns>True if the file or folder is compressed.</returns>
163        public static bool IsCompressed(string path)
164        {
165            ushort compressionStatus = 0;
166            uint bytesReturned = 0;
167
168            using (FileStream strm = new FileStream(CreateFile(path,
169                GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING,
170                FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero), FileAccess.Read))
171            {
172                if (DeviceIoControl(strm.SafeFileHandle.DangerousGetHandle(),
173                    FSCTL_GET_COMPRESSION, IntPtr.Zero, 0, out compressionStatus,
174                    sizeof(ushort), out bytesReturned, IntPtr.Zero))
175                {
176                    const ushort COMPRESSION_FORMAT_NONE = 0x0000;
177                    return compressionStatus != COMPRESSION_FORMAT_NONE;
178                }
179            }
180
181            throw new Exception("Unknown DeviceIoControl error.");
182        }
183
184        /// <summary>
185        /// Sets whether the file system object pointed to by path is compressed.
186        /// </summary>
187        /// <param name="path">The path to the file or folder.</param>
188        /// <returns>True if the file or folder has its compression value set.</returns>
189        public static bool SetCompression(string path, bool compressed)
190        {
191            ushort compressionStatus = compressed ?
192                COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;
193            uint bytesReturned = 0;
194
195            using (FileStream strm = new FileStream(CreateFile(path,
196                GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING,
197                FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero), FileAccess.ReadWrite))
198            {
199                return DeviceIoControl(strm.SafeFileHandle.DangerousGetHandle(),
200                    FSCTL_SET_COMPRESSION, ref compressionStatus,
201                    sizeof(ushort), IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);
202            }
203        }
204
205        /// <summary>
206        /// Retrieves information about an object in the file system, such as a
207        /// file, folder, directory, or drive root.
208        /// </summary>
209        /// <param name="path">[in] A pointer to a null-terminated string of maximum
210        /// length MAX_PATH that contains the path and file name. Both absolute
211        /// and relative paths are valid.
212        ///
213        /// If the uFlags parameter includes the SHGFI_PIDL flag, this parameter
214        /// must be the address of an ITEMIDLIST (PIDL) structure that contains
215        /// the list of item identifiers that uniquely identifies the file within
216        /// the Shell's namespace. The pointer to an item identifier list (PIDL)
217        /// must be a fully qualified PIDL. Relative PIDLs are not allowed.
218        ///
219        /// If the uFlags parameter includes the SHGFI_USEFILEATTRIBUTES flag,
220        /// this parameter does not have to be a valid file name. The function
221        /// will proceed as if the file exists with the specified name and with
222        /// the file attributes passed in the dwFileAttributes parameter. This
223        /// allows you to obtain information about a file type by passing just
224        /// the extension for pszPath and passing FILE_ATTRIBUTE_NORMAL in
225        /// dwFileAttributes.
226        ///
227        /// This string can use either short (the 8.3 form) or long file names.</param>
228        /// <param name="fileAttributes">[in] A combination of one or more file
229        /// attribute flags (FILE_ATTRIBUTE_ values as defined in Winnt.h). If
230        /// uFlags does not include the SHGFI_USEFILEATTRIBUTES flag, this
231        /// parameter is ignored.</param>
232        /// <param name="psfi">[out] The address of a SHFILEINFO structure to
233        /// receive the file information.</param>
234        /// <param name="cbFileInfo">[in] The size, in bytes, of the SHFILEINFO
235        /// structure pointed to by the psfi parameter.</param>
236        /// <param name="uFlags">[in] The flags that specify the file information to retrieve.
237        /// This parameter can be a combination of the values in SHGetFileInfoFlags</param>
238        /// <returns>Returns a value whose meaning depends on the uFlags parameter.
239        ///
240        /// If uFlags does not contain SHGFI_EXETYPE or SHGFI_SYSICONINDEX, the return
241        /// value is nonzero if successful, or zero otherwise.
242        ///
243        /// If uFlags contains the SHGFI_EXETYPE flag, the return value specifies
244        /// the type of the executable file. It will be one of the following values.
245        ///     0                                               Nonexecutable file or an error condition.
246        ///     LOWORD = NE or PE and HIWORD = Windows version  Microsoft Windows application.
247        ///     LOWORD = MZ and HIWORD = 0                      Windows 95, Windows 98: Microsoft MS-DOS .exe, .com, or .bat file
248        ///                                                     Microsoft Windows NT, Windows 2000, Windows XP: MS-DOS .exe or .com file
249        ///     LOWORD = PE and HIWORD = 0                      Windows 95, Windows 98: Microsoft Win32 console application
250        ///                                                     Windows NT, Windows 2000, Windows XP: Win32 console application or .bat file
251        /// </returns>
252        [DllImport("Shell32.dll")]
253        private static extern IntPtr SHGetFileInfo(string path, uint fileAttributes,
254            ref SHFILEINFO psfi, int fileInfo, SHGetFileInfoFlags flags);
255
256        enum SHGetFileInfoFlags
257        {
258            /// <summary>
259            /// Retrieve the handle to the icon that represents the file and the
260            /// index of the icon within the system image list. The handle is
261            /// copied to the hIcon member of the structure specified by psfi,
262            /// and the index is copied to the iIcon member.
263            /// </summary>
264            SHGFI_ICON              = 0x000000100,
265
266            /// <summary>
267            /// Retrieve the display name for the file. The name is copied to the
268            /// szDisplayName member of the structure specified in psfi. The returned
269            /// display name uses the long file name, if there is one, rather than
270            /// the 8.3 form of the file name.
271            /// </summary>
272            SHGFI_DISPLAYNAME       = 0x000000200,
273
274            /// <summary>
275            /// Retrieve the string that describes the file's type. The string
276            /// is copied to the szTypeName member of the structure specified in
277            /// psfi.
278            /// </summary>
279            SHGFI_TYPENAME          = 0x000000400,
280
281            /// <summary>
282            /// Retrieve the item attributes. The attributes are copied to the
283            /// dwAttributes member of the structure specified in the psfi parameter.
284            /// These are the same attributes that are obtained from
285            /// IShellFolder::GetAttributesOf.
286            /// </summary>
287            SHGFI_ATTRIBUTES        = 0x000000800,
288
289            /// <summary>
290            /// Retrieve the name of the file that contains the icon representing
291            /// the file specified by pszPath, as returned by the
292            /// IExtractIcon::GetIconLocation method of the file's icon handler.
293            /// Also retrieve the icon index within that file. The name of the
294            /// file containing the icon is copied to the szDisplayName member
295            /// of the structure specified by psfi. The icon's index is copied to
296            /// that structure's iIcon member.
297            /// </summary>
298            SHGFI_ICONLOCATION      = 0x000001000,
299
300            /// <summary>
301            /// Retrieve the type of the executable file if pszPath identifies an
302            /// executable file. The information is packed into the return value.
303            /// This flag cannot be specified with any other flags.
304            /// </summary>
305            SHGFI_EXETYPE           = 0x000002000,
306
307            /// <summary>
308            /// Retrieve the index of a system image list icon. If successful,
309            /// the index is copied to the iIcon member of psfi. The return value
310            /// is a handle to the system image list. Only those images whose
311            /// indices are successfully copied to iIcon are valid. Attempting
312            /// to access other images in the system image list will result in
313            /// undefined behavior.
314            /// </summary>
315            SHGFI_SYSICONINDEX      = 0x000004000,
316           
317            /// <summary>
318            /// Modify SHGFI_ICON, causing the function to add the link overlay
319            /// to the file's icon. The SHGFI_ICON flag must also be set.
320            /// </summary>
321            SHGFI_LINKOVERLAY       = 0x000008000,
322
323            /// <summary>
324            /// Modify SHGFI_ICON, causing the function to blend the file's icon
325            /// with the system highlight color. The SHGFI_ICON flag must also
326            /// be set.
327            /// </summary>
328            SHGFI_SELECTED          = 0x000010000,
329
330            /// <summary>
331            /// Modify SHGFI_ATTRIBUTES to indicate that the dwAttributes member
332            /// of the SHFILEINFO structure at psfi contains the specific attributes
333            /// that are desired. These attributes are passed to IShellFolder::GetAttributesOf.
334            /// If this flag is not specified, 0xFFFFFFFF is passed to
335            /// IShellFolder::GetAttributesOf, requesting all attributes. This flag
336            /// cannot be specified with the SHGFI_ICON flag.
337            /// </summary>
338            SHGFI_ATTR_SPECIFIED    = 0x000020000,
339
340            /// <summary>
341            /// Modify SHGFI_ICON, causing the function to retrieve the file's
342            /// large icon. The SHGFI_ICON flag must also be set.
343            /// </summary>
344            SHGFI_LARGEICON         = 0x000000000,
345
346            /// <summary>
347            /// Modify SHGFI_ICON, causing the function to retrieve the file's
348            /// small icon. Also used to modify SHGFI_SYSICONINDEX, causing the
349            /// function to return the handle to the system image list that
350            /// contains small icon images. The SHGFI_ICON and/or
351            /// SHGFI_SYSICONINDEX flag must also be set.
352            /// </summary>
353            SHGFI_SMALLICON         = 0x000000001,
354
355            /// <summary>
356            /// Modify SHGFI_ICON, causing the function to retrieve the file's
357            /// open icon. Also used to modify SHGFI_SYSICONINDEX, causing the
358            /// function to return the handle to the system image list that
359            /// contains the file's small open icon. A container object displays
360            /// an open icon to indicate that the container is open. The SHGFI_ICON
361            /// and/or SHGFI_SYSICONINDEX flag must also be set.
362            /// </summary>
363            SHGFI_OPENICON          = 0x000000002,
364
365            /// <summary>
366            /// Modify SHGFI_ICON, causing the function to retrieve a Shell-sized
367            /// icon. If this flag is not specified the function sizes the icon
368            /// according to the system metric values. The SHGFI_ICON flag must
369            /// also be set.
370            /// </summary>
371            SHGFI_SHELLICONSIZE     = 0x000000004,
372           
373            /// <summary>
374            /// Indicate that pszPath is the address of an ITEMIDLIST structure
375            /// rather than a path name.
376            /// </summary>
377            SHGFI_PIDL              = 0x000000008,
378
379            /// <summary>
380            /// Indicates that the function should not attempt to access the file
381            /// specified by pszPath. Rather, it should act as if the file specified
382            /// by pszPath exists with the file attributes passed in dwFileAttributes.
383            /// This flag cannot be combined with the SHGFI_ATTRIBUTES, SHGFI_EXETYPE,
384            /// or SHGFI_PIDL flags.
385            /// </summary>
386            SHGFI_USEFILEATTRIBUTES = 0x000000010,
387
388            /// <summary>
389            /// Version 5.0. Apply the appropriate overlays to the file's icon.
390            /// The SHGFI_ICON flag must also be set.
391            /// </summary>
392            SHGFI_ADDOVERLAYS       = 0x000000020,
393           
394            /// <summary>
395            /// Version 5.0. Return the index of the overlay icon. The value of
396            /// the overlay index is returned in the upper eight bits of the iIcon
397            /// member of the structure specified by psfi. This flag requires that
398            /// the SHGFI_ICON be set as well.
399            /// </summary>
400            SHGFI_OVERLAYINDEX      = 0x000000040
401        }
402
403        [StructLayout(LayoutKind.Sequential)]
404        private struct SHFILEINFO
405        {
406            /// <summary>
407            /// A handle to the icon that represents the file. You are responsible
408            /// for destroying this handle with DestroyIcon when you no longer need it.
409            /// </summary>
410            public HICON hIcon;
411
412            /// <summary>
413            /// The index of the icon image within the system image list.
414            /// </summary>
415            public int iIcon;
416
417            /// <summary>
418            /// An array of values that indicates the attributes of the file object.
419            /// For information about these values, see the IShellFolder::GetAttributesOf
420            /// method.
421            /// </summary>
422            public uint dwAttributes;
423
424            /// <summary>
425            /// A string that contains the name of the file as it appears in the
426            /// Microsoft Windows Shell, or the path and file name of the file
427            /// that contains the icon representing the file.
428            /// </summary>
429            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
430            public string szDisplayName;
431
432            /// <summary>
433            /// A string that describes the type of file.
434            /// </summary>
435            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
436            public string szTypeName;
437        }
438
439        /// <summary>
440        /// Truncates a path to fit within a certain number of characters by
441        /// replacing path components with ellipses.
442        /// </summary>
443        /// <param name="pszOut">[out] The address of the string that has been altered.</param>
444        /// <param name="pszSrc">[in] A pointer to a null-terminated string of maximum
445        /// length MAX_PATH that contains the path to be altered.</param>
446        /// <param name="cchMax">[in] The maximum number of characters to be
447        /// contained in the new string, including the terminating NULL character.
448        /// For example, if cchMax = 8, the resulting string can contain a maximum
449        /// of 7 characters plus the terminating NULL character.</param>
450        /// <param name="dwFlags">Reserved.</param>
451        /// <returns>Returns TRUE if successful, or FALSE otherwise.</returns>
452        [DllImport("Shlwapi.dll")]
453        [return: MarshalAs(UnmanagedType.Bool)]
454        private static extern bool PathCompactPathEx(
455            StringBuilder pszOut, string pszSrc, uint cchMax, uint dwFlags);
456
457        /// <summary>
458        /// Determines whether the specified file is protected. Applications
459        /// should avoid replacing protected system files.
460        /// </summary>
461        /// <param name="RpcHandle">This parameter must be NULL.</param>
462        /// <param name="ProtFileName">The name of the file.</param>
463        /// <returns>If the file is protected, the return value is true.
464        ///
465        /// If the file is not protected, the return value is false and
466        /// Marshal.GetLastWin32Error() returns ERROR_FILE_NOT_FOUND. If the
467        /// function fails, Marshal.GetLastWin32Error() will return a different
468        /// error code.</returns>
469        [DllImport("Sfc.dll", SetLastError = true)]
470        [return: MarshalAs(UnmanagedType.Bool)]
471        private static extern bool SfcIsFileProtected(IntPtr RpcHandle,
472            [MarshalAs(UnmanagedType.LPWStr)]string ProtFileName);
473
474        /// <summary>
475        /// The BackupRead function can be used to back up a file or directory,
476        /// including the security information. The function reads data associated
477        /// with a specified file or directory into a buffer, which can then be
478        /// written to the backup medium using the WriteFile function.
479        /// </summary>
480        /// <param name="hFile">Handle to the file or directory to be backed up.
481        /// To obtain the handle, call the CreateFile function. The SACLs are not
482        /// read unless the file handle was created with the ACCESS_SYSTEM_SECURITY
483        /// access right. For more information, see File Security and Access Rights.
484        ///
485        /// The BackupRead function may fail if CreateFile was called with the flag
486        /// FILE_FLAG_NO_BUFFERING. In this case, the GetLastError function
487        /// returns the value ERROR_INVALID_PARAMETER.</param>
488        /// <param name="lpBuffer">Pointer to a buffer that receives the data.</param>
489        /// <param name="nNumberOfBytesToRead">Length of the buffer, in bytes. The
490        /// buffer size must be greater than the size of a WIN32_STREAM_ID structure.</param>
491        /// <param name="lpNumberOfBytesRead">Pointer to a variable that receives
492        /// the number of bytes read.
493        ///
494        /// If the function returns a nonzero value, and the variable pointed to
495        /// by lpNumberOfBytesRead is zero, then all the data associated with the
496        /// file handle has been read.</param>
497        /// <param name="bAbort">Indicates whether you have finished using BackupRead
498        /// on the handle. While you are backing up the file, specify this parameter
499        /// as FALSE. Once you are done using BackupRead, you must call BackupRead
500        /// one more time specifying TRUE for this parameter and passing the appropriate
501        /// lpContext. lpContext must be passed when bAbort is TRUE; all other
502        /// parameters are ignored.</param>
503        /// <param name="bProcessSecurity">Indicates whether the function will
504        /// restore the access-control list (ACL) data for the file or directory.
505        ///
506        /// If bProcessSecurity is TRUE, the ACL data will be backed up.</param>
507        /// <param name="lpContext">Pointer to a variable that receives a pointer
508        /// to an internal data structure used by BackupRead to maintain context
509        /// information during a backup operation.
510        ///
511        /// You must set the variable pointed to by lpContext to NULL before the
512        /// first call to BackupRead for the specified file or directory. The
513        /// function allocates memory for the data structure, and then sets the
514        /// variable to point to that structure. You must not change lpContext or
515        /// the variable that it points to between calls to BackupRead.
516        ///
517        /// To release the memory used by the data structure, call BackupRead with
518        /// the bAbort parameter set to TRUE when the backup operation is complete.</param>
519        /// <returns>If the function succeeds, the return value is nonzero.
520        ///
521        /// If the function fails, the return value is zero, indicating that an
522        /// I/O error occurred. To get extended error information, call
523        /// Marshal.GetLastWin32Error.</returns>
524        [DllImport("Kernel32.dll", SetLastError = true)]
525        [return: MarshalAs(UnmanagedType.Bool)]
526        private static extern bool BackupRead(SafeFileHandle hFile,
527            IntPtr lpBuffer, uint nNumberOfBytesToRead, ref uint lpNumberOfBytesRead,
528            [MarshalAs(UnmanagedType.Bool)] bool bAbort,
529            [MarshalAs(UnmanagedType.Bool)] bool bProcessSecurity,
530            ref IntPtr lpContext);
531
532       
533        [DllImport("Kernel32.dll", SetLastError = true)]
534        [return: MarshalAs(UnmanagedType.Bool)]
535        private static extern bool BackupRead(SafeFileHandle hFile,
536            ref WIN32_STREAM_ID lpBuffer, uint nNumberOfBytesToRead,
537            ref uint lpNumberOfBytesRead, [MarshalAs(UnmanagedType.Bool)] bool bAbort,
538            [MarshalAs(UnmanagedType.Bool)] bool bProcessSecurity,
539            ref IntPtr lpContext);
540
541        /// <summary>
542        /// The BackupSeek function seeks forward in a data stream initially
543        /// accessed by using the BackupRead or BackupWrite function.
544        /// </summary>
545        /// <param name="hFile">Handle to the file or directory. This handle is
546        /// created by using the CreateFile function.</param>
547        /// <param name="dwLowBytesToSeek">Low-order part of the number of bytes
548        /// to seek.</param>
549        /// <param name="dwHighBytesToSeek">High-order part of the number of bytes
550        /// to seek.</param>
551        /// <param name="lpdwLowByteSeeked">Pointer to a variable that receives
552        /// the low-order bits of the number of bytes the function actually seeks.</param>
553        /// <param name="lpdwHighByteSeeked">Pointer to a variable that receives
554        /// the high-order bits of the number of bytes the function actually seeks.</param>
555        /// <param name="lpContext">Pointer to an internal data structure used by
556        /// the function. This structure must be the same structure that was
557        /// initialized by the BackupRead function. An application must not touch
558        /// the contents of this structure.</param>
559        /// <returns>If the function could seek the requested amount, the function
560        /// returns a nonzero value.
561        ///
562        /// If the function could not seek the requested amount, the function
563        /// returns zero. To get extended error information, call
564        /// Marshal.GetLastWin32Error.</returns>
565        [DllImport("Kernel32.dll", SetLastError = true)]
566        [return: MarshalAs(UnmanagedType.Bool)]
567        private static extern bool BackupSeek(SafeFileHandle hFile, uint dwLowBytesToSeek,
568            uint dwHighBytesToSeek, out uint lpdwLowByteSeeked, out uint lpdwHighByteSeeked,
569            ref IntPtr lpContext);
570
571        /// <summary>
572        /// The WIN32_STREAM_ID structure contains stream data.
573        /// </summary>
574        [StructLayout(LayoutKind.Sequential, Pack = 4)]
575        private struct WIN32_STREAM_ID
576        {
577            /// <summary>
578            /// Type of data. This member can be one of the BACKUP_* values.
579            /// </summary>
580            public uint dwStreamId;
581
582            /// <summary>
583            /// Attributes of data to facilitate cross-operating system transfer.
584            /// This member can be one or more of the following values.
585            /// Value                       Meaning
586            /// STREAM_MODIFIED_WHEN_READ   Attribute set if the stream contains
587            ///                             data that is modified when read. Allows
588            ///                             the backup application to know that
589            ///                             verification of data will fail.
590            /// STREAM_CONTAINS_SECURITY    Stream contains security data
591            ///                             (general attributes). Allows the stream
592            ///                             to be ignored on cross-operations restore.
593            /// </summary>
594            public uint dwStreamAttributes;
595
596            /// <summary>
597            /// Size of data, in bytes.
598            /// </summary>
599            public long Size;
600
601            /// <summary>
602            /// Length of the name of the alternative data stream, in bytes.
603            /// </summary>
604            public uint dwStreamNameSize;
605        }
606
607        /// <summary>
608        /// Alternative data streams.
609        /// </summary>
610        public const uint BACKUP_ALTERNATE_DATA = 0x00000004;
611
612        /// <summary>
613        /// Standard data.
614        /// </summary>
615        public const uint BACKUP_DATA = 0x00000001;
616
617        /// <summary>
618        /// Extended attribute data.
619        /// </summary>
620        public const uint BACKUP_EA_DATA = 0x00000002;
621
622        /// <summary>
623        /// Hard link information.
624        /// </summary>
625        public const uint BACKUP_LINK = 0x00000005;
626
627        /// <summary>
628        /// Objects identifiers.
629        /// </summary>
630        public const uint BACKUP_OBJECT_ID = 0x00000007;
631
632        /// <summary>
633        /// Property data.
634        /// </summary>
635        public const uint BACKUP_PROPERTY_DATA = 0x00000006;
636
637        /// <summary>
638        /// Reparse points.
639        /// </summary>
640        public const uint BACKUP_REPARSE_DATA = 0x00000008;
641
642        /// <summary>
643        /// Security descriptor data.
644        /// </summary>
645        public const uint BACKUP_SECURITY_DATA = 0x00000003;
646
647        /// <summary>
648        /// Sparse file.
649        /// </summary>
650        public const uint BACKUP_SPARSE_BLOCK = 0x00000009;
651
652        /// <summary>
653        /// The CreateFile function creates or opens a file, file stream, directory,
654        /// physical disk, volume, console buffer, tape drive, communications resource,
655        /// mailslot, or named pipe. The function returns a handle that can be used
656        /// to access an object.
657        /// </summary>
658        /// <param name="FileName"></param>
659        /// <param name="DesiredAccess"> access to the object, which can be read,
660        /// write, or both</param>
661        /// <param name="ShareMode">The sharing mode of an object, which can be
662        /// read, write, both, or none</param>
663        /// <param name="SecurityAttributes">A pointer to a SECURITY_ATTRIBUTES
664        /// structure that determines whether or not the returned handle can be
665        /// inherited by child processes. Can be null</param>
666        /// <param name="CreationDisposition">An action to take on files that exist
667        /// and do not exist</param>
668        /// <param name="FlagsAndAttributes">The file attributes and flags.</param>
669        /// <param name="hTemplateFile">A handle to a template file with the
670        /// GENERIC_READ access right. The template file supplies file attributes
671        /// and extended attributes for the file that is being created. This
672        /// parameter can be null</param>
673        /// <returns>If the function succeeds, the return value is an open handle
674        /// to a specified file. If a specified file exists before the function
675        /// all and dwCreationDisposition is CREATE_ALWAYS or OPEN_ALWAYS, a call
676        /// to GetLastError returns ERROR_ALREADY_EXISTS, even when the function
677        /// succeeds. If a file does not exist before the call, GetLastError
678        /// returns 0.
679        ///
680        /// If the function fails, the return value is INVALID_HANDLE_VALUE.
681        /// To get extended error information, call Marshal.GetLastWin32Error().</returns>
682        [DllImport("Kernel32.dll", SetLastError = true)]
683        public static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
684            uint dwShareMode, IntPtr SecurityAttributes, uint dwCreationDisposition,
685            uint dwFlagsAndAttributes, IntPtr hTemplateFile);
686
687        public const uint GENERIC_READ = 0x80000000;
688        public const uint GENERIC_WRITE = 0x40000000;
689        public const uint GENERIC_EXECUTE = 0x20000000;
690        public const uint GENERIC_ALL = 0x10000000;
691
692        public const uint FILE_SHARE_READ = 0x00000001;
693        public const uint FILE_SHARE_WRITE = 0x00000002;
694        public const uint FILE_SHARE_DELETE = 0x00000004;
695
696        public const uint CREATE_NEW = 1;
697        public const uint CREATE_ALWAYS = 2;
698        public const uint OPEN_EXISTING = 3;
699        public const uint OPEN_ALWAYS = 4;
700        public const uint TRUNCATE_EXISTING = 5;
701
702        public const uint FILE_FLAG_WRITE_THROUGH = 0x80000000;
703        public const uint FILE_FLAG_OVERLAPPED = 0x40000000;
704        public const uint FILE_FLAG_NO_BUFFERING = 0x20000000;
705        public const uint FILE_FLAG_RANDOM_ACCESS = 0x10000000;
706        public const uint FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000;
707        public const uint FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
708        public const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
709        public const uint FILE_FLAG_POSIX_SEMANTICS = 0x01000000;
710        public const uint FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000;
711        public const uint FILE_FLAG_OPEN_NO_RECALL = 0x00100000;
712        public const uint FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000;
713
714        [DllImport("Kernel32.dll", SetLastError = true)]
715        [return: MarshalAs(UnmanagedType.Bool)]
716        private extern static bool DeviceIoControl(IntPtr hDevice,
717            uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize,
718            IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned,
719            IntPtr lpOverlapped);
720
721        [DllImport("Kernel32.dll", SetLastError = true)]
722        [return: MarshalAs(UnmanagedType.Bool)]
723        private extern static bool DeviceIoControl(IntPtr hDevice,
724            uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize,
725            out ushort lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned,
726            IntPtr lpOverlapped);
727
728        [DllImport("Kernel32.dll", SetLastError = true)]
729        [return: MarshalAs(UnmanagedType.Bool)]
730        private extern static bool DeviceIoControl(IntPtr hDevice,
731            uint dwIoControlCode, ref ushort lpInBuffer, uint nInBufferSize,
732            IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned,
733            IntPtr lpOverlapped);
734
735        private const uint FSCTL_GET_COMPRESSION = 0x9003C;
736        private const uint FSCTL_SET_COMPRESSION = 0x9C040;
737        private const ushort COMPRESSION_FORMAT_NONE = 0x0000;
738        private const ushort COMPRESSION_FORMAT_DEFAULT = 0x0001;
739    }
740}
Note: See TracBrowser for help on using the repository browser.