ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mft.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.