2003-06-07 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / drivers / fs / vfat / vfat.h
1 /* $Id: vfat.h,v 1.58 2003/06/07 11:34:36 chorns Exp $ */
2
3 #include <ddk/ntifs.h>
4
5 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
6 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
7
8 struct _BootSector
9 {
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;
17 unsigned char Media;
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));
26
27 struct _BootSector32
28 {
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));
54
55 struct _FsInfoSector
56 {
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));
65
66 typedef struct _BootSector BootSector;
67
68 #define VFAT_CASE_LOWER_BASE 8 // base is lower case
69 #define VFAT_CASE_LOWER_EXT 16 // extension is lower case
70
71 struct _FATDirEntry
72 {
73 unsigned char Filename[8], Ext[3];
74 unsigned char Attrib;
75 unsigned char lCase;
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));
84
85 typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
86
87 struct _slot
88 {
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));
98
99
100 typedef struct _slot slot;
101
102 #define BLOCKSIZE 512
103
104 #define FAT16 (1)
105 #define FAT12 (2)
106 #define FAT32 (3)
107
108 #define VCB_VOLUME_LOCKED 0x0001
109 #define VCB_DISMOUNT_PENDING 0x0002
110
111 typedef struct
112 {
113 ULONG VolumeID;
114 ULONG FATStart;
115 ULONG FATCount;
116 ULONG FATSectors;
117 ULONG rootDirectorySectors;
118 ULONG rootStart;
119 ULONG dataStart;
120 ULONG RootCluster;
121 ULONG SectorsPerCluster;
122 ULONG BytesPerSector;
123 ULONG BytesPerCluster;
124 ULONG NumberOfClusters;
125 ULONG FatType;
126 ULONG Sectors;
127 } FATINFO, *PFATINFO;
128
129 struct _VFATFCB;
130
131 typedef struct _HASHENTRY
132 {
133 ULONG Hash;
134 struct _VFATFCB* self;
135 struct _HASHENTRY* next;
136 }
137 HASHENTRY;
138
139 #define FCB_HASH_TABLE_SIZE 1024
140
141 typedef struct
142 {
143 ERESOURCE DirResource;
144 ERESOURCE FatResource;
145
146 KSPIN_LOCK FcbListLock;
147 LIST_ENTRY FcbListHead;
148
149 PDEVICE_OBJECT StorageDevice;
150 PFILE_OBJECT FATFileObject;
151 FATINFO FatInfo;
152 ULONG LastAvailableCluster;
153 ULONG AvailableClusters;
154 BOOLEAN AvailableClustersValid;
155 ULONG Flags;
156 struct _VFATFCB * VolumeFcb;
157 struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE];
158
159 LIST_ENTRY VolumeListEntry;
160 } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
161
162 typedef struct
163 {
164 PDRIVER_OBJECT DriverObject;
165 PDEVICE_OBJECT DeviceObject;
166 ULONG Flags;
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;
173
174 extern PVFAT_GLOBAL_DATA VfatGlobalData;
175
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
181
182 typedef struct _VFATFCB
183 {
184 /* FCB header required by ROS/NT */
185 FSRTL_COMMON_FCB_HEADER RFCB;
186 SECTION_OBJECT_POINTERS SectionObjectPointers;
187 ERESOURCE MainResource;
188 ERESOURCE PagingIoResource;
189 /* end FCB header required by ROS/NT */
190
191 /* */
192 FATDirEntry entry;
193
194 /* point on filename (250 chars max) in PathName */
195 WCHAR *ObjectName;
196
197 /* path+filename 260 max */
198 WCHAR PathName[MAX_PATH];
199
200 /* short file name */
201 WCHAR ShortName[14];
202
203 /* */
204 LONG RefCount;
205
206 /* List of FCB's for this volume */
207 LIST_ENTRY FcbListEntry;
208
209 /* pointer to the parent fcb */
210 struct _VFATFCB* parentFcb;
211
212 /* Flags for the fcb */
213 ULONG Flags;
214
215 /* pointer to the file object which has initialized the fcb */
216 PFILE_OBJECT FileObject;
217
218 /* Directory index for the short name entry */
219 ULONG dirIndex;
220
221 /* Directory index where the long name starts */
222 ULONG startIndex;
223
224 /* Share access for the file object */
225 SHARE_ACCESS FCBShareAccess;
226
227 /* Entry into the hash table for the path + long name */
228 HASHENTRY Hash;
229
230 /* Entry into the hash table for the path + short name */
231 HASHENTRY ShortHash;
232
233 /* List of byte-range locks for this file */
234 FILE_LOCK FileLock;
235
236 } VFATFCB, *PVFATFCB;
237
238 typedef struct _VFATCCB
239 {
240 LARGE_INTEGER CurrentByteOffset;
241 /* for DirectoryControl */
242 ULONG Entry;
243 /* for DirectoryControl */
244 PWCHAR DirectorySearchPattern;
245 ULONG LastCluster;
246 ULONG LastOffset;
247
248 } VFATCCB, *PVFATCCB;
249
250 #ifndef TAG
251 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
252 #endif
253
254 #define TAG_CCB TAG('V', 'C', 'C', 'B')
255 #define TAG_FCB TAG('V', 'F', 'C', 'B')
256 #define TAG_IRP TAG('V', 'I', 'R', 'P')
257
258 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
259
260 typedef struct __DOSTIME
261 {
262 WORD Second:5;
263 WORD Minute:6;
264 WORD Hour:5;
265 }
266 DOSTIME, *PDOSTIME;
267
268 typedef struct __DOSDATE
269 {
270 WORD Day:5;
271 WORD Month:4;
272 WORD Year:5;
273 }
274 DOSDATE, *PDOSDATE;
275
276 #define IRPCONTEXT_CANWAIT 0x0001
277
278 typedef struct
279 {
280 PIRP Irp;
281 PDEVICE_OBJECT DeviceObject;
282 PDEVICE_EXTENSION DeviceExt;
283 ULONG Flags;
284 WORK_QUEUE_ITEM WorkQueueItem;
285 PIO_STACK_LOCATION Stack;
286 UCHAR MajorFunction;
287 UCHAR MinorFunction;
288 PFILE_OBJECT FileObject;
289 } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
290
291 /* ------------------------------------------------------ shutdown.c */
292
293 NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject,
294 PIRP Irp);
295
296 /* -------------------------------------------------------- volume.c */
297
298 NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
299
300 NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
301
302 /* ------------------------------------------------------ blockdev.c */
303
304 NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject,
305 IN PLARGE_INTEGER ReadOffset,
306 IN ULONG ReadLength,
307 IN PUCHAR Buffer);
308
309 NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject,
310 IN PLARGE_INTEGER WriteOffset,
311 IN ULONG WriteLength,
312 IN PUCHAR Buffer);
313
314 NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
315 IN ULONG CtlCode,
316 IN PVOID InputBuffer,
317 IN ULONG InputBufferSize,
318 IN OUT PVOID OutputBuffer,
319 IN OUT PULONG pOutputBufferSize);
320
321 /* ----------------------------------------------------------- dir.c */
322
323 NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
324
325 BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
326 WORD wDosTime,
327 TIME *FileTime);
328
329 BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
330 WORD *pwDosDate,
331 WORD *pwDosTime);
332
333 /* -------------------------------------------------------- create.c */
334
335 NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
336
337 NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
338 PFILE_OBJECT FileObject,
339 PWSTR FileName);
340
341 NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
342 PVFATFCB Fcb,
343 PVFATFCB Parent,
344 PWSTR FileToFind,
345 PULONG pDirIndex,
346 PULONG pDirIndex2);
347
348 VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry,
349 PWSTR pName);
350
351 NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,
352 PVPB Vpb);
353
354 BOOLEAN IsDeletedEntry (PVOID Block,
355 ULONG Offset);
356
357 BOOLEAN IsLastEntry (PVOID Block,
358 ULONG Offset);
359
360 /* --------------------------------------------------------- close.c */
361
362 NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext);
363
364 NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt,
365 PFILE_OBJECT FileObject);
366
367 /* ------------------------------------------------------- cleanup.c */
368
369 NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext);
370
371 /* --------------------------------------------------------- fsctl.c */
372
373 NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext);
374
375 /* --------------------------------------------------------- finfo.c */
376
377 NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext);
378
379 NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
380
381 NTSTATUS
382 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
383 PVFATFCB Fcb,
384 PDEVICE_EXTENSION DeviceExt,
385 PLARGE_INTEGER AllocationSize);
386
387 /* --------------------------------------------------------- iface.c */
388
389 NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
390 PUNICODE_STRING RegistryPath);
391
392 /* --------------------------------------------------------- dirwr.c */
393
394 NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
395 PFILE_OBJECT pFileObject,
396 ULONG RequestedOptions,UCHAR ReqAttr);
397
398 NTSTATUS VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt,
399 PFILE_OBJECT pFileObject);
400
401 NTSTATUS delEntry(PDEVICE_EXTENSION,
402 PFILE_OBJECT);
403
404 /* -------------------------------------------------------- string.c */
405
406 BOOLEAN wstrcmpjoki (PWSTR s1,
407 PWSTR s2);
408
409 PWCHAR vfatGetNextPathElement (PWCHAR pFileName);
410
411 VOID vfatWSubString (PWCHAR pTarget,
412 const PWCHAR pSource,
413 size_t pLength);
414
415 BOOL vfatIsFileNameValid (PWCHAR pFileName);
416
417 /* ----------------------------------------------------------- fat.c */
418
419 NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
420 ULONG FirstCluster,
421 ULONG FileOffset,
422 PULONG Cluster,
423 BOOLEAN Extend);
424
425 ULONGLONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
426 ULONG Cluster);
427
428 NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt,
429 ULONG CurrentCluster,
430 PULONG NextCluster,
431 BOOLEAN Extend);
432
433 NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
434 PLARGE_INTEGER Clusters);
435
436 /* ------------------------------------------------------ direntry.c */
437
438 ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
439 PFAT_DIR_ENTRY pDirEntry);
440
441 BOOL vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
442
443 BOOL vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry);
444
445 BOOL vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
446
447 VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,
448 PWSTR pEntryName);
449
450 NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
451 PVOID * pPage,
452 IN PVFATFCB pDirFcb,
453 IN OUT PULONG pDirIndex,
454 OUT PWSTR pFileName,
455 OUT PFAT_DIR_ENTRY pDirEntry,
456 OUT PULONG pStartIndex);
457
458 /* ----------------------------------------------------------- fcb.c */
459
460 PVFATFCB vfatNewFCB (PWCHAR pFileName);
461
462 VOID vfatDestroyFCB (PVFATFCB pFCB);
463
464 VOID vfatGrabFCB (PDEVICE_EXTENSION pVCB,
465 PVFATFCB pFCB);
466
467 VOID vfatReleaseFCB (PDEVICE_EXTENSION pVCB,
468 PVFATFCB pFCB);
469
470 VOID vfatAddFCBToTable (PDEVICE_EXTENSION pVCB,
471 PVFATFCB pFCB);
472
473 PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt,
474 PWSTR pFileName);
475
476 PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB);
477
478 PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
479
480 BOOL vfatFCBIsDirectory (PVFATFCB FCB);
481
482 NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
483 PVFATFCB fcb,
484 PFILE_OBJECT fileObject);
485
486 NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB,
487 PVFATFCB parentFCB,
488 PWSTR elementName,
489 PVFATFCB * fileFCB);
490
491 NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
492 PVFATFCB *pParentFCB,
493 PVFATFCB *pFCB,
494 const PWSTR pFileName);
495
496 NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb,
497 PVFATFCB directoryFCB,
498 PWSTR longName,
499 PFAT_DIR_ENTRY dirEntry,
500 ULONG startIndex,
501 ULONG dirIndex,
502 PVFATFCB * fileFCB);
503
504 /* ------------------------------------------------------------ rw.c */
505
506 NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
507
508 NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
509
510 NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
511 ULONG FirstCluster,
512 PULONG CurrentCluster,
513 BOOLEAN Extend);
514
515 /* ----------------------------------------------------------- misc.c */
516
517 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
518
519 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
520 PIRP Irp);
521
522 VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
523
524 NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject,
525 PIRP Irp);
526
527 PVOID VfatGetUserBuffer(IN PIRP);
528
529 NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
530 IN LOCK_OPERATION);
531
532 NTSTATUS
533 VfatSetExtendedAttributes(PFILE_OBJECT FileObject,
534 PVOID Ea,
535 ULONG EaLength);
536 /* ------------------------------------------------------------- flush.c */
537
538 NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext);
539
540 NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb);
541
542 /* EOF */