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

fat.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS FAT file system driver
00003  * LICENSE:         GNU GPLv3 as published by the Free Software Foundation
00004  * FILE:            drivers/filesystems/fastfat/fat.c
00005  * PURPOSE:         FAT support routines
00006  * PROGRAMMERS:     Aleksey Bragin <aleksey@reactos.org>
00007  */
00008 
00009 /* INCLUDES *****************************************************************/
00010 
00011 #define NDEBUG
00012 #include "fastfat.h"
00013 
00014 /* PROTOTYPES ***************************************************************/
00015 
00016 BOOLEAN
00017 NTAPI
00018 FatValidBpb(IN PBIOS_PARAMETER_BLOCK Bpb);
00019 
00020 /* VARIABLES ****************************************************************/
00021 
00022 BOOLEAN
00023 NTAPI
00024 FatValidBpb(IN PBIOS_PARAMETER_BLOCK Bpb)
00025 {
00026     return (FatValidBytesPerSector(Bpb->BytesPerSector)
00027         && FatValidSectorsPerCluster(Bpb->SectorsPerCluster)
00028         && Bpb->ReservedSectors > 0
00029         && Bpb->Fats > 0
00030         && (Bpb->Sectors > 0 || Bpb->LargeSectors > 0)
00031         && (Bpb->SectorsPerFat > 0
00032             || (Bpb->LargeSectorsPerFat > 0 && Bpb->FsVersion == 0))
00033         && (Bpb->Media == 0xf0
00034             || Bpb->Media == 0xf8
00035             || Bpb->Media == 0xf9
00036             || Bpb->Media == 0xfb
00037             || Bpb->Media == 0xfc
00038             || Bpb->Media == 0xfd
00039             || Bpb->Media == 0xfe
00040             || Bpb->Media == 0xff)
00041         && (Bpb->SectorsPerFat == 0 || Bpb->RootEntries > 0)
00042         && (Bpb->SectorsPerFat > 0 || !Bpb->MirrorDisabled));
00043 }
00044 
00054 FORCEINLINE
00055 ULONG
00056 FatPowerOfTwo(
00057     ULONG Number)
00058 {
00059     ULONG Temp;
00060     Temp = Number
00061         - ((Number >> 1) & 033333333333)
00062         - ((Number >> 2) & 011111111111);
00063     return (((Temp + (Temp >> 3)) & 030707070707) % 63);
00064 }
00065 
00066 VOID
00067 NTAPI
00068 FatiInitializeVcb(PVCB Vcb)
00069 {
00070     ULONG ClustersCapacity;
00071 
00072     /* Various characteristics needed for navigation in FAT */
00073     if ((Vcb->Sectors = Vcb->Bpb.Sectors) == 0)
00074         Vcb->Sectors = Vcb->Bpb.LargeSectors;
00075     if ((Vcb->SectorsPerFat = Vcb->Bpb.SectorsPerFat) == 0)
00076         Vcb->SectorsPerFat = Vcb->Bpb.LargeSectorsPerFat;
00077     Vcb->RootDirent = Vcb->Bpb.ReservedSectors + Vcb->Bpb.Fats * Vcb->SectorsPerFat;
00078     Vcb->RootDirentSectors = BytesToSectors(Vcb,
00079         Vcb->Bpb.RootEntries * sizeof(DIR_ENTRY));
00080     Vcb->DataArea = Vcb->RootDirent + Vcb->RootDirentSectors;
00081     Vcb->Clusters = (Vcb->Sectors - Vcb->Bpb.ReservedSectors
00082         - Vcb->Bpb.Fats * Vcb->SectorsPerFat
00083         - Vcb->RootDirentSectors) / Vcb->Bpb.SectorsPerCluster;
00084     if (Vcb->BytesPerClusterLog < 4087)
00085     {
00086         Vcb->IndexDepth = 0x0c;
00087         //Vcb->Methods = Fat12Methods;
00088     }
00089     else
00090     {
00091         Vcb->IndexDepth = 0x10;
00092         //Vcb->Methods = Fat16Methods;
00093     }
00094     /* Large Sectors are used for FAT32 */
00095     if (Vcb->Bpb.Sectors == 0) {
00096         Vcb->IndexDepth = 0x20;
00097         //Vcb->Methods = Fat32Methods;
00098     }
00099     ClustersCapacity = (SectorsToBytes(Vcb, Vcb->Sectors) * 0x8 / Vcb->IndexDepth) - 1;
00100     if (Vcb->Clusters > ClustersCapacity)
00101         Vcb->Clusters = ClustersCapacity;
00102     Vcb->BytesPerCluster = SectorsToBytes(Vcb, Vcb->Bpb.SectorsPerCluster);
00103     Vcb->BytesPerClusterLog = FatPowerOfTwo(Vcb->BytesPerCluster);
00104     Vcb->BeyondLastClusterInFat = ((LONGLONG) Vcb->Clusters) * Vcb->IndexDepth / 0x8;
00105 
00106     /* Update real volume size with the real value. */
00107     Vcb->Header.FileSize.QuadPart =
00108     Vcb->Header.AllocationSize.QuadPart = SectorsToBytes(Vcb, Vcb->Sectors);
00109 }
00110 
00111 NTSTATUS
00112 NTAPI
00113 FatInitializeVcb(IN PFAT_IRP_CONTEXT IrpContext,
00114                  IN PVCB Vcb,
00115                  IN PDEVICE_OBJECT TargetDeviceObject,
00116                  IN PVPB Vpb)
00117 {
00118     NTSTATUS Status;
00119     PBCB Bcb;
00120     PVOID Buffer;
00121     LARGE_INTEGER Offset;
00122 
00123     RtlZeroMemory(Vcb, sizeof(*Vcb));
00124 
00125     /* Initialize list head, so that it will
00126      * not fail in cleanup.
00127      */
00128     InitializeListHead(&Vcb->VcbLinks);
00129 
00130     /* Setup FCB Header */
00131     Vcb->Header.NodeTypeCode = FAT_NTC_VCB;
00132     Vcb->Header.NodeByteSize = sizeof(*Vcb);
00133 
00134     /* Setup Vcb fields */
00135     Vcb->TargetDeviceObject = TargetDeviceObject;
00136     ObReferenceObject(TargetDeviceObject);
00137     Vcb->Vpb = Vpb;
00138 
00139     /* Setup FCB Header */
00140     ExInitializeFastMutex(&Vcb->HeaderMutex);
00141     FsRtlSetupAdvancedHeader(&Vcb->Header, &Vcb->HeaderMutex);
00142 
00143     /* Create Volume File Object */
00144     Vcb->StreamFileObject = IoCreateStreamFileObject(NULL,
00145                                                      Vcb->TargetDeviceObject);
00146 
00147     /* We have to setup all FCB fields needed for CC */
00148     Vcb->StreamFileObject->FsContext = Vcb;
00149     Vcb->StreamFileObject->SectionObjectPointer = &Vcb->SectionObjectPointers;
00150 
00151     /* At least full boot sector should be available */
00152     //Vcb->Header.FileSize.QuadPart = sizeof(PACKED_BOOT_SECTOR);
00153     //Vcb->Header.AllocationSize.QuadPart = sizeof(PACKED_BOOT_SECTOR);
00154     Vcb->Header.ValidDataLength.HighPart = MAXLONG;
00155     Vcb->Header.ValidDataLength.LowPart = MAXULONG;
00156 
00157     Vcb->Header.AllocationSize.QuadPart = Int32x32To64(5*1024, 1024*1024); //HACK: 5 Gb
00158     Vcb->Header.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart;
00159 
00160     /* Set VCB to a good condition */
00161     Vcb->Condition = VcbGood;
00162 
00163     /* Initialize VCB's resource */
00164     ExInitializeResourceLite(&Vcb->Resource);
00165 
00166     /* Initialize close queue lists */
00167     InitializeListHead(&Vcb->AsyncCloseList);
00168     InitializeListHead(&Vcb->DelayedCloseList);
00169 
00170     /* Initialize CC */
00171     CcInitializeCacheMap(Vcb->StreamFileObject,
00172                          (PCC_FILE_SIZES)&Vcb->Header.AllocationSize,
00173                          FALSE,
00174                          &FatGlobalData.CacheMgrNoopCallbacks,
00175                          Vcb);
00176 
00177     /* Read boot sector */
00178     Offset.QuadPart = 0;
00179     Bcb = NULL;
00180 
00181     /* Note: Volume Read path does not require
00182      * any of the parameters set further
00183      * in this routine.
00184      */
00185     if (CcMapData(Vcb->StreamFileObject,
00186                   &Offset,
00187                   sizeof(PACKED_BOOT_SECTOR),
00188                   TRUE,
00189                   &Bcb,
00190                   &Buffer))
00191     {
00192         PPACKED_BOOT_SECTOR BootSector = (PPACKED_BOOT_SECTOR) Buffer;
00193         FatUnpackBios(&Vcb->Bpb, &BootSector->PackedBpb);
00194         if (!(FatBootSectorJumpValid(BootSector->Jump) &&
00195             FatValidBpb(&Vcb->Bpb)))
00196         {
00197             Status = STATUS_UNRECOGNIZED_VOLUME;
00198         }
00199         CopyUchar4(&Vcb->Vpb->SerialNumber, BootSector->Id);
00200         CcUnpinData(Bcb);
00201     }
00202     else
00203     {
00204         Status = STATUS_UNRECOGNIZED_VOLUME;
00205         goto FatInitializeVcbCleanup;
00206     }
00207 
00208     /* Increase internal / residual open counter */
00209     InterlockedIncrement((PLONG)&(Vcb->InternalOpenCount));
00210     InterlockedIncrement((PLONG)&(Vcb->ResidualOpenCount));
00211 
00212     /* Set up notifications */
00213     FsRtlNotifyInitializeSync(&Vcb->NotifySync);
00214     InitializeListHead(&Vcb->NotifyList);
00215 
00216     /* Call helper function */
00217     FatiInitializeVcb(Vcb);
00218 
00219     /* Add this Vcb to global Vcb list */
00220     (VOID)FatAcquireExclusiveGlobal(IrpContext);
00221     InsertTailList(&FatGlobalData.VcbListHead, &Vcb->VcbLinks);
00222     FatReleaseGlobal(IrpContext);
00223 
00224     return STATUS_SUCCESS;
00225 
00226 FatInitializeVcbCleanup:
00227 
00228     /* Unwind the routine actions */
00229     FatUninitializeVcb(Vcb);
00230     return Status;
00231 }
00232 
00233 VOID
00234 NTAPI
00235 FatUninitializeVcb(IN PVCB Vcb)
00236 {
00237     LARGE_INTEGER ZeroSize;
00238 
00239     ZeroSize.QuadPart = 0LL;
00240 
00241     /* Close volume file */
00242     if (Vcb->StreamFileObject != NULL)
00243     {
00244         /* Uninitialize CC. */
00245         CcUninitializeCacheMap(Vcb->StreamFileObject, &ZeroSize, NULL);
00246         ObDereferenceObject(Vcb->StreamFileObject);
00247         Vcb->StreamFileObject = NULL;
00248     }
00249 
00250     /* Free ContextClose if it's not freed up already */
00251     if (Vcb->CloseContext) ExFreePool(Vcb->CloseContext);
00252 
00253     /* Free notifications stuff */
00254     FsRtlNotifyUninitializeSync(&Vcb->NotifySync);
00255 
00256     /* Unlink from global Vcb list. */
00257     RemoveEntryList(&Vcb->VcbLinks);
00258 
00259     /* Release Target Device */
00260     ObDereferenceObject(Vcb->TargetDeviceObject);
00261     Vcb->TargetDeviceObject = NULL;
00262 }
00263 
00264 /* EOF */
00265 
00266 

Generated on Sat May 26 2012 04:17:57 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.