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.

2763 lines
64 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. FatProcs.h
  5. Abstract:
  6. This module defines all of the globally used procedures in the FAT
  7. file system.
  8. // @@BEGIN_DDKSPLIT
  9. Author:
  10. Gary Kimura [GaryKi] 28-Dec-1989
  11. Revision History:
  12. // @@END_DDKSPLIT
  13. --*/
  14. #ifndef _FATPROCS_
  15. #define _FATPROCS_
  16. #include <ntifs.h>
  17. #include <ntddcdrm.h>
  18. #include <ntdddisk.h>
  19. #include <ntddstor.h>
  20. #include "nodetype.h"
  21. #include "Fat.h"
  22. #include "Lfn.h"
  23. #include "FatStruc.h"
  24. #include "FatData.h"
  25. #ifndef INLINE
  26. #define INLINE __inline
  27. #endif
  28. //
  29. // We must explicitly tag our allocations.
  30. //
  31. #undef FsRtlAllocatePool
  32. #undef FsRtlAllocatePoolWithQuota
  33. //
  34. // A function that returns finished denotes if it was able to complete the
  35. // operation (TRUE) or could not complete the operation (FALSE) because the
  36. // wait value stored in the irp context was false and we would have had
  37. // to block for a resource or I/O
  38. //
  39. typedef BOOLEAN FINISHED;
  40. //
  41. // Size (characters) of stack allocated name component buffers in
  42. // the create/rename paths.
  43. //
  44. #define FAT_CREATE_INITIAL_NAME_BUF_SIZE 32
  45. //
  46. // Some string buffer handling functions, implemented in strucsup.c
  47. //
  48. VOID
  49. FatFreeStringBuffer(
  50. IN PVOID String
  51. );
  52. VOID
  53. FatEnsureStringBufferEnough(
  54. IN OUT PVOID String,
  55. IN USHORT DesiredBufferSize
  56. );
  57. BOOLEAN
  58. FatAddMcbEntry (
  59. IN PVCB Vcb,
  60. IN PLARGE_MCB Mcb,
  61. IN VBO Vbo,
  62. IN LBO Lbo,
  63. IN ULONG SectorCount
  64. );
  65. BOOLEAN
  66. FatLookupMcbEntry (
  67. IN PVCB Vcb,
  68. IN PLARGE_MCB Mcb,
  69. IN VBO Vbo,
  70. OUT PLBO Lbo,
  71. OUT PULONG SectorCount OPTIONAL,
  72. OUT PULONG Index OPTIONAL
  73. );
  74. BOOLEAN
  75. FatLookupLastMcbEntry (
  76. IN PVCB Vcb,
  77. IN PLARGE_MCB Mcb,
  78. OUT PVBO Vbo,
  79. OUT PLBO Lbo,
  80. OUT PULONG Index OPTIONAL
  81. );
  82. BOOLEAN
  83. FatGetNextMcbEntry (
  84. IN PVCB Vcb,
  85. IN PLARGE_MCB Mcb,
  86. IN ULONG RunIndex,
  87. OUT PVBO Vbo,
  88. OUT PLBO Lbo,
  89. OUT PULONG SectorCount
  90. );
  91. VOID
  92. FatRemoveMcbEntry (
  93. IN PVCB Vcb,
  94. IN PLARGE_MCB Mcb,
  95. IN VBO Vbo,
  96. IN ULONG SectorCount
  97. );
  98. //
  99. // File access check routine, implemented in AcChkSup.c
  100. //
  101. BOOLEAN
  102. FatCheckFileAccess (
  103. PIRP_CONTEXT IrpContext,
  104. IN UCHAR DirentAttributes,
  105. IN PACCESS_MASK DesiredAccess
  106. );
  107. NTSTATUS
  108. FatExplicitDeviceAccessGranted (
  109. IN PIRP_CONTEXT IrpContext,
  110. IN PDEVICE_OBJECT DeviceObject,
  111. IN PACCESS_STATE AccessState,
  112. IN KPROCESSOR_MODE ProcessorMode
  113. );
  114. //
  115. // Allocation support routines, implemented in AllocSup.c
  116. //
  117. INLINE
  118. BOOLEAN
  119. FatIsIoRangeValid (
  120. IN PVCB Vcb,
  121. IN LARGE_INTEGER Start,
  122. IN ULONG Length
  123. )
  124. /*++
  125. Routine Description:
  126. This routine enforces the restriction that object space must be
  127. representable in 32 bits.
  128. Arguments:
  129. Vcb - the volume the range is on
  130. Start - starting byte (zero based) of the range
  131. Length - size of the range
  132. Return Value:
  133. BOOLEAN - if, considering the cluster size, the neccesary size of
  134. the object to contain the range can be represented in 32 bits.
  135. --*/
  136. {
  137. //
  138. // The only restriction on a FAT object is that the filesize must
  139. // fit in 32bits, i.e. <= 0xffffffff. This then implies that the
  140. // range of valid byte offsets is [0, fffffffe].
  141. //
  142. // Two phases which check for illegality
  143. //
  144. // - if the high 32bits are nonzero
  145. // - if the length would cause a 32bit overflow
  146. //
  147. return !(Start.HighPart ||
  148. Start.LowPart + Length < Start.LowPart);
  149. }
  150. VOID
  151. FatSetupAllocationSupport (
  152. IN PIRP_CONTEXT IrpContext,
  153. IN PVCB Vcb
  154. );
  155. VOID
  156. FatTearDownAllocationSupport (
  157. IN PIRP_CONTEXT IrpContext,
  158. IN PVCB Vcb
  159. );
  160. VOID
  161. FatLookupFileAllocation (
  162. IN PIRP_CONTEXT IrpContext,
  163. IN PFCB FcbOrDcb,
  164. IN VBO Vbo,
  165. OUT PLBO Lbo,
  166. OUT PULONG ByteCount,
  167. OUT PBOOLEAN Allocated,
  168. OUT PBOOLEAN EndOnMax,
  169. OUT PULONG Index OPTIONAL
  170. );
  171. VOID
  172. FatAddFileAllocation (
  173. IN PIRP_CONTEXT IrpContext,
  174. IN PFCB FcbOrDcb,
  175. IN PFILE_OBJECT FileObject OPTIONAL,
  176. IN ULONG AllocationSize
  177. );
  178. VOID
  179. FatTruncateFileAllocation (
  180. IN PIRP_CONTEXT IrpContext,
  181. IN PFCB FcbOrDcb,
  182. IN ULONG AllocationSize
  183. );
  184. VOID
  185. FatLookupFileAllocationSize (
  186. IN PIRP_CONTEXT IrpContext,
  187. IN PFCB FcbOrDcb
  188. );
  189. VOID
  190. FatAllocateDiskSpace (
  191. IN PIRP_CONTEXT IrpContext,
  192. IN PVCB Vcb,
  193. IN ULONG AbsoluteClusterHint,
  194. IN OUT PULONG ByteCount,
  195. IN BOOLEAN ExactMatchRequired,
  196. OUT PLARGE_MCB Mcb
  197. );
  198. VOID
  199. FatDeallocateDiskSpace (
  200. IN PIRP_CONTEXT IrpContext,
  201. IN PVCB Vcb,
  202. IN PLARGE_MCB Mcb
  203. );
  204. VOID
  205. FatSplitAllocation (
  206. IN PIRP_CONTEXT IrpContext,
  207. IN PVCB Vcb,
  208. IN OUT PLARGE_MCB Mcb,
  209. IN VBO SplitAtVbo,
  210. OUT PLARGE_MCB RemainingMcb
  211. );
  212. VOID
  213. FatMergeAllocation (
  214. IN PIRP_CONTEXT IrpContext,
  215. IN PVCB Vcb,
  216. IN OUT PLARGE_MCB Mcb,
  217. IN PLARGE_MCB SecondMcb
  218. );
  219. VOID
  220. FatSetFatEntry (
  221. IN PIRP_CONTEXT IrpContext,
  222. IN PVCB Vcb,
  223. IN ULONG FatIndex,
  224. IN FAT_ENTRY FatEntry
  225. );
  226. UCHAR
  227. FatLogOf(
  228. IN ULONG Value
  229. );
  230. //
  231. // Buffer control routines for data caching, implemented in CacheSup.c
  232. //
  233. VOID
  234. FatReadVolumeFile (
  235. IN PIRP_CONTEXT IrpContext,
  236. IN PVCB Vcb,
  237. IN VBO StartingVbo,
  238. IN ULONG ByteCount,
  239. OUT PBCB *Bcb,
  240. OUT PVOID *Buffer
  241. );
  242. VOID
  243. FatPrepareWriteVolumeFile (
  244. IN PIRP_CONTEXT IrpContext,
  245. IN PVCB Vcb,
  246. IN VBO StartingVbo,
  247. IN ULONG ByteCount,
  248. OUT PBCB *Bcb,
  249. OUT PVOID *Buffer,
  250. IN BOOLEAN Reversible,
  251. IN BOOLEAN Zero
  252. );
  253. VOID
  254. FatReadDirectoryFile (
  255. IN PIRP_CONTEXT IrpContext,
  256. IN PDCB Dcb,
  257. IN VBO StartingVbo,
  258. IN ULONG ByteCount,
  259. IN BOOLEAN Pin,
  260. OUT PBCB *Bcb,
  261. OUT PVOID *Buffer,
  262. OUT PNTSTATUS Status
  263. );
  264. VOID
  265. FatPrepareWriteDirectoryFile (
  266. IN PIRP_CONTEXT IrpContext,
  267. IN PDCB Dcb,
  268. IN VBO StartingVbo,
  269. IN ULONG ByteCount,
  270. OUT PBCB *Bcb,
  271. OUT PVOID *Buffer,
  272. IN BOOLEAN Zero,
  273. IN BOOLEAN Reversible,
  274. OUT PNTSTATUS Status
  275. );
  276. VOID
  277. FatOpenDirectoryFile (
  278. IN PIRP_CONTEXT IrpContext,
  279. IN PDCB Dcb
  280. );
  281. PFILE_OBJECT
  282. FatOpenEaFile (
  283. IN PIRP_CONTEXT IrpContext,
  284. IN PFCB EaFcb
  285. );
  286. VOID
  287. FatCloseEaFile (
  288. IN PIRP_CONTEXT IrpContext,
  289. IN PVCB Vcb,
  290. IN BOOLEAN FlushFirst
  291. );
  292. VOID
  293. FatSetDirtyBcb (
  294. IN PIRP_CONTEXT IrpContext,
  295. IN PBCB Bcb,
  296. IN PVCB Vcb OPTIONAL,
  297. IN BOOLEAN Reversible
  298. );
  299. VOID
  300. FatRepinBcb (
  301. IN PIRP_CONTEXT IrpContext,
  302. IN PBCB Bcb
  303. );
  304. VOID
  305. FatUnpinRepinnedBcbs (
  306. IN PIRP_CONTEXT IrpContext
  307. );
  308. FINISHED
  309. FatZeroData (
  310. IN PIRP_CONTEXT IrpContext,
  311. IN PVCB Vcb,
  312. IN PFILE_OBJECT FileObject,
  313. IN ULONG StartingZero,
  314. IN ULONG ByteCount
  315. );
  316. NTSTATUS
  317. FatCompleteMdl (
  318. IN PIRP_CONTEXT IrpContext,
  319. IN PIRP Irp
  320. );
  321. VOID
  322. FatPinMappedData (
  323. IN PIRP_CONTEXT IrpContext,
  324. IN PDCB Dcb,
  325. IN VBO StartingVbo,
  326. IN ULONG ByteCount,
  327. OUT PBCB *Bcb
  328. );
  329. //
  330. // VOID
  331. // FatUnpinBcb (
  332. // IN PIRP_CONTEXT IrpContext,
  333. // IN OUT PBCB Bcb,
  334. // );
  335. //
  336. //
  337. // This macro unpins a Bcb, in the checked build make sure all
  338. // requests unpin all Bcbs before leaving.
  339. //
  340. #if DBG
  341. #define FatUnpinBcb(IRPCONTEXT,BCB) { \
  342. if ((BCB) != NULL) { \
  343. CcUnpinData((BCB)); \
  344. ASSERT( (IRPCONTEXT)->PinCount ); \
  345. (IRPCONTEXT)->PinCount -= 1; \
  346. (BCB) = NULL; \
  347. } \
  348. }
  349. #else
  350. #define FatUnpinBcb(IRPCONTEXT,BCB) { \
  351. if ((BCB) != NULL) { \
  352. CcUnpinData((BCB)); \
  353. (BCB) = NULL; \
  354. } \
  355. }
  356. #endif // DBG
  357. VOID
  358. FatSyncUninitializeCacheMap (
  359. IN PIRP_CONTEXT IrpContext,
  360. IN PFILE_OBJECT FileObject
  361. );
  362. //
  363. // Device I/O routines, implemented in DevIoSup.c
  364. //
  365. // These routines perform the actual device read and writes. They only affect
  366. // the on disk structure and do not alter any other data structures.
  367. //
  368. VOID
  369. FatPagingFileIo (
  370. IN PIRP Irp,
  371. IN PFCB Fcb
  372. );
  373. NTSTATUS
  374. FatNonCachedIo (
  375. IN PIRP_CONTEXT IrpContext,
  376. IN PIRP Irp,
  377. IN PFCB FcbOrDcb,
  378. IN ULONG StartingVbo,
  379. IN ULONG ByteCount,
  380. IN ULONG UserByteCount
  381. );
  382. VOID
  383. FatNonCachedNonAlignedRead (
  384. IN PIRP_CONTEXT IrpContext,
  385. IN PIRP Irp,
  386. IN PFCB FcbOrDcb,
  387. IN ULONG StartingVbo,
  388. IN ULONG ByteCount
  389. );
  390. VOID
  391. FatMultipleAsync (
  392. IN PIRP_CONTEXT IrpContext,
  393. IN PVCB Vcb,
  394. IN PIRP Irp,
  395. IN ULONG MultipleIrpCount,
  396. IN PIO_RUN IoRuns
  397. );
  398. VOID
  399. FatSingleAsync (
  400. IN PIRP_CONTEXT IrpContext,
  401. IN PVCB Vcb,
  402. IN LBO Lbo,
  403. IN ULONG ByteCount,
  404. IN PIRP Irp
  405. );
  406. VOID
  407. FatWaitSync (
  408. IN PIRP_CONTEXT IrpContext
  409. );
  410. VOID
  411. FatLockUserBuffer (
  412. IN PIRP_CONTEXT IrpContext,
  413. IN OUT PIRP Irp,
  414. IN LOCK_OPERATION Operation,
  415. IN ULONG BufferLength
  416. );
  417. PVOID
  418. FatBufferUserBuffer (
  419. IN PIRP_CONTEXT IrpContext,
  420. IN OUT PIRP Irp,
  421. IN ULONG BufferLength
  422. );
  423. PVOID
  424. FatMapUserBuffer (
  425. IN PIRP_CONTEXT IrpContext,
  426. IN OUT PIRP Irp
  427. );
  428. NTSTATUS
  429. FatToggleMediaEjectDisable (
  430. IN PIRP_CONTEXT IrpContext,
  431. IN PVCB Vcb,
  432. IN BOOLEAN PreventRemoval
  433. );
  434. NTSTATUS
  435. FatPerformDevIoCtrl (
  436. IN PIRP_CONTEXT IrpContext,
  437. IN ULONG IoControlCode,
  438. IN PDEVICE_OBJECT Device,
  439. OUT PVOID OutputBuffer OPTIONAL,
  440. IN ULONG OutputBufferLength,
  441. IN BOOLEAN InternalDeviceIoControl,
  442. IN BOOLEAN OverrideVerify,
  443. OUT PIO_STATUS_BLOCK Iosb OPTIONAL
  444. );
  445. //
  446. // Dirent support routines, implemented in DirSup.c
  447. //
  448. //
  449. // Tunneling is a deletion precursor (all tunneling cases do
  450. // not involve deleting dirents, however)
  451. //
  452. VOID
  453. FatTunnelFcbOrDcb (
  454. IN PFCB FcbOrDcb,
  455. IN PCCB Ccb OPTIONAL
  456. );
  457. ULONG
  458. FatCreateNewDirent (
  459. IN PIRP_CONTEXT IrpContext,
  460. IN PDCB ParentDirectory,
  461. IN ULONG DirentsNeeded
  462. );
  463. VOID
  464. FatInitializeDirectoryDirent (
  465. IN PIRP_CONTEXT IrpContext,
  466. IN PDCB Dcb,
  467. IN PDIRENT ParentDirent
  468. );
  469. VOID
  470. FatDeleteDirent (
  471. IN PIRP_CONTEXT IrpContext,
  472. IN PFCB FcbOrDcb,
  473. IN PDELETE_CONTEXT DeleteContext OPTIONAL,
  474. IN BOOLEAN DeleteEa
  475. );
  476. VOID
  477. FatLocateDirent (
  478. IN PIRP_CONTEXT IrpContext,
  479. IN PDCB ParentDirectory,
  480. IN PCCB Ccb,
  481. IN VBO OffsetToStartSearchFrom,
  482. OUT PDIRENT *Dirent,
  483. OUT PBCB *Bcb,
  484. OUT PVBO ByteOffset,
  485. OUT PBOOLEAN FileNameDos OPTIONAL,
  486. OUT PUNICODE_STRING Lfn OPTIONAL
  487. );
  488. VOID
  489. FatLocateSimpleOemDirent (
  490. IN PIRP_CONTEXT IrpContext,
  491. IN PDCB ParentDirectory,
  492. IN POEM_STRING FileName,
  493. OUT PDIRENT *Dirent,
  494. OUT PBCB *Bcb,
  495. OUT PVBO ByteOffset
  496. );
  497. BOOLEAN
  498. FatLfnDirentExists (
  499. IN PIRP_CONTEXT IrpContext,
  500. IN PDCB Dcb,
  501. IN PUNICODE_STRING Lfn,
  502. IN PUNICODE_STRING LfnTmp
  503. );
  504. VOID
  505. FatLocateVolumeLabel (
  506. IN PIRP_CONTEXT IrpContext,
  507. IN PVCB Vcb,
  508. OUT PDIRENT *Dirent,
  509. OUT PBCB *Bcb,
  510. OUT PVBO ByteOffset
  511. );
  512. VOID
  513. FatGetDirentFromFcbOrDcb (
  514. IN PIRP_CONTEXT IrpContext,
  515. IN PFCB FcbOrDcb,
  516. OUT PDIRENT *Dirent,
  517. OUT PBCB *Bcb
  518. );
  519. BOOLEAN
  520. FatIsDirectoryEmpty (
  521. IN PIRP_CONTEXT IrpContext,
  522. IN PDCB Dcb
  523. );
  524. VOID
  525. FatConstructDirent (
  526. IN PIRP_CONTEXT IrpContext,
  527. IN OUT PDIRENT Dirent,
  528. IN POEM_STRING FileName,
  529. IN BOOLEAN ComponentReallyLowercase,
  530. IN BOOLEAN ExtensionReallyLowercase,
  531. IN PUNICODE_STRING Lfn OPTIONAL,
  532. IN UCHAR Attributes,
  533. IN BOOLEAN ZeroAndSetTimeFields,
  534. IN PLARGE_INTEGER SetCreationTime OPTIONAL
  535. );
  536. VOID
  537. FatConstructLabelDirent (
  538. IN PIRP_CONTEXT IrpContext,
  539. IN OUT PDIRENT Dirent,
  540. IN POEM_STRING Label
  541. );
  542. VOID
  543. FatSetFileSizeInDirent (
  544. IN PIRP_CONTEXT IrpContext,
  545. IN PFCB Fcb,
  546. IN PULONG AlternativeFileSize OPTIONAL
  547. );
  548. VOID
  549. FatUpdateDirentFromFcb (
  550. IN PIRP_CONTEXT IrpContext,
  551. IN PFILE_OBJECT FileObject,
  552. IN PFCB FcbOrDcb,
  553. IN PCCB Ccb
  554. );
  555. //
  556. // Generate a relatively unique static 64bit ID from a FAT Fcb/Dcb
  557. //
  558. // ULONGLONG
  559. // FatDirectoryKey (FcbOrDcb);
  560. //
  561. #define FatDirectoryKey(FcbOrDcb) ((ULONGLONG)((FcbOrDcb)->CreationTime.QuadPart ^ (FcbOrDcb)->FirstClusterOfFile))
  562. //
  563. // The following routines are used to access and manipulate the
  564. // clusters containing EA data in the ea data file. They are
  565. // implemented in EaSup.c
  566. //
  567. //
  568. // VOID
  569. // FatUpcaseEaName (
  570. // IN PIRP_CONTEXT IrpContext,
  571. // IN POEM_STRING EaName,
  572. // OUT POEM_STRING UpcasedEaName
  573. // );
  574. //
  575. #define FatUpcaseEaName( IRPCONTEXT, NAME, UPCASEDNAME ) \
  576. RtlUpperString( UPCASEDNAME, NAME )
  577. VOID
  578. FatGetEaLength (
  579. IN PIRP_CONTEXT IrpContext,
  580. IN PVCB Vcb,
  581. IN PDIRENT Dirent,
  582. OUT PULONG EaLength
  583. );
  584. VOID
  585. FatGetNeedEaCount (
  586. IN PIRP_CONTEXT IrpContext,
  587. IN PVCB Vcb,
  588. IN PDIRENT Dirent,
  589. OUT PULONG NeedEaCount
  590. );
  591. VOID
  592. FatCreateEa (
  593. IN PIRP_CONTEXT IrpContext,
  594. IN PVCB Vcb,
  595. IN PUCHAR Buffer,
  596. IN ULONG Length,
  597. IN POEM_STRING FileName,
  598. OUT PUSHORT EaHandle
  599. );
  600. VOID
  601. FatDeleteEa (
  602. IN PIRP_CONTEXT IrpContext,
  603. IN PVCB Vcb,
  604. IN USHORT EaHandle,
  605. IN POEM_STRING FileName
  606. );
  607. VOID
  608. FatGetEaFile (
  609. IN PIRP_CONTEXT IrpContext,
  610. IN OUT PVCB Vcb,
  611. OUT PDIRENT *EaDirent,
  612. OUT PBCB *EaBcb,
  613. IN BOOLEAN CreateFile,
  614. IN BOOLEAN ExclusiveFcb
  615. );
  616. VOID
  617. FatReadEaSet (
  618. IN PIRP_CONTEXT IrpContext,
  619. IN PVCB Vcb,
  620. IN USHORT EaHandle,
  621. IN POEM_STRING FileName,
  622. IN BOOLEAN ReturnEntireSet,
  623. OUT PEA_RANGE EaSetRange
  624. );
  625. VOID
  626. FatDeleteEaSet (
  627. IN PIRP_CONTEXT IrpContext,
  628. IN PVCB Vcb,
  629. IN PBCB EaBcb,
  630. OUT PDIRENT EaDirent,
  631. IN USHORT EaHandle,
  632. IN POEM_STRING Filename
  633. );
  634. VOID
  635. FatAddEaSet (
  636. IN PIRP_CONTEXT IrpContext,
  637. IN PVCB Vcb,
  638. IN ULONG EaSetLength,
  639. IN PBCB EaBcb,
  640. OUT PDIRENT EaDirent,
  641. OUT PUSHORT EaHandle,
  642. OUT PEA_RANGE EaSetRange
  643. );
  644. VOID
  645. FatDeletePackedEa (
  646. IN PIRP_CONTEXT IrpContext,
  647. IN OUT PEA_SET_HEADER EaSetHeader,
  648. IN OUT PULONG PackedEasLength,
  649. IN ULONG Offset
  650. );
  651. VOID
  652. FatAppendPackedEa (
  653. IN PIRP_CONTEXT IrpContext,
  654. IN OUT PEA_SET_HEADER *EaSetHeader,
  655. IN OUT PULONG PackedEasLength,
  656. IN OUT PULONG AllocationLength,
  657. IN PFILE_FULL_EA_INFORMATION FullEa,
  658. IN ULONG BytesPerCluster
  659. );
  660. ULONG
  661. FatLocateNextEa (
  662. IN PIRP_CONTEXT IrpContext,
  663. IN PPACKED_EA FirstPackedEa,
  664. IN ULONG PackedEasLength,
  665. IN ULONG PreviousOffset
  666. );
  667. BOOLEAN
  668. FatLocateEaByName (
  669. IN PIRP_CONTEXT IrpContext,
  670. IN PPACKED_EA FirstPackedEa,
  671. IN ULONG PackedEasLength,
  672. IN POEM_STRING EaName,
  673. OUT PULONG Offset
  674. );
  675. BOOLEAN
  676. FatIsEaNameValid (
  677. IN PIRP_CONTEXT IrpContext,
  678. IN OEM_STRING Name
  679. );
  680. VOID
  681. FatPinEaRange (
  682. IN PIRP_CONTEXT IrpContext,
  683. IN PFILE_OBJECT VirtualEaFile,
  684. IN PFCB EaFcb,
  685. IN OUT PEA_RANGE EaRange,
  686. IN ULONG StartingVbo,
  687. IN ULONG Length,
  688. IN NTSTATUS ErrorStatus
  689. );
  690. VOID
  691. FatMarkEaRangeDirty (
  692. IN PIRP_CONTEXT IrpContext,
  693. IN PFILE_OBJECT EaFileObject,
  694. IN OUT PEA_RANGE EaRange
  695. );
  696. VOID
  697. FatUnpinEaRange (
  698. IN PIRP_CONTEXT IrpContext,
  699. IN OUT PEA_RANGE EaRange
  700. );
  701. //
  702. // The following macro computes the size of a full ea (not including
  703. // padding to bring it to a longword. A full ea has a 4 byte offset,
  704. // folowed by 1 byte flag, 1 byte name length, 2 bytes value length,
  705. // the name, 1 null byte, and the value.
  706. //
  707. // ULONG
  708. // SizeOfFullEa (
  709. // IN PFILE_FULL_EA_INFORMATION FullEa
  710. // );
  711. //
  712. #define SizeOfFullEa(EA) (4+1+1+2+(EA)->EaNameLength+1+(EA)->EaValueLength)
  713. //
  714. // The following routines are used to manipulate the fscontext fields
  715. // of the file object, implemented in FilObSup.c
  716. //
  717. typedef enum _TYPE_OF_OPEN {
  718. UnopenedFileObject = 1,
  719. UserFileOpen,
  720. UserDirectoryOpen,
  721. UserVolumeOpen,
  722. VirtualVolumeFile,
  723. DirectoryFile,
  724. EaFile
  725. } TYPE_OF_OPEN;
  726. typedef enum _FAT_FLUSH_TYPE {
  727. NoFlush = 0,
  728. Flush,
  729. FlushAndInvalidate,
  730. FlushWithoutPurge
  731. } FAT_FLUSH_TYPE;
  732. VOID
  733. FatSetFileObject (
  734. IN PFILE_OBJECT FileObject OPTIONAL,
  735. IN TYPE_OF_OPEN TypeOfOpen,
  736. IN PVOID VcbOrFcbOrDcb,
  737. IN PCCB Ccb OPTIONAL
  738. );
  739. TYPE_OF_OPEN
  740. FatDecodeFileObject (
  741. IN PFILE_OBJECT FileObject,
  742. OUT PVCB *Vcb,
  743. OUT PFCB *FcbOrDcb,
  744. OUT PCCB *Ccb
  745. );
  746. VOID
  747. FatPurgeReferencedFileObjects (
  748. IN PIRP_CONTEXT IrpContext,
  749. IN PFCB FcbOrDcb,
  750. IN FAT_FLUSH_TYPE FlushType
  751. );
  752. VOID
  753. FatForceCacheMiss (
  754. IN PIRP_CONTEXT IrpContext,
  755. IN PFCB Fcb,
  756. IN FAT_FLUSH_TYPE FlushType
  757. );
  758. //
  759. // File system control routines, implemented in FsCtrl.c
  760. //
  761. VOID
  762. FatFlushAndCleanVolume(
  763. IN PIRP_CONTEXT IrpContext,
  764. IN PIRP Irp,
  765. IN PVCB Vcb,
  766. IN FAT_FLUSH_TYPE FlushType
  767. );
  768. BOOLEAN
  769. FatIsBootSectorFat (
  770. IN PPACKED_BOOT_SECTOR BootSector
  771. );
  772. NTSTATUS
  773. FatLockVolumeInternal (
  774. IN PIRP_CONTEXT IrpContext,
  775. IN PVCB Vcb,
  776. IN PFILE_OBJECT FileObject OPTIONAL
  777. );
  778. NTSTATUS
  779. FatUnlockVolumeInternal (
  780. IN PIRP_CONTEXT IrpContext,
  781. IN PVCB Vcb,
  782. IN PFILE_OBJECT FileObject OPTIONAL
  783. );
  784. //
  785. // Name support routines, implemented in NameSup.c
  786. //
  787. //
  788. // VOID
  789. // FatDissectName (
  790. // IN PIRP_CONTEXT IrpContext,
  791. // IN OEM_STRING InputString,
  792. // OUT POEM_STRING FirstPart,
  793. // OUT POEM_STRING RemainingPart
  794. // )
  795. //
  796. // /*++
  797. //
  798. // Routine Description:
  799. //
  800. // This routine takes an input string and dissects it into two substrings.
  801. // The first output string contains the name that appears at the beginning
  802. // of the input string, the second output string contains the remainder of
  803. // the input string.
  804. //
  805. // In the input string backslashes are used to separate names. The input
  806. // string must not start with a backslash. Both output strings will not
  807. // begin with a backslash.
  808. //
  809. // If the input string does not contain any names then both output strings
  810. // are empty. If the input string contains only one name then the first
  811. // output string contains the name and the second string is empty.
  812. //
  813. // Note that both output strings use the same string buffer memory of the
  814. // input string.
  815. //
  816. // Example of its results are:
  817. //
  818. // //. . InputString FirstPart RemainingPart
  819. // //
  820. // //. . empty empty empty
  821. // //
  822. // //. . A A empty
  823. // //
  824. // //. . A\B\C\D\E A B\C\D\E
  825. // //
  826. // //. . *A? *A? empty
  827. // //
  828. // //. . \A A empty
  829. // //
  830. // //. . A[,] A[,] empty
  831. // //
  832. // //. . A\\B+;\C A \B+;\C
  833. //
  834. // Arguments:
  835. //
  836. // InputString - Supplies the input string being dissected
  837. //
  838. // FirstPart - Receives the first name in the input string
  839. //
  840. // RemainingPart - Receives the remaining part of the input string
  841. //
  842. // Return Value:
  843. //
  844. // BOOLEAN - TRUE if the input string is well formed and its first part
  845. // does not contain any illegal characters, and FALSE otherwise.
  846. //
  847. // --*/
  848. //
  849. #define FatDissectName(IRPCONTEXT,INPUT_STRING,FIRST_PART,REMAINING_PART) { \
  850. FsRtlDissectDbcs( (INPUT_STRING), \
  851. (FIRST_PART), \
  852. (REMAINING_PART) ); \
  853. }
  854. //
  855. // BOOLEAN
  856. // FatDoesNameContainWildCards (
  857. // IN PIRP_CONTEXT IrpContext,
  858. // IN OEM_STRING Name
  859. // )
  860. //
  861. // /*++
  862. //
  863. // Routine Description:
  864. //
  865. // This routine checks if the input name contains any wild card characters.
  866. //
  867. // Arguments:
  868. //
  869. // Name - Supplies the name to examine
  870. //
  871. // Return Value:
  872. //
  873. // BOOLEAN - TRUE if the input name contains any wildcard characters and
  874. // FALSE otherwise.
  875. //
  876. // --*/
  877. //
  878. #define FatDoesNameContainWildCards(IRPCONTEXT,NAME) ( \
  879. FsRtlDoesDbcsContainWildCards( &(NAME) ) \
  880. )
  881. //
  882. // BOOLEAN
  883. // FatAreNamesEqual (
  884. // IN PIRP_CONTEXT IrpContext,
  885. // IN OEM_STRING ConstantNameA,
  886. // IN OEM_STRING ConstantNameB
  887. // )
  888. //
  889. // /*++
  890. //
  891. // Routine Description:
  892. //
  893. // This routine simple returns whether the two names are exactly equal.
  894. // If the two names are known to be constant, this routine is much
  895. // faster than FatIsDbcsInExpression.
  896. //
  897. // Arguments:
  898. //
  899. // ConstantNameA - Constant name.
  900. //
  901. // ConstantNameB - Constant name.
  902. //
  903. // Return Value:
  904. //
  905. // BOOLEAN - TRUE if the two names are lexically equal.
  906. //
  907. #define FatAreNamesEqual(IRPCONTEXT,NAMEA,NAMEB) ( \
  908. ((ULONG)(NAMEA).Length == (ULONG)(NAMEB).Length) && \
  909. (RtlEqualMemory( &(NAMEA).Buffer[0], \
  910. &(NAMEB).Buffer[0], \
  911. (NAMEA).Length )) \
  912. )
  913. //
  914. // BOOLEAN
  915. // FatIsNameShortOemValid (
  916. // IN PIRP_CONTEXT IrpContext,
  917. // IN OEM_STRING Name,
  918. // IN BOOLEAN CanContainWildCards,
  919. // IN BOOLEAN PathNamePermissible,
  920. // IN BOOLEAN LeadingBackslashPermissible
  921. // )
  922. //
  923. // /*++
  924. //
  925. // Routine Description:
  926. //
  927. // This routine scans the input name and verifies that if only
  928. // contains valid characters
  929. //
  930. // Arguments:
  931. //
  932. // Name - Supplies the input name to check.
  933. //
  934. // CanContainWildCards - Indicates if the name can contain wild cards
  935. // (i.e., * and ?).
  936. //
  937. // Return Value:
  938. //
  939. // BOOLEAN - Returns TRUE if the name is valid and FALSE otherwise.
  940. //
  941. // --*/
  942. //
  943. // The FatIsNameLongOemValid and FatIsNameLongUnicodeValid are similar.
  944. //
  945. #define FatIsNameShortOemValid(IRPCONTEXT,NAME,CAN_CONTAIN_WILD_CARDS,PATH_NAME_OK,LEADING_BACKSLASH_OK) ( \
  946. FsRtlIsFatDbcsLegal((NAME), \
  947. (CAN_CONTAIN_WILD_CARDS), \
  948. (PATH_NAME_OK), \
  949. (LEADING_BACKSLASH_OK)) \
  950. )
  951. #define FatIsNameLongOemValid(IRPCONTEXT,NAME,CAN_CONTAIN_WILD_CARDS,PATH_NAME_OK,LEADING_BACKSLASH_OK) ( \
  952. FsRtlIsHpfsDbcsLegal((NAME), \
  953. (CAN_CONTAIN_WILD_CARDS), \
  954. (PATH_NAME_OK), \
  955. (LEADING_BACKSLASH_OK)) \
  956. )
  957. INLINE
  958. BOOLEAN
  959. FatIsNameLongUnicodeValid (
  960. PIRP_CONTEXT IrpContext,
  961. PUNICODE_STRING Name,
  962. BOOLEAN CanContainWildcards,
  963. BOOLEAN PathNameOk,
  964. BOOLEAN LeadingBackslashOk
  965. )
  966. {
  967. ULONG i;
  968. //
  969. // I'm not bothering to do the whole thing, just enough to make this call look
  970. // the same as the others.
  971. //
  972. ASSERT( !PathNameOk && !LeadingBackslashOk );
  973. for (i=0; i < Name->Length/sizeof(WCHAR); i++) {
  974. if ((Name->Buffer[i] < 0x80) &&
  975. !(FsRtlIsAnsiCharacterLegalHpfs(Name->Buffer[i], CanContainWildcards))) {
  976. return FALSE;
  977. }
  978. }
  979. return TRUE;
  980. }
  981. BOOLEAN
  982. FatIsNameInExpression (
  983. IN PIRP_CONTEXT IrpContext,
  984. IN OEM_STRING Expression,
  985. IN OEM_STRING Name
  986. );
  987. VOID
  988. FatStringTo8dot3 (
  989. IN PIRP_CONTEXT IrpContext,
  990. IN OEM_STRING InputString,
  991. OUT PFAT8DOT3 Output8dot3
  992. );
  993. VOID
  994. Fat8dot3ToString (
  995. IN PIRP_CONTEXT IrpContext,
  996. IN PDIRENT Dirent,
  997. IN BOOLEAN RestoreCase,
  998. OUT POEM_STRING OutputString
  999. );
  1000. VOID
  1001. FatGetUnicodeNameFromFcb (
  1002. IN PIRP_CONTEXT IrpContext,
  1003. IN PFCB Fcb,
  1004. IN OUT PUNICODE_STRING Lfn
  1005. );
  1006. VOID
  1007. FatSetFullFileNameInFcb (
  1008. IN PIRP_CONTEXT IrpContext,
  1009. IN PFCB Fcb
  1010. );
  1011. VOID
  1012. FatSetFullNameInFcb(
  1013. IN PIRP_CONTEXT IrpContext,
  1014. IN PFCB Fcb,
  1015. IN PUNICODE_STRING FinalName
  1016. );
  1017. VOID
  1018. FatUnicodeToUpcaseOem (
  1019. IN PIRP_CONTEXT IrpContext,
  1020. IN POEM_STRING OemString,
  1021. IN PUNICODE_STRING UnicodeString
  1022. );
  1023. VOID
  1024. FatSelectNames (
  1025. IN PIRP_CONTEXT IrpContext,
  1026. IN PDCB Parent,
  1027. IN POEM_STRING OemName,
  1028. IN PUNICODE_STRING UnicodeName,
  1029. IN OUT POEM_STRING ShortName,
  1030. IN PUNICODE_STRING SuggestedShortName OPTIONAL,
  1031. IN OUT BOOLEAN *AllLowerComponent,
  1032. IN OUT BOOLEAN *AllLowerExtension,
  1033. IN OUT BOOLEAN *CreateLfn
  1034. );
  1035. VOID
  1036. FatEvaluateNameCase (
  1037. IN PIRP_CONTEXT IrpContext,
  1038. IN PUNICODE_STRING Name,
  1039. IN OUT BOOLEAN *AllLowerComponent,
  1040. IN OUT BOOLEAN *AllLowerExtension,
  1041. IN OUT BOOLEAN *CreateLfn
  1042. );
  1043. BOOLEAN
  1044. FatSpaceInName (
  1045. IN PIRP_CONTEXT IrpContext,
  1046. IN PUNICODE_STRING UnicodeName
  1047. );
  1048. //
  1049. // Resources support routines/macros, implemented in ResrcSup.c
  1050. //
  1051. // The following routines/macros are used for gaining shared and exclusive
  1052. // access to the global/vcb data structures. The routines are implemented
  1053. // in ResrcSup.c. There is a global resources that everyone tries to take
  1054. // out shared to do their work, with the exception of mount/dismount which
  1055. // take out the global resource exclusive. All other resources only work
  1056. // on their individual item. For example, an Fcb resource does not take out
  1057. // a Vcb resource. But the way the file system is structured we know
  1058. // that when we are processing an Fcb other threads cannot be trying to remove
  1059. // or alter the Fcb, so we do not need to acquire the Vcb.
  1060. //
  1061. // The procedures/macros are:
  1062. //
  1063. // Macro FatData Vcb Fcb Subsequent macros
  1064. //
  1065. // AcquireExclusiveGlobal Read/Write None None ReleaseGlobal
  1066. //
  1067. // AcquireSharedGlobal Read None None ReleaseGlobal
  1068. //
  1069. // AcquireExclusiveVcb Read Read/Write None ReleaseVcb
  1070. //
  1071. // AcquireSharedVcb Read Read None ReleaseVcb
  1072. //
  1073. // AcquireExclusiveFcb Read None Read/Write ConvertToSharFcb
  1074. // ReleaseFcb
  1075. //
  1076. // AcquireSharedFcb Read None Read ReleaseFcb
  1077. //
  1078. // ConvertToSharedFcb Read None Read ReleaseFcb
  1079. //
  1080. // ReleaseGlobal
  1081. //
  1082. // ReleaseVcb
  1083. //
  1084. // ReleaseFcb
  1085. //
  1086. //
  1087. // FINISHED
  1088. // FatAcquireExclusiveGlobal (
  1089. // IN PIRP_CONTEXT IrpContext
  1090. // );
  1091. //
  1092. // FINISHED
  1093. // FatAcquireSharedGlobal (
  1094. // IN PIRP_CONTEXT IrpContext
  1095. // );
  1096. //
  1097. #define FatAcquireExclusiveGlobal(IRPCONTEXT) ( \
  1098. ExAcquireResourceExclusiveLite( &FatData.Resource, BooleanFlagOn((IRPCONTEXT)->Flags, IRP_CONTEXT_FLAG_WAIT) ) \
  1099. )
  1100. #define FatAcquireSharedGlobal(IRPCONTEXT) ( \
  1101. ExAcquireResourceSharedLite( &FatData.Resource, BooleanFlagOn((IRPCONTEXT)->Flags, IRP_CONTEXT_FLAG_WAIT) ) \
  1102. )
  1103. //
  1104. // The following macro must only be called when Wait is TRUE!
  1105. //
  1106. // FatAcquireExclusiveVolume (
  1107. // IN PIRP_CONTEXT IrpContext,
  1108. // IN PVCB Vcb
  1109. // );
  1110. //
  1111. // FatReleaseVolume (
  1112. // IN PIRP_CONTEXT IrpContext,
  1113. // IN PVCB Vcb
  1114. // );
  1115. //
  1116. #define FatAcquireExclusiveVolume(IRPCONTEXT,VCB) { \
  1117. PFCB Fcb = NULL; \
  1118. ASSERT(FlagOn((IRPCONTEXT)->Flags, IRP_CONTEXT_FLAG_WAIT)); \
  1119. (VOID)FatAcquireExclusiveVcb( (IRPCONTEXT), (VCB) ); \
  1120. while ( (Fcb = FatGetNextFcbBottomUp((IRPCONTEXT), Fcb, (VCB)->RootDcb)) != NULL) { \
  1121. (VOID)FatAcquireExclusiveFcb((IRPCONTEXT), Fcb ); \
  1122. } \
  1123. }
  1124. #define FatReleaseVolume(IRPCONTEXT,VCB) { \
  1125. PFCB Fcb = NULL; \
  1126. ASSERT(FlagOn((IRPCONTEXT)->Flags, IRP_CONTEXT_FLAG_WAIT)); \
  1127. while ( (Fcb = FatGetNextFcbBottomUp((IRPCONTEXT), Fcb, (VCB)->RootDcb)) != NULL) { \
  1128. (VOID)ExReleaseResourceLite( Fcb->Header.Resource ); \
  1129. } \
  1130. FatReleaseVcb((IRPCONTEXT), (VCB)); \
  1131. }
  1132. //
  1133. // These macros can be used to determine what kind of FAT we have for an
  1134. // initialized Vcb. It is somewhat more elegant to use these (visually).
  1135. //
  1136. #define FatIsFat32(VCB) ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 32))
  1137. #define FatIsFat16(VCB) ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 16))
  1138. #define FatIsFat12(VCB) ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 12))
  1139. FINISHED
  1140. FatAcquireExclusiveVcb (
  1141. IN PIRP_CONTEXT IrpContext,
  1142. IN PVCB Vcb
  1143. );
  1144. FINISHED
  1145. FatAcquireSharedVcb (
  1146. IN PIRP_CONTEXT IrpContext,
  1147. IN PVCB Vcb
  1148. );
  1149. FINISHED
  1150. FatAcquireExclusiveFcb (
  1151. IN PIRP_CONTEXT IrpContext,
  1152. IN PFCB Fcb
  1153. );
  1154. FINISHED
  1155. FatAcquireSharedFcb (
  1156. IN PIRP_CONTEXT IrpContext,
  1157. IN PFCB Fcb
  1158. );
  1159. FINISHED
  1160. FatAcquireSharedFcbWaitForEx (
  1161. IN PIRP_CONTEXT IrpContext,
  1162. IN PFCB Fcb
  1163. );
  1164. #define FatVcbAcquiredExclusive(IRPCONTEXT,VCB) ( \
  1165. ExIsResourceAcquiredExclusiveLite(&(VCB)->Resource) || \
  1166. ExIsResourceAcquiredExclusiveLite(&FatData.Resource) \
  1167. )
  1168. #define FatFcbAcquiredShared(IRPCONTEXT,FCB) ( \
  1169. ExIsResourceAcquiredSharedLite((FCB)->Header.Resource) \
  1170. )
  1171. #define FatAcquireDirectoryFileMutex(VCB) { \
  1172. ASSERT(KeAreApcsDisabled()); \
  1173. ExAcquireFastMutexUnsafe(&(VCB)->DirectoryFileCreationMutex); \
  1174. }
  1175. #define FatReleaseDirectoryFileMutex(VCB) { \
  1176. ASSERT(KeAreApcsDisabled()); \
  1177. ExReleaseFastMutexUnsafe(&(VCB)->DirectoryFileCreationMutex); \
  1178. }
  1179. //
  1180. // The following are cache manager call backs
  1181. BOOLEAN
  1182. FatAcquireVolumeForClose (
  1183. IN PVOID Vcb,
  1184. IN BOOLEAN Wait
  1185. );
  1186. VOID
  1187. FatReleaseVolumeFromClose (
  1188. IN PVOID Vcb
  1189. );
  1190. BOOLEAN
  1191. FatAcquireFcbForLazyWrite (
  1192. IN PVOID Null,
  1193. IN BOOLEAN Wait
  1194. );
  1195. VOID
  1196. FatReleaseFcbFromLazyWrite (
  1197. IN PVOID Null
  1198. );
  1199. BOOLEAN
  1200. FatAcquireFcbForReadAhead (
  1201. IN PVOID Null,
  1202. IN BOOLEAN Wait
  1203. );
  1204. VOID
  1205. FatReleaseFcbFromReadAhead (
  1206. IN PVOID Null
  1207. );
  1208. NTSTATUS
  1209. FatAcquireForCcFlush (
  1210. IN PFILE_OBJECT FileObject,
  1211. IN PDEVICE_OBJECT DeviceObject
  1212. );
  1213. NTSTATUS
  1214. FatReleaseForCcFlush (
  1215. IN PFILE_OBJECT FileObject,
  1216. IN PDEVICE_OBJECT DeviceObject
  1217. );
  1218. BOOLEAN
  1219. FatNoOpAcquire (
  1220. IN PVOID Fcb,
  1221. IN BOOLEAN Wait
  1222. );
  1223. VOID
  1224. FatNoOpRelease (
  1225. IN PVOID Fcb
  1226. );
  1227. //
  1228. // VOID
  1229. // FatConvertToSharedFcb (
  1230. // IN PIRP_CONTEXT IrpContext,
  1231. // IN PFCB Fcb
  1232. // );
  1233. //
  1234. #define FatConvertToSharedFcb(IRPCONTEXT,Fcb) { \
  1235. ExConvertExclusiveToSharedLite( (Fcb)->Header.Resource ); \
  1236. }
  1237. //
  1238. // VOID
  1239. // FatReleaseGlobal (
  1240. // IN PIRP_CONTEXT IrpContext
  1241. // );
  1242. //
  1243. // VOID
  1244. // FatReleaseVcb (
  1245. // IN PIRP_CONTEXT IrpContext,
  1246. // IN PVCB Vcb
  1247. // );
  1248. //
  1249. // VOID
  1250. // FatReleaseFcb (
  1251. // IN PIRP_CONTEXT IrpContext,
  1252. // IN PVCB Vcb
  1253. // );
  1254. //
  1255. #define FatDeleteResource(RESRC) { \
  1256. ExDeleteResourceLite( (RESRC) ); \
  1257. }
  1258. #define FatReleaseGlobal(IRPCONTEXT) { \
  1259. ExReleaseResourceLite( &(FatData.Resource) ); \
  1260. }
  1261. #define FatReleaseVcb(IRPCONTEXT,Vcb) { \
  1262. ExReleaseResourceLite( &((Vcb)->Resource) ); \
  1263. }
  1264. #define FatReleaseFcb(IRPCONTEXT,Fcb) { \
  1265. ExReleaseResourceLite( (Fcb)->Header.Resource ); \
  1266. }
  1267. //
  1268. // In-memory structure support routine, implemented in StrucSup.c
  1269. //
  1270. VOID
  1271. FatInitializeVcb (
  1272. IN PIRP_CONTEXT IrpContext,
  1273. IN OUT PVCB Vcb,
  1274. IN PDEVICE_OBJECT TargetDeviceObject,
  1275. IN PVPB Vpb,
  1276. IN PDEVICE_OBJECT FsDeviceObject
  1277. );
  1278. VOID
  1279. FatDeleteVcb (
  1280. IN PIRP_CONTEXT IrpContext,
  1281. IN PVCB Vcb
  1282. );
  1283. VOID
  1284. FatCreateRootDcb (
  1285. IN PIRP_CONTEXT IrpContext,
  1286. IN PVCB Vcb
  1287. );
  1288. PFCB
  1289. FatCreateFcb (
  1290. IN PIRP_CONTEXT IrpContext,
  1291. IN PVCB Vcb,
  1292. IN PDCB ParentDcb,
  1293. IN ULONG LfnOffsetWithinDirectory,
  1294. IN ULONG DirentOffsetWithinDirectory,
  1295. IN PDIRENT Dirent,
  1296. IN PUNICODE_STRING Lfn OPTIONAL,
  1297. IN BOOLEAN IsPagingFile,
  1298. IN BOOLEAN SingleResource
  1299. );
  1300. PDCB
  1301. FatCreateDcb (
  1302. IN PIRP_CONTEXT IrpContext,
  1303. IN PVCB Vcb,
  1304. IN PDCB ParentDcb,
  1305. IN ULONG LfnOffsetWithinDirectory,
  1306. IN ULONG DirentOffsetWithinDirectory,
  1307. IN PDIRENT Dirent,
  1308. IN PUNICODE_STRING Lfn OPTIONAL
  1309. );
  1310. VOID
  1311. FatDeleteFcb_Real (
  1312. IN PIRP_CONTEXT IrpContext,
  1313. IN PFCB Fcb
  1314. );
  1315. #ifdef FASTFATDBG
  1316. #define FatDeleteFcb(IRPCONTEXT,FCB) { \
  1317. FatDeleteFcb_Real((IRPCONTEXT),(FCB)); \
  1318. (FCB) = NULL; \
  1319. }
  1320. #else
  1321. #define FatDeleteFcb(IRPCONTEXT,VCB) { \
  1322. FatDeleteFcb_Real((IRPCONTEXT),(VCB)); \
  1323. }
  1324. #endif // FASTFAT_DBG
  1325. PCCB
  1326. FatCreateCcb (
  1327. IN PIRP_CONTEXT IrpContext
  1328. );
  1329. VOID
  1330. FatDeallocateCcbStrings(
  1331. IN PCCB Ccb
  1332. );
  1333. VOID
  1334. FatDeleteCcb_Real (
  1335. IN PIRP_CONTEXT IrpContext,
  1336. IN PCCB Ccb
  1337. );
  1338. #ifdef FASTFATDBG
  1339. #define FatDeleteCcb(IRPCONTEXT,CCB) { \
  1340. FatDeleteCcb_Real((IRPCONTEXT),(CCB)); \
  1341. (CCB) = NULL; \
  1342. }
  1343. #else
  1344. #define FatDeleteCcb(IRPCONTEXT,VCB) { \
  1345. FatDeleteCcb_Real((IRPCONTEXT),(VCB)); \
  1346. }
  1347. #endif // FASTFAT_DBG
  1348. PIRP_CONTEXT
  1349. FatCreateIrpContext (
  1350. IN PIRP Irp,
  1351. IN BOOLEAN Wait
  1352. );
  1353. VOID
  1354. FatDeleteIrpContext_Real (
  1355. IN PIRP_CONTEXT IrpContext
  1356. );
  1357. #ifdef FASTFATDBG
  1358. #define FatDeleteIrpContext(IRPCONTEXT) { \
  1359. FatDeleteIrpContext_Real((IRPCONTEXT)); \
  1360. (IRPCONTEXT) = NULL; \
  1361. }
  1362. #else
  1363. #define FatDeleteIrpContext(IRPCONTEXT) { \
  1364. FatDeleteIrpContext_Real((IRPCONTEXT)); \
  1365. }
  1366. #endif // FASTFAT_DBG
  1367. PFCB
  1368. FatGetNextFcbTopDown (
  1369. IN PIRP_CONTEXT IrpContext,
  1370. IN PFCB Fcb,
  1371. IN PFCB TerminationFcb
  1372. );
  1373. PFCB
  1374. FatGetNextFcbBottomUp (
  1375. IN PIRP_CONTEXT IrpContext,
  1376. IN PFCB Fcb,
  1377. IN PFCB TerminationFcb
  1378. );
  1379. //
  1380. // These two macros just make the code a bit cleaner.
  1381. //
  1382. #define FatGetFirstChild(DIR) ((PFCB)( \
  1383. IsListEmpty(&(DIR)->Specific.Dcb.ParentDcbQueue) ? NULL : \
  1384. CONTAINING_RECORD((DIR)->Specific.Dcb.ParentDcbQueue.Flink, \
  1385. DCB, \
  1386. ParentDcbLinks.Flink)))
  1387. #define FatGetNextSibling(FILE) ((PFCB)( \
  1388. &(FILE)->ParentDcb->Specific.Dcb.ParentDcbQueue.Flink == \
  1389. (PVOID)(FILE)->ParentDcbLinks.Flink ? NULL : \
  1390. CONTAINING_RECORD((FILE)->ParentDcbLinks.Flink, \
  1391. FCB, \
  1392. ParentDcbLinks.Flink)))
  1393. BOOLEAN
  1394. FatCheckForDismount (
  1395. IN PIRP_CONTEXT IrpContext,
  1396. PVCB Vcb,
  1397. IN BOOLEAN Force
  1398. );
  1399. VOID
  1400. FatConstructNamesInFcb (
  1401. IN PIRP_CONTEXT IrpContext,
  1402. PFCB Fcb,
  1403. PDIRENT Dirent,
  1404. PUNICODE_STRING Lfn OPTIONAL
  1405. );
  1406. VOID
  1407. FatCheckFreeDirentBitmap (
  1408. IN PIRP_CONTEXT IrpContext,
  1409. IN PDCB Dcb
  1410. );
  1411. ULONG
  1412. FatVolumeUncleanCount (
  1413. IN PIRP_CONTEXT IrpContext,
  1414. IN PVCB Vcb
  1415. );
  1416. VOID
  1417. FatPreallocateCloseContext (
  1418. );
  1419. // VOID
  1420. // FatAllocateCloseContext (
  1421. // )
  1422. //
  1423. // This routine allocates a close context, presumeably on behalf
  1424. // of a fileobject which does not have a structure we can embed one
  1425. // in.
  1426. #define FatAllocateCloseContext() (PCLOSE_CONTEXT) \
  1427. ExInterlockedPopEntrySList( &FatCloseContextSList, \
  1428. &FatData.GeneralSpinLock )
  1429. //
  1430. // BOOLEAN
  1431. // FatIsRawDevice (
  1432. // IN PIRP_CONTEXT IrpContext,
  1433. // IN NTSTATUS Status
  1434. // );
  1435. //
  1436. #define FatIsRawDevice(IC,S) ( \
  1437. ((S) == STATUS_DEVICE_NOT_READY) || \
  1438. ((S) == STATUS_NO_MEDIA_IN_DEVICE) \
  1439. )
  1440. //
  1441. // Routines to support managing file names Fcbs and Dcbs.
  1442. // Implemented in SplaySup.c
  1443. //
  1444. VOID
  1445. FatInsertName (
  1446. IN PIRP_CONTEXT IrpContext,
  1447. IN PRTL_SPLAY_LINKS *RootNode,
  1448. IN PFILE_NAME_NODE Name
  1449. );
  1450. VOID
  1451. FatRemoveNames (
  1452. IN PIRP_CONTEXT IrpContext,
  1453. IN PFCB Fcb
  1454. );
  1455. PFCB
  1456. FatFindFcb (
  1457. IN PIRP_CONTEXT IrpContext,
  1458. IN OUT PRTL_SPLAY_LINKS *RootNode,
  1459. IN PSTRING Name,
  1460. OUT PBOOLEAN FileNameDos OPTIONAL
  1461. );
  1462. BOOLEAN
  1463. FatIsHandleCountZero (
  1464. IN PIRP_CONTEXT IrpContext,
  1465. IN PVCB Vcb
  1466. );
  1467. //
  1468. // Time conversion support routines, implemented in TimeSup.c
  1469. //
  1470. BOOLEAN
  1471. FatNtTimeToFatTime (
  1472. IN PIRP_CONTEXT IrpContext,
  1473. IN PLARGE_INTEGER NtTime,
  1474. IN BOOLEAN Rounding,
  1475. OUT PFAT_TIME_STAMP FatTime,
  1476. OUT OPTIONAL PCHAR TenMsecs
  1477. );
  1478. LARGE_INTEGER
  1479. FatFatTimeToNtTime (
  1480. IN PIRP_CONTEXT IrpContext,
  1481. IN FAT_TIME_STAMP FatTime,
  1482. IN UCHAR TenMilliSeconds
  1483. );
  1484. LARGE_INTEGER
  1485. FatFatDateToNtTime (
  1486. IN PIRP_CONTEXT IrpContext,
  1487. IN FAT_DATE FatDate
  1488. );
  1489. FAT_TIME_STAMP
  1490. FatGetCurrentFatTime (
  1491. IN PIRP_CONTEXT IrpContext
  1492. );
  1493. //
  1494. // Low level verification routines, implemented in VerfySup.c
  1495. //
  1496. // The first routine is called to help process a verify IRP. Its job is
  1497. // to walk every Fcb/Dcb and mark them as need to be verified.
  1498. //
  1499. // The other routines are used by every dispatch routine to verify that
  1500. // an Vcb/Fcb/Dcb is still good. The routine walks as much of the opened
  1501. // file/directory tree as necessary to make sure that the path is still valid.
  1502. // The function result indicates if the procedure needed to block for I/O.
  1503. // If the structure is bad the procedure raise the error condition
  1504. // STATUS_FILE_INVALID, otherwise they simply return to their caller
  1505. //
  1506. typedef enum _FAT_VOLUME_STATE {
  1507. VolumeClean,
  1508. VolumeDirty,
  1509. VolumeDirtyWithSurfaceTest
  1510. } FAT_VOLUME_STATE, *PFAT_VOLUME_STATE;
  1511. VOID
  1512. FatMarkFcbCondition (
  1513. IN PIRP_CONTEXT IrpContext,
  1514. IN PFCB Fcb,
  1515. IN FCB_CONDITION FcbCondition,
  1516. IN BOOLEAN Recursive
  1517. );
  1518. VOID
  1519. FatVerifyVcb (
  1520. IN PIRP_CONTEXT IrpContext,
  1521. IN PVCB Vcb
  1522. );
  1523. VOID
  1524. FatVerifyFcb (
  1525. IN PIRP_CONTEXT IrpContext,
  1526. IN PFCB Fcb
  1527. );
  1528. VOID
  1529. FatCleanVolumeDpc (
  1530. IN PKDPC Dpc,
  1531. IN PVOID DeferredContext,
  1532. IN PVOID SystemArgument1,
  1533. IN PVOID SystemArgument2
  1534. );
  1535. VOID
  1536. FatMarkVolume (
  1537. IN PIRP_CONTEXT IrpContext,
  1538. IN PVCB Vcb,
  1539. IN FAT_VOLUME_STATE VolumeState
  1540. );
  1541. VOID
  1542. FatFspMarkVolumeDirtyWithRecover (
  1543. PVOID Parameter
  1544. );
  1545. VOID
  1546. FatCheckDirtyBit (
  1547. IN PIRP_CONTEXT IrpContext,
  1548. IN PVCB Vcb
  1549. );
  1550. VOID
  1551. FatQuickVerifyVcb (
  1552. IN PIRP_CONTEXT IrpContext,
  1553. IN PVCB Vcb
  1554. );
  1555. VOID
  1556. FatVerifyOperationIsLegal (
  1557. IN PIRP_CONTEXT IrpContext
  1558. );
  1559. NTSTATUS
  1560. FatPerformVerify (
  1561. IN PIRP_CONTEXT IrpContext,
  1562. IN PIRP Irp,
  1563. IN PDEVICE_OBJECT Device
  1564. );
  1565. //
  1566. // Work queue routines for posting and retrieving an Irp, implemented in
  1567. // workque.c
  1568. //
  1569. VOID
  1570. FatOplockComplete (
  1571. IN PVOID Context,
  1572. IN PIRP Irp
  1573. );
  1574. VOID
  1575. FatPrePostIrp (
  1576. IN PVOID Context,
  1577. IN PIRP Irp
  1578. );
  1579. VOID
  1580. FatAddToWorkque (
  1581. IN PIRP_CONTEXT IrpContext,
  1582. IN PIRP Irp
  1583. );
  1584. NTSTATUS
  1585. FatFsdPostRequest (
  1586. IN PIRP_CONTEXT IrpContext,
  1587. IN PIRP Irp
  1588. );
  1589. //
  1590. // Miscellaneous support routines
  1591. //
  1592. //
  1593. // This macro returns TRUE if a flag in a set of flags is on and FALSE
  1594. // otherwise. It is followed by two macros for setting and clearing
  1595. // flags
  1596. //
  1597. //#ifndef BooleanFlagOn
  1598. //#define BooleanFlagOn(Flags,SingleFlag) ((BOOLEAN)((((Flags) & (SingleFlag)) != 0)))
  1599. //#endif
  1600. //#ifndef SetFlag
  1601. //#define SetFlag(Flags,SingleFlag) { \
  1602. // (Flags) |= (SingleFlag); \
  1603. //}
  1604. //#endif
  1605. //#ifndef ClearFlag
  1606. //#define ClearFlag(Flags,SingleFlag) { \
  1607. // (Flags) &= ~(SingleFlag); \
  1608. //}
  1609. //#endif
  1610. //
  1611. // ULONG
  1612. // PtrOffset (
  1613. // IN PVOID BasePtr,
  1614. // IN PVOID OffsetPtr
  1615. // );
  1616. //
  1617. #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
  1618. //
  1619. // This macro takes a pointer (or ulong) and returns its rounded up word
  1620. // value
  1621. //
  1622. #define WordAlign(Ptr) ( \
  1623. ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
  1624. )
  1625. //
  1626. // This macro takes a pointer (or ulong) and returns its rounded up longword
  1627. // value
  1628. //
  1629. #define LongAlign(Ptr) ( \
  1630. ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
  1631. )
  1632. //
  1633. // This macro takes a pointer (or ulong) and returns its rounded up quadword
  1634. // value
  1635. //
  1636. #define QuadAlign(Ptr) ( \
  1637. ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
  1638. )
  1639. //
  1640. // The following types and macros are used to help unpack the packed and
  1641. // misaligned fields found in the Bios parameter block
  1642. //
  1643. typedef union _UCHAR1 {
  1644. UCHAR Uchar[1];
  1645. UCHAR ForceAlignment;
  1646. } UCHAR1, *PUCHAR1;
  1647. typedef union _UCHAR2 {
  1648. UCHAR Uchar[2];
  1649. USHORT ForceAlignment;
  1650. } UCHAR2, *PUCHAR2;
  1651. typedef union _UCHAR4 {
  1652. UCHAR Uchar[4];
  1653. ULONG ForceAlignment;
  1654. } UCHAR4, *PUCHAR4;
  1655. //
  1656. // This macro copies an unaligned src byte to an aligned dst byte
  1657. //
  1658. #define CopyUchar1(Dst,Src) { \
  1659. *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
  1660. }
  1661. //
  1662. // This macro copies an unaligned src word to an aligned dst word
  1663. //
  1664. #define CopyUchar2(Dst,Src) { \
  1665. *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
  1666. }
  1667. //
  1668. // This macro copies an unaligned src longword to an aligned dsr longword
  1669. //
  1670. #define CopyUchar4(Dst,Src) { \
  1671. *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
  1672. }
  1673. #define CopyU4char(Dst,Src) { \
  1674. *((UNALIGNED UCHAR4 *)(Dst)) = *((UCHAR4 *)(Src)); \
  1675. }
  1676. //
  1677. // VOID
  1678. // FatNotifyReportChange (
  1679. // IN PIRP_CONTEXT IrpContext,
  1680. // IN PVCB Vcb,
  1681. // IN PFCB Fcb,
  1682. // IN ULONG Filter,
  1683. // IN ULONG Action
  1684. // );
  1685. //
  1686. #define FatNotifyReportChange(I,V,F,FL,A) { \
  1687. if ((F)->FullFileName.Buffer == NULL) { \
  1688. FatSetFullFileNameInFcb((I),(F)); \
  1689. } \
  1690. ASSERT( (F)->FullFileName.Length != 0 ); \
  1691. ASSERT( (F)->FinalNameLength != 0 ); \
  1692. ASSERT( (F)->FullFileName.Length > (F)->FinalNameLength ); \
  1693. ASSERT( (F)->FullFileName.Buffer[((F)->FullFileName.Length - (F)->FinalNameLength)/sizeof(WCHAR) - 1] == L'\\' ); \
  1694. FsRtlNotifyFullReportChange( (V)->NotifySync, \
  1695. &(V)->DirNotifyList, \
  1696. (PSTRING)&(F)->FullFileName, \
  1697. (USHORT) ((F)->FullFileName.Length - \
  1698. (F)->FinalNameLength), \
  1699. (PSTRING)NULL, \
  1700. (PSTRING)NULL, \
  1701. (ULONG)FL, \
  1702. (ULONG)A, \
  1703. (PVOID)NULL ); \
  1704. }
  1705. //
  1706. // The FSD Level dispatch routines. These routines are called by the
  1707. // I/O system via the dispatch table in the Driver Object.
  1708. //
  1709. // They each accept as input a pointer to a device object (actually most
  1710. // expect a volume device object, with the exception of the file system
  1711. // control function which can also take a file system device object), and
  1712. // a pointer to the IRP. They either perform the function at the FSD level
  1713. // or post the request to the FSP work queue for FSP level processing.
  1714. //
  1715. NTSTATUS
  1716. FatFsdCleanup ( // implemented in Cleanup.c
  1717. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1718. IN PIRP Irp
  1719. );
  1720. NTSTATUS
  1721. FatFsdClose ( // implemented in Close.c
  1722. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1723. IN PIRP Irp
  1724. );
  1725. NTSTATUS
  1726. FatFsdCreate ( // implemented in Create.c
  1727. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1728. IN PIRP Irp
  1729. );
  1730. NTSTATUS
  1731. FatFsdDeviceControl ( // implemented in DevCtrl.c
  1732. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1733. IN PIRP Irp
  1734. );
  1735. NTSTATUS
  1736. FatFsdDirectoryControl ( // implemented in DirCtrl.c
  1737. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1738. IN PIRP Irp
  1739. );
  1740. NTSTATUS
  1741. FatFsdQueryEa ( // implemented in Ea.c
  1742. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1743. IN PIRP Irp
  1744. );
  1745. NTSTATUS
  1746. FatFsdSetEa ( // implemented in Ea.c
  1747. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1748. IN PIRP Irp
  1749. );
  1750. NTSTATUS
  1751. FatFsdQueryInformation ( // implemented in FileInfo.c
  1752. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1753. IN PIRP Irp
  1754. );
  1755. NTSTATUS
  1756. FatFsdSetInformation ( // implemented in FileInfo.c
  1757. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1758. IN PIRP Irp
  1759. );
  1760. NTSTATUS
  1761. FatFsdFlushBuffers ( // implemented in Flush.c
  1762. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1763. IN PIRP Irp
  1764. );
  1765. NTSTATUS
  1766. FatFsdFileSystemControl ( // implemented in FsCtrl.c
  1767. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1768. IN PIRP Irp
  1769. );
  1770. NTSTATUS
  1771. FatFsdLockControl ( // implemented in LockCtrl.c
  1772. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1773. IN PIRP Irp
  1774. );
  1775. NTSTATUS
  1776. FatFsdPnp ( // implemented in Pnp.c
  1777. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1778. IN PIRP Irp
  1779. );
  1780. NTSTATUS
  1781. FatFsdRead ( // implemented in Read.c
  1782. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1783. IN PIRP Irp
  1784. );
  1785. NTSTATUS
  1786. FatFsdShutdown ( // implemented in Shutdown.c
  1787. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1788. IN PIRP Irp
  1789. );
  1790. NTSTATUS
  1791. FatFsdQueryVolumeInformation ( // implemented in VolInfo.c
  1792. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1793. IN PIRP Irp
  1794. );
  1795. NTSTATUS
  1796. FatFsdSetVolumeInformation ( // implemented in VolInfo.c
  1797. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1798. IN PIRP Irp
  1799. );
  1800. NTSTATUS
  1801. FatFsdWrite ( // implemented in Write.c
  1802. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1803. IN PIRP Irp
  1804. );
  1805. //
  1806. // The following macro is used to determine if an FSD thread can block
  1807. // for I/O or wait for a resource. It returns TRUE if the thread can
  1808. // block and FALSE otherwise. This attribute can then be used to call
  1809. // the FSD & FSP common work routine with the proper wait value.
  1810. //
  1811. #define CanFsdWait(IRP) IoIsOperationSynchronous(Irp)
  1812. //
  1813. // The FSP level dispatch/main routine. This is the routine that takes
  1814. // IRP's off of the work queue and calls the appropriate FSP level
  1815. // work routine.
  1816. //
  1817. VOID
  1818. FatFspDispatch ( // implemented in FspDisp.c
  1819. IN PVOID Context
  1820. );
  1821. //
  1822. // The following routines are the FSP work routines that are called
  1823. // by the preceding FatFspDispath routine. Each takes as input a pointer
  1824. // to the IRP, perform the function, and return a pointer to the volume
  1825. // device object that they just finished servicing (if any). The return
  1826. // pointer is then used by the main Fsp dispatch routine to check for
  1827. // additional IRPs in the volume's overflow queue.
  1828. //
  1829. // Each of the following routines is also responsible for completing the IRP.
  1830. // We moved this responsibility from the main loop to the individual routines
  1831. // to allow them the ability to complete the IRP and continue post processing
  1832. // actions.
  1833. //
  1834. NTSTATUS
  1835. FatCommonCleanup ( // implemented in Cleanup.c
  1836. IN PIRP_CONTEXT IrpContext,
  1837. IN PIRP Irp
  1838. );
  1839. NTSTATUS
  1840. FatCommonClose ( // implemented in Close.c
  1841. IN PVCB Vcb,
  1842. IN PFCB Fcb,
  1843. IN PCCB Ccb,
  1844. IN TYPE_OF_OPEN TypeOfOpen,
  1845. IN BOOLEAN Wait,
  1846. IN PVOLUME_DEVICE_OBJECT *VolDo OPTIONAL
  1847. );
  1848. VOID
  1849. FatFspClose ( // implemented in Close.c
  1850. IN PVCB Vcb OPTIONAL
  1851. );
  1852. NTSTATUS
  1853. FatCommonCreate ( // implemented in Create.c
  1854. IN PIRP_CONTEXT IrpContext,
  1855. IN PIRP Irp
  1856. );
  1857. NTSTATUS
  1858. FatCommonDirectoryControl ( // implemented in DirCtrl.c
  1859. IN PIRP_CONTEXT IrpContext,
  1860. IN PIRP Irp
  1861. );
  1862. NTSTATUS
  1863. FatCommonDeviceControl ( // implemented in DevCtrl.c
  1864. IN PIRP_CONTEXT IrpContext,
  1865. IN PIRP Irp
  1866. );
  1867. NTSTATUS
  1868. FatCommonQueryEa ( // implemented in Ea.c
  1869. IN PIRP_CONTEXT IrpContext,
  1870. IN PIRP Irp
  1871. );
  1872. NTSTATUS
  1873. FatCommonSetEa ( // implemented in Ea.c
  1874. IN PIRP_CONTEXT IrpContext,
  1875. IN PIRP Irp
  1876. );
  1877. NTSTATUS
  1878. FatCommonQueryInformation ( // implemented in FileInfo.c
  1879. IN PIRP_CONTEXT IrpContext,
  1880. IN PIRP Irp
  1881. );
  1882. NTSTATUS
  1883. FatCommonSetInformation ( // implemented in FileInfo.c
  1884. IN PIRP_CONTEXT IrpContext,
  1885. IN PIRP Irp
  1886. );
  1887. NTSTATUS
  1888. FatCommonFlushBuffers ( // implemented in Flush.c
  1889. IN PIRP_CONTEXT IrpContext,
  1890. IN PIRP Irp
  1891. );
  1892. NTSTATUS
  1893. FatCommonFileSystemControl ( // implemented in FsCtrl.c
  1894. IN PIRP_CONTEXT IrpContext,
  1895. IN PIRP Irp
  1896. );
  1897. NTSTATUS
  1898. FatCommonLockControl ( // implemented in LockCtrl.c
  1899. IN PIRP_CONTEXT IrpContext,
  1900. IN PIRP Irp
  1901. );
  1902. NTSTATUS
  1903. FatCommonPnp ( // implemented in Pnp.c
  1904. IN PIRP_CONTEXT IrpContext,
  1905. IN PIRP Irp
  1906. );
  1907. NTSTATUS
  1908. FatCommonRead ( // implemented in Read.c
  1909. IN PIRP_CONTEXT IrpContext,
  1910. IN PIRP Irp
  1911. );
  1912. NTSTATUS
  1913. FatCommonShutdown ( // implemented in Shutdown.c
  1914. IN PIRP_CONTEXT IrpContext,
  1915. IN PIRP Irp
  1916. );
  1917. NTSTATUS
  1918. FatCommonQueryVolumeInfo ( // implemented in VolInfo.c
  1919. IN PIRP_CONTEXT IrpContext,
  1920. IN PIRP Irp
  1921. );
  1922. NTSTATUS
  1923. FatCommonSetVolumeInfo ( // implemented in VolInfo.c
  1924. IN PIRP_CONTEXT IrpContext,
  1925. IN PIRP Irp
  1926. );
  1927. NTSTATUS
  1928. FatCommonWrite ( // implemented in Write.c
  1929. IN PIRP_CONTEXT IrpContext,
  1930. IN PIRP Irp
  1931. );
  1932. //
  1933. // The following is implemented in Flush.c, and does what is says.
  1934. //
  1935. NTSTATUS
  1936. FatFlushFile (
  1937. IN PIRP_CONTEXT IrpContext,
  1938. IN PFCB Fcb,
  1939. IN FAT_FLUSH_TYPE FlushType
  1940. );
  1941. NTSTATUS
  1942. FatFlushDirectory (
  1943. IN PIRP_CONTEXT IrpContext,
  1944. IN PDCB Dcb,
  1945. IN FAT_FLUSH_TYPE FlushType
  1946. );
  1947. NTSTATUS
  1948. FatFlushFat (
  1949. IN PIRP_CONTEXT IrpContext,
  1950. IN PVCB Vcb
  1951. );
  1952. NTSTATUS
  1953. FatFlushVolume (
  1954. IN PIRP_CONTEXT IrpContext,
  1955. IN PVCB Vcb,
  1956. IN FAT_FLUSH_TYPE FlushType
  1957. );
  1958. NTSTATUS
  1959. FatHijackIrpAndFlushDevice (
  1960. IN PIRP_CONTEXT IrpContext,
  1961. IN PIRP Irp,
  1962. IN PDEVICE_OBJECT TargetDeviceObject
  1963. );
  1964. VOID
  1965. FatFlushFatEntries (
  1966. IN PIRP_CONTEXT IrpContext,
  1967. IN PVCB Vcb,
  1968. IN ULONG Cluster,
  1969. IN ULONG Count
  1970. );
  1971. VOID
  1972. FatFlushDirentForFile (
  1973. IN PIRP_CONTEXT IrpContext,
  1974. IN PFCB Fcb
  1975. );
  1976. //
  1977. // The following procedure is used by the FSP and FSD routines to complete
  1978. // an IRP.
  1979. //
  1980. // Note that this macro allows either the Irp or the IrpContext to be
  1981. // null, however the only legal order to do this in is:
  1982. //
  1983. // FatCompleteRequest( NULL, Irp, Status ); // completes Irp & preserves context
  1984. // ...
  1985. // FatCompleteRequest( IrpContext, NULL, DontCare ); // deallocates context
  1986. //
  1987. // This would typically be done in order to pass a "naked" IrpContext off to
  1988. // the Fsp for post processing, such as read ahead.
  1989. //
  1990. VOID
  1991. FatCompleteRequest_Real (
  1992. IN PIRP_CONTEXT IrpContext,
  1993. IN PIRP Irp,
  1994. IN NTSTATUS Status
  1995. );
  1996. #define FatCompleteRequest(IRPCONTEXT,IRP,STATUS) { \
  1997. FatCompleteRequest_Real(IRPCONTEXT,IRP,STATUS); \
  1998. }
  1999. BOOLEAN
  2000. FatIsIrpTopLevel (
  2001. IN PIRP Irp
  2002. );
  2003. //
  2004. // The Following routine makes a popup
  2005. //
  2006. VOID
  2007. FatPopUpFileCorrupt (
  2008. IN PIRP_CONTEXT IrpContext,
  2009. IN PFCB Fcb
  2010. );
  2011. //
  2012. // Here are the callbacks used by the I/O system for checking for fast I/O or
  2013. // doing a fast query info call, or doing fast lock calls.
  2014. //
  2015. BOOLEAN
  2016. FatFastIoCheckIfPossible (
  2017. IN PFILE_OBJECT FileObject,
  2018. IN PLARGE_INTEGER FileOffset,
  2019. IN ULONG Length,
  2020. IN BOOLEAN Wait,
  2021. IN ULONG LockKey,
  2022. IN BOOLEAN CheckForReadOperation,
  2023. OUT PIO_STATUS_BLOCK IoStatus,
  2024. IN PDEVICE_OBJECT DeviceObject
  2025. );
  2026. BOOLEAN
  2027. FatFastQueryBasicInfo (
  2028. IN PFILE_OBJECT FileObject,
  2029. IN BOOLEAN Wait,
  2030. IN OUT PFILE_BASIC_INFORMATION Buffer,
  2031. OUT PIO_STATUS_BLOCK IoStatus,
  2032. IN PDEVICE_OBJECT DeviceObject
  2033. );
  2034. BOOLEAN
  2035. FatFastQueryStdInfo (
  2036. IN PFILE_OBJECT FileObject,
  2037. IN BOOLEAN Wait,
  2038. IN OUT PFILE_STANDARD_INFORMATION Buffer,
  2039. OUT PIO_STATUS_BLOCK IoStatus,
  2040. IN PDEVICE_OBJECT DeviceObject
  2041. );
  2042. BOOLEAN
  2043. FatFastQueryNetworkOpenInfo (
  2044. IN PFILE_OBJECT FileObject,
  2045. IN BOOLEAN Wait,
  2046. IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
  2047. OUT PIO_STATUS_BLOCK IoStatus,
  2048. IN PDEVICE_OBJECT DeviceObject
  2049. );
  2050. BOOLEAN
  2051. FatFastLock (
  2052. IN PFILE_OBJECT FileObject,
  2053. IN PLARGE_INTEGER FileOffset,
  2054. IN PLARGE_INTEGER Length,
  2055. PEPROCESS ProcessId,
  2056. ULONG Key,
  2057. BOOLEAN FailImmediately,
  2058. BOOLEAN ExclusiveLock,
  2059. OUT PIO_STATUS_BLOCK IoStatus,
  2060. IN PDEVICE_OBJECT DeviceObject
  2061. );
  2062. BOOLEAN
  2063. FatFastUnlockSingle (
  2064. IN PFILE_OBJECT FileObject,
  2065. IN PLARGE_INTEGER FileOffset,
  2066. IN PLARGE_INTEGER Length,
  2067. PEPROCESS ProcessId,
  2068. ULONG Key,
  2069. OUT PIO_STATUS_BLOCK IoStatus,
  2070. IN PDEVICE_OBJECT DeviceObject
  2071. );
  2072. BOOLEAN
  2073. FatFastUnlockAll (
  2074. IN PFILE_OBJECT FileObject,
  2075. PEPROCESS ProcessId,
  2076. OUT PIO_STATUS_BLOCK IoStatus,
  2077. IN PDEVICE_OBJECT DeviceObject
  2078. );
  2079. BOOLEAN
  2080. FatFastUnlockAllByKey (
  2081. IN PFILE_OBJECT FileObject,
  2082. PVOID ProcessId,
  2083. ULONG Key,
  2084. OUT PIO_STATUS_BLOCK IoStatus,
  2085. IN PDEVICE_OBJECT DeviceObject
  2086. );
  2087. VOID
  2088. FatExamineFatEntries(
  2089. IN PIRP_CONTEXT IrpContext,
  2090. IN PVCB Vcb,
  2091. IN ULONG StartIndex OPTIONAL,
  2092. IN ULONG EndIndex OPTIONAL,
  2093. IN BOOLEAN SetupWindows,
  2094. IN PFAT_WINDOW SwitchToWindow OPTIONAL,
  2095. IN PULONG BitMapBuffer OPTIONAL
  2096. );
  2097. BOOLEAN
  2098. FatScanForDataTrack(
  2099. IN PIRP_CONTEXT IrpContext,
  2100. IN PDEVICE_OBJECT TargetDeviceObject
  2101. );
  2102. //
  2103. // The following macro is used to determine is a file has been deleted.
  2104. //
  2105. // BOOLEAN
  2106. // IsFileDeleted (
  2107. // IN PIRP_CONTEXT IrpContext,
  2108. // IN PFCB Fcb
  2109. // );
  2110. //
  2111. #define IsFileDeleted(IRPCONTEXT,FCB) \
  2112. (FlagOn((FCB)->FcbState, FCB_STATE_DELETE_ON_CLOSE) && \
  2113. ((FCB)->UncleanCount == 0))
  2114. //
  2115. // The following macro is used by the dispatch routines to determine if
  2116. // an operation is to be done with or without Write Through.
  2117. //
  2118. // BOOLEAN
  2119. // IsFileWriteThrough (
  2120. // IN PFILE_OBJECT FileObject,
  2121. // IN PVCB Vcb
  2122. // );
  2123. //
  2124. #define IsFileWriteThrough(FO,VCB) ( \
  2125. BooleanFlagOn((FO)->Flags, FO_WRITE_THROUGH) \
  2126. )
  2127. //
  2128. // The following macro is used to set the is fast i/o possible field in
  2129. // the common part of the nonpaged fcb
  2130. //
  2131. //
  2132. // BOOLEAN
  2133. // FatIsFastIoPossible (
  2134. // IN PFCB Fcb
  2135. // );
  2136. //
  2137. #define FatIsFastIoPossible(FCB) ((BOOLEAN) \
  2138. (((FCB)->FcbCondition != FcbGood || !FsRtlOplockIsFastIoPossible( &(FCB)->Specific.Fcb.Oplock )) ? \
  2139. FastIoIsNotPossible \
  2140. : \
  2141. (!FsRtlAreThereCurrentFileLocks( &(FCB)->Specific.Fcb.FileLock ) && \
  2142. ((FCB)->NonPaged->OutstandingAsyncWrites == 0) && \
  2143. !FlagOn( (FCB)->Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED ) ? \
  2144. FastIoIsPossible \
  2145. : \
  2146. FastIoIsQuestionable \
  2147. ) \
  2148. ) \
  2149. )
  2150. //
  2151. // The following macro is used to detemine if the file object is opened
  2152. // for read only access (i.e., it is not also opened for write access or
  2153. // delete access).
  2154. //
  2155. // BOOLEAN
  2156. // IsFileObjectReadOnly (
  2157. // IN PFILE_OBJECT FileObject
  2158. // );
  2159. //
  2160. #define IsFileObjectReadOnly(FO) (!((FO)->WriteAccess | (FO)->DeleteAccess))
  2161. //
  2162. // The following two macro are used by the Fsd/Fsp exception handlers to
  2163. // process an exception. The first macro is the exception filter used in the
  2164. // Fsd/Fsp to decide if an exception should be handled at this level.
  2165. // The second macro decides if the exception is to be finished off by
  2166. // completing the IRP, and cleaning up the Irp Context, or if we should
  2167. // bugcheck. Exception values such as STATUS_FILE_INVALID (raised by
  2168. // VerfySup.c) cause us to complete the Irp and cleanup, while exceptions
  2169. // such as accvio cause us to bugcheck.
  2170. //
  2171. // The basic structure for fsd/fsp exception handling is as follows:
  2172. //
  2173. // FatFsdXxx(...)
  2174. // {
  2175. // try {
  2176. //
  2177. // ...
  2178. //
  2179. // } except(FatExceptionFilter( IrpContext, GetExceptionCode() )) {
  2180. //
  2181. // Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
  2182. // }
  2183. //
  2184. // Return Status;
  2185. // }
  2186. //
  2187. // To explicitly raise an exception that we expect, such as
  2188. // STATUS_FILE_INVALID, use the below macro FatRaiseStatus(). To raise a
  2189. // status from an unknown origin (such as CcFlushCache()), use the macro
  2190. // FatNormalizeAndRaiseStatus. This will raise the status if it is expected,
  2191. // or raise STATUS_UNEXPECTED_IO_ERROR if it is not.
  2192. //
  2193. // If we are vicariously handling exceptions without using FatProcessException(),
  2194. // if there is the possibility that we raised that exception, one *must*
  2195. // reset the IrpContext so a subsequent raise in the course of handling this
  2196. // request that is *not* explicit, i.e. like a pagein error, does not get
  2197. // spoofed into believing that the first raise status is the reason the second
  2198. // occured. This could have really nasty consequences.
  2199. //
  2200. // It is an excellent idea to always FatResetExceptionState in these cases.
  2201. //
  2202. // Note that when using these two macros, the original status is placed in
  2203. // IrpContext->ExceptionStatus, signaling FatExceptionFilter and
  2204. // FatProcessException that the status we actually raise is by definition
  2205. // expected.
  2206. //
  2207. ULONG
  2208. FatExceptionFilter (
  2209. IN PIRP_CONTEXT IrpContext,
  2210. IN PEXCEPTION_POINTERS ExceptionPointer
  2211. );
  2212. #if DBG
  2213. ULONG
  2214. FatBugCheckExceptionFilter (
  2215. IN PEXCEPTION_POINTERS ExceptionPointer
  2216. );
  2217. #endif
  2218. NTSTATUS
  2219. FatProcessException (
  2220. IN PIRP_CONTEXT IrpContext,
  2221. IN PIRP Irp,
  2222. IN NTSTATUS ExceptionCode
  2223. );
  2224. //
  2225. // VOID
  2226. // FatRaiseStatus (
  2227. // IN PRIP_CONTEXT IrpContext,
  2228. // IN NT_STATUS Status
  2229. // );
  2230. //
  2231. //
  2232. #if DBG
  2233. #define DebugBreakOnStatus(S) { \
  2234. if (FatTestRaisedStatus) { \
  2235. if ((S) == STATUS_DISK_CORRUPT_ERROR || (S) == STATUS_FILE_CORRUPT_ERROR) { \
  2236. DbgPrint( "FAT: Breaking on interesting raised status (%08x)\n", (S) ); \
  2237. DbgPrint( "FAT: Set FatTestRaisedStatus @ %08x to 0 to disable\n", \
  2238. &FatTestRaisedStatus ); \
  2239. DbgBreakPoint(); \
  2240. } \
  2241. } \
  2242. }
  2243. #else
  2244. #define DebugBreakOnStatus(S)
  2245. #endif
  2246. #define FatRaiseStatus(IRPCONTEXT,STATUS) { \
  2247. (IRPCONTEXT)->ExceptionStatus = (STATUS); \
  2248. DebugBreakOnStatus( (STATUS) ) \
  2249. ExRaiseStatus( (STATUS) ); \
  2250. }
  2251. #define FatResetExceptionState( IRPCONTEXT ) { \
  2252. (IRPCONTEXT)->ExceptionStatus = STATUS_SUCCESS; \
  2253. }
  2254. //
  2255. // VOID
  2256. // FatNormalAndRaiseStatus (
  2257. // IN PRIP_CONTEXT IrpContext,
  2258. // IN NT_STATUS Status
  2259. // );
  2260. //
  2261. #define FatNormalizeAndRaiseStatus(IRPCONTEXT,STATUS) { \
  2262. (IRPCONTEXT)->ExceptionStatus = (STATUS); \
  2263. ExRaiseStatus(FsRtlNormalizeNtstatus((STATUS),STATUS_UNEXPECTED_IO_ERROR)); \
  2264. }
  2265. //
  2266. // The following macros are used to establish the semantics needed
  2267. // to do a return from within a try-finally clause. As a rule every
  2268. // try clause must end with a label call try_exit. For example,
  2269. //
  2270. // try {
  2271. // :
  2272. // :
  2273. //
  2274. // try_exit: NOTHING;
  2275. // } finally {
  2276. //
  2277. // :
  2278. // :
  2279. // }
  2280. //
  2281. // Every return statement executed inside of a try clause should use the
  2282. // try_return macro. If the compiler fully supports the try-finally construct
  2283. // then the macro should be
  2284. //
  2285. // #define try_return(S) { return(S); }
  2286. //
  2287. // If the compiler does not support the try-finally construct then the macro
  2288. // should be
  2289. //
  2290. // #define try_return(S) { S; goto try_exit; }
  2291. //
  2292. #define try_return(S) { S; goto try_exit; }
  2293. #define try_leave(S) { S; leave; }
  2294. CLUSTER_TYPE
  2295. FatInterpretClusterType (
  2296. IN PVCB Vcb,
  2297. IN FAT_ENTRY Entry
  2298. );
  2299. //
  2300. // These routines define the FileId for FAT. Lacking a fixed/uniquifiable
  2301. // notion, we simply come up with one which is unique in a given snapshot
  2302. // of the volume. As long as the parent directory is not moved or compacted,
  2303. // it may even be permanent.
  2304. //
  2305. //
  2306. // The internal information used to identify the fcb/dcb on the
  2307. // volume is the byte offset of the dirent of the file on disc.
  2308. // Our root always has fileid 0. FAT32 roots are chains and can
  2309. // use the LBO of the cluster, 12/16 roots use the lbo in the Vcb.
  2310. //
  2311. #define FatGenerateFileIdFromDirentOffset(ParentDcb,DirentOffset) \
  2312. ((ParentDcb) ? ((NodeType(ParentDcb) != FAT_NTC_ROOT_DCB || FatIsFat32((ParentDcb)->Vcb)) ? \
  2313. FatGetLboFromIndex( (ParentDcb)->Vcb, \
  2314. (ParentDcb)->FirstClusterOfFile ) : \
  2315. (ParentDcb)->Vcb->AllocationSupport.RootDirectoryLbo) + \
  2316. (DirentOffset) \
  2317. : \
  2318. 0)
  2319. //
  2320. //
  2321. #define FatGenerateFileIdFromFcb(Fcb) \
  2322. FatGenerateFileIdFromDirentOffset( (Fcb)->ParentDcb, (Fcb)->DirentOffsetWithinDirectory )
  2323. //
  2324. // Wrap to handle the ./.. cases appropriately. Note that we commute NULL parent to 0. This would
  2325. // only occur in an illegal root ".." entry.
  2326. //
  2327. #define FATDOT ((ULONG)0x2020202E)
  2328. #define FATDOTDOT ((ULONG)0x20202E2E)
  2329. #define FatGenerateFileIdFromDirentAndOffset(Dcb,Dirent,DirentOffset) \
  2330. ((*((PULONG)(Dirent)->FileName)) == FATDOT ? FatGenerateFileIdFromFcb(Dcb) : \
  2331. ((*((PULONG)(Dirent)->FileName)) == FATDOTDOT ? ((Dcb)->ParentDcb ? \
  2332. FatGenerateFileIdFromFcb((Dcb)->ParentDcb) : \
  2333. 0) : \
  2334. FatGenerateFileIdFromDirentOffset(Dcb,DirentOffset)))
  2335. //
  2336. // BOOLEAN
  2337. // FatDeviceIsFatFsdo(
  2338. // IN PDEVICE_OBJECT D
  2339. // );
  2340. //
  2341. // Evaluates to TRUE if the supplied device object is one of the file system devices
  2342. // we created at initialisation.
  2343. //
  2344. #define FatDeviceIsFatFsdo( D) (((D) == FatData.DiskFileSystemDeviceObject) || ((D) == FatData.CdromFileSystemDeviceObject))
  2345. #endif // _FATPROCS_