Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfat.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
1.7.6.1
|