Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1605 lines
43 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. FatStruc.h
  5. Abstract:
  6. This module defines the data structures that make up the major internal
  7. part of the Fat file system.
  8. // @@BEGIN_DDKSPLIT
  9. Author:
  10. Gary Kimura [GaryKi] 28-Dec-1989
  11. Revision History:
  12. // @@END_DDKSPLIT
  13. --*/
  14. #ifndef _FATSTRUC_
  15. #define _FATSTRUC_
  16. typedef PVOID PBCB; //**** Bcb's are now part of the cache module
  17. //
  18. // The FAT_DATA record is the top record in the Fat file system in-memory
  19. // data structure. This structure must be allocated from non-paged pool.
  20. //
  21. typedef struct _FAT_DATA {
  22. //
  23. // The type and size of this record (must be FAT_NTC_DATA_HEADER)
  24. //
  25. NODE_TYPE_CODE NodeTypeCode;
  26. NODE_BYTE_SIZE NodeByteSize;
  27. PVOID LazyWriteThread;
  28. //
  29. // A queue of all the devices that are mounted by the file system.
  30. //
  31. LIST_ENTRY VcbQueue;
  32. //
  33. // A pointer to the Driver object we were initialized with
  34. //
  35. PDRIVER_OBJECT DriverObject;
  36. //
  37. // A pointer to the filesystem device objects we created.
  38. //
  39. PVOID DiskFileSystemDeviceObject;
  40. PVOID CdromFileSystemDeviceObject;
  41. //
  42. // A resource variable to control access to the global Fat data record
  43. //
  44. ERESOURCE Resource;
  45. //
  46. // A pointer to our EPROCESS struct, which is a required input to the
  47. // Cache Management subsystem.
  48. //
  49. PEPROCESS OurProcess;
  50. //
  51. // The following tells us if we should use Chicago extensions.
  52. //
  53. BOOLEAN ChicagoMode:1;
  54. //
  55. // The following field tells us if we are running on a Fujitsu
  56. // FMR Series. These machines supports extra formats on the
  57. // FAT file system.
  58. //
  59. BOOLEAN FujitsuFMR:1;
  60. //
  61. // Inidicates that FspClose is currently processing closes.
  62. //
  63. BOOLEAN AsyncCloseActive:1;
  64. //
  65. // The following BOOLEAN says shutdown has started on FAT. It
  66. // instructs FspClose to not keep the Vcb resources anymore.
  67. //
  68. BOOLEAN ShutdownStarted:1;
  69. //
  70. // The following flag tells us if we are going to generate LFNs
  71. // for valid 8.3 names with extended characters.
  72. //
  73. BOOLEAN CodePageInvariant:1;
  74. //
  75. // The following flags tell us if we are in an aggresive push to lower
  76. // the size of the deferred close queues.
  77. //
  78. BOOLEAN HighAsync:1;
  79. BOOLEAN HighDelayed:1;
  80. //
  81. // The following list entry is used for performing closes that can't
  82. // be done in the context of the original caller.
  83. //
  84. ULONG AsyncCloseCount;
  85. LIST_ENTRY AsyncCloseList;
  86. //
  87. // The following two fields record if we are delaying a close.
  88. //
  89. ULONG DelayedCloseCount;
  90. LIST_ENTRY DelayedCloseList;
  91. //
  92. // This is the ExWorkerItem that does both kinds of deferred closes.
  93. //
  94. PIO_WORKITEM FatCloseItem;
  95. //
  96. // This spinlock protects several rapid-fire operations. NOTE: this is
  97. // pretty horrible style.
  98. //
  99. KSPIN_LOCK GeneralSpinLock;
  100. //
  101. // Cache manager call back structures, which must be passed on each call
  102. // to CcInitializeCacheMap.
  103. //
  104. CACHE_MANAGER_CALLBACKS CacheManagerCallbacks;
  105. CACHE_MANAGER_CALLBACKS CacheManagerNoOpCallbacks;
  106. } FAT_DATA;
  107. typedef FAT_DATA *PFAT_DATA;
  108. //
  109. // An array of these structures will keep
  110. typedef struct _FAT_WINDOW {
  111. ULONG FirstCluster; // The first cluster in this window.
  112. ULONG LastCluster; // The last cluster in this window.
  113. ULONG ClustersFree; // The number of clusters free in this window.
  114. } FAT_WINDOW;
  115. typedef FAT_WINDOW *PFAT_WINDOW;
  116. //
  117. // The Vcb (Volume control Block) record corresponds to every volume mounted
  118. // by the file system. They are ordered in a queue off of FatData.VcbQueue.
  119. // This structure must be allocated from non-paged pool
  120. //
  121. typedef enum _VCB_CONDITION {
  122. VcbGood = 1,
  123. VcbNotMounted,
  124. VcbBad
  125. } VCB_CONDITION;
  126. typedef struct _VCB {
  127. //
  128. // This is a common head for the FAT volume file
  129. //
  130. FSRTL_ADVANCED_FCB_HEADER VolumeFileHeader;
  131. //
  132. // The links for the device queue off of FatData.VcbQueue
  133. //
  134. LIST_ENTRY VcbLinks;
  135. //
  136. // A pointer the device object passed in by the I/O system on a mount
  137. // This is the target device object that the file system talks to when it
  138. // needs to do any I/O (e.g., the disk stripper device object).
  139. //
  140. //
  141. PDEVICE_OBJECT TargetDeviceObject;
  142. //
  143. // A pointer to the VPB for the volume passed in by the I/O system on
  144. // a mount.
  145. //
  146. PVPB Vpb;
  147. //
  148. // The internal state of the device. This is a collection of fsd device
  149. // state flags.
  150. //
  151. ULONG VcbState;
  152. VCB_CONDITION VcbCondition;
  153. //
  154. // A pointer to the root DCB for this volume
  155. //
  156. struct _FCB *RootDcb;
  157. //
  158. // If the FAT has so many entries that the free cluster bitmap would
  159. // be too large, we split the FAT into buckets, and only one bucket's
  160. // worth of bits are kept in the bitmap.
  161. //
  162. ULONG NumberOfWindows;
  163. PFAT_WINDOW Windows;
  164. PFAT_WINDOW CurrentWindow;
  165. //
  166. // A count of the number of file objects that have opened the volume
  167. // for direct access, and their share access state.
  168. //
  169. CLONG DirectAccessOpenCount;
  170. SHARE_ACCESS ShareAccess;
  171. //
  172. // A count of the number of file objects that have any file/directory
  173. // opened on this volume, not including direct access. And also the
  174. // count of the number of file objects that have a file opened for
  175. // only read access (i.e., they cannot be modifying the disk).
  176. //
  177. CLONG OpenFileCount;
  178. CLONG ReadOnlyCount;
  179. //
  180. // The bios parameter block field contains
  181. // an unpacked copy of the bpb for the volume, it is initialized
  182. // during mount time and can be read by everyone else after that.
  183. //
  184. BIOS_PARAMETER_BLOCK Bpb;
  185. PUCHAR First0x24BytesOfBootSector;
  186. //
  187. // The following structure contains information useful to the
  188. // allocation support routines. Many of them are computed from
  189. // elements of the Bpb, but are too involved to recompute every time
  190. // they are needed.
  191. //
  192. struct {
  193. LBO RootDirectoryLbo; // Lbo of beginning of root directory
  194. LBO FileAreaLbo; // Lbo of beginning of file area
  195. ULONG RootDirectorySize; // size of root directory in bytes
  196. ULONG NumberOfClusters; // total number of clusters on the volume
  197. ULONG NumberOfFreeClusters; // number of free clusters on the volume
  198. UCHAR FatIndexBitSize; // indicates if 12, 16, or 32 bit fat table
  199. UCHAR LogOfBytesPerSector; // Log(Bios->BytesPerSector)
  200. UCHAR LogOfBytesPerCluster; // Log(Bios->SectorsPerCluster)
  201. } AllocationSupport;
  202. //
  203. // The following Mcb is used to keep track of dirty sectors in the Fat.
  204. // Runs of holes denote clean sectors while runs of LBO == VBO denote
  205. // dirty sectors. The VBOs are that of the volume file, starting at
  206. // 0. The granuality of dirt is one sectors, and additions are only
  207. // made in sector chunks to prevent problems with several simultaneous
  208. // updaters.
  209. //
  210. LARGE_MCB DirtyFatMcb;
  211. //
  212. // The FreeClusterBitMap keeps track of all the clusters in the fat.
  213. // A 1 means occupied while a 0 means free. It allows quick location
  214. // of contiguous runs of free clusters. It is initialized on mount
  215. // or verify.
  216. //
  217. RTL_BITMAP FreeClusterBitMap;
  218. //
  219. // The following fast mutex controls access to the free cluster bit map
  220. // and the buckets.
  221. //
  222. FAST_MUTEX FreeClusterBitMapMutex;
  223. //
  224. // A resource variable to control access to the volume specific data
  225. // structures
  226. //
  227. ERESOURCE Resource;
  228. //
  229. // A resource to make sure no one changes the volume bitmap while
  230. // you're using it. Only for volumes with NumberOfWindows > 1.
  231. //
  232. ERESOURCE ChangeBitMapResource;
  233. //
  234. // The following field points to the file object used to do I/O to
  235. // the virtual volume file. The virtual volume file maps sectors
  236. // 0 through the end of fat and is of a fixed size (determined during
  237. // mount)
  238. //
  239. PFILE_OBJECT VirtualVolumeFile;
  240. //
  241. // The following field contains a record of special pointers used by
  242. // MM and Cache to manipluate section objects. Note that the values
  243. // are set outside of the file system. However the file system on an
  244. // open/create will set the file object's SectionObject field to point
  245. // to this field
  246. //
  247. SECTION_OBJECT_POINTERS SectionObjectPointers;
  248. //
  249. // The following fields is a hint cluster index used by the file system
  250. // when allocating a new cluster.
  251. //
  252. ULONG ClusterHint;
  253. //
  254. // This field contains the "DeviceObject" that this volume is
  255. // currently mounted on. Note Vcb->Vpb->RealDevice is constant.
  256. //
  257. PDEVICE_OBJECT CurrentDevice;
  258. //
  259. // This is a pointer to the file object and the Fcb which represent the ea data.
  260. //
  261. PFILE_OBJECT VirtualEaFile;
  262. struct _FCB *EaFcb;
  263. //
  264. // The following field is a pointer to the file object that has the
  265. // volume locked. if the VcbState has the locked flag set.
  266. //
  267. PFILE_OBJECT FileObjectWithVcbLocked;
  268. //
  269. // The following is the head of a list of notify Irps.
  270. //
  271. LIST_ENTRY DirNotifyList;
  272. //
  273. // The following is used to synchronize the dir notify list.
  274. //
  275. PNOTIFY_SYNC NotifySync;
  276. //
  277. // The following fast mutex is used to synchronize directory stream
  278. // file object creation.
  279. //
  280. FAST_MUTEX DirectoryFileCreationMutex;
  281. //
  282. // This field holds the thread address of the current (or most recent
  283. // depending on VcbState) thread doing a verify operation on this volume.
  284. //
  285. PKTHREAD VerifyThread;
  286. //
  287. // The following two structures are used for CleanVolume callbacks.
  288. //
  289. KDPC CleanVolumeDpc;
  290. KTIMER CleanVolumeTimer;
  291. //
  292. // This field records the last time FatMarkVolumeDirty was called, and
  293. // avoids excessive calls to push the CleanVolume forward in time.
  294. //
  295. LARGE_INTEGER LastFatMarkVolumeDirtyCall;
  296. //
  297. // The following fields holds a pointer to a struct which is used to
  298. // hold performance counters.
  299. //
  300. struct _FILE_SYSTEM_STATISTICS *Statistics;
  301. //
  302. // The property tunneling cache for this volume
  303. //
  304. TUNNEL Tunnel;
  305. //
  306. // The media change count is returned by IOCTL_CHECK_VERIFY and
  307. // is used to verify that no user-mode app has swallowed a media change
  308. // notification. This is only meaningful for removable media.
  309. //
  310. ULONG ChangeCount;
  311. //
  312. // Preallocated VPB for swapout, so we are not forced to consider
  313. // must succeed pool.
  314. //
  315. PVPB SwapVpb;
  316. //
  317. // Per volume threading of the close queues.
  318. //
  319. LIST_ENTRY AsyncCloseList;
  320. LIST_ENTRY DelayedCloseList;
  321. //
  322. // Fast mutex used by the ADVANCED FCB HEADER in this structure
  323. //
  324. FAST_MUTEX AdvancedFcbHeaderMutex;
  325. } VCB;
  326. typedef VCB *PVCB;
  327. #define VCB_STATE_FLAG_LOCKED (0x00000001)
  328. #define VCB_STATE_FLAG_REMOVABLE_MEDIA (0x00000002)
  329. #define VCB_STATE_FLAG_VOLUME_DIRTY (0x00000004)
  330. #define VCB_STATE_FLAG_MOUNTED_DIRTY (0x00000010)
  331. #define VCB_STATE_FLAG_SHUTDOWN (0x00000040)
  332. #define VCB_STATE_FLAG_CLOSE_IN_PROGRESS (0x00000080)
  333. #define VCB_STATE_FLAG_DELETED_FCB (0x00000100)
  334. #define VCB_STATE_FLAG_CREATE_IN_PROGRESS (0x00000200)
  335. #define VCB_STATE_FLAG_BOOT_OR_PAGING_FILE (0x00000800)
  336. #define VCB_STATE_FLAG_DEFERRED_FLUSH (0x00001000)
  337. #define VCB_STATE_FLAG_ASYNC_CLOSE_ACTIVE (0x00002000)
  338. #define VCB_STATE_FLAG_WRITE_PROTECTED (0x00004000)
  339. #define VCB_STATE_FLAG_REMOVAL_PREVENTED (0x00008000)
  340. #define VCB_STATE_FLAG_VOLUME_DISMOUNTED (0x00010000)
  341. //
  342. // N.B - VOLUME_DISMOUNTED is an indication that FSCTL_DISMOUNT volume was
  343. // executed on a volume. It does not replace VcbCondition as an indication
  344. // that the volume is invalid/unrecoverable.
  345. //
  346. //
  347. // Define the file system statistics struct. Vcb->Statistics points to an
  348. // array of these (one per processor) and they must be 64 byte aligned to
  349. // prevent cache line tearing.
  350. //
  351. typedef struct _FILE_SYSTEM_STATISTICS {
  352. //
  353. // This contains the actual data.
  354. //
  355. FILESYSTEM_STATISTICS Common;
  356. FAT_STATISTICS Fat;
  357. //
  358. // Pad this structure to a multiple of 64 bytes.
  359. //
  360. UCHAR Pad[64-(sizeof(FILESYSTEM_STATISTICS)+sizeof(FAT_STATISTICS))%64];
  361. } FILE_SYSTEM_STATISTICS;
  362. typedef FILE_SYSTEM_STATISTICS *PFILE_SYSTEM_STATISTICS;
  363. //
  364. // The Volume Device Object is an I/O system device object with a workqueue
  365. // and an VCB record appended to the end. There are multiple of these
  366. // records, one for every mounted volume, and are created during
  367. // a volume mount operation. The work queue is for handling an overload of
  368. // work requests to the volume.
  369. //
  370. typedef struct _VOLUME_DEVICE_OBJECT {
  371. DEVICE_OBJECT DeviceObject;
  372. //
  373. // The following field tells how many requests for this volume have
  374. // either been enqueued to ExWorker threads or are currently being
  375. // serviced by ExWorker threads. If the number goes above
  376. // a certain threshold, put the request on the overflow queue to be
  377. // executed later.
  378. //
  379. ULONG PostedRequestCount;
  380. //
  381. // The following field indicates the number of IRP's waiting
  382. // to be serviced in the overflow queue.
  383. //
  384. ULONG OverflowQueueCount;
  385. //
  386. // The following field contains the queue header of the overflow queue.
  387. // The Overflow queue is a list of IRP's linked via the IRP's ListEntry
  388. // field.
  389. //
  390. LIST_ENTRY OverflowQueue;
  391. //
  392. // The following spinlock protects access to all the above fields.
  393. //
  394. KSPIN_LOCK OverflowQueueSpinLock;
  395. //
  396. // This is a common head for the FAT volume file
  397. //
  398. FSRTL_COMMON_FCB_HEADER VolumeFileHeader;
  399. //
  400. // This is the file system specific volume control block.
  401. //
  402. VCB Vcb;
  403. } VOLUME_DEVICE_OBJECT;
  404. typedef VOLUME_DEVICE_OBJECT *PVOLUME_DEVICE_OBJECT;
  405. //
  406. // This is the structure used to contains the short name for a file
  407. //
  408. typedef struct _FILE_NAME_NODE {
  409. //
  410. // This points back to the Fcb for this file.
  411. //
  412. struct _FCB *Fcb;
  413. //
  414. // This is the name of this node.
  415. //
  416. union {
  417. OEM_STRING Oem;
  418. UNICODE_STRING Unicode;
  419. } Name;
  420. //
  421. // Marker so we can figure out what kind of name we opened up in
  422. // Fcb searches
  423. //
  424. BOOLEAN FileNameDos;
  425. //
  426. // And the links. Our parent Dcb has a pointer to the root entry.
  427. //
  428. RTL_SPLAY_LINKS Links;
  429. } FILE_NAME_NODE;
  430. typedef FILE_NAME_NODE *PFILE_NAME_NODE;
  431. //
  432. // This structure contains fields which must be in non-paged pool.
  433. //
  434. typedef struct _NON_PAGED_FCB {
  435. //
  436. // The following field contains a record of special pointers used by
  437. // MM and Cache to manipluate section objects. Note that the values
  438. // are set outside of the file system. However the file system on an
  439. // open/create will set the file object's SectionObject field to point
  440. // to this field
  441. //
  442. SECTION_OBJECT_POINTERS SectionObjectPointers;
  443. //
  444. // This context is non-zero only if the file currently has asynchronous
  445. // non-cached valid data length extending writes. It allows
  446. // synchronization between pending writes and other operations.
  447. //
  448. ULONG OutstandingAsyncWrites;
  449. //
  450. // This event is set when OutstandingAsyncWrites transitions to zero.
  451. //
  452. PKEVENT OutstandingAsyncEvent;
  453. //
  454. // This is the mutex that is inserted into the FCB_ADVANCED_HEADER
  455. // FastMutex field
  456. //
  457. FAST_MUTEX AdvancedFcbHeaderMutex;
  458. } NON_PAGED_FCB;
  459. typedef NON_PAGED_FCB *PNON_PAGED_FCB;
  460. //
  461. // The Fcb/Dcb record corresponds to every open file and directory, and to
  462. // every directory on an opened path. They are ordered in two queues, one
  463. // queue contains every Fcb/Dcb record off of FatData.FcbQueue, the other
  464. // queue contains only device specific records off of Vcb.VcbSpecificFcbQueue
  465. //
  466. typedef enum _FCB_CONDITION {
  467. FcbGood = 1,
  468. FcbBad,
  469. FcbNeedsToBeVerified
  470. } FCB_CONDITION;
  471. typedef struct _FCB {
  472. //
  473. // The following field is used for fast I/O
  474. //
  475. // The following comments refer to the use of the AllocationSize field
  476. // of the FsRtl-defined header to the nonpaged Fcb.
  477. //
  478. // For a directory when we create a Dcb we will not immediately
  479. // initialize the cache map, instead we will postpone it until our first
  480. // call to FatReadDirectoryFile or FatPrepareWriteDirectoryFile.
  481. // At that time we will search the Fat to find out the current allocation
  482. // size (by calling FatLookupFileAllocationSize) and then initialize the
  483. // cache map to this allocation size.
  484. //
  485. // For a file when we create an Fcb we will not immediately initialize
  486. // the cache map, instead we will postpone it until we need it and
  487. // then we determine the allocation size from either searching the
  488. // fat to determine the real file allocation, or from the allocation
  489. // that we've just allocated if we're creating a file.
  490. //
  491. // A value of -1 indicates that we do not know what the current allocation
  492. // size really is, and need to examine the fat to find it. A value
  493. // of than -1 is the real file/directory allocation size.
  494. //
  495. // Whenever we need to extend the allocation size we call
  496. // FatAddFileAllocation which (if we're really extending the allocation)
  497. // will modify the Fat, Mcb, and update this field. The caller
  498. // of FatAddFileAllocation is then responsible for altering the Cache
  499. // map size.
  500. //
  501. // We are now using the ADVANCED fcb header to support filter contexts
  502. // at the stream level
  503. //
  504. FSRTL_ADVANCED_FCB_HEADER Header;
  505. //
  506. // This structure contains fields which must be in non-paged pool.
  507. //
  508. PNON_PAGED_FCB NonPaged;
  509. //
  510. // The head of the fat alloaction chain. FirstClusterOfFile == 0
  511. // means that the file has no current allocation.
  512. //
  513. ULONG FirstClusterOfFile;
  514. //
  515. // The links for the queue of all fcbs for a specific dcb off of
  516. // Dcb.ParentDcbQueue. For the root directory this queue is empty
  517. // For a non-existent fcb this queue is off of the non existent
  518. // fcb queue entry in the vcb.
  519. //
  520. LIST_ENTRY ParentDcbLinks;
  521. //
  522. // A pointer to the Dcb that is the parent directory containing
  523. // this fcb. If this record itself is the root dcb then this field
  524. // is null.
  525. //
  526. struct _FCB *ParentDcb;
  527. //
  528. // A pointer to the Vcb containing this Fcb
  529. //
  530. PVCB Vcb;
  531. //
  532. // The internal state of the Fcb. This is a collection Fcb state flags.
  533. // Also the shared access for each time this file/directory is opened.
  534. //
  535. ULONG FcbState;
  536. FCB_CONDITION FcbCondition;
  537. SHARE_ACCESS ShareAccess;
  538. #ifdef SYSCACHE_COMPILE
  539. //
  540. // For syscache we keep a bitmask that tells us if we have dispatched IO for
  541. // the page aligned chunks of the stream.
  542. //
  543. PULONG WriteMask;
  544. ULONG WriteMaskData;
  545. #endif
  546. //
  547. // A count of the number of file objects that have been opened for
  548. // this file/directory, but not yet been cleaned up yet. This count
  549. // is only used for data file objects, not for the Acl or Ea stream
  550. // file objects. This count gets decremented in FatCommonCleanup,
  551. // while the OpenCount below gets decremented in FatCommonClose.
  552. //
  553. CLONG UncleanCount;
  554. //
  555. // A count of the number of file objects that have opened
  556. // this file/directory. For files & directories the FsContext of the
  557. // file object points to this record.
  558. //
  559. CLONG OpenCount;
  560. //
  561. // A count of how many of "UncleanCount" handles were opened for
  562. // non-cached I/O.
  563. //
  564. CLONG NonCachedUncleanCount;
  565. //
  566. // The following field is used to locate the dirent for this fcb/dcb.
  567. // All directory are opened as mapped files so the only additional
  568. // information we need to locate this dirent (beside its parent directory)
  569. // is the byte offset for the dirent. Note that for the root dcb
  570. // this field is not used.
  571. //
  572. VBO DirentOffsetWithinDirectory;
  573. //
  574. // The following field is filled in when there is an Lfn associated
  575. // with this file. It is the STARTING offset of the Lfn.
  576. //
  577. VBO LfnOffsetWithinDirectory;
  578. //
  579. // Thess entries is kept in ssync with the dirent. It allows a more
  580. // accurate verify capability and speeds up FatFastQueryBasicInfo().
  581. //
  582. LARGE_INTEGER CreationTime;
  583. LARGE_INTEGER LastAccessTime;
  584. LARGE_INTEGER LastWriteTime;
  585. //
  586. // Valid data to disk
  587. //
  588. ULONG ValidDataToDisk;
  589. //
  590. // The following field contains the retrieval mapping structure
  591. // for the file/directory. Note that for the Root Dcb this
  592. // structure is set at mount time. Also note that in this
  593. // implementation of Fat the Mcb really maps VBOs to LBOs and not
  594. // VBNs to LBNs.
  595. //
  596. LARGE_MCB Mcb;
  597. //
  598. // The following union is cased off of the node type code for the fcb.
  599. // There is a seperate case for the directory versus file fcbs.
  600. //
  601. union {
  602. //
  603. // A Directory Control Block (Dcb)
  604. //
  605. struct {
  606. //
  607. // A queue of all the fcbs/dcbs that are opened under this
  608. // Dcb.
  609. //
  610. LIST_ENTRY ParentDcbQueue;
  611. //
  612. // The following field points to the file object used to do I/O to
  613. // the directory file for this dcb. The directory file maps the
  614. // sectors for the directory. This field is initialized by
  615. // CreateRootDcb but is left null by CreateDcb. It isn't
  616. // until we try to read/write the directory file that we
  617. // create the stream file object for non root dcbs.
  618. //
  619. ULONG DirectoryFileOpenCount;
  620. PFILE_OBJECT DirectoryFile;
  621. //
  622. // If the UnusedDirentVbo is != 0xffffffff, then the dirent at this
  623. // offset is guarenteed to unused. A value of 0xffffffff means
  624. // it has yet to be initialized. Note that a value beyond the
  625. // end of allocation means that there an unused dirent, but we
  626. // will have to allocate another cluster to use it.
  627. //
  628. // DeletedDirentHint contains lowest possible VBO of a deleted
  629. // dirent (assuming as above that it is not 0xffffffff).
  630. //
  631. VBO UnusedDirentVbo;
  632. VBO DeletedDirentHint;
  633. //
  634. // The following two entries links together all the Fcbs
  635. // opened under this Dcb sorted in a splay tree by name.
  636. //
  637. // I'd like to go into why we have (and must have) two separate
  638. // splay trees within the current fastfat architecture. I will
  639. // provide some insight into what would have to change if we
  640. // wanted to have a single UNICODE tree.
  641. //
  642. // What makes FAT unique is that both Oem and Unicode names sit
  643. // side by side on disk. Several unique UNICODE names coming
  644. // into fastfat can match a single OEM on-disk name, and there
  645. // is really no way to enumerate all the possible UNICODE
  646. // source strings that can map to a given OEM name. This argues
  647. // for converting the incomming UNICODE name into OEM, and then
  648. // running through an OEM splay tree of the open files. This
  649. // works well when there are only OEM names on disk.
  650. //
  651. // The UNICODE name on disk can be VERY different from the short
  652. // name in the DIRENT and not even representable in the OEM code
  653. // page. Even if it were representable in OEM, it is possible
  654. // that a case varient of the original UNICODE name would match
  655. // a different OEM name, causing us to miss the Fcb in the
  656. // prefix lookup phase. In these cases, we must put UNICODE
  657. // name in the splay to guarentee that we find any case varient
  658. // of the input UNICODE name. See the routine description of
  659. // FatConstructNamesInFcb() for a detailed analysis of how we
  660. // detect this case.
  661. //
  662. // The fundamental limitation we are imposing here is that if
  663. // an Fcb exists for an open file, we MUST find it during the
  664. // prefix stage. This is a basic premise of the create path
  665. // in fastfat. In fact if we later find it gravelling through
  666. // the disk (but not the splay tree), we will bug check if we
  667. // try to add a duplicate entry to the splay tree (not to
  668. // mention having two Fcbs). If we had some mechanism to deal
  669. // with cases (and they would be rare) that we don't find the
  670. // entry in the splay tree, but the Fcb is actually in there,
  671. // then we could go to a single UNICODE splay tree. While
  672. // this uses more pool for the splay tree, and makes string
  673. // compares maybe take a bit as longer, it would eliminate the
  674. // need for any NLS conversion during the prefix phase, so it
  675. // might really be a net win.
  676. //
  677. // The current scheme was optimized for non-extended names
  678. // (i.e. US names). As soon as you start using extended
  679. // characters, then it is clearly a win as many code paths
  680. // become active that would otherwise not be needed if we
  681. // only had a single UNICODE splay tree.
  682. //
  683. // We may think about changing this someday.
  684. //
  685. PRTL_SPLAY_LINKS RootOemNode;
  686. PRTL_SPLAY_LINKS RootUnicodeNode;
  687. //
  688. // The following field keeps track of free dirents, i.e.,
  689. // dirents that are either unallocated for deleted.
  690. //
  691. RTL_BITMAP FreeDirentBitmap;
  692. //
  693. // Since the FCB specific part of this union is larger, use
  694. // the slack here for an initial bitmap buffer. Currently
  695. // there is enough space here for an 8K cluster.
  696. //
  697. ULONG FreeDirentBitmapBuffer[1];
  698. } Dcb;
  699. //
  700. // A File Control Block (Fcb)
  701. //
  702. struct {
  703. //
  704. // The following field is used by the filelock module
  705. // to maintain current byte range locking information.
  706. //
  707. FILE_LOCK FileLock;
  708. //
  709. // The following field is used by the oplock module
  710. // to maintain current oplock information.
  711. //
  712. OPLOCK Oplock;
  713. //
  714. // This pointer is used to detect writes that eminated in the
  715. // cache manager's lazywriter. It prevents lazy writer threads,
  716. // who already have the Fcb shared, from trying to acquire it
  717. // exclusive, and thus causing a deadlock.
  718. //
  719. PVOID LazyWriteThread;
  720. } Fcb;
  721. } Specific;
  722. //
  723. // The following field is used to verify that the Ea's for a file
  724. // have not changed between calls to query for Ea's. It is compared
  725. // with a similar field in a Ccb.
  726. //
  727. // IMPORTANT!! **** DO NOT MOVE THIS FIELD ****
  728. //
  729. // The slack space in the union above is computed from
  730. // the field offset of the EaModificationCount.
  731. //
  732. ULONG EaModificationCount;
  733. //
  734. // The following field is the fully qualified file name for this FCB/DCB
  735. // starting from the root of the volume, and last file name in the
  736. // fully qualified name.
  737. //
  738. FILE_NAME_NODE ShortName;
  739. //
  740. // The following field is only filled in if it is needed with the user's
  741. // opened path
  742. //
  743. UNICODE_STRING FullFileName;
  744. USHORT FinalNameLength;
  745. //
  746. // To make life simpler we also keep in the Fcb/Dcb a current copy of
  747. // the fat attribute byte for the file/directory. This field must
  748. // also be updated when we create the Fcb, modify the File, or verify
  749. // the Fcb
  750. //
  751. UCHAR DirentFatFlags;
  752. //
  753. // The case preserved long filename
  754. //
  755. UNICODE_STRING ExactCaseLongName;
  756. //
  757. // If the UNICODE Lfn is fully expressible in the system Oem code
  758. // page, then we will store it in a prefix table, otherwise we will
  759. // store the last UNICODE name in the Fcb. In both cases the name
  760. // has been upcased.
  761. //
  762. // Note that we may need neither of these fields if an LFN was strict
  763. // 8.3 or differed only in case. Indeed if there wasn't an LFN, we
  764. // don't need them at all.
  765. //
  766. union {
  767. //
  768. // This first field is present if FCB_STATE_HAS_OEM_LONG_NAME
  769. // is set in the FcbState.
  770. //
  771. FILE_NAME_NODE Oem;
  772. //
  773. // This first field is present if FCB_STATE_HAS_UNICODE_LONG_NAME
  774. // is set in the FcbState.
  775. //
  776. FILE_NAME_NODE Unicode;
  777. } LongName;
  778. //
  779. // Defragmentation / ReallocateOnWrite synchronization object. This
  780. // is filled in by FatMoveFile() and affects the read and write paths.
  781. //
  782. PKEVENT MoveFileEvent;
  783. } FCB, *PFCB;
  784. #ifndef BUILDING_FSKDEXT
  785. //
  786. // DCB clashes with a type defined outside the filesystems, in headers
  787. // pulled in by FSKD. We don't need this typedef for fskd anyway....
  788. //
  789. typedef FCB DCB;
  790. typedef DCB *PDCB;
  791. #endif
  792. //
  793. // Here are the Fcb state fields.
  794. //
  795. #define FCB_STATE_DELETE_ON_CLOSE (0x00000001)
  796. #define FCB_STATE_TRUNCATE_ON_CLOSE (0x00000002)
  797. #define FCB_STATE_PAGING_FILE (0x00000004)
  798. #define FCB_STATE_FORCE_MISS_IN_PROGRESS (0x00000008)
  799. #define FCB_STATE_FLUSH_FAT (0x00000010)
  800. #define FCB_STATE_TEMPORARY (0x00000020)
  801. #define FCB_STATE_SYSTEM_FILE (0x00000080)
  802. #define FCB_STATE_NAMES_IN_SPLAY_TREE (0x00000100)
  803. #define FCB_STATE_HAS_OEM_LONG_NAME (0x00000200)
  804. #define FCB_STATE_HAS_UNICODE_LONG_NAME (0x00000400)
  805. #define FCB_STATE_DELAY_CLOSE (0x00000800)
  806. //
  807. // Copies of the dirent's FAT_DIRENT_NT_BYTE_* flags for
  808. // preserving case of the short name of a file
  809. //
  810. #define FCB_STATE_8_LOWER_CASE (0x00001000)
  811. #define FCB_STATE_3_LOWER_CASE (0x00002000)
  812. //
  813. // This is the slack allocation in the Dcb part of the UNION above
  814. //
  815. #define DCB_UNION_SLACK_SPACE ((ULONG) \
  816. (FIELD_OFFSET(DCB, EaModificationCount) - \
  817. FIELD_OFFSET(DCB, Specific.Dcb.FreeDirentBitmapBuffer)) \
  818. )
  819. //
  820. // This is the special (64bit) allocation size that indicates the
  821. // real size must be retrieved from disk. Define it here so we
  822. // avoid excessive magic numbering around the driver.
  823. //
  824. #define FCB_LOOKUP_ALLOCATIONSIZE_HINT ((LONGLONG) -1)
  825. //
  826. // The Ccb record is allocated for every file object. Note that this
  827. // record is exactly 0x34 long on x86 so that it will fit into a 0x40
  828. // piece of pool. Please carefully consider modifications.
  829. //
  830. // Define the Flags field.
  831. //
  832. #define CCB_FLAG_MATCH_ALL (0x0001)
  833. #define CCB_FLAG_SKIP_SHORT_NAME_COMPARE (0x0002)
  834. //
  835. // This tells us whether we allocated buffers to hold search templates.
  836. //
  837. #define CCB_FLAG_FREE_OEM_BEST_FIT (0x0004)
  838. #define CCB_FLAG_FREE_UNICODE (0x0008)
  839. //
  840. // These flags prevents cleanup from updating the modify time, etc.
  841. //
  842. #define CCB_FLAG_USER_SET_LAST_WRITE (0x0010)
  843. #define CCB_FLAG_USER_SET_LAST_ACCESS (0x0020)
  844. #define CCB_FLAG_USER_SET_CREATION (0x0040)
  845. //
  846. // This bit says the file object associated with this Ccb was opened for
  847. // read only access.
  848. //
  849. #define CCB_FLAG_READ_ONLY (0x0080)
  850. //
  851. // These flags, are used is DASD handles in read and write.
  852. //
  853. #define CCB_FLAG_DASD_FLUSH_DONE (0x0100)
  854. #define CCB_FLAG_DASD_PURGE_DONE (0x0200)
  855. //
  856. // This flag keeps track of a handle that was opened for
  857. // DELETE_ON_CLOSE.
  858. //
  859. #define CCB_FLAG_DELETE_ON_CLOSE (0x0400)
  860. //
  861. // This flag keeps track of which side of the name pair on the file
  862. // associated with the handle was opened
  863. //
  864. #define CCB_FLAG_OPENED_BY_SHORTNAME (0x0800)
  865. //
  866. // This flag indicates that the query template has not been upcased
  867. // (i.e., query should be case-insensitive)
  868. //
  869. #define CCB_FLAG_QUERY_TEMPLATE_MIXED (0x1000)
  870. //
  871. // This flag indicates that reads and writes via this DASD handle
  872. // are allowed to start or extend past the end of file.
  873. //
  874. #define CCB_FLAG_ALLOW_EXTENDED_DASD_IO (0x2000)
  875. //
  876. // This flag indicates we want to match volume labels in directory
  877. // searches (important for the root dir defrag).
  878. //
  879. #define CCB_FLAG_MATCH_VOLUME_ID (0x4000)
  880. //
  881. // This flag indicates the ccb has been converted over into a
  882. // close context for asynchronous/delayed closing of the handle.
  883. //
  884. #define CCB_FLAG_CLOSE_CONTEXT (0x8000)
  885. //
  886. // This flag indicates that when the handle is closed, we want
  887. // a physical dismount to occur.
  888. //
  889. #define CCB_FLAG_COMPLETE_DISMOUNT (0x10000)
  890. //
  891. // This flag indicates the handle may not call priveleged
  892. // FSCTL which modify the volume.
  893. //
  894. #define CCB_FLAG_MANAGE_VOLUME_ACCESS (0x20000)
  895. //
  896. // This structure is used to keep track of information needed to do a
  897. // deferred close. It is now embedded in a CCB so we don't have to
  898. // allocate one in the close path (with mustsucceed).
  899. //
  900. typedef struct _CLOSE_CONTEXT {
  901. //
  902. // Two sets of links, one for the global list and one for closes
  903. // on a particular volume.
  904. //
  905. LIST_ENTRY GlobalLinks;
  906. LIST_ENTRY VcbLinks;
  907. PVCB Vcb;
  908. PFCB Fcb;
  909. enum _TYPE_OF_OPEN TypeOfOpen;
  910. BOOLEAN Free;
  911. } CLOSE_CONTEXT;
  912. typedef CLOSE_CONTEXT *PCLOSE_CONTEXT;
  913. typedef struct _CCB {
  914. //
  915. // Type and size of this record (must be FAT_NTC_CCB)
  916. //
  917. NODE_TYPE_CODE NodeTypeCode;
  918. NODE_BYTE_SIZE NodeByteSize;
  919. //
  920. // Define a 24bit wide field for Flags, but a UCHAR for Wild Cards Present
  921. // since it is used so often. Line these up on byte boundaries for grins.
  922. //
  923. ULONG Flags:24;
  924. BOOLEAN ContainsWildCards;
  925. //
  926. // Overlay a close context on the data of the CCB. The remaining
  927. // fields are not useful during close, and we would like to avoid
  928. // paying extra pool for it.
  929. //
  930. union {
  931. struct {
  932. //
  933. // Save the offset to start search from.
  934. //
  935. VBO OffsetToStartSearchFrom;
  936. //
  937. // The query template is used to filter directory query requests.
  938. // It originally is set to null and on the first call the NtQueryDirectory
  939. // it is set to the input filename or "*" if the name is not supplied.
  940. // All subsquent queries then use this template.
  941. //
  942. // The Oem structure are unions because if the name is wild we store
  943. // the arbitrary length string, while if the name is constant we store
  944. // 8.3 representation for fast comparison.
  945. //
  946. union {
  947. //
  948. // If the template contains a wild card use this.
  949. //
  950. OEM_STRING Wild;
  951. //
  952. // If the name is constant, use this part.
  953. //
  954. FAT8DOT3 Constant;
  955. } OemQueryTemplate;
  956. UNICODE_STRING UnicodeQueryTemplate;
  957. //
  958. // The field is compared with the similar field in the Fcb to determine
  959. // if the Ea's for a file have been modified.
  960. //
  961. ULONG EaModificationCount;
  962. //
  963. // The following field is used as an offset into the Eas for a
  964. // particular file. This will be the offset for the next
  965. // Ea to return. A value of 0xffffffff indicates that the
  966. // Ea's are exhausted.
  967. //
  968. ULONG OffsetOfNextEaToReturn;
  969. };
  970. CLOSE_CONTEXT CloseContext;
  971. };
  972. } CCB;
  973. typedef CCB *PCCB;
  974. //
  975. // The Irp Context record is allocated for every orginating Irp. It is
  976. // created by the Fsd dispatch routines, and deallocated by the FatComplete
  977. // request routine. It contains a structure called of type REPINNED_BCBS
  978. // which is used to retain pinned bcbs needed to handle abnormal termination
  979. // unwinding.
  980. //
  981. #define REPINNED_BCBS_ARRAY_SIZE (4)
  982. typedef struct _REPINNED_BCBS {
  983. //
  984. // A pointer to the next structure contains additional repinned bcbs
  985. //
  986. struct _REPINNED_BCBS *Next;
  987. //
  988. // A fixed size array of pinned bcbs. Whenever a new bcb is added to
  989. // the repinned bcb structure it is added to this array. If the
  990. // array is already full then another repinned bcb structure is allocated
  991. // and pointed to with Next.
  992. //
  993. PBCB Bcb[ REPINNED_BCBS_ARRAY_SIZE ];
  994. } REPINNED_BCBS;
  995. typedef REPINNED_BCBS *PREPINNED_BCBS;
  996. typedef struct _IRP_CONTEXT {
  997. //
  998. // Type and size of this record (must be FAT_NTC_IRP_CONTEXT)
  999. //
  1000. NODE_TYPE_CODE NodeTypeCode;
  1001. NODE_BYTE_SIZE NodeByteSize;
  1002. //
  1003. // This structure is used for posting to the Ex worker threads.
  1004. //
  1005. WORK_QUEUE_ITEM WorkQueueItem;
  1006. //
  1007. // A pointer to the originating Irp.
  1008. //
  1009. PIRP OriginatingIrp;
  1010. //
  1011. // Originating Device (required for workque algorithms)
  1012. //
  1013. PDEVICE_OBJECT RealDevice;
  1014. //
  1015. // Originating Vcb (required for exception handling)
  1016. // On mounts, this will be set before any exceptions
  1017. // indicating corruption can be thrown.
  1018. //
  1019. PVCB Vcb;
  1020. //
  1021. // Major and minor function codes copied from the Irp
  1022. //
  1023. UCHAR MajorFunction;
  1024. UCHAR MinorFunction;
  1025. //
  1026. // The following fields indicate if we can wait/block for a resource
  1027. // or I/O, if we are to do everything write through, and if this
  1028. // entry into the Fsd is a recursive call.
  1029. //
  1030. UCHAR PinCount;
  1031. ULONG Flags;
  1032. //
  1033. // The following field contains the NTSTATUS value used when we are
  1034. // unwinding due to an exception
  1035. //
  1036. NTSTATUS ExceptionStatus;
  1037. //
  1038. // The following context block is used for non-cached Io
  1039. //
  1040. struct _FAT_IO_CONTEXT *FatIoContext;
  1041. //
  1042. // For a abnormal termination unwinding this field contains the Bcbs
  1043. // that are kept pinned until the Irp is completed.
  1044. //
  1045. REPINNED_BCBS Repinned;
  1046. } IRP_CONTEXT;
  1047. typedef IRP_CONTEXT *PIRP_CONTEXT;
  1048. #define IRP_CONTEXT_FLAG_DISABLE_DIRTY (0x00000001)
  1049. #define IRP_CONTEXT_FLAG_WAIT (0x00000002)
  1050. #define IRP_CONTEXT_FLAG_WRITE_THROUGH (0x00000004)
  1051. #define IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH (0x00000008)
  1052. #define IRP_CONTEXT_FLAG_RECURSIVE_CALL (0x00000010)
  1053. #define IRP_CONTEXT_FLAG_DISABLE_POPUPS (0x00000020)
  1054. #define IRP_CONTEXT_FLAG_DEFERRED_WRITE (0x00000040)
  1055. #define IRP_CONTEXT_FLAG_VERIFY_READ (0x00000080)
  1056. #define IRP_CONTEXT_STACK_IO_CONTEXT (0x00000100)
  1057. #define IRP_CONTEXT_FLAG_IN_FSP (0x00000200)
  1058. #define IRP_CONTEXT_FLAG_USER_IO (0x00000400) // for performance counters
  1059. #define IRP_CONTEXT_FLAG_DISABLE_RAISE (0x00000800)
  1060. #define IRP_CONTEXT_FLAG_PARENT_BY_CHILD (0x80000000)
  1061. //
  1062. // Context structure for non-cached I/O calls. Most of these fields
  1063. // are actually only required for the Read/Write Multiple routines, but
  1064. // the caller must allocate one as a local variable anyway before knowing
  1065. // whether there are multiple requests are not. Therefore, a single
  1066. // structure is used for simplicity.
  1067. //
  1068. typedef struct _FAT_IO_CONTEXT {
  1069. //
  1070. // These two field are used for multiple run Io
  1071. //
  1072. LONG IrpCount;
  1073. PIRP MasterIrp;
  1074. //
  1075. // MDL to describe partial sector zeroing
  1076. //
  1077. PMDL ZeroMdl;
  1078. union {
  1079. //
  1080. // This element handles the asychronous non-cached Io
  1081. //
  1082. struct {
  1083. PERESOURCE Resource;
  1084. PERESOURCE Resource2;
  1085. ERESOURCE_THREAD ResourceThreadId;
  1086. ULONG RequestedByteCount;
  1087. PFILE_OBJECT FileObject;
  1088. PNON_PAGED_FCB NonPagedFcb;
  1089. } Async;
  1090. //
  1091. // and this element the sycnrhonous non-cached Io
  1092. //
  1093. KEVENT SyncEvent;
  1094. } Wait;
  1095. } FAT_IO_CONTEXT;
  1096. typedef FAT_IO_CONTEXT *PFAT_IO_CONTEXT;
  1097. //
  1098. // An array of these structures is passed to FatMultipleAsync describing
  1099. // a set of runs to execute in parallel.
  1100. //
  1101. typedef struct _IO_RUNS {
  1102. LBO Lbo;
  1103. VBO Vbo;
  1104. ULONG Offset;
  1105. ULONG ByteCount;
  1106. PIRP SavedIrp;
  1107. } IO_RUN;
  1108. typedef IO_RUN *PIO_RUN;
  1109. //
  1110. // This structure is used by FatDeleteDirent to preserve the first cluster
  1111. // and file size info for undelete utilities.
  1112. //
  1113. typedef struct _DELETE_CONTEXT {
  1114. ULONG FileSize;
  1115. ULONG FirstClusterOfFile;
  1116. } DELETE_CONTEXT;
  1117. typedef DELETE_CONTEXT *PDELETE_CONTEXT;
  1118. //
  1119. // This record is used with to set a flush to go off one second after the
  1120. // first write on slow devices with a physical indication of activity, like
  1121. // a floppy. This is an attempt to keep the red light on.
  1122. //
  1123. typedef struct _DEFERRED_FLUSH_CONTEXT {
  1124. KDPC Dpc;
  1125. KTIMER Timer;
  1126. WORK_QUEUE_ITEM Item;
  1127. PFILE_OBJECT File;
  1128. } DEFERRED_FLUSH_CONTEXT;
  1129. typedef DEFERRED_FLUSH_CONTEXT *PDEFERRED_FLUSH_CONTEXT;
  1130. //
  1131. // This structure is used for the FatMarkVolumeClean callbacks.
  1132. //
  1133. typedef struct _CLEAN_AND_DIRTY_VOLUME_PACKET {
  1134. WORK_QUEUE_ITEM Item;
  1135. PIRP Irp;
  1136. PVCB Vcb;
  1137. PKEVENT Event;
  1138. } CLEAN_AND_DIRTY_VOLUME_PACKET, *PCLEAN_AND_DIRTY_VOLUME_PACKET;
  1139. //
  1140. // This structure is used when a page fault is running out of stack.
  1141. //
  1142. typedef struct _PAGING_FILE_OVERFLOW_PACKET {
  1143. PIRP Irp;
  1144. PFCB Fcb;
  1145. } PAGING_FILE_OVERFLOW_PACKET, *PPAGING_FILE_OVERFLOW_PACKET;
  1146. //
  1147. // This structure is used to access the EaFile.
  1148. //
  1149. #define EA_BCB_ARRAY_SIZE 8
  1150. typedef struct _EA_RANGE {
  1151. PCHAR Data;
  1152. ULONG StartingVbo;
  1153. ULONG Length;
  1154. USHORT BcbChainLength;
  1155. BOOLEAN AuxilaryBuffer;
  1156. PBCB *BcbChain;
  1157. PBCB BcbArray[EA_BCB_ARRAY_SIZE];
  1158. } EA_RANGE, *PEA_RANGE;
  1159. #define EA_RANGE_HEADER_SIZE (FIELD_OFFSET( EA_RANGE, BcbArray ))
  1160. //
  1161. // These symbols are used by the upcase/downcase routines.
  1162. //
  1163. #define WIDE_LATIN_CAPITAL_A (0xff21)
  1164. #define WIDE_LATIN_CAPITAL_Z (0xff3a)
  1165. #define WIDE_LATIN_SMALL_A (0xff41)
  1166. #define WIDE_LATIN_SMALL_Z (0xff5a)
  1167. //
  1168. // These values are returned by FatInterpretClusterType.
  1169. //
  1170. typedef enum _CLUSTER_TYPE {
  1171. FatClusterAvailable,
  1172. FatClusterReserved,
  1173. FatClusterBad,
  1174. FatClusterLast,
  1175. FatClusterNext
  1176. } CLUSTER_TYPE;
  1177. #endif // _FATSTRUC_