YourDefrag
SVN
|
00001 00002 00003 #define MFTBUFFERSIZE 256 * 1024 /* 256 KB seems to be the optimum. */ 00004 00005 00006 00007 struct INODE_REFERENCE { 00008 ULONG InodeNumberLowPart; 00009 USHORT InodeNumberHighPart; 00010 USHORT SequenceNumber; 00011 }; 00012 00013 struct NTFS_RECORD_HEADER { 00014 ULONG Type; /* File type, for example 'FILE' */ 00015 USHORT UsaOffset; /* Offset to the Update Sequence Array */ 00016 USHORT UsaCount; /* Size in words of Update Sequence Array */ 00017 USN Lsn; /* $LogFile Sequence Number (LSN) */ 00018 }; 00019 struct FILE_RECORD_HEADER { 00020 struct NTFS_RECORD_HEADER RecHdr; 00021 USHORT SequenceNumber; /* Sequence number */ 00022 USHORT LinkCount; /* Hard link count */ 00023 USHORT AttributeOffset; /* Offset to the first Attribute */ 00024 USHORT Flags; /* Flags. bit 1 = in use, bit 2 = directory, bit 4 & 8 = unknown. */ 00025 ULONG BytesInUse; /* Real size of the FILE record */ 00026 ULONG BytesAllocated; /* Allocated size of the FILE record */ 00027 INODE_REFERENCE BaseFileRecord; /* File reference to the base FILE record */ 00028 USHORT NextAttributeNumber; /* Next Attribute Id */ 00029 USHORT Padding; /* Align to 4 UCHAR boundary (XP) */ 00030 ULONG MFTRecordNumber; /* Number of this MFT Record (XP) */ 00031 USHORT UpdateSeqNum; /* */ 00032 }; 00033 00034 enum ATTRIBUTE_TYPE { 00035 AttributeInvalid = 0x00, /* Not defined by Windows */ 00036 AttributeStandardInformation = 0x10, 00037 AttributeAttributeList = 0x20, 00038 AttributeFileName = 0x30, 00039 AttributeObjectId = 0x40, 00040 AttributeSecurityDescriptor = 0x50, 00041 AttributeVolumeName = 0x60, 00042 AttributeVolumeInformation = 0x70, 00043 AttributeData = 0x80, 00044 AttributeIndexRoot = 0x90, 00045 AttributeIndexAllocation = 0xA0, 00046 AttributeBitmap = 0xB0, 00047 AttributeReparsePoint = 0xC0, /* Reparse Point = Symbolic link */ 00048 AttributeEAInformation = 0xD0, 00049 AttributeEA = 0xE0, 00050 AttributePropertySet = 0xF0, 00051 AttributeLoggedUtilityStream = 0x100 00052 }; 00053 00054 struct ATTRIBUTE { 00055 enum ATTRIBUTE_TYPE AttributeType; 00056 ULONG Length; 00057 BOOLEAN Nonresident; 00058 UCHAR NameLength; 00059 USHORT NameOffset; 00060 USHORT Flags; /* 0x0001 = Compressed, 0x4000 = Encrypted, 0x8000 = Sparse */ 00061 USHORT AttributeNumber; 00062 }; 00063 00064 struct RESIDENT_ATTRIBUTE { 00065 struct ATTRIBUTE Attribute; 00066 ULONG ValueLength; 00067 USHORT ValueOffset; 00068 USHORT Flags; // 0x0001 = Indexed 00069 }; 00070 00071 struct NONRESIDENT_ATTRIBUTE { 00072 struct ATTRIBUTE Attribute; 00073 ULONGLONG StartingVcn; 00074 ULONGLONG LastVcn; 00075 USHORT RunArrayOffset; 00076 UCHAR CompressionUnit; 00077 UCHAR AlignmentOrReserved[5]; 00078 ULONGLONG AllocatedSize; 00079 ULONGLONG DataSize; 00080 ULONGLONG InitializedSize; 00081 ULONGLONG CompressedSize; // Only when compressed 00082 }; 00083 00084 struct STANDARD_INFORMATION { 00085 ULONG64 CreationTime; 00086 ULONG64 FileChangeTime; 00087 ULONG64 MftChangeTime; 00088 ULONG64 LastAccessTime; 00089 ULONG FileAttributes; /* READ_ONLY=0x01, HIDDEN=0x02, SYSTEM=0x04, VOLUME_ID=0x08, ARCHIVE=0x20, DEVICE=0x40 */ 00090 ULONG MaximumVersions; 00091 ULONG VersionNumber; 00092 ULONG ClassId; 00093 ULONG OwnerId; // NTFS 3.0 only 00094 ULONG SecurityId; // NTFS 3.0 only 00095 ULONGLONG QuotaCharge; // NTFS 3.0 only 00096 USN Usn; // NTFS 3.0 only 00097 }; 00098 00099 struct ATTRIBUTE_LIST { 00100 enum ATTRIBUTE_TYPE AttributeType; 00101 USHORT Length; 00102 UCHAR NameLength; 00103 UCHAR NameOffset; 00104 ULONGLONG LowestVcn; 00105 INODE_REFERENCE FileReferenceNumber; 00106 USHORT Instance; 00107 USHORT AlignmentOrReserved[3]; 00108 }; 00109 00110 struct FILENAME_ATTRIBUTE { 00111 struct INODE_REFERENCE ParentDirectory; 00112 ULONG64 CreationTime; 00113 ULONG64 ChangeTime; 00114 ULONG64 LastWriteTime; 00115 ULONG64 LastAccessTime; 00116 ULONGLONG AllocatedSize; 00117 ULONGLONG DataSize; 00118 ULONG FileAttributes; 00119 ULONG AlignmentOrReserved; 00120 UCHAR NameLength; 00121 UCHAR NameType; /* NTFS=0x01, DOS=0x02 */ 00122 WCHAR Name[1]; 00123 }; 00124 00125 struct OBJECTID_ATTRIBUTE { 00126 GUID ObjectId; 00127 union { 00128 struct { 00129 GUID BirthVolumeId; 00130 GUID BirthObjectId; 00131 GUID DomainId; 00132 }; 00133 UCHAR ExtendedInfo[48]; 00134 }; 00135 }; 00136 00137 struct VOLUME_INFORMATION { 00138 LONGLONG Reserved; 00139 UCHAR MajorVersion; 00140 UCHAR MinorVersion; 00141 USHORT Flags; /* DIRTY=0x01, RESIZE_LOG_FILE=0x02 */ 00142 }; 00143 00144 struct DIRECTORY_INDEX { 00145 ULONG EntriesOffset; 00146 ULONG IndexBlockLength; 00147 ULONG AllocatedSize; 00148 ULONG Flags; /* SMALL=0x00, LARGE=0x01 */ 00149 }; 00150 00151 struct DIRECTORY_ENTRY { 00152 ULONGLONG FileReferenceNumber; 00153 USHORT Length; 00154 USHORT AttributeLength; 00155 ULONG Flags; // 0x01 = Has trailing VCN, 0x02 = Last entry 00156 // FILENAME_ATTRIBUTE Name; 00157 // ULONGLONG Vcn; // VCN in IndexAllocation of earlier entries 00158 }; 00159 00160 struct INDEX_ROOT { 00161 enum ATTRIBUTE_TYPE Type; 00162 ULONG CollationRule; 00163 ULONG BytesPerIndexBlock; 00164 ULONG ClustersPerIndexBlock; 00165 struct DIRECTORY_INDEX DirectoryIndex; 00166 }; 00167 00168 struct INDEX_BLOCK_HEADER { 00169 struct NTFS_RECORD_HEADER Ntfs; 00170 ULONGLONG IndexBlockVcn; 00171 struct DIRECTORY_INDEX DirectoryIndex; 00172 }; 00173 00174 struct REPARSE_POINT { 00175 ULONG ReparseTag; 00176 USHORT ReparseDataLength; 00177 USHORT Reserved; 00178 UCHAR ReparseData[1]; 00179 }; 00180 00181 struct EA_INFORMATION { 00182 ULONG EaLength; 00183 ULONG EaQueryLength; 00184 }; 00185 00186 struct EA_ATTRIBUTE { 00187 ULONG NextEntryOffset; 00188 UCHAR Flags; 00189 UCHAR EaNameLength; 00190 USHORT EaValueLength; 00191 CHAR EaName[1]; 00192 // UCHAR EaData[]; 00193 }; 00194 00195 struct ATTRIBUTE_DEFINITION { 00196 WCHAR AttributeName[64]; 00197 ULONG AttributeNumber; 00198 ULONG Unknown[2]; 00199 ULONG Flags; 00200 ULONGLONG MinimumSize; 00201 ULONGLONG MaximumSize; 00202 }; 00203 00204 00205 00206 00207 /* The NTFS scanner will construct an ItemStruct list in memory, but needs some 00208 extra information while constructing it. The following structs wrap the ItemStruct 00209 into a new struct with some extra info, discarded when the ItemStruct list is 00210 ready. 00211 A single Inode can contain multiple streams of data. Every stream has it's own 00212 list of fragments. The name of a stream is the same as the filename plus two 00213 extensions separated by colons: 00214 filename:"stream name":"stream type" 00215 For example: 00216 myfile.dat:stream1:$DATA 00217 The "stream name" is an empty string for the default stream, which is the data 00218 of regular files. The "stream type" is one of the following strings: 00219 0x10 $STANDARD_INFORMATION 00220 0x20 $ATTRIBUTE_LIST 00221 0x30 $FILE_NAME 00222 0x40 NT $VOLUME_VERSION 00223 0x40 2K $OBJECT_ID 00224 0x50 $SECURITY_DESCRIPTOR 00225 0x60 $VOLUME_NAME 00226 0x70 $VOLUME_INFORMATION 00227 0x80 $DATA 00228 0x90 $INDEX_ROOT 00229 0xA0 $INDEX_ALLOCATION 00230 0xB0 $BITMAP 00231 0xC0 NT $SYMBOLIC_LINK 00232 0xC0 2K $REPARSE_POINT 00233 0xD0 $EA_INFORMATION 00234 0xE0 $EA 00235 0xF0 NT $PROPERTY_SET 00236 0x100 2K $LOGGED_UTILITY_STREAM 00237 */ 00238 struct StreamStruct { 00239 struct StreamStruct *Next; 00240 WCHAR *StreamName; /* "stream name" */ 00241 ATTRIBUTE_TYPE StreamType; /* "stream type" */ 00242 struct FragmentListStruct *Fragments; /* The fragments of the stream. */ 00243 ULONG64 Clusters; /* Total number of clusters. */ 00244 ULONG64 Bytes; /* Total number of bytes. */ 00245 }; 00246 struct InodeDataStruct { 00247 ULONG64 Inode; /* The Inode number. */ 00248 ULONG64 ParentInode; /* The Inode number of the parent directory. */ 00249 BOOL Directory; /* YES: it's a directory. */ 00250 WCHAR *LongFilename; /* Long filename. */ 00251 WCHAR *ShortFilename; /* Short filename (8.3 DOS). */ 00252 ULONG64 Bytes; /* Total number of bytes. */ 00253 ULONG64 CreationTime; /* 1 second = 10000000 */ 00254 ULONG64 MftChangeTime; 00255 ULONG64 LastAccessTime; 00256 struct StreamStruct *Streams; /* List of StreamStruct. */ 00257 struct FragmentListStruct *MftDataFragments; /* The Fragments of the $MFT::$DATA stream. */ 00258 ULONG64 MftDataBytes; /* Length of the $MFT::$DATA. */ 00259 struct FragmentListStruct *MftBitmapFragments; /* The Fragments of the $MFT::$BITMAP stream. */ 00260 ULONG64 MftBitmapBytes; /* Length of the $MFT::$BITMAP. */ 00261 }; 00262 struct NtfsDiskInfoStruct { 00263 ULONG64 BytesPerSector; 00264 ULONG64 SectorsPerCluster; 00265 ULONG64 TotalSectors; 00266 ULONG64 MftStartLcn; 00267 ULONG64 Mft2StartLcn; 00268 ULONG64 BytesPerMftRecord; 00269 ULONG64 ClustersPerIndexRecord; 00270 struct { 00271 BYTE Buffer[MFTBUFFERSIZE]; 00272 ULONG64 Offset; 00273 int Age; 00274 } Buffers[3]; 00275 }; 00276 00277 00278 00279 BOOL AnalyzeNtfsVolume(struct DefragDataStruct *Data);