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