- Removed the using of the media change count to recognize a median change.
[reactos.git] / reactos / drivers / fs / vfat / vfat.h
1 /* $Id: vfat.h,v 1.65 2004/07/05 21:39:02 hbirr 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[448];
24 unsigned short 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[420]; // 90
52 unsigned short Signature1; // 510
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 #define ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5)
72 #define ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0)
73 #define ENTRY_LONG(DirEntry) (((DirEntry)->Attrib & 0x3f) == 0x0f)
74 #define ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
75
76 struct _FATDirEntry
77 {
78 unsigned char Filename[8], Ext[3];
79 unsigned char Attrib;
80 unsigned char lCase;
81 unsigned char CreationTimeMs;
82 unsigned short CreationTime,CreationDate,AccessDate;
83 unsigned short FirstClusterHigh; // higher
84 unsigned short UpdateTime; //time create/update
85 unsigned short UpdateDate; //date create/update
86 unsigned short FirstCluster;
87 unsigned long FileSize;
88 } __attribute__((packed));
89
90 typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
91
92 struct _slot
93 {
94 unsigned char id; // sequence number for slot
95 WCHAR name0_4[5]; // first 5 characters in name
96 unsigned char attr; // attribute byte
97 unsigned char reserved; // always 0
98 unsigned char alias_checksum; // checksum for 8.3 alias
99 WCHAR name5_10[6]; // 6 more characters in name
100 unsigned char start[2]; // starting cluster number
101 WCHAR name11_12[2]; // last 2 characters in name
102 } __attribute__((packed));
103
104
105 typedef struct _slot slot;
106
107 #define BLOCKSIZE 512
108
109 #define FAT16 (1)
110 #define FAT12 (2)
111 #define FAT32 (3)
112
113 #define VCB_VOLUME_LOCKED 0x0001
114 #define VCB_DISMOUNT_PENDING 0x0002
115
116 typedef struct
117 {
118 ULONG VolumeID;
119 ULONG FATStart;
120 ULONG FATCount;
121 ULONG FATSectors;
122 ULONG rootDirectorySectors;
123 ULONG rootStart;
124 ULONG dataStart;
125 ULONG RootCluster;
126 ULONG SectorsPerCluster;
127 ULONG BytesPerSector;
128 ULONG BytesPerCluster;
129 ULONG NumberOfClusters;
130 ULONG FatType;
131 ULONG Sectors;
132 BOOL FixedMedia;
133 } FATINFO, *PFATINFO;
134
135 struct _VFATFCB;
136
137 typedef struct _HASHENTRY
138 {
139 ULONG Hash;
140 struct _VFATFCB* self;
141 struct _HASHENTRY* next;
142 }
143 HASHENTRY;
144
145 #define FCB_HASH_TABLE_SIZE 1024
146
147 typedef struct
148 {
149 ERESOURCE DirResource;
150 ERESOURCE FatResource;
151
152 KSPIN_LOCK FcbListLock;
153 LIST_ENTRY FcbListHead;
154 struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE];
155
156 PDEVICE_OBJECT StorageDevice;
157 PFILE_OBJECT FATFileObject;
158 FATINFO FatInfo;
159 ULONG LastAvailableCluster;
160 ULONG AvailableClusters;
161 BOOLEAN AvailableClustersValid;
162 ULONG Flags;
163 struct _VFATFCB * VolumeFcb;
164
165 LIST_ENTRY VolumeListEntry;
166 } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
167
168 typedef struct
169 {
170 PDRIVER_OBJECT DriverObject;
171 PDEVICE_OBJECT DeviceObject;
172 ULONG Flags;
173 ERESOURCE VolumeListLock;
174 LIST_ENTRY VolumeListHead;
175 NPAGED_LOOKASIDE_LIST FcbLookasideList;
176 NPAGED_LOOKASIDE_LIST CcbLookasideList;
177 NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
178 } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
179
180 extern PVFAT_GLOBAL_DATA VfatGlobalData;
181
182 #define FCB_CACHE_INITIALIZED 0x0001
183 #define FCB_DELETE_PENDING 0x0002
184 #define FCB_IS_FAT 0x0004
185 #define FCB_IS_PAGE_FILE 0x0008
186 #define FCB_IS_VOLUME 0x0010
187 #define FCB_IS_DIRTY 0x0020
188
189 typedef struct _VFATFCB
190 {
191 /* FCB header required by ROS/NT */
192 FSRTL_COMMON_FCB_HEADER RFCB;
193 SECTION_OBJECT_POINTERS SectionObjectPointers;
194 ERESOURCE MainResource;
195 ERESOURCE PagingIoResource;
196 /* end FCB header required by ROS/NT */
197
198 /* directory entry for this file or directory */
199 FATDirEntry entry;
200
201 /* long file name, points into PathNameBuffer */
202 UNICODE_STRING LongNameU;
203
204 /* short file name */
205 UNICODE_STRING ShortNameU;
206
207 /* directory name, points into PathNameBuffer */
208 UNICODE_STRING DirNameU;
209
210 /* path + long file name 260 max*/
211 UNICODE_STRING PathNameU;
212
213 /* buffer for PathNameU */
214 WCHAR PathNameBuffer[MAX_PATH];
215
216 /* buffer for ShortNameU */
217 WCHAR ShortNameBuffer[13];
218
219 /* */
220 LONG RefCount;
221
222 /* List of FCB's for this volume */
223 LIST_ENTRY FcbListEntry;
224
225 /* pointer to the parent fcb */
226 struct _VFATFCB* parentFcb;
227
228 /* Flags for the fcb */
229 ULONG Flags;
230
231 /* pointer to the file object which has initialized the fcb */
232 PFILE_OBJECT FileObject;
233
234 /* Directory index for the short name entry */
235 ULONG dirIndex;
236
237 /* Directory index where the long name starts */
238 ULONG startIndex;
239
240 /* Share access for the file object */
241 SHARE_ACCESS FCBShareAccess;
242
243 /* Entry into the hash table for the path + long name */
244 HASHENTRY Hash;
245
246 /* Entry into the hash table for the path + short name */
247 HASHENTRY ShortHash;
248
249 /* List of byte-range locks for this file */
250 FILE_LOCK FileLock;
251
252 } VFATFCB, *PVFATFCB;
253
254 typedef struct _VFATCCB
255 {
256 LARGE_INTEGER CurrentByteOffset;
257 /* for DirectoryControl */
258 ULONG Entry;
259 /* for DirectoryControl */
260 UNICODE_STRING SearchPattern;
261 ULONG LastCluster;
262 ULONG LastOffset;
263
264 } VFATCCB, *PVFATCCB;
265
266 #ifndef TAG
267 #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
268 #endif
269
270 #define TAG_CCB TAG('V', 'C', 'C', 'B')
271 #define TAG_FCB TAG('V', 'F', 'C', 'B')
272 #define TAG_IRP TAG('V', 'I', 'R', 'P')
273
274 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
275
276 typedef struct __DOSTIME
277 {
278 WORD Second:5;
279 WORD Minute:6;
280 WORD Hour:5;
281 }
282 DOSTIME, *PDOSTIME;
283
284 typedef struct __DOSDATE
285 {
286 WORD Day:5;
287 WORD Month:4;
288 WORD Year:5;
289 }
290 DOSDATE, *PDOSDATE;
291
292 #define IRPCONTEXT_CANWAIT 0x0001
293 #define IRPCONTEXT_PENDINGRETURNED 0x0002
294
295 typedef struct
296 {
297 PIRP Irp;
298 PDEVICE_OBJECT DeviceObject;
299 PDEVICE_EXTENSION DeviceExt;
300 ULONG Flags;
301 WORK_QUEUE_ITEM WorkQueueItem;
302 PIO_STACK_LOCATION Stack;
303 UCHAR MajorFunction;
304 UCHAR MinorFunction;
305 PFILE_OBJECT FileObject;
306 ULONG RefCount;
307 KEVENT Event;
308 } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
309
310 typedef struct _VFAT_DIRENTRY_CONTEXT
311 {
312 ULONG StartIndex;
313 ULONG DirIndex;
314 FAT_DIR_ENTRY FatDirEntry;
315 UNICODE_STRING LongNameU;
316 UNICODE_STRING ShortNameU;
317 } VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
318
319
320 /* ------------------------------------------------------ shutdown.c */
321
322 NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject,
323 PIRP Irp);
324
325 /* -------------------------------------------------------- volume.c */
326
327 NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
328
329 NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
330
331 /* ------------------------------------------------------ blockdev.c */
332
333 NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject,
334 IN PLARGE_INTEGER ReadOffset,
335 IN ULONG ReadLength,
336 IN PUCHAR Buffer,
337 IN BOOLEAN Override);
338
339 NTSTATUS VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext,
340 IN PLARGE_INTEGER ReadOffset,
341 IN ULONG ReadLength,
342 IN ULONG BufferOffset,
343 IN BOOLEAN Wait);
344
345 NTSTATUS VfatWriteDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext,
346 IN PLARGE_INTEGER WriteOffset,
347 IN ULONG WriteLength,
348 IN ULONG BufferOffset,
349 IN BOOLEAN Wait);
350
351 NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
352 IN ULONG CtlCode,
353 IN PVOID InputBuffer,
354 IN ULONG InputBufferSize,
355 IN OUT PVOID OutputBuffer,
356 IN OUT PULONG pOutputBufferSize,
357 IN BOOLEAN Override);
358
359 /* ----------------------------------------------------------- dir.c */
360
361 NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
362
363 BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
364 WORD wDosTime,
365 TIME *FileTime);
366
367 BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
368 WORD *pwDosDate,
369 WORD *pwDosTime);
370
371 /* -------------------------------------------------------- create.c */
372
373 NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
374
375 NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
376 PFILE_OBJECT FileObject,
377 PUNICODE_STRING FileNameU);
378
379 NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
380 PVFATFCB Parent,
381 PUNICODE_STRING FileToFindU,
382 PVFAT_DIRENTRY_CONTEXT DirContext,
383 BOOLEAN First);
384
385 VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry,
386 PUNICODE_STRING NameU);
387
388 NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,
389 PVPB Vpb);
390
391 /* --------------------------------------------------------- close.c */
392
393 NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext);
394
395 NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt,
396 PFILE_OBJECT FileObject);
397
398 /* ------------------------------------------------------- cleanup.c */
399
400 NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext);
401
402 /* --------------------------------------------------------- fsctl.c */
403
404 NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext);
405
406 /* --------------------------------------------------------- finfo.c */
407
408 NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext);
409
410 NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
411
412 NTSTATUS
413 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
414 PVFATFCB Fcb,
415 PDEVICE_EXTENSION DeviceExt,
416 PLARGE_INTEGER AllocationSize);
417
418 /* --------------------------------------------------------- iface.c */
419
420 NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
421 PUNICODE_STRING RegistryPath);
422
423 /* --------------------------------------------------------- dirwr.c */
424
425 NTSTATUS VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
426 PUNICODE_STRING PathNameU,
427 PFILE_OBJECT pFileObject,
428 ULONG RequestedOptions,
429 UCHAR ReqAttr);
430
431 NTSTATUS VfatUpdateEntry (PVFATFCB pFcb);
432
433 NTSTATUS VfatDelEntry(PDEVICE_EXTENSION, PVFATFCB);
434
435 /* -------------------------------------------------------- string.c */
436
437 VOID
438 vfatSplitPathName(PUNICODE_STRING PathNameU,
439 PUNICODE_STRING DirNameU,
440 PUNICODE_STRING FileNameU);
441
442 BOOLEAN vfatIsLongIllegal(WCHAR c);
443
444 BOOLEAN wstrcmpjoki (PWSTR s1,
445 PWSTR s2);
446
447 /* ----------------------------------------------------------- fat.c */
448
449 NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
450 ULONG FirstCluster,
451 ULONG FileOffset,
452 PULONG Cluster,
453 BOOLEAN Extend);
454
455 ULONGLONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
456 ULONG Cluster);
457
458 NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt,
459 ULONG CurrentCluster,
460 PULONG NextCluster,
461 BOOLEAN Extend);
462
463 NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
464 PLARGE_INTEGER Clusters);
465
466 NTSTATUS
467 WriteCluster(PDEVICE_EXTENSION DeviceExt,
468 ULONG ClusterToWrite,
469 ULONG NewValue);
470
471 /* ------------------------------------------------------ direntry.c */
472
473 ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
474 PFAT_DIR_ENTRY pDirEntry);
475
476 BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb);
477
478 NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
479 PVOID * pPage,
480 IN PVFATFCB pDirFcb,
481 IN PVFAT_DIRENTRY_CONTEXT DirContext,
482 BOOLEAN First);
483
484 /* ----------------------------------------------------------- fcb.c */
485
486 PVFATFCB vfatNewFCB (PUNICODE_STRING pFileNameU);
487
488 VOID vfatDestroyFCB (PVFATFCB pFCB);
489
490 VOID vfatDestroyCCB(PVFATCCB pCcb);
491
492 VOID vfatGrabFCB (PDEVICE_EXTENSION pVCB,
493 PVFATFCB pFCB);
494
495 VOID vfatReleaseFCB (PDEVICE_EXTENSION pVCB,
496 PVFATFCB pFCB);
497
498 VOID vfatAddFCBToTable (PDEVICE_EXTENSION pVCB,
499 PVFATFCB pFCB);
500
501 PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt,
502 PUNICODE_STRING pFileNameU);
503
504 PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB);
505
506 PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
507
508 BOOL vfatFCBIsDirectory (PVFATFCB FCB);
509
510 BOOL vfatFCBIsRoot(PVFATFCB FCB);
511
512 NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
513 PVFATFCB fcb,
514 PFILE_OBJECT fileObject);
515
516 NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB,
517 PVFATFCB parentFCB,
518 PUNICODE_STRING FileToFindU,
519 PVFATFCB * fileFCB);
520
521 NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
522 PVFATFCB *pParentFCB,
523 PVFATFCB *pFCB,
524 PUNICODE_STRING pFileNameU);
525
526 NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb,
527 PVFATFCB directoryFCB,
528 PVFAT_DIRENTRY_CONTEXT DirContext,
529 PVFATFCB * fileFCB);
530
531 /* ------------------------------------------------------------ rw.c */
532
533 NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
534
535 NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
536
537 NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
538 ULONG FirstCluster,
539 PULONG CurrentCluster,
540 BOOLEAN Extend);
541
542 /* ----------------------------------------------------------- misc.c */
543
544 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
545
546 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
547 PIRP Irp);
548
549 VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
550
551 NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject,
552 PIRP Irp);
553
554 PVOID VfatGetUserBuffer(IN PIRP);
555
556 NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
557 IN LOCK_OPERATION);
558
559 NTSTATUS
560 VfatSetExtendedAttributes(PFILE_OBJECT FileObject,
561 PVOID Ea,
562 ULONG EaLength);
563 /* ------------------------------------------------------------- flush.c */
564
565 NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext);
566
567 NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb);
568
569
570 /* EOF */