Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmft.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2002 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * COPYRIGHT: See COPYING in the top level directory 00020 * PROJECT: ReactOS kernel 00021 * FILE: drivers/filesystem/ntfs/mft.c 00022 * PURPOSE: NTFS filesystem driver 00023 * PROGRAMMER: Eric Kohl 00024 * Updated by Valentin Verkhovsky 2003/09/12 00025 */ 00026 00027 /* INCLUDES *****************************************************************/ 00028 00029 #include "ntfs.h" 00030 00031 #define NDEBUG 00032 #include <debug.h> 00033 00034 /* GLOBALS *****************************************************************/ 00035 00036 00037 /* FUNCTIONS ****************************************************************/ 00038 00039 00040 NTSTATUS 00041 NtfsOpenMft (PDEVICE_EXTENSION Vcb) 00042 { 00043 // PVOID Bitmap; 00044 PFILE_RECORD_HEADER MftRecord; 00045 PFILE_RECORD_HEADER FileRecord; 00046 // PATTRIBUTE Attribute; 00047 // PATTRIBUTE AttrData; 00048 // PRESIDENT_ATTRIBUTE ResAttr; 00049 00050 NTSTATUS Status; 00051 ULONG BytesPerFileRecord; 00052 ULONG n; 00053 ULONG i; 00054 00055 DPRINT1("NtfsOpenMft() called\n"); 00056 00057 BytesPerFileRecord = Vcb->NtfsInfo.BytesPerFileRecord; 00058 00059 MftRecord = ExAllocatePoolWithTag(NonPagedPool, 00060 BytesPerFileRecord, TAG_NTFS); 00061 if (MftRecord == NULL) 00062 { 00063 return STATUS_INSUFFICIENT_RESOURCES; 00064 } 00065 00066 Status = NtfsReadSectors(Vcb->StorageDevice, 00067 Vcb->NtfsInfo.MftStart.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster, 00068 BytesPerFileRecord / Vcb->NtfsInfo.BytesPerSector, 00069 Vcb->NtfsInfo.BytesPerSector, 00070 (PVOID)MftRecord, 00071 FALSE); 00072 if (!NT_SUCCESS(Status)) 00073 { 00074 ExFreePool(MftRecord); 00075 return Status; 00076 } 00077 00078 00079 FixupUpdateSequenceArray(MftRecord); 00080 00081 // Attribute = FindAttribute(MftRecord, AttributeBitmap, 0); 00082 00083 /* Get number of file records*/ 00084 n = AttributeDataLength (FindAttribute (MftRecord, AttributeData, 0)) 00085 / BytesPerFileRecord; 00086 00087 FileRecord = ExAllocatePoolWithTag(NonPagedPool, BytesPerFileRecord, TAG_NTFS); 00088 if (FileRecord == NULL) 00089 { 00090 ExFreePool(MftRecord); 00091 return(STATUS_INSUFFICIENT_RESOURCES); 00092 } 00093 00094 /* Enumerate MFT Records */ 00095 DPRINT("Enumerate MFT records\n"); 00096 for ( i=0; i < n; i++) 00097 { 00098 ReadFileRecord(Vcb, i, FileRecord, MftRecord); 00099 00100 if (FileRecord->Ntfs.Type == NRH_FILE_TYPE && (FileRecord->Flags & FRH_IN_USE)) 00101 { 00102 DPRINT("\nFile %lu\n\n", i); 00103 00104 /* Enumerate attributtes */ 00105 NtfsDumpFileAttributes (FileRecord); 00106 DbgPrint("\n\n"); 00107 } 00108 } 00109 00110 ExFreePool(FileRecord); 00111 ExFreePool(MftRecord); 00112 00113 return Status; 00114 } 00115 00116 00117 PATTRIBUTE 00118 FindAttribute (PFILE_RECORD_HEADER FileRecord, 00119 ATTRIBUTE_TYPE Type, 00120 PWSTR name) 00121 { 00122 PATTRIBUTE Attribute; 00123 00124 Attribute = (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset); 00125 while (Attribute < (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) && 00126 Attribute->AttributeType != (ATTRIBUTE_TYPE)-1) 00127 { 00128 if (Attribute->AttributeType == Type) 00129 { 00130 return Attribute; 00131 } 00132 00133 Attribute = (PATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Length); 00134 } 00135 00136 return NULL; 00137 } 00138 00139 00140 ULONG 00141 AttributeAllocatedLength (PATTRIBUTE Attribute) 00142 { 00143 if (Attribute->Nonresident) 00144 { 00145 return ((PNONRESIDENT_ATTRIBUTE)Attribute)->AllocatedSize; 00146 } 00147 00148 return ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength; 00149 } 00150 00151 00152 ULONG 00153 AttributeDataLength (PATTRIBUTE Attribute) 00154 { 00155 if (Attribute->Nonresident) 00156 { 00157 return ((PNONRESIDENT_ATTRIBUTE)Attribute)->DataSize; 00158 } 00159 00160 return ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength; 00161 } 00162 00163 00164 VOID 00165 ReadAttribute (PATTRIBUTE attr, 00166 PVOID buffer, 00167 PDEVICE_EXTENSION Vcb, 00168 PDEVICE_OBJECT DeviceObject) 00169 { 00170 PNONRESIDENT_ATTRIBUTE NresAttr = (PNONRESIDENT_ATTRIBUTE)attr; 00171 if (attr->Nonresident == FALSE) 00172 { 00173 memcpy (buffer, 00174 (PVOID)((ULONG_PTR)attr + ((PRESIDENT_ATTRIBUTE)attr)->ValueOffset), 00175 ((PRESIDENT_ATTRIBUTE)attr)->ValueLength); 00176 } 00177 00178 ReadExternalAttribute(Vcb, NresAttr, 0, (ULONG)(NresAttr->LastVcn) + 1, 00179 buffer); 00180 } 00181 00182 00183 00184 00185 00186 NTSTATUS 00187 ReadFileRecord (PDEVICE_EXTENSION Vcb, 00188 ULONG index, 00189 PFILE_RECORD_HEADER file, 00190 PFILE_RECORD_HEADER Mft) 00191 { 00192 PVOID p; 00193 ULONG BytesPerFileRecord = Vcb->NtfsInfo.BytesPerFileRecord; 00194 ULONG clusters = max(BytesPerFileRecord / Vcb->NtfsInfo.BytesPerCluster, 1); 00195 ULONGLONG vcn = index * BytesPerFileRecord / Vcb->NtfsInfo.BytesPerCluster; 00196 LONG m = (Vcb->NtfsInfo.BytesPerCluster / BytesPerFileRecord) - 1; 00197 ULONG n = m > 0 ? (index & m) : 0; 00198 00199 p = ExAllocatePoolWithTag(NonPagedPool, clusters * Vcb->NtfsInfo.BytesPerCluster, TAG_NTFS); 00200 00201 ReadVCN (Vcb, Mft, AttributeData, vcn, clusters, p); 00202 00203 memcpy(file, (PVOID)((ULONG_PTR)p + n * BytesPerFileRecord), BytesPerFileRecord); 00204 00205 ExFreePool(p); 00206 00207 FixupUpdateSequenceArray(file); 00208 00209 return STATUS_SUCCESS; 00210 } 00211 00212 00213 00214 VOID 00215 ReadExternalAttribute (PDEVICE_EXTENSION Vcb, 00216 PNONRESIDENT_ATTRIBUTE NresAttr, 00217 ULONGLONG vcn, 00218 ULONG count, 00219 PVOID buffer) 00220 { 00221 ULONGLONG lcn; 00222 ULONGLONG runcount; 00223 ULONG readcount; 00224 ULONG left; 00225 ULONG n; 00226 00227 PUCHAR bytes = (PUCHAR)buffer; 00228 00229 for (left = count; left>0; left -=readcount) 00230 { 00231 FindRun(NresAttr, vcn, &lcn, &runcount); 00232 00233 // readcount = (ULONG)(__min(runcount, left)); 00234 readcount = (ULONG)min (runcount, left); 00235 00236 00237 n = readcount * Vcb->NtfsInfo.BytesPerCluster; 00238 00239 if (lcn == 0) 00240 memset(bytes, 0, n); 00241 else 00242 ReadLCN(Vcb, lcn, readcount, bytes); 00243 00244 vcn += readcount; 00245 bytes += n; 00246 00247 00248 } 00249 } 00250 00251 00252 VOID 00253 ReadVCN (PDEVICE_EXTENSION Vcb, 00254 PFILE_RECORD_HEADER file, 00255 ATTRIBUTE_TYPE type, 00256 ULONGLONG vcn, 00257 ULONG count, 00258 PVOID buffer) 00259 { 00260 PNONRESIDENT_ATTRIBUTE NresAttr; 00261 PATTRIBUTE attr; 00262 00263 attr = FindAttribute(file, type, 0); 00264 00265 NresAttr = (PNONRESIDENT_ATTRIBUTE) attr; 00266 00267 if (NresAttr == 0 || (vcn < NresAttr->StartVcn ||vcn > NresAttr->LastVcn)) 00268 { 00269 // PATTRIBUTE attrList = FindAttribute(file,AttributeAttributeList,0); 00270 DbgPrint("Exeption \n"); 00271 // KeDebugCheck(0); 00272 } 00273 00274 ReadExternalAttribute(Vcb, NresAttr, vcn, count, buffer); 00275 } 00276 00277 00278 #if 0 00279 BOOL bitset(PUCHAR bitmap, ULONG i) 00280 { 00281 return (bitmap[i>>3] & (1 << (i & 7))) !=0; 00282 } 00283 #endif 00284 00285 00286 VOID FixupUpdateSequenceArray(PFILE_RECORD_HEADER file) 00287 { 00288 PUSHORT usa = (PUSHORT)((ULONG_PTR)file + file->Ntfs.UsaOffset); 00289 PUSHORT sector = (PUSHORT)file; 00290 ULONG i; 00291 00292 for( i =1; i < file->Ntfs.UsaCount; i++) 00293 { 00294 sector[255] = usa[i]; 00295 sector += 256; 00296 00297 } 00298 00299 } 00300 00301 00302 NTSTATUS 00303 ReadLCN (PDEVICE_EXTENSION Vcb, 00304 ULONGLONG lcn, 00305 ULONG count, 00306 PVOID buffer) 00307 { 00308 LARGE_INTEGER DiskSector; 00309 00310 DiskSector.QuadPart = lcn; 00311 00312 return NtfsReadSectors (Vcb->StorageDevice, 00313 DiskSector.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster, 00314 count * Vcb->NtfsInfo.SectorsPerCluster, 00315 Vcb->NtfsInfo.BytesPerSector, 00316 buffer, 00317 FALSE); 00318 } 00319 00320 /* EOF */ Generated on Sun May 27 2012 04:27:47 for ReactOS by
1.7.6.1
|