5 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
6 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
10 unsigned char magic0, res0, magic1;
11 unsigned char OEMName[8];
12 unsigned short BytesPerSector;
13 unsigned char SectorsPerCluster;
14 unsigned short ReservedSectors;
15 unsigned char FATCount;
16 unsigned short RootEntries, Sectors;
18 unsigned short FATSectors, SectorsPerTrack, Heads;
19 unsigned long HiddenSectors, SectorsHuge;
20 unsigned char Drive, Res1, Sig;
21 unsigned long VolumeID;
22 unsigned char VolumeLabel[11], SysType[8];
23 unsigned char Res2[446];
24 unsigned long Signatur1;
25 } __attribute__((packed));
29 unsigned char magic0, res0, magic1; // 0
30 unsigned char OEMName[8]; // 3
31 unsigned short BytesPerSector; // 11
32 unsigned char SectorsPerCluster; // 13
33 unsigned short ReservedSectors; // 14
34 unsigned char FATCount; // 16
35 unsigned short RootEntries, Sectors; // 17
36 unsigned char Media; // 21
37 unsigned short FATSectors, SectorsPerTrack, Heads; // 22
38 unsigned long HiddenSectors, SectorsHuge; // 28
39 unsigned long FATSectors32; // 36
40 unsigned short ExtFlag; // 40
41 unsigned short FSVersion; // 42
42 unsigned long RootCluster; // 44
43 unsigned short FSInfoSector; // 48
44 unsigned short BootBackup; // 50
45 unsigned char Res3[12]; // 52
46 unsigned char Drive; // 64
47 unsigned char Res4; // 65
48 unsigned char ExtBootSignature; // 66
49 unsigned long VolumeID; // 67
50 unsigned char VolumeLabel[11], SysType[8]; // 71
51 unsigned char Res2[418]; // 90
52 unsigned long Signature1; // 508
53 } __attribute__((packed));
57 unsigned long ExtBootSignature2; // 0
58 unsigned char Res6[480]; // 4
59 unsigned long FSINFOSignature; // 484
60 unsigned long FreeCluster; // 488
61 unsigned long NextCluster; // 492
62 unsigned char Res7[12]; // 496
63 unsigned long Signatur2; // 508
64 } __attribute__((packed));
66 typedef struct _BootSector BootSector;
68 #define VFAT_CASE_LOWER_BASE 8 // base is lower case
69 #define VFAT_CASE_LOWER_EXT 16 // extension is lower case
73 unsigned char Filename[8], Ext[3];
76 unsigned char CreationTimeMs;
77 unsigned short CreationTime,CreationDate,AccessDate;
78 unsigned short FirstClusterHigh; // higher
79 unsigned short UpdateTime; //time create/update
80 unsigned short UpdateDate; //date create/update
81 unsigned short FirstCluster;
82 unsigned long FileSize;
83 } __attribute__((packed));
85 typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
89 unsigned char id; // sequence number for slot
90 WCHAR name0_4[5]; // first 5 characters in name
91 unsigned char attr; // attribute byte
92 unsigned char reserved; // always 0
93 unsigned char alias_checksum; // checksum for 8.3 alias
94 WCHAR name5_10[6]; // 6 more characters in name
95 unsigned char start[2]; // starting cluster number
96 WCHAR name11_12[2]; // last 2 characters in name
97 } __attribute__((packed));
100 typedef struct _slot slot;
102 #define BLOCKSIZE 512
108 #define VCB_VOLUME_LOCKED 0x0001
109 #define VCB_DISMOUNT_PENDING 0x0002
117 ULONG rootDirectorySectors;
121 ULONG SectorsPerCluster;
122 ULONG BytesPerSector;
123 ULONG BytesPerCluster;
124 ULONG NumberOfClusters;
127 } FATINFO, *PFATINFO;
131 typedef struct _HASHENTRY
134 struct _VFATFCB* self;
135 struct _HASHENTRY* next;
139 #define FCB_HASH_TABLE_SIZE 1024
143 ERESOURCE DirResource;
144 ERESOURCE FatResource;
146 KSPIN_LOCK FcbListLock;
147 LIST_ENTRY FcbListHead;
149 PDEVICE_OBJECT StorageDevice;
150 PFILE_OBJECT FATFileObject;
152 ULONG LastAvailableCluster;
153 ULONG AvailableClusters;
154 BOOLEAN AvailableClustersValid;
156 struct _VFATFCB * VolumeFcb;
157 struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE];
159 LIST_ENTRY VolumeListEntry;
160 } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
164 PDRIVER_OBJECT DriverObject;
165 PDEVICE_OBJECT DeviceObject;
167 ERESOURCE VolumeListLock;
168 LIST_ENTRY VolumeListHead;
169 NPAGED_LOOKASIDE_LIST FcbLookasideList;
170 NPAGED_LOOKASIDE_LIST CcbLookasideList;
171 NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
172 } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
174 extern PVFAT_GLOBAL_DATA VfatGlobalData;
176 #define FCB_CACHE_INITIALIZED 0x0001
177 #define FCB_DELETE_PENDING 0x0002
178 #define FCB_IS_FAT 0x0004
179 #define FCB_IS_PAGE_FILE 0x0008
180 #define FCB_IS_VOLUME 0x0010
182 typedef struct _VFATFCB
184 REACTOS_COMMON_FCB_HEADER RFCB;
185 SECTION_OBJECT_POINTERS SectionObjectPointers;
187 /* point on filename (250 chars max) in PathName */
189 /* path+filename 260 max */
190 WCHAR PathName[MAX_PATH];
193 PDEVICE_EXTENSION pDevExt;
194 LIST_ENTRY FcbListEntry;
195 struct _VFATFCB* parentFcb;
197 PFILE_OBJECT FileObject;
200 ERESOURCE PagingIoResource;
201 ERESOURCE MainResource;
203 SHARE_ACCESS FCBShareAccess;
208 /* Structure members used only for paging files. */
211 } VFATFCB, *PVFATFCB;
213 typedef struct _VFATCCB
217 PFILE_OBJECT PtrFileObject;
218 LARGE_INTEGER CurrentByteOffset;
219 /* for DirectoryControl */
221 /* for DirectoryControl */
222 PWCHAR DirectorySearchPattern;
226 } VFATCCB, *PVFATCCB;
229 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
232 #define TAG_CCB TAG('V', 'C', 'C', 'B')
233 #define TAG_FCB TAG('V', 'F', 'C', 'B')
234 #define TAG_IRP TAG('V', 'I', 'R', 'P')
236 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
238 typedef struct __DOSTIME
246 typedef struct __DOSDATE
254 #define IRPCONTEXT_CANWAIT 0x0001
259 PDEVICE_OBJECT DeviceObject;
260 PDEVICE_EXTENSION DeviceExt;
262 WORK_QUEUE_ITEM WorkQueueItem;
263 PIO_STACK_LOCATION Stack;
266 PFILE_OBJECT FileObject;
267 } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
269 /* ------------------------------------------------------ shutdown.c */
271 NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject,
274 /* -------------------------------------------------------- volume.c */
276 NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
278 NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
280 /* ------------------------------------------------------ blockdev.c */
282 NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject,
283 IN PLARGE_INTEGER ReadOffset,
287 NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject,
288 IN PLARGE_INTEGER WriteOffset,
289 IN ULONG WriteLength,
292 NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
294 IN PVOID InputBuffer,
295 IN ULONG InputBufferSize,
296 IN OUT PVOID OutputBuffer,
297 IN OUT PULONG pOutputBufferSize);
299 /* ----------------------------------------------------------- dir.c */
301 NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
303 BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
307 BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
311 /* -------------------------------------------------------- create.c */
313 NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
315 NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
316 PFILE_OBJECT FileObject,
319 NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
326 VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry,
329 NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,
332 BOOLEAN IsDeletedEntry (PVOID Block,
335 BOOLEAN IsLastEntry (PVOID Block,
338 /* --------------------------------------------------------- close.c */
340 NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext);
342 NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt,
343 PFILE_OBJECT FileObject);
345 /* ------------------------------------------------------- cleanup.c */
347 NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext);
349 /* --------------------------------------------------------- fsctl.c */
351 NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext);
353 /* --------------------------------------------------------- finfo.c */
355 NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext);
357 NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
360 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
362 PDEVICE_EXTENSION DeviceExt,
363 PLARGE_INTEGER AllocationSize);
365 /* --------------------------------------------------------- iface.c */
367 NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
368 PUNICODE_STRING RegistryPath);
370 /* --------------------------------------------------------- dirwr.c */
372 NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
373 PFILE_OBJECT pFileObject,
374 ULONG RequestedOptions,UCHAR ReqAttr);
376 NTSTATUS VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt,
377 PFILE_OBJECT pFileObject);
379 NTSTATUS delEntry(PDEVICE_EXTENSION,
382 /* -------------------------------------------------------- string.c */
384 BOOLEAN wstrcmpjoki (PWSTR s1,
387 PWCHAR vfatGetNextPathElement (PWCHAR pFileName);
389 VOID vfatWSubString (PWCHAR pTarget,
390 const PWCHAR pSource,
393 BOOL vfatIsFileNameValid (PWCHAR pFileName);
395 /* ----------------------------------------------------------- fat.c */
397 NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
404 ULONGLONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
407 NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt,
408 ULONG CurrentCluster,
412 NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
413 PLARGE_INTEGER Clusters);
415 /* ------------------------------------------------------ direntry.c */
417 ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
418 PFAT_DIR_ENTRY pDirEntry);
420 BOOL vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
422 BOOL vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry);
424 BOOL vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
426 VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,
429 NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
432 IN OUT PULONG pDirIndex,
434 OUT PFAT_DIR_ENTRY pDirEntry,
435 OUT PULONG pStartIndex);
437 /* ----------------------------------------------------------- fcb.c */
439 PVFATFCB vfatNewFCB (PWCHAR pFileName);
441 VOID vfatDestroyFCB (PVFATFCB pFCB);
443 VOID vfatGrabFCB (PDEVICE_EXTENSION pVCB,
446 VOID vfatReleaseFCB (PDEVICE_EXTENSION pVCB,
449 VOID vfatAddFCBToTable (PDEVICE_EXTENSION pVCB,
452 PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt,
455 PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB);
457 PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
459 BOOL vfatFCBIsDirectory (PVFATFCB FCB);
461 NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
463 PFILE_OBJECT fileObject);
465 NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB,
470 NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
471 PVFATFCB *pParentFCB,
473 const PWSTR pFileName);
475 NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb,
476 PVFATFCB directoryFCB,
478 PFAT_DIR_ENTRY dirEntry,
483 /* ------------------------------------------------------------ rw.c */
485 NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
487 NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
489 NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
492 PULONG CurrentCluster,
495 /* ----------------------------------------------------------- misc.c */
497 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
499 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
502 VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
504 NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject,
507 PVOID VfatGetUserBuffer(IN PIRP);
509 NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
513 VfatSetExtendedAttributes(PFILE_OBJECT FileObject,
516 /* ------------------------------------------------------------- flush.c */
518 NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext);
520 NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb);