Changeset 1086


Ignore:
Timestamp:
6/2/2009 2:53:07 AM (6 years ago)
Author:
lowjoel
Message:

Use NtQueryInformationFile? to get ADS information instead of the backup reading APIs

Location:
trunk/eraser6/Eraser.Util
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser6/Eraser.Util/Eraser.Util.csproj

    r1075 r1086  
    2222    <ErrorReport>prompt</ErrorReport> 
    2323    <WarningLevel>4</WarningLevel> 
    24     <AllowUnsafeBlocks>false</AllowUnsafeBlocks> 
     24    <AllowUnsafeBlocks>true</AllowUnsafeBlocks> 
    2525    <CodeAnalysisRules>-Microsoft.Interoperability#CA1404;-Microsoft.Naming#CA1704;-Microsoft.Naming#CA1707</CodeAnalysisRules> 
    2626  </PropertyGroup> 
     
    3232    <ErrorReport>prompt</ErrorReport> 
    3333    <WarningLevel>4</WarningLevel> 
    34     <AllowUnsafeBlocks>false</AllowUnsafeBlocks> 
     34    <AllowUnsafeBlocks>true</AllowUnsafeBlocks> 
    3535  </PropertyGroup> 
    3636  <ItemGroup> 
  • trunk/eraser6/Eraser.Util/File.cs

    r1084 r1086  
    5050            { 
    5151                //Allocate the structures 
    52                 KernelApi.NativeMethods.WIN32_STREAM_ID streamID = 
    53                     new KernelApi.NativeMethods.WIN32_STREAM_ID(); 
    54                 IntPtr context = IntPtr.Zero; 
    55                 uint bytesRead = 0; 
    56  
    57                 //Read the header of the WIN32_STREAM_ID 
    58                 KernelApi.NativeMethods.BackupRead(streamHandle, out streamID, 
    59                     (uint)Marshal.SizeOf(streamID), out bytesRead, false, false, 
    60                     ref context); 
    61  
    62                 while (bytesRead == Marshal.SizeOf(streamID)) 
     52                NTApi.NativeMethods.FILE_STREAM_INFORMATION[] streams = 
     53                    NTApi.NativeMethods.NtQueryInformationFile(streamHandle); 
     54 
     55                foreach (NTApi.NativeMethods.FILE_STREAM_INFORMATION streamInfo in streams) 
    6356                { 
    64                     if (streamID.dwStreamId == KernelApi.NativeMethods.BACKUP_ALTERNATE_DATA) 
    65                     { 
    66                         //Allocate memory to copy the stream name into, then copy the name 
    67                         IntPtr pName = Marshal.AllocHGlobal((int)streamID.dwStreamNameSize); 
    68                         uint nameLength = streamID.dwStreamNameSize / sizeof(char); 
    69                         char[] name = new char[nameLength]; 
    70  
    71                         try 
    72                         { 
    73                             KernelApi.NativeMethods.BackupRead(streamHandle, pName, 
    74                                 streamID.dwStreamNameSize, out bytesRead, false, false, 
    75                                 ref context); 
    76                             Marshal.Copy(pName, name, 0, (int)nameLength); 
    77                         } 
    78                         finally 
    79                         { 
    80                             Marshal.FreeHGlobal(pName); 
    81                         } 
    82  
    83                         //Get the name of the stream. The raw value is :NAME:$DATA 
    84                         string streamName = new string(name); 
    85                         result.Add(streamName.Substring(1, streamName.LastIndexOf(':') - 1)); 
    86                     } 
    87  
    88                     //Skip the file contents. Jump to the next header. 
    89                     uint seekLow = 0, seekHigh = 0; 
    90                     KernelApi.NativeMethods.BackupSeek(streamHandle, 
    91                         (uint)(streamID.Size & uint.MaxValue), 
    92                         (uint)(streamID.Size >> (sizeof(uint) * 8)), out seekLow, 
    93                         out seekHigh, ref context); 
    94  
    95                     //And try to read the header 
    96                     KernelApi.NativeMethods.BackupRead(streamHandle, out streamID, 
    97                         (uint)Marshal.SizeOf(streamID), out bytesRead, false, false, 
    98                         ref context); 
     57                    //Get the name of the stream. The raw value is :NAME:$DATA 
     58                    string streamName = streamInfo.StreamName.Substring(1, 
     59                        streamInfo.StreamName.LastIndexOf(':') - 1); 
     60                     
     61                    if (streamName.Length != 0) 
     62                        result.Add(streamName); 
    9963                } 
    100  
    101                 //Free the context 
    102                 KernelApi.NativeMethods.BackupRead(streamHandle, IntPtr.Zero, 0, 
    103                     out bytesRead, true, false, ref context); 
    10464            } 
    10565 
  • trunk/eraser6/Eraser.Util/NTApi.cs

    r1009 r1086  
    6262 
    6363            /// <summary> 
     64            /// The ZwQueryInformationFile routine returns various kinds of information 
     65            /// about a file object. 
     66            /// </summary> 
     67            /// <param name="FileHandle">Handle to a file object. The handle is created 
     68            /// by a successful call to ZwCreateFile or ZwOpenFile.</param> 
     69            /// <param name="IoStatusBlock">Pointer to an IO_STATUS_BLOCK structure 
     70            /// that receives the final completion status and information about 
     71            /// the operation. The Information member receives the number of bytes 
     72            /// that this routine actually writes to the FileInformation buffer.</param> 
     73            /// <param name="FileInformation">Pointer to a caller-allocated buffer 
     74            /// into which the routine writes the requested information about the 
     75            /// file object. The FileInformationClass parameter specifies the type 
     76            /// of information that the caller requests.</param> 
     77            /// <param name="Length">The size, in bytes, of the buffer pointed to 
     78            /// by FileInformation.</param> 
     79            /// <param name="FileInformationClass">Specifies the type of information 
     80            /// to be returned about the file, in the buffer that FileInformation 
     81            /// points to. Device and intermediate drivers can specify any of the 
     82            /// following FILE_INFORMATION_CLASS enumeration values, which are defined 
     83            /// in header file Wdm.h.</param> 
     84            /// <returns>ZwQueryInformationFile returns STATUS_SUCCESS or an appropriate 
     85            /// NTSTATUS error code.</returns> 
     86            [DllImport("NtDll.dll")] 
     87            private static extern uint NtQueryInformationFile(SafeFileHandle FileHandle, 
     88                ref IO_STATUS_BLOCK IoStatusBlock, IntPtr FileInformation, uint Length, 
     89                FILE_INFORMATION_CLASS FileInformationClass); 
     90 
     91            public static FILE_STREAM_INFORMATION[] NtQueryInformationFile(SafeFileHandle FileHandle) 
     92            { 
     93                IO_STATUS_BLOCK status = new IO_STATUS_BLOCK(); 
     94                IntPtr fileInfoPtr = IntPtr.Zero; 
     95 
     96                try 
     97                { 
     98                    FILE_STREAM_INFORMATION streamInfo = new FILE_STREAM_INFORMATION(); 
     99                    int fileInfoPtrLength = (Marshal.SizeOf(streamInfo) + 32768) / 2; 
     100                    uint ntStatus = 0; 
     101 
     102                    do 
     103                    { 
     104                        fileInfoPtrLength *= 2; 
     105                        if (fileInfoPtr != IntPtr.Zero) 
     106                            Marshal.FreeHGlobal(fileInfoPtr); 
     107                        fileInfoPtr = Marshal.AllocHGlobal(fileInfoPtrLength); 
     108 
     109                        ntStatus = NtQueryInformationFile(FileHandle, ref status, fileInfoPtr, 
     110                            (uint)fileInfoPtrLength, FILE_INFORMATION_CLASS.FileStreamInformation); 
     111                    } 
     112                    while (ntStatus != 0 /*STATUS_SUCCESS*/ && ntStatus == 0x80000005 /*STATUS_BUFFER_OVERFLOW*/); 
     113 
     114                    //Marshal the structure manually (argh!) 
     115                    List<FILE_STREAM_INFORMATION> result = new List<FILE_STREAM_INFORMATION>(); 
     116                    unsafe 
     117                    { 
     118                        for (byte* i = (byte*)fileInfoPtr; ; i += streamInfo.NextEntryOffset) 
     119                        { 
     120                            byte* currStreamPtr = i; 
     121                            streamInfo.NextEntryOffset = *(uint*)currStreamPtr; 
     122                            byte* nextEntry = currStreamPtr + streamInfo.NextEntryOffset; 
     123                            currStreamPtr += sizeof(uint); 
     124 
     125                            streamInfo.StreamNameLength = *(uint*)currStreamPtr; 
     126                            currStreamPtr += sizeof(uint); 
     127 
     128                            streamInfo.StreamSize = *(long*)currStreamPtr; 
     129                            currStreamPtr += sizeof(long); 
     130 
     131                            streamInfo.StreamAllocationSize = *(long*)currStreamPtr; 
     132                            currStreamPtr += sizeof(long); 
     133 
     134                            streamInfo.StreamName = Marshal.PtrToStringUni((IntPtr)currStreamPtr, 
     135                                (int)streamInfo.StreamNameLength / 2); 
     136                            result.Add(streamInfo); 
     137 
     138                            if (streamInfo.NextEntryOffset == 0) 
     139                                break; 
     140                        } 
     141                    } 
     142 
     143                    return result.ToArray(); 
     144                } 
     145                finally 
     146                { 
     147                    Marshal.FreeHGlobal(fileInfoPtr); 
     148                } 
     149            } 
     150 
     151            public struct IO_STATUS_BLOCK 
     152            { 
     153                public IntPtr PointerStatus; 
     154                public UIntPtr Information; 
     155            } 
     156             
     157            public struct FILE_STREAM_INFORMATION 
     158            { 
     159                /// <summary> 
     160                /// The offset of the next FILE_STREAM_INFORMATION entry. This 
     161                /// member is zero if no other entries follow this one.  
     162                /// </summary> 
     163                public uint NextEntryOffset; 
     164 
     165                /// <summary> 
     166                /// Length, in bytes, of the StreamName string.  
     167                /// </summary> 
     168                public uint StreamNameLength; 
     169 
     170                /// <summary> 
     171                /// Size, in bytes, of the stream.  
     172                /// </summary> 
     173                public long StreamSize; 
     174 
     175                /// <summary> 
     176                /// File stream allocation size, in bytes. Usually this value 
     177                /// is a multiple of the sector or cluster size of the underlying 
     178                /// physical device. 
     179                /// </summary> 
     180                public long StreamAllocationSize; 
     181 
     182                /// <summary> 
     183                /// Unicode string that contains the name of the stream.  
     184                /// </summary> 
     185                public string StreamName; 
     186            } 
     187 
     188            public enum FILE_INFORMATION_CLASS 
     189            { 
     190                FileDirectoryInformation = 1, 
     191                FileFullDirectoryInformation, 
     192                FileBothDirectoryInformation, 
     193                FileBasicInformation, 
     194                FileStandardInformation, 
     195                FileInternalInformation, 
     196                FileEaInformation, 
     197                FileAccessInformation, 
     198                FileNameInformation, 
     199                FileRenameInformation, 
     200                FileLinkInformation, 
     201                FileNamesInformation, 
     202                FileDispositionInformation, 
     203                FilePositionInformation, 
     204                FileFullEaInformation, 
     205                FileModeInformation, 
     206                FileAlignmentInformation, 
     207                FileAllInformation, 
     208                FileAllocationInformation, 
     209                FileEndOfFileInformation, 
     210                FileAlternateNameInformation, 
     211                FileStreamInformation, 
     212                FilePipeInformation, 
     213                FilePipeLocalInformation, 
     214                FilePipeRemoteInformation, 
     215                FileMailslotQueryInformation, 
     216                FileMailslotSetInformation, 
     217                FileCompressionInformation, 
     218                FileCopyOnWriteInformation, 
     219                FileCompletionInformation, 
     220                FileMoveClusterInformation, 
     221                FileQuotaInformation, 
     222                FileReparsePointInformation, 
     223                FileNetworkOpenInformation, 
     224                FileObjectIdInformation, 
     225                FileTrackingInformation, 
     226                FileOleDirectoryInformation, 
     227                FileContentIndexInformation, 
     228                FileInheritContentIndexInformation, 
     229                FileOleInformation, 
     230                FileMaximumInformation 
     231            } 
     232 
     233            /// <summary> 
    64234            /// Represents volume data. This structure is passed to the 
    65235            /// FSCTL_GET_NTFS_VOLUME_DATA control code. 
Note: See TracChangeset for help on using the changeset viewer.