77b2998dadeb228559d5806e2b4cd097db7c825f
[reactos.git] / drivers / filesystems / fastfat / vfat.h
1 #ifndef _FASTFAT_PCH_
2 #define _FASTFAT_PCH_
3
4 #include <ntifs.h>
5 #include <ntdddisk.h>
6 #include <dos.h>
7 #include <pseh/pseh2.h>
8 #ifdef KDBG
9 #include <ndk/kdfuncs.h>
10 #include <reactos/kdros.h>
11 #endif
12
13 #ifdef __GNUC__
14 #define INIT_SECTION __attribute__((section ("INIT")))
15 #else
16 #define INIT_SECTION /* Done via alloc_text for MSC */
17 #endif
18
19
20 #define USE_ROS_CC_AND_FS
21 #define ENABLE_SWAPOUT
22
23 /* FIXME: because volume is not cached, we have to perform direct IOs
24 * The day this is fixed, just comment out that line, and check
25 * it still works (and delete old code ;-))
26 */
27 #define VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
28
29
30 #define ROUND_DOWN(n, align) \
31 (((ULONG)n) & ~((align) - 1l))
32
33 #define ROUND_UP(n, align) \
34 ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
35
36 #define ROUND_DOWN_64(n, align) \
37 (((ULONGLONG)n) & ~((align) - 1LL))
38
39 #define ROUND_UP_64(n, align) \
40 ROUND_DOWN_64(((ULONGLONG)n) + (align) - 1LL, (align))
41
42 #include <pshpack1.h>
43 struct _BootSector
44 {
45 unsigned char magic0, res0, magic1;
46 unsigned char OEMName[8];
47 unsigned short BytesPerSector;
48 unsigned char SectorsPerCluster;
49 unsigned short ReservedSectors;
50 unsigned char FATCount;
51 unsigned short RootEntries, Sectors;
52 unsigned char Media;
53 unsigned short FATSectors, SectorsPerTrack, Heads;
54 unsigned long HiddenSectors, SectorsHuge;
55 unsigned char Drive, Res1, Sig;
56 unsigned long VolumeID;
57 unsigned char VolumeLabel[11], SysType[8];
58 unsigned char Res2[448];
59 unsigned short Signatur1;
60 };
61
62 struct _BootSector32
63 {
64 unsigned char magic0, res0, magic1; // 0
65 unsigned char OEMName[8]; // 3
66 unsigned short BytesPerSector; // 11
67 unsigned char SectorsPerCluster; // 13
68 unsigned short ReservedSectors; // 14
69 unsigned char FATCount; // 16
70 unsigned short RootEntries, Sectors; // 17
71 unsigned char Media; // 21
72 unsigned short FATSectors, SectorsPerTrack, Heads; // 22
73 unsigned long HiddenSectors, SectorsHuge; // 28
74 unsigned long FATSectors32; // 36
75 unsigned short ExtFlag; // 40
76 unsigned short FSVersion; // 42
77 unsigned long RootCluster; // 44
78 unsigned short FSInfoSector; // 48
79 unsigned short BootBackup; // 50
80 unsigned char Res3[12]; // 52
81 unsigned char Drive; // 64
82 unsigned char Res4; // 65
83 unsigned char ExtBootSignature; // 66
84 unsigned long VolumeID; // 67
85 unsigned char VolumeLabel[11], SysType[8]; // 71
86 unsigned char Res2[420]; // 90
87 unsigned short Signature1; // 510
88 };
89
90 #define FAT_DIRTY_BIT 0x01
91
92 struct _BootSectorFatX
93 {
94 unsigned char SysType[4]; // 0
95 unsigned long VolumeID; // 4
96 unsigned long SectorsPerCluster; // 8
97 unsigned short FATCount; // 12
98 unsigned long Unknown; // 14
99 unsigned char Unused[4078]; // 18
100 };
101
102 struct _FsInfoSector
103 {
104 unsigned long ExtBootSignature2; // 0
105 unsigned char Res6[480]; // 4
106 unsigned long FSINFOSignature; // 484
107 unsigned long FreeCluster; // 488
108 unsigned long NextCluster; // 492
109 unsigned char Res7[12]; // 496
110 unsigned long Signatur2; // 508
111 };
112
113 typedef struct _BootSector BootSector;
114
115 struct _FATDirEntry
116 {
117 union
118 {
119 struct { unsigned char Filename[8], Ext[3]; };
120 unsigned char ShortName[11];
121 };
122 unsigned char Attrib;
123 unsigned char lCase;
124 unsigned char CreationTimeMs;
125 unsigned short CreationTime,CreationDate,AccessDate;
126 union
127 {
128 unsigned short FirstClusterHigh; // FAT32
129 unsigned short ExtendedAttributes; // FAT12/FAT16
130 };
131 unsigned short UpdateTime; //time create/update
132 unsigned short UpdateDate; //date create/update
133 unsigned short FirstCluster;
134 unsigned long FileSize;
135 };
136
137 #define FAT_EAFILE "EA DATA. SF"
138
139 typedef struct _EAFileHeader FAT_EA_FILE_HEADER, *PFAT_EA_FILE_HEADER;
140
141 struct _EAFileHeader
142 {
143 unsigned short Signature; // ED
144 unsigned short Unknown[15];
145 unsigned short EASetTable[240];
146 };
147
148 typedef struct _EASetHeader FAT_EA_SET_HEADER, *PFAT_EA_SET_HEADER;
149
150 struct _EASetHeader
151 {
152 unsigned short Signature; // EA
153 unsigned short Offset; // relative offset, same value as in the EASetTable
154 unsigned short Unknown1[2];
155 char TargetFileName[12];
156 unsigned short Unknown2[3];
157 unsigned int EALength;
158 // EA Header
159 };
160
161 typedef struct _EAHeader FAT_EA_HEADER, *PFAT_EA_HEADER;
162
163 struct _EAHeader
164 {
165 unsigned char Unknown;
166 unsigned char EANameLength;
167 unsigned short EAValueLength;
168 // Name Data
169 // Value Data
170 };
171
172 typedef struct _FATDirEntry FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
173
174 struct _FATXDirEntry
175 {
176 unsigned char FilenameLength; // 0
177 unsigned char Attrib; // 1
178 unsigned char Filename[42]; // 2
179 unsigned long FirstCluster; // 44
180 unsigned long FileSize; // 48
181 unsigned short UpdateTime; // 52
182 unsigned short UpdateDate; // 54
183 unsigned short CreationTime; // 56
184 unsigned short CreationDate; // 58
185 unsigned short AccessTime; // 60
186 unsigned short AccessDate; // 62
187 };
188
189 struct _slot
190 {
191 unsigned char id; // sequence number for slot
192 WCHAR name0_4[5]; // first 5 characters in name
193 unsigned char attr; // attribute byte
194 unsigned char reserved; // always 0
195 unsigned char alias_checksum; // checksum for 8.3 alias
196 WCHAR name5_10[6]; // 6 more characters in name
197 unsigned char start[2]; // starting cluster number
198 WCHAR name11_12[2]; // last 2 characters in name
199 };
200
201 typedef struct _slot slot;
202
203 #include <poppack.h>
204
205 #define VFAT_CASE_LOWER_BASE 8 // base is lower case
206 #define VFAT_CASE_LOWER_EXT 16 // extension is lower case
207
208 #define LONGNAME_MAX_LENGTH 256 // max length for a long filename
209
210 #define ENTRY_DELETED(IsFatX, DirEntry) (IsFatX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat)))
211 #define ENTRY_VOLUME(IsFatX, DirEntry) (IsFatX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat)))
212 #define ENTRY_END(IsFatX, DirEntry) (IsFatX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat)))
213
214 #define FAT_ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5)
215 #define FAT_ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0)
216 #define FAT_ENTRY_LONG(DirEntry) (((DirEntry)->Attrib & 0x3f) == 0x0f)
217 #define FAT_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
218
219 #define FATX_ENTRY_DELETED(DirEntry) ((DirEntry)->FilenameLength == 0xe5)
220 #define FATX_ENTRY_END(DirEntry) ((DirEntry)->FilenameLength == 0xff)
221 #define FATX_ENTRY_LONG(DirEntry) (FALSE)
222 #define FATX_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
223
224 #define FAT_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FAT_DIR_ENTRY))
225 #define FATX_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATX_DIR_ENTRY))
226
227 typedef struct _FATXDirEntry FATX_DIR_ENTRY, *PFATX_DIR_ENTRY;
228
229 union _DIR_ENTRY
230 {
231 FAT_DIR_ENTRY Fat;
232 FATX_DIR_ENTRY FatX;
233 };
234
235 typedef union _DIR_ENTRY DIR_ENTRY, *PDIR_ENTRY;
236
237 #define BLOCKSIZE 512
238
239 #define FAT16 (1)
240 #define FAT12 (2)
241 #define FAT32 (3)
242 #define FATX16 (4)
243 #define FATX32 (5)
244
245 #define VCB_VOLUME_LOCKED 0x0001
246 #define VCB_DISMOUNT_PENDING 0x0002
247 #define VCB_IS_FATX 0x0004
248 #define VCB_IS_SYS_OR_HAS_PAGE 0x0008
249 #define VCB_IS_DIRTY 0x4000 /* Volume is dirty */
250 #define VCB_CLEAR_DIRTY 0x8000 /* Clean dirty flag at shutdown */
251 /* VCB condition state */
252 #define VCB_GOOD 0x0010 /* If not set, the VCB is improper for usage */
253
254 typedef struct
255 {
256 ULONG VolumeID;
257 CHAR VolumeLabel[11];
258 ULONG FATStart;
259 ULONG FATCount;
260 ULONG FATSectors;
261 ULONG rootDirectorySectors;
262 ULONG rootStart;
263 ULONG dataStart;
264 ULONG RootCluster;
265 ULONG SectorsPerCluster;
266 ULONG BytesPerSector;
267 ULONG BytesPerCluster;
268 ULONG NumberOfClusters;
269 ULONG FatType;
270 ULONG Sectors;
271 BOOLEAN FixedMedia;
272 ULONG FSInfoSector;
273 } FATINFO, *PFATINFO;
274
275 struct _VFATFCB;
276 struct _VFAT_DIRENTRY_CONTEXT;
277 struct _VFAT_MOVE_CONTEXT;
278 struct _VFAT_CLOSE_CONTEXT;
279
280 typedef struct _HASHENTRY
281 {
282 ULONG Hash;
283 struct _VFATFCB* self;
284 struct _HASHENTRY* next;
285 }
286 HASHENTRY;
287
288 typedef struct DEVICE_EXTENSION *PDEVICE_EXTENSION;
289
290 typedef NTSTATUS (*PGET_NEXT_CLUSTER)(PDEVICE_EXTENSION,ULONG,PULONG);
291 typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG);
292 typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG);
293
294 typedef BOOLEAN (*PIS_DIRECTORY_EMPTY)(PDEVICE_EXTENSION,struct _VFATFCB*);
295 typedef NTSTATUS (*PADD_ENTRY)(PDEVICE_EXTENSION,PUNICODE_STRING,struct _VFATFCB**,struct _VFATFCB*,ULONG,UCHAR,struct _VFAT_MOVE_CONTEXT*);
296 typedef NTSTATUS (*PDEL_ENTRY)(PDEVICE_EXTENSION,struct _VFATFCB*,struct _VFAT_MOVE_CONTEXT*);
297 typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN);
298 typedef NTSTATUS (*PGET_DIRTY_STATUS)(PDEVICE_EXTENSION,PBOOLEAN);
299 typedef NTSTATUS (*PSET_DIRTY_STATUS)(PDEVICE_EXTENSION,BOOLEAN);
300
301 typedef struct _VFAT_DISPATCH
302 {
303 PIS_DIRECTORY_EMPTY IsDirectoryEmpty;
304 PADD_ENTRY AddEntry;
305 PDEL_ENTRY DelEntry;
306 PGET_NEXT_DIR_ENTRY GetNextDirEntry;
307 } VFAT_DISPATCH, *PVFAT_DISPATCH;
308
309 #define STATISTICS_SIZE_NO_PAD (sizeof(FILESYSTEM_STATISTICS) + sizeof(FAT_STATISTICS))
310 typedef struct _STATISTICS {
311 FILESYSTEM_STATISTICS Base;
312 FAT_STATISTICS Fat;
313 UCHAR Pad[((STATISTICS_SIZE_NO_PAD + 0x3f) & ~0x3f) - STATISTICS_SIZE_NO_PAD];
314 } STATISTICS, *PSTATISTICS;
315
316 typedef struct DEVICE_EXTENSION
317 {
318 ERESOURCE DirResource;
319 ERESOURCE FatResource;
320
321 KSPIN_LOCK FcbListLock;
322 LIST_ENTRY FcbListHead;
323 ULONG HashTableSize;
324 struct _HASHENTRY **FcbHashTable;
325
326 PDEVICE_OBJECT VolumeDevice;
327 PDEVICE_OBJECT StorageDevice;
328 PFILE_OBJECT FATFileObject;
329 FATINFO FatInfo;
330 ULONG LastAvailableCluster;
331 ULONG AvailableClusters;
332 BOOLEAN AvailableClustersValid;
333 ULONG Flags;
334 struct _VFATFCB *VolumeFcb;
335 struct _VFATFCB *RootFcb;
336 PSTATISTICS Statistics;
337
338 /* Pointers to functions for manipulating FAT. */
339 PGET_NEXT_CLUSTER GetNextCluster;
340 PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster;
341 PWRITE_CLUSTER WriteCluster;
342 PGET_DIRTY_STATUS GetDirtyStatus;
343 PSET_DIRTY_STATUS SetDirtyStatus;
344
345 ULONG BaseDateYear;
346
347 LIST_ENTRY VolumeListEntry;
348
349 /* Notifications */
350 LIST_ENTRY NotifyList;
351 PNOTIFY_SYNC NotifySync;
352
353 /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE */
354 ULONG OpenHandleCount;
355
356 /* VPBs for dismount */
357 PVPB IoVPB;
358 PVPB SpareVPB;
359
360 /* Pointers to functions for manipulating directory entries. */
361 VFAT_DISPATCH Dispatch;
362 } DEVICE_EXTENSION, VCB, *PVCB;
363
364 FORCEINLINE
365 BOOLEAN
366 VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt,
367 struct _VFATFCB* Fcb)
368 {
369 return DeviceExt->Dispatch.IsDirectoryEmpty(DeviceExt, Fcb);
370 }
371
372 FORCEINLINE
373 NTSTATUS
374 VfatAddEntry(PDEVICE_EXTENSION DeviceExt,
375 PUNICODE_STRING NameU,
376 struct _VFATFCB** Fcb,
377 struct _VFATFCB* ParentFcb,
378 ULONG RequestedOptions,
379 UCHAR ReqAttr,
380 struct _VFAT_MOVE_CONTEXT* MoveContext)
381 {
382 return DeviceExt->Dispatch.AddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr, MoveContext);
383 }
384
385 FORCEINLINE
386 NTSTATUS
387 VfatDelEntry(PDEVICE_EXTENSION DeviceExt,
388 struct _VFATFCB* Fcb,
389 struct _VFAT_MOVE_CONTEXT* MoveContext)
390 {
391 return DeviceExt->Dispatch.DelEntry(DeviceExt, Fcb, MoveContext);
392 }
393
394 FORCEINLINE
395 NTSTATUS
396 VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt,
397 PVOID *pContext,
398 PVOID *pPage,
399 struct _VFATFCB* pDirFcb,
400 struct _VFAT_DIRENTRY_CONTEXT* DirContext,
401 BOOLEAN First)
402 {
403 return DeviceExt->Dispatch.GetNextDirEntry(pContext, pPage, pDirFcb, DirContext, First);
404 }
405
406 #define VFAT_BREAK_ON_CORRUPTION 1
407
408 typedef struct
409 {
410 PDRIVER_OBJECT DriverObject;
411 PDEVICE_OBJECT DeviceObject;
412 ULONG Flags;
413 ULONG NumberProcessors;
414 ERESOURCE VolumeListLock;
415 LIST_ENTRY VolumeListHead;
416 NPAGED_LOOKASIDE_LIST FcbLookasideList;
417 NPAGED_LOOKASIDE_LIST CcbLookasideList;
418 NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
419 PAGED_LOOKASIDE_LIST CloseContextLookasideList;
420 FAST_IO_DISPATCH FastIoDispatch;
421 CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
422 FAST_MUTEX CloseMutex;
423 ULONG CloseCount;
424 LIST_ENTRY CloseListHead;
425 BOOLEAN CloseWorkerRunning;
426 PIO_WORKITEM CloseWorkItem;
427 BOOLEAN ShutdownStarted;
428 } VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
429
430 extern PVFAT_GLOBAL_DATA VfatGlobalData;
431
432 #define FCB_CACHE_INITIALIZED 0x0001
433 #define FCB_DELETE_PENDING 0x0002
434 #define FCB_IS_FAT 0x0004
435 #define FCB_IS_PAGE_FILE 0x0008
436 #define FCB_IS_VOLUME 0x0010
437 #define FCB_IS_DIRTY 0x0020
438 #define FCB_DELAYED_CLOSE 0x0040
439 #ifdef KDBG
440 #define FCB_CLEANED_UP 0x0080
441 #define FCB_CLOSED 0x0100
442 #endif
443
444 #define NODE_TYPE_FCB ((CSHORT)0x0502)
445
446 typedef struct _VFATFCB
447 {
448 /* FCB header required by ROS/NT */
449 FSRTL_COMMON_FCB_HEADER RFCB;
450 SECTION_OBJECT_POINTERS SectionObjectPointers;
451 ERESOURCE MainResource;
452 ERESOURCE PagingIoResource;
453 /* end FCB header required by ROS/NT */
454
455 /* directory entry for this file or directory */
456 DIR_ENTRY entry;
457
458 /* Pointer to attributes in entry */
459 PUCHAR Attributes;
460
461 /* long file name, points into PathNameBuffer */
462 UNICODE_STRING LongNameU;
463
464 /* short file name */
465 UNICODE_STRING ShortNameU;
466
467 /* directory name, points into PathNameBuffer */
468 UNICODE_STRING DirNameU;
469
470 /* path + long file name 260 max*/
471 UNICODE_STRING PathNameU;
472
473 /* buffer for PathNameU */
474 PWCHAR PathNameBuffer;
475
476 /* buffer for ShortNameU */
477 WCHAR ShortNameBuffer[13];
478
479 /* */
480 LONG RefCount;
481
482 /* List of FCB's for this volume */
483 LIST_ENTRY FcbListEntry;
484
485 /* List of FCB's for the parent */
486 LIST_ENTRY ParentListEntry;
487
488 /* pointer to the parent fcb */
489 struct _VFATFCB *parentFcb;
490
491 /* List for the children */
492 LIST_ENTRY ParentListHead;
493
494 /* Flags for the fcb */
495 ULONG Flags;
496
497 /* pointer to the file object which has initialized the fcb */
498 PFILE_OBJECT FileObject;
499
500 /* Directory index for the short name entry */
501 ULONG dirIndex;
502
503 /* Directory index where the long name starts */
504 ULONG startIndex;
505
506 /* Share access for the file object */
507 SHARE_ACCESS FCBShareAccess;
508
509 /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP */
510 ULONG OpenHandleCount;
511
512 /* Entry into the hash table for the path + long name */
513 HASHENTRY Hash;
514
515 /* Entry into the hash table for the path + short name */
516 HASHENTRY ShortHash;
517
518 /* List of byte-range locks for this file */
519 FILE_LOCK FileLock;
520
521 /*
522 * Optimization: caching of last read/write cluster+offset pair. Can't
523 * be in VFATCCB because it must be reset everytime the allocated clusters
524 * change.
525 */
526 FAST_MUTEX LastMutex;
527 ULONG LastCluster;
528 ULONG LastOffset;
529
530 struct _VFAT_CLOSE_CONTEXT * CloseContext;
531 } VFATFCB, *PVFATFCB;
532
533 #define CCB_DELETE_ON_CLOSE 0x0001
534
535 typedef struct _VFATCCB
536 {
537 LARGE_INTEGER CurrentByteOffset;
538 ULONG Flags;
539 /* for DirectoryControl */
540 ULONG Entry;
541 /* for DirectoryControl */
542 UNICODE_STRING SearchPattern;
543 } VFATCCB, *PVFATCCB;
544
545 #define TAG_CCB 'CtaF'
546 #define TAG_FCB 'FtaF'
547 #define TAG_IRP 'ItaF'
548 #define TAG_CLOSE 'xtaF'
549 #define TAG_STATS 'VtaF'
550 #define TAG_BUFFER 'OtaF'
551 #define TAG_VPB 'vtaF'
552 #define TAG_NAME 'ntaF'
553 #define TAG_SEARCH 'LtaF'
554 #define TAG_DIRENT 'DtaF'
555
556 #define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
557
558 typedef struct __DOSTIME
559 {
560 USHORT Second:5;
561 USHORT Minute:6;
562 USHORT Hour:5;
563 }
564 DOSTIME, *PDOSTIME;
565
566 typedef struct __DOSDATE
567 {
568 USHORT Day:5;
569 USHORT Month:4;
570 USHORT Year:7;
571 }
572 DOSDATE, *PDOSDATE;
573
574 #define IRPCONTEXT_CANWAIT 0x0001
575 #define IRPCONTEXT_COMPLETE 0x0002
576 #define IRPCONTEXT_QUEUE 0x0004
577 #define IRPCONTEXT_PENDINGRETURNED 0x0008
578 #define IRPCONTEXT_DEFERRED_WRITE 0x0010
579
580 typedef struct
581 {
582 PIRP Irp;
583 PDEVICE_OBJECT DeviceObject;
584 PDEVICE_EXTENSION DeviceExt;
585 ULONG Flags;
586 WORK_QUEUE_ITEM WorkQueueItem;
587 PIO_STACK_LOCATION Stack;
588 UCHAR MajorFunction;
589 UCHAR MinorFunction;
590 PFILE_OBJECT FileObject;
591 ULONG RefCount;
592 KEVENT Event;
593 CCHAR PriorityBoost;
594 } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
595
596 typedef struct _VFAT_DIRENTRY_CONTEXT
597 {
598 ULONG StartIndex;
599 ULONG DirIndex;
600 DIR_ENTRY DirEntry;
601 UNICODE_STRING LongNameU;
602 UNICODE_STRING ShortNameU;
603 PDEVICE_EXTENSION DeviceExt;
604 } VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
605
606 typedef struct _VFAT_MOVE_CONTEXT
607 {
608 ULONG FirstCluster;
609 ULONG FileSize;
610 USHORT CreationDate;
611 USHORT CreationTime;
612 BOOLEAN InPlace;
613 } VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT;
614
615 typedef struct _VFAT_CLOSE_CONTEXT
616 {
617 PDEVICE_EXTENSION Vcb;
618 PVFATFCB Fcb;
619 LIST_ENTRY CloseListEntry;
620 } VFAT_CLOSE_CONTEXT, *PVFAT_CLOSE_CONTEXT;
621
622 FORCEINLINE
623 NTSTATUS
624 VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
625 {
626 PULONG Flags = &IrpContext->Flags;
627
628 *Flags &= ~IRPCONTEXT_COMPLETE;
629 *Flags |= IRPCONTEXT_QUEUE;
630
631 return STATUS_PENDING;
632 }
633
634 FORCEINLINE
635 BOOLEAN
636 vfatFCBIsDirectory(PVFATFCB FCB)
637 {
638 return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_DIRECTORY);
639 }
640
641 FORCEINLINE
642 BOOLEAN
643 vfatFCBIsReadOnly(PVFATFCB FCB)
644 {
645 return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_READONLY);
646 }
647
648 FORCEINLINE
649 BOOLEAN
650 vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt)
651 {
652 return BooleanFlagOn(DeviceExt->Flags, VCB_IS_FATX);
653 }
654
655 FORCEINLINE
656 VOID
657 vfatReportChange(
658 IN PDEVICE_EXTENSION DeviceExt,
659 IN PVFATFCB Fcb,
660 IN ULONG FilterMatch,
661 IN ULONG Action)
662 {
663 FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
664 &(DeviceExt->NotifyList),
665 (PSTRING)&Fcb->PathNameU,
666 Fcb->PathNameU.Length - Fcb->LongNameU.Length,
667 NULL, NULL, FilterMatch, Action, NULL);
668 }
669
670 #define vfatAddToStat(Vcb, Stat, Inc) \
671 { \
672 PSTATISTICS Stats = &(Vcb)->Statistics[KeGetCurrentProcessorNumber() % VfatGlobalData->NumberProcessors]; \
673 Stats->Stat += Inc; \
674 }
675
676 /* blockdev.c */
677
678 NTSTATUS
679 VfatReadDisk(
680 IN PDEVICE_OBJECT pDeviceObject,
681 IN PLARGE_INTEGER ReadOffset,
682 IN ULONG ReadLength,
683 IN PUCHAR Buffer,
684 IN BOOLEAN Override);
685
686 NTSTATUS
687 VfatReadDiskPartial(
688 IN PVFAT_IRP_CONTEXT IrpContext,
689 IN PLARGE_INTEGER ReadOffset,
690 IN ULONG ReadLength,
691 IN ULONG BufferOffset,
692 IN BOOLEAN Wait);
693
694 NTSTATUS
695 VfatWriteDisk(
696 IN PDEVICE_OBJECT pDeviceObject,
697 IN PLARGE_INTEGER WriteOffset,
698 IN ULONG WriteLength,
699 IN OUT PUCHAR Buffer,
700 IN BOOLEAN Override);
701
702 NTSTATUS
703 VfatWriteDiskPartial(
704 IN PVFAT_IRP_CONTEXT IrpContext,
705 IN PLARGE_INTEGER WriteOffset,
706 IN ULONG WriteLength,
707 IN ULONG BufferOffset,
708 IN BOOLEAN Wait);
709
710 NTSTATUS
711 VfatBlockDeviceIoControl(
712 IN PDEVICE_OBJECT DeviceObject,
713 IN ULONG CtlCode,
714 IN PVOID InputBuffer,
715 IN ULONG InputBufferSize,
716 IN OUT PVOID OutputBuffer,
717 IN OUT PULONG pOutputBufferSize,
718 IN BOOLEAN Override);
719
720 /* cleanup.c */
721
722 NTSTATUS
723 VfatCleanup(
724 PVFAT_IRP_CONTEXT IrpContext);
725
726 /* close.c */
727
728 NTSTATUS
729 VfatClose(
730 PVFAT_IRP_CONTEXT IrpContext);
731
732 NTSTATUS
733 VfatCloseFile(
734 PDEVICE_EXTENSION DeviceExt,
735 PFILE_OBJECT FileObject);
736
737 /* create.c */
738
739 NTSTATUS
740 VfatCreate(
741 PVFAT_IRP_CONTEXT IrpContext);
742
743 NTSTATUS
744 FindFile(
745 PDEVICE_EXTENSION DeviceExt,
746 PVFATFCB Parent,
747 PUNICODE_STRING FileToFindU,
748 PVFAT_DIRENTRY_CONTEXT DirContext,
749 BOOLEAN First);
750
751 VOID
752 vfat8Dot3ToString(
753 PFAT_DIR_ENTRY pEntry,
754 PUNICODE_STRING NameU);
755
756 /* dir.c */
757
758 NTSTATUS
759 VfatDirectoryControl(
760 PVFAT_IRP_CONTEXT IrpContext);
761
762 BOOLEAN
763 FsdDosDateTimeToSystemTime(
764 PDEVICE_EXTENSION DeviceExt,
765 USHORT DosDate,
766 USHORT DosTime,
767 PLARGE_INTEGER SystemTime);
768
769 BOOLEAN
770 FsdSystemTimeToDosDateTime(
771 PDEVICE_EXTENSION DeviceExt,
772 PLARGE_INTEGER SystemTime,
773 USHORT *pDosDate,
774 USHORT *pDosTime);
775
776 /* direntry.c */
777
778 ULONG
779 vfatDirEntryGetFirstCluster(
780 PDEVICE_EXTENSION pDeviceExt,
781 PDIR_ENTRY pDirEntry);
782
783 /* dirwr.c */
784
785 NTSTATUS
786 vfatFCBInitializeCacheFromVolume(
787 PVCB vcb,
788 PVFATFCB fcb);
789
790 NTSTATUS
791 VfatUpdateEntry(
792 IN PDEVICE_EXTENSION DeviceExt,
793 PVFATFCB pFcb);
794
795 BOOLEAN
796 vfatFindDirSpace(
797 PDEVICE_EXTENSION DeviceExt,
798 PVFATFCB pDirFcb,
799 ULONG nbSlots,
800 PULONG start);
801
802 NTSTATUS
803 vfatRenameEntry(
804 IN PDEVICE_EXTENSION DeviceExt,
805 IN PVFATFCB pFcb,
806 IN PUNICODE_STRING FileName,
807 IN BOOLEAN CaseChangeOnly);
808
809 NTSTATUS
810 VfatMoveEntry(
811 IN PDEVICE_EXTENSION DeviceExt,
812 IN PVFATFCB pFcb,
813 IN PUNICODE_STRING FileName,
814 IN PVFATFCB ParentFcb);
815
816 /* ea.h */
817
818 NTSTATUS
819 VfatSetExtendedAttributes(
820 PFILE_OBJECT FileObject,
821 PVOID Ea,
822 ULONG EaLength);
823
824 /* fastio.c */
825
826 VOID
827 VfatInitFastIoRoutines(
828 PFAST_IO_DISPATCH FastIoDispatch);
829
830 BOOLEAN
831 NTAPI
832 VfatAcquireForLazyWrite(
833 IN PVOID Context,
834 IN BOOLEAN Wait);
835
836 VOID
837 NTAPI
838 VfatReleaseFromLazyWrite(
839 IN PVOID Context);
840
841 /* fat.c */
842
843 NTSTATUS
844 FAT12GetNextCluster(
845 PDEVICE_EXTENSION DeviceExt,
846 ULONG CurrentCluster,
847 PULONG NextCluster);
848
849 NTSTATUS
850 FAT12FindAndMarkAvailableCluster(
851 PDEVICE_EXTENSION DeviceExt,
852 PULONG Cluster);
853
854 NTSTATUS
855 FAT12WriteCluster(
856 PDEVICE_EXTENSION DeviceExt,
857 ULONG ClusterToWrite,
858 ULONG NewValue,
859 PULONG OldValue);
860
861 NTSTATUS
862 FAT16GetNextCluster(
863 PDEVICE_EXTENSION DeviceExt,
864 ULONG CurrentCluster,
865 PULONG NextCluster);
866
867 NTSTATUS
868 FAT16FindAndMarkAvailableCluster(
869 PDEVICE_EXTENSION DeviceExt,
870 PULONG Cluster);
871
872 NTSTATUS
873 FAT16WriteCluster(
874 PDEVICE_EXTENSION DeviceExt,
875 ULONG ClusterToWrite,
876 ULONG NewValue,
877 PULONG OldValue);
878
879 NTSTATUS
880 FAT32GetNextCluster(
881 PDEVICE_EXTENSION DeviceExt,
882 ULONG CurrentCluster,
883 PULONG NextCluster);
884
885 NTSTATUS
886 FAT32FindAndMarkAvailableCluster(
887 PDEVICE_EXTENSION DeviceExt,
888 PULONG Cluster);
889
890 NTSTATUS
891 FAT32WriteCluster(
892 PDEVICE_EXTENSION DeviceExt,
893 ULONG ClusterToWrite,
894 ULONG NewValue,
895 PULONG OldValue);
896
897 NTSTATUS
898 OffsetToCluster(
899 PDEVICE_EXTENSION DeviceExt,
900 ULONG FirstCluster,
901 ULONG FileOffset,
902 PULONG Cluster,
903 BOOLEAN Extend);
904
905 ULONGLONG
906 ClusterToSector(
907 PDEVICE_EXTENSION DeviceExt,
908 ULONG Cluster);
909
910 NTSTATUS
911 GetNextCluster(
912 PDEVICE_EXTENSION DeviceExt,
913 ULONG CurrentCluster,
914 PULONG NextCluster);
915
916 NTSTATUS
917 GetNextClusterExtend(
918 PDEVICE_EXTENSION DeviceExt,
919 ULONG CurrentCluster,
920 PULONG NextCluster);
921
922 NTSTATUS
923 CountAvailableClusters(
924 PDEVICE_EXTENSION DeviceExt,
925 PLARGE_INTEGER Clusters);
926
927 NTSTATUS
928 WriteCluster(
929 PDEVICE_EXTENSION DeviceExt,
930 ULONG ClusterToWrite,
931 ULONG NewValue);
932
933 NTSTATUS
934 GetDirtyStatus(
935 PDEVICE_EXTENSION DeviceExt,
936 PBOOLEAN DirtyStatus);
937
938 NTSTATUS
939 FAT16GetDirtyStatus(
940 PDEVICE_EXTENSION DeviceExt,
941 PBOOLEAN DirtyStatus);
942
943 NTSTATUS
944 FAT32GetDirtyStatus(
945 PDEVICE_EXTENSION DeviceExt,
946 PBOOLEAN DirtyStatus);
947
948 NTSTATUS
949 SetDirtyStatus(
950 PDEVICE_EXTENSION DeviceExt,
951 BOOLEAN DirtyStatus);
952
953 NTSTATUS
954 FAT16SetDirtyStatus(
955 PDEVICE_EXTENSION DeviceExt,
956 BOOLEAN DirtyStatus);
957
958 NTSTATUS
959 FAT32SetDirtyStatus(
960 PDEVICE_EXTENSION DeviceExt,
961 BOOLEAN DirtyStatus);
962
963 NTSTATUS
964 FAT32UpdateFreeClustersCount(
965 PDEVICE_EXTENSION DeviceExt);
966
967 /* fcb.c */
968
969 PVFATFCB
970 vfatNewFCB(
971 PDEVICE_EXTENSION pVCB,
972 PUNICODE_STRING pFileNameU);
973
974 NTSTATUS
975 vfatSetFCBNewDirName(
976 PDEVICE_EXTENSION pVCB,
977 PVFATFCB Fcb,
978 PVFATFCB ParentFcb);
979
980 NTSTATUS
981 vfatUpdateFCB(
982 PDEVICE_EXTENSION pVCB,
983 PVFATFCB Fcb,
984 PVFAT_DIRENTRY_CONTEXT DirContext,
985 PVFATFCB ParentFcb);
986
987 VOID
988 vfatDestroyFCB(
989 PVFATFCB pFCB);
990
991 VOID
992 vfatDestroyCCB(
993 PVFATCCB pCcb);
994
995 VOID
996 #ifndef KDBG
997 vfatGrabFCB(
998 #else
999 _vfatGrabFCB(
1000 #endif
1001 PDEVICE_EXTENSION pVCB,
1002 PVFATFCB pFCB
1003 #ifdef KDBG
1004 ,
1005 PCSTR File,
1006 ULONG Line,
1007 PCSTR Func
1008 #endif
1009 );
1010
1011 VOID
1012 #ifndef KDBG
1013 vfatReleaseFCB(
1014 #else
1015 _vfatReleaseFCB(
1016 #endif
1017 PDEVICE_EXTENSION pVCB,
1018 PVFATFCB pFCB
1019 #ifdef KDBG
1020 ,
1021 PCSTR File,
1022 ULONG Line,
1023 PCSTR Func
1024 #endif
1025 );
1026
1027 #ifdef KDBG
1028 #define vfatGrabFCB(v, f) _vfatGrabFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
1029 #define vfatReleaseFCB(v, f) _vfatReleaseFCB(v, f, __FILE__, __LINE__, __FUNCTION__)
1030 #endif
1031
1032 PVFATFCB
1033 vfatGrabFCBFromTable(
1034 PDEVICE_EXTENSION pDeviceExt,
1035 PUNICODE_STRING pFileNameU);
1036
1037 PVFATFCB
1038 vfatMakeRootFCB(
1039 PDEVICE_EXTENSION pVCB);
1040
1041 PVFATFCB
1042 vfatOpenRootFCB(
1043 PDEVICE_EXTENSION pVCB);
1044
1045 BOOLEAN
1046 vfatFCBIsDirectory(
1047 PVFATFCB FCB);
1048
1049 BOOLEAN
1050 vfatFCBIsRoot(
1051 PVFATFCB FCB);
1052
1053 NTSTATUS
1054 vfatAttachFCBToFileObject(
1055 PDEVICE_EXTENSION vcb,
1056 PVFATFCB fcb,
1057 PFILE_OBJECT fileObject);
1058
1059 NTSTATUS
1060 vfatDirFindFile(
1061 PDEVICE_EXTENSION pVCB,
1062 PVFATFCB parentFCB,
1063 PUNICODE_STRING FileToFindU,
1064 PVFATFCB *fileFCB);
1065
1066 NTSTATUS
1067 vfatGetFCBForFile(
1068 PDEVICE_EXTENSION pVCB,
1069 PVFATFCB *pParentFCB,
1070 PVFATFCB *pFCB,
1071 PUNICODE_STRING pFileNameU);
1072
1073 NTSTATUS
1074 vfatMakeFCBFromDirEntry(
1075 PVCB vcb,
1076 PVFATFCB directoryFCB,
1077 PVFAT_DIRENTRY_CONTEXT DirContext,
1078 PVFATFCB *fileFCB);
1079
1080 /* finfo.c */
1081
1082 NTSTATUS
1083 VfatGetStandardInformation(
1084 PVFATFCB FCB,
1085 PFILE_STANDARD_INFORMATION StandardInfo,
1086 PULONG BufferLength);
1087
1088 NTSTATUS
1089 VfatGetBasicInformation(
1090 PFILE_OBJECT FileObject,
1091 PVFATFCB FCB,
1092 PDEVICE_EXTENSION DeviceExt,
1093 PFILE_BASIC_INFORMATION BasicInfo,
1094 PULONG BufferLength);
1095
1096 NTSTATUS
1097 VfatQueryInformation(
1098 PVFAT_IRP_CONTEXT IrpContext);
1099
1100 NTSTATUS
1101 VfatSetInformation(
1102 PVFAT_IRP_CONTEXT IrpContext);
1103
1104 NTSTATUS
1105 VfatSetAllocationSizeInformation(
1106 PFILE_OBJECT FileObject,
1107 PVFATFCB Fcb,
1108 PDEVICE_EXTENSION DeviceExt,
1109 PLARGE_INTEGER AllocationSize);
1110
1111 /* flush.c */
1112
1113 NTSTATUS
1114 VfatFlush(
1115 PVFAT_IRP_CONTEXT IrpContext);
1116
1117 NTSTATUS
1118 VfatFlushVolume(
1119 PDEVICE_EXTENSION DeviceExt,
1120 PVFATFCB VolumeFcb);
1121
1122 /* fsctl.c */
1123
1124 NTSTATUS
1125 VfatFileSystemControl(
1126 PVFAT_IRP_CONTEXT IrpContext);
1127
1128 /* iface.c */
1129
1130 NTSTATUS
1131 NTAPI
1132 DriverEntry(
1133 PDRIVER_OBJECT DriverObject,
1134 PUNICODE_STRING RegistryPath);
1135
1136 #ifdef KDBG
1137 /* kdbg.c */
1138 KDBG_CLI_ROUTINE vfatKdbgHandler;
1139 #endif
1140
1141 /* misc.c */
1142
1143 DRIVER_DISPATCH
1144 VfatBuildRequest;
1145
1146 NTSTATUS
1147 NTAPI
1148 VfatBuildRequest(
1149 PDEVICE_OBJECT DeviceObject,
1150 PIRP Irp);
1151
1152 PVOID
1153 VfatGetUserBuffer(
1154 IN PIRP,
1155 IN BOOLEAN Paging);
1156
1157 NTSTATUS
1158 VfatLockUserBuffer(
1159 IN PIRP,
1160 IN ULONG,
1161 IN LOCK_OPERATION);
1162
1163 BOOLEAN
1164 VfatCheckForDismount(
1165 IN PDEVICE_EXTENSION DeviceExt,
1166 IN BOOLEAN Create);
1167
1168 VOID
1169 vfatReportChange(
1170 IN PDEVICE_EXTENSION DeviceExt,
1171 IN PVFATFCB Fcb,
1172 IN ULONG FilterMatch,
1173 IN ULONG Action);
1174
1175 VOID
1176 NTAPI
1177 VfatHandleDeferredWrite(
1178 IN PVOID IrpContext,
1179 IN PVOID Unused);
1180
1181 /* pnp.c */
1182
1183 NTSTATUS
1184 VfatPnp(
1185 PVFAT_IRP_CONTEXT IrpContext);
1186
1187 /* rw.c */
1188
1189 NTSTATUS
1190 VfatRead(
1191 PVFAT_IRP_CONTEXT IrpContext);
1192
1193 NTSTATUS
1194 VfatWrite(
1195 PVFAT_IRP_CONTEXT IrpContext);
1196
1197 NTSTATUS
1198 NextCluster(
1199 PDEVICE_EXTENSION DeviceExt,
1200 ULONG FirstCluster,
1201 PULONG CurrentCluster,
1202 BOOLEAN Extend);
1203
1204 /* shutdown.c */
1205
1206 DRIVER_DISPATCH
1207 VfatShutdown;
1208
1209 NTSTATUS
1210 NTAPI
1211 VfatShutdown(
1212 PDEVICE_OBJECT DeviceObject,
1213 PIRP Irp);
1214
1215 /* string.c */
1216
1217 VOID
1218 vfatSplitPathName(
1219 PUNICODE_STRING PathNameU,
1220 PUNICODE_STRING DirNameU,
1221 PUNICODE_STRING FileNameU);
1222
1223 BOOLEAN
1224 vfatIsLongIllegal(
1225 WCHAR c);
1226
1227 BOOLEAN
1228 wstrcmpjoki(
1229 PWSTR s1,
1230 PWSTR s2);
1231
1232 /* volume.c */
1233
1234 NTSTATUS
1235 VfatQueryVolumeInformation(
1236 PVFAT_IRP_CONTEXT IrpContext);
1237
1238 NTSTATUS
1239 VfatSetVolumeInformation(
1240 PVFAT_IRP_CONTEXT IrpContext);
1241
1242 #endif /* _FASTFAT_PCH_ */