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

Revision 292, 30.9 KB checked in by lowjoel, 7 years ago (diff)

Implemented (quite completely, I believe) ADS support
-Cluster tips of ADSes are erased too, this is an improvement over v5
-File times of ADSes are not changed. TODO: Is there a need to?
-Restore the Read only flag after the erase procedure is done
-Implemented the stream equivalent for FileInfo?: StreamInfo?. It lacks many of the features of FileInfo? like ACLs and encryption/decryption, but is complex enough to work as a FileInfo? drop-in in most cases

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