Leaked source code of windows server 2003
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.

2769 lines
66 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. // Macro to enable easy tracking of Vcb state transitions.
  1134. //
  1135. #ifdef FASTFATDBG
  1136. #define FatSetVcbCondition( V, X) { \
  1137. DebugTrace(0,DEBUG_TRACE_VERFYSUP,"%d -> ",(V)->VcbCondition); \
  1138. DebugTrace(0,DEBUG_TRACE_VERFYSUP,"%x\n",(X)); \
  1139. (V)->VcbCondition = (X); \
  1140. }
  1141. #else
  1142. #define FatSetVcbCondition( V, X) (V)->VcbCondition = (X)
  1143. #endif
  1144. //
  1145. // These macros can be used to determine what kind of FAT we have for an
  1146. // initialized Vcb. It is somewhat more elegant to use these (visually).
  1147. //
  1148. #define FatIsFat32(VCB) ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 32))
  1149. #define FatIsFat16(VCB) ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 16))
  1150. #define FatIsFat12(VCB) ((BOOLEAN)((VCB)->AllocationSupport.FatIndexBitSize == 12))
  1151. FINISHED
  1152. FatAcquireExclusiveVcb (
  1153. IN PIRP_CONTEXT IrpContext,
  1154. IN PVCB Vcb
  1155. );
  1156. FINISHED
  1157. FatAcquireSharedVcb (
  1158. IN PIRP_CONTEXT IrpContext,
  1159. IN PVCB Vcb
  1160. );
  1161. FINISHED
  1162. FatAcquireExclusiveFcb (
  1163. IN PIRP_CONTEXT IrpContext,
  1164. IN PFCB Fcb
  1165. );
  1166. FINISHED
  1167. FatAcquireSharedFcb (
  1168. IN PIRP_CONTEXT IrpContext,
  1169. IN PFCB Fcb
  1170. );
  1171. FINISHED
  1172. FatAcquireSharedFcbWaitForEx (
  1173. IN PIRP_CONTEXT IrpContext,
  1174. IN PFCB Fcb
  1175. );
  1176. #define FatVcbAcquiredExclusive(IRPCONTEXT,VCB) ( \
  1177. ExIsResourceAcquiredExclusiveLite(&(VCB)->Resource) || \
  1178. ExIsResourceAcquiredExclusiveLite(&FatData.Resource) \
  1179. )
  1180. #define FatFcbAcquiredShared(IRPCONTEXT,FCB) ( \
  1181. ExIsResourceAcquiredSharedLite((FCB)->Header.Resource) \
  1182. )
  1183. #define FatAcquireDirectoryFileMutex(VCB) { \
  1184. ASSERT(KeAreApcsDisabled()); \
  1185. ExAcquireFastMutexUnsafe(&(VCB)->DirectoryFileCreationMutex); \
  1186. }
  1187. #define FatReleaseDirectoryFileMutex(VCB) { \
  1188. ASSERT(KeAreApcsDisabled()); \
  1189. ExReleaseFastMutexUnsafe(&(VCB)->DirectoryFileCreationMutex); \
  1190. }
  1191. //
  1192. // The following are cache manager call backs
  1193. BOOLEAN
  1194. FatAcquireVolumeForClose (
  1195. IN PVOID Vcb,
  1196. IN BOOLEAN Wait
  1197. );
  1198. VOID
  1199. FatReleaseVolumeFromClose (
  1200. IN PVOID Vcb
  1201. );
  1202. BOOLEAN
  1203. FatAcquireFcbForLazyWrite (
  1204. IN PVOID Null,
  1205. IN BOOLEAN Wait
  1206. );
  1207. VOID
  1208. FatReleaseFcbFromLazyWrite (
  1209. IN PVOID Null
  1210. );
  1211. BOOLEAN
  1212. FatAcquireFcbForReadAhead (
  1213. IN PVOID Null,
  1214. IN BOOLEAN Wait
  1215. );
  1216. VOID
  1217. FatReleaseFcbFromReadAhead (
  1218. IN PVOID Null
  1219. );
  1220. NTSTATUS
  1221. FatAcquireForCcFlush (
  1222. IN PFILE_OBJECT FileObject,
  1223. IN PDEVICE_OBJECT DeviceObject
  1224. );
  1225. NTSTATUS
  1226. FatReleaseForCcFlush (
  1227. IN PFILE_OBJECT FileObject,
  1228. IN PDEVICE_OBJECT DeviceObject
  1229. );
  1230. BOOLEAN
  1231. FatNoOpAcquire (
  1232. IN PVOID Fcb,
  1233. IN BOOLEAN Wait
  1234. );
  1235. VOID
  1236. FatNoOpRelease (
  1237. IN PVOID Fcb
  1238. );
  1239. //
  1240. // VOID
  1241. // FatConvertToSharedFcb (
  1242. // IN PIRP_CONTEXT IrpContext,
  1243. // IN PFCB Fcb
  1244. // );
  1245. //
  1246. #define FatConvertToSharedFcb(IRPCONTEXT,Fcb) { \
  1247. ExConvertExclusiveToSharedLite( (Fcb)->Header.Resource ); \
  1248. }
  1249. //
  1250. // VOID
  1251. // FatReleaseGlobal (
  1252. // IN PIRP_CONTEXT IrpContext
  1253. // );
  1254. //
  1255. // VOID
  1256. // FatReleaseVcb (
  1257. // IN PIRP_CONTEXT IrpContext,
  1258. // IN PVCB Vcb
  1259. // );
  1260. //
  1261. // VOID
  1262. // FatReleaseFcb (
  1263. // IN PIRP_CONTEXT IrpContext,
  1264. // IN PVCB Vcb
  1265. // );
  1266. //
  1267. #define FatDeleteResource(RESRC) { \
  1268. ExDeleteResourceLite( (RESRC) ); \
  1269. }
  1270. #define FatReleaseGlobal(IRPCONTEXT) { \
  1271. ExReleaseResourceLite( &(FatData.Resource) ); \
  1272. }
  1273. #define FatReleaseVcb(IRPCONTEXT,Vcb) { \
  1274. ExReleaseResourceLite( &((Vcb)->Resource) ); \
  1275. }
  1276. #define FatReleaseFcb(IRPCONTEXT,Fcb) { \
  1277. ExReleaseResourceLite( (Fcb)->Header.Resource ); \
  1278. }
  1279. //
  1280. // In-memory structure support routine, implemented in StrucSup.c
  1281. //
  1282. VOID
  1283. FatInitializeVcb (
  1284. IN PIRP_CONTEXT IrpContext,
  1285. IN OUT PVCB Vcb,
  1286. IN PDEVICE_OBJECT TargetDeviceObject,
  1287. IN PVPB Vpb,
  1288. IN PDEVICE_OBJECT FsDeviceObject
  1289. );
  1290. VOID
  1291. FatDeleteVcb (
  1292. IN PIRP_CONTEXT IrpContext,
  1293. IN PVCB Vcb
  1294. );
  1295. VOID
  1296. FatCreateRootDcb (
  1297. IN PIRP_CONTEXT IrpContext,
  1298. IN PVCB Vcb
  1299. );
  1300. PFCB
  1301. FatCreateFcb (
  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. IN BOOLEAN IsPagingFile,
  1310. IN BOOLEAN SingleResource
  1311. );
  1312. PDCB
  1313. FatCreateDcb (
  1314. IN PIRP_CONTEXT IrpContext,
  1315. IN PVCB Vcb,
  1316. IN PDCB ParentDcb,
  1317. IN ULONG LfnOffsetWithinDirectory,
  1318. IN ULONG DirentOffsetWithinDirectory,
  1319. IN PDIRENT Dirent,
  1320. IN PUNICODE_STRING Lfn OPTIONAL
  1321. );
  1322. VOID
  1323. FatDeleteFcb_Real (
  1324. IN PIRP_CONTEXT IrpContext,
  1325. IN PFCB Fcb
  1326. );
  1327. #ifdef FASTFATDBG
  1328. #define FatDeleteFcb(IRPCONTEXT,FCB) { \
  1329. FatDeleteFcb_Real((IRPCONTEXT),(FCB)); \
  1330. (FCB) = NULL; \
  1331. }
  1332. #else
  1333. #define FatDeleteFcb(IRPCONTEXT,VCB) { \
  1334. FatDeleteFcb_Real((IRPCONTEXT),(VCB)); \
  1335. }
  1336. #endif // FASTFAT_DBG
  1337. PCCB
  1338. FatCreateCcb (
  1339. IN PIRP_CONTEXT IrpContext
  1340. );
  1341. VOID
  1342. FatDeallocateCcbStrings(
  1343. IN PCCB Ccb
  1344. );
  1345. VOID
  1346. FatDeleteCcb_Real (
  1347. IN PIRP_CONTEXT IrpContext,
  1348. IN PCCB Ccb
  1349. );
  1350. #ifdef FASTFATDBG
  1351. #define FatDeleteCcb(IRPCONTEXT,CCB) { \
  1352. FatDeleteCcb_Real((IRPCONTEXT),(CCB)); \
  1353. (CCB) = NULL; \
  1354. }
  1355. #else
  1356. #define FatDeleteCcb(IRPCONTEXT,VCB) { \
  1357. FatDeleteCcb_Real((IRPCONTEXT),(VCB)); \
  1358. }
  1359. #endif // FASTFAT_DBG
  1360. PIRP_CONTEXT
  1361. FatCreateIrpContext (
  1362. IN PIRP Irp,
  1363. IN BOOLEAN Wait
  1364. );
  1365. VOID
  1366. FatDeleteIrpContext_Real (
  1367. IN PIRP_CONTEXT IrpContext
  1368. );
  1369. #ifdef FASTFATDBG
  1370. #define FatDeleteIrpContext(IRPCONTEXT) { \
  1371. FatDeleteIrpContext_Real((IRPCONTEXT)); \
  1372. (IRPCONTEXT) = NULL; \
  1373. }
  1374. #else
  1375. #define FatDeleteIrpContext(IRPCONTEXT) { \
  1376. FatDeleteIrpContext_Real((IRPCONTEXT)); \
  1377. }
  1378. #endif // FASTFAT_DBG
  1379. PFCB
  1380. FatGetNextFcbTopDown (
  1381. IN PIRP_CONTEXT IrpContext,
  1382. IN PFCB Fcb,
  1383. IN PFCB TerminationFcb
  1384. );
  1385. PFCB
  1386. FatGetNextFcbBottomUp (
  1387. IN PIRP_CONTEXT IrpContext,
  1388. IN PFCB Fcb,
  1389. IN PFCB TerminationFcb
  1390. );
  1391. //
  1392. // These two macros just make the code a bit cleaner.
  1393. //
  1394. #define FatGetFirstChild(DIR) ((PFCB)( \
  1395. IsListEmpty(&(DIR)->Specific.Dcb.ParentDcbQueue) ? NULL : \
  1396. CONTAINING_RECORD((DIR)->Specific.Dcb.ParentDcbQueue.Flink, \
  1397. DCB, \
  1398. ParentDcbLinks.Flink)))
  1399. #define FatGetNextSibling(FILE) ((PFCB)( \
  1400. &(FILE)->ParentDcb->Specific.Dcb.ParentDcbQueue.Flink == \
  1401. (PVOID)(FILE)->ParentDcbLinks.Flink ? NULL : \
  1402. CONTAINING_RECORD((FILE)->ParentDcbLinks.Flink, \
  1403. FCB, \
  1404. ParentDcbLinks.Flink)))
  1405. BOOLEAN
  1406. FatCheckForDismount (
  1407. IN PIRP_CONTEXT IrpContext,
  1408. PVCB Vcb,
  1409. IN BOOLEAN Force
  1410. );
  1411. VOID
  1412. FatConstructNamesInFcb (
  1413. IN PIRP_CONTEXT IrpContext,
  1414. PFCB Fcb,
  1415. PDIRENT Dirent,
  1416. PUNICODE_STRING Lfn OPTIONAL
  1417. );
  1418. VOID
  1419. FatCheckFreeDirentBitmap (
  1420. IN PIRP_CONTEXT IrpContext,
  1421. IN PDCB Dcb
  1422. );
  1423. ULONG
  1424. FatVolumeUncleanCount (
  1425. IN PIRP_CONTEXT IrpContext,
  1426. IN PVCB Vcb
  1427. );
  1428. VOID
  1429. FatPreallocateCloseContext (
  1430. );
  1431. PCLOSE_CONTEXT
  1432. FatAllocateCloseContext(
  1433. PVCB Vcb
  1434. );
  1435. //
  1436. // BOOLEAN
  1437. // FatIsRawDevice (
  1438. // IN PIRP_CONTEXT IrpContext,
  1439. // IN NTSTATUS Status
  1440. // );
  1441. //
  1442. #define FatIsRawDevice(IC,S) ( \
  1443. ((S) == STATUS_DEVICE_NOT_READY) || \
  1444. ((S) == STATUS_NO_MEDIA_IN_DEVICE) \
  1445. )
  1446. //
  1447. // Routines to support managing file names Fcbs and Dcbs.
  1448. // Implemented in SplaySup.c
  1449. //
  1450. VOID
  1451. FatInsertName (
  1452. IN PIRP_CONTEXT IrpContext,
  1453. IN PRTL_SPLAY_LINKS *RootNode,
  1454. IN PFILE_NAME_NODE Name
  1455. );
  1456. VOID
  1457. FatRemoveNames (
  1458. IN PIRP_CONTEXT IrpContext,
  1459. IN PFCB Fcb
  1460. );
  1461. PFCB
  1462. FatFindFcb (
  1463. IN PIRP_CONTEXT IrpContext,
  1464. IN OUT PRTL_SPLAY_LINKS *RootNode,
  1465. IN PSTRING Name,
  1466. OUT PBOOLEAN FileNameDos OPTIONAL
  1467. );
  1468. BOOLEAN
  1469. FatIsHandleCountZero (
  1470. IN PIRP_CONTEXT IrpContext,
  1471. IN PVCB Vcb
  1472. );
  1473. //
  1474. // Time conversion support routines, implemented in TimeSup.c
  1475. //
  1476. BOOLEAN
  1477. FatNtTimeToFatTime (
  1478. IN PIRP_CONTEXT IrpContext,
  1479. IN PLARGE_INTEGER NtTime,
  1480. IN BOOLEAN Rounding,
  1481. OUT PFAT_TIME_STAMP FatTime,
  1482. OUT OPTIONAL PCHAR TenMsecs
  1483. );
  1484. LARGE_INTEGER
  1485. FatFatTimeToNtTime (
  1486. IN PIRP_CONTEXT IrpContext,
  1487. IN FAT_TIME_STAMP FatTime,
  1488. IN UCHAR TenMilliSeconds
  1489. );
  1490. LARGE_INTEGER
  1491. FatFatDateToNtTime (
  1492. IN PIRP_CONTEXT IrpContext,
  1493. IN FAT_DATE FatDate
  1494. );
  1495. FAT_TIME_STAMP
  1496. FatGetCurrentFatTime (
  1497. IN PIRP_CONTEXT IrpContext
  1498. );
  1499. //
  1500. // Low level verification routines, implemented in VerfySup.c
  1501. //
  1502. // The first routine is called to help process a verify IRP. Its job is
  1503. // to walk every Fcb/Dcb and mark them as need to be verified.
  1504. //
  1505. // The other routines are used by every dispatch routine to verify that
  1506. // an Vcb/Fcb/Dcb is still good. The routine walks as much of the opened
  1507. // file/directory tree as necessary to make sure that the path is still valid.
  1508. // The function result indicates if the procedure needed to block for I/O.
  1509. // If the structure is bad the procedure raise the error condition
  1510. // STATUS_FILE_INVALID, otherwise they simply return to their caller
  1511. //
  1512. typedef enum _FAT_VOLUME_STATE {
  1513. VolumeClean,
  1514. VolumeDirty,
  1515. VolumeDirtyWithSurfaceTest
  1516. } FAT_VOLUME_STATE, *PFAT_VOLUME_STATE;
  1517. VOID
  1518. FatMarkFcbCondition (
  1519. IN PIRP_CONTEXT IrpContext,
  1520. IN PFCB Fcb,
  1521. IN FCB_CONDITION FcbCondition,
  1522. IN BOOLEAN Recursive
  1523. );
  1524. VOID
  1525. FatVerifyVcb (
  1526. IN PIRP_CONTEXT IrpContext,
  1527. IN PVCB Vcb
  1528. );
  1529. VOID
  1530. FatVerifyFcb (
  1531. IN PIRP_CONTEXT IrpContext,
  1532. IN PFCB Fcb
  1533. );
  1534. VOID
  1535. FatCleanVolumeDpc (
  1536. IN PKDPC Dpc,
  1537. IN PVOID DeferredContext,
  1538. IN PVOID SystemArgument1,
  1539. IN PVOID SystemArgument2
  1540. );
  1541. VOID
  1542. FatMarkVolume (
  1543. IN PIRP_CONTEXT IrpContext,
  1544. IN PVCB Vcb,
  1545. IN FAT_VOLUME_STATE VolumeState
  1546. );
  1547. VOID
  1548. FatFspMarkVolumeDirtyWithRecover (
  1549. PVOID Parameter
  1550. );
  1551. VOID
  1552. FatCheckDirtyBit (
  1553. IN PIRP_CONTEXT IrpContext,
  1554. IN PVCB Vcb
  1555. );
  1556. VOID
  1557. FatQuickVerifyVcb (
  1558. IN PIRP_CONTEXT IrpContext,
  1559. IN PVCB Vcb
  1560. );
  1561. VOID
  1562. FatVerifyOperationIsLegal (
  1563. IN PIRP_CONTEXT IrpContext
  1564. );
  1565. NTSTATUS
  1566. FatPerformVerify (
  1567. IN PIRP_CONTEXT IrpContext,
  1568. IN PIRP Irp,
  1569. IN PDEVICE_OBJECT Device
  1570. );
  1571. //
  1572. // Work queue routines for posting and retrieving an Irp, implemented in
  1573. // workque.c
  1574. //
  1575. VOID
  1576. FatOplockComplete (
  1577. IN PVOID Context,
  1578. IN PIRP Irp
  1579. );
  1580. VOID
  1581. FatPrePostIrp (
  1582. IN PVOID Context,
  1583. IN PIRP Irp
  1584. );
  1585. VOID
  1586. FatAddToWorkque (
  1587. IN PIRP_CONTEXT IrpContext,
  1588. IN PIRP Irp
  1589. );
  1590. NTSTATUS
  1591. FatFsdPostRequest (
  1592. IN PIRP_CONTEXT IrpContext,
  1593. IN PIRP Irp
  1594. );
  1595. //
  1596. // Miscellaneous support routines
  1597. //
  1598. //
  1599. // This macro returns TRUE if a flag in a set of flags is on and FALSE
  1600. // otherwise. It is followed by two macros for setting and clearing
  1601. // flags
  1602. //
  1603. //#ifndef BooleanFlagOn
  1604. //#define BooleanFlagOn(Flags,SingleFlag) ((BOOLEAN)((((Flags) & (SingleFlag)) != 0)))
  1605. //#endif
  1606. //#ifndef SetFlag
  1607. //#define SetFlag(Flags,SingleFlag) { \
  1608. // (Flags) |= (SingleFlag); \
  1609. //}
  1610. //#endif
  1611. //#ifndef ClearFlag
  1612. //#define ClearFlag(Flags,SingleFlag) { \
  1613. // (Flags) &= ~(SingleFlag); \
  1614. //}
  1615. //#endif
  1616. //
  1617. // ULONG
  1618. // PtrOffset (
  1619. // IN PVOID BasePtr,
  1620. // IN PVOID OffsetPtr
  1621. // );
  1622. //
  1623. #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
  1624. //
  1625. // This macro takes a pointer (or ulong) and returns its rounded up word
  1626. // value
  1627. //
  1628. #define WordAlign(Ptr) ( \
  1629. ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
  1630. )
  1631. //
  1632. // This macro takes a pointer (or ulong) and returns its rounded up longword
  1633. // value
  1634. //
  1635. #define LongAlign(Ptr) ( \
  1636. ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
  1637. )
  1638. //
  1639. // This macro takes a pointer (or ulong) and returns its rounded up quadword
  1640. // value
  1641. //
  1642. #define QuadAlign(Ptr) ( \
  1643. ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
  1644. )
  1645. //
  1646. // The following types and macros are used to help unpack the packed and
  1647. // misaligned fields found in the Bios parameter block
  1648. //
  1649. typedef union _UCHAR1 {
  1650. UCHAR Uchar[1];
  1651. UCHAR ForceAlignment;
  1652. } UCHAR1, *PUCHAR1;
  1653. typedef union _UCHAR2 {
  1654. UCHAR Uchar[2];
  1655. USHORT ForceAlignment;
  1656. } UCHAR2, *PUCHAR2;
  1657. typedef union _UCHAR4 {
  1658. UCHAR Uchar[4];
  1659. ULONG ForceAlignment;
  1660. } UCHAR4, *PUCHAR4;
  1661. //
  1662. // This macro copies an unaligned src byte to an aligned dst byte
  1663. //
  1664. #define CopyUchar1(Dst,Src) { \
  1665. *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
  1666. }
  1667. //
  1668. // This macro copies an unaligned src word to an aligned dst word
  1669. //
  1670. #define CopyUchar2(Dst,Src) { \
  1671. *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
  1672. }
  1673. //
  1674. // This macro copies an unaligned src longword to an aligned dsr longword
  1675. //
  1676. #define CopyUchar4(Dst,Src) { \
  1677. *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
  1678. }
  1679. #define CopyU4char(Dst,Src) { \
  1680. *((UNALIGNED UCHAR4 *)(Dst)) = *((UCHAR4 *)(Src)); \
  1681. }
  1682. //
  1683. // VOID
  1684. // FatNotifyReportChange (
  1685. // IN PIRP_CONTEXT IrpContext,
  1686. // IN PVCB Vcb,
  1687. // IN PFCB Fcb,
  1688. // IN ULONG Filter,
  1689. // IN ULONG Action
  1690. // );
  1691. //
  1692. #define FatNotifyReportChange(I,V,F,FL,A) { \
  1693. if ((F)->FullFileName.Buffer == NULL) { \
  1694. FatSetFullFileNameInFcb((I),(F)); \
  1695. } \
  1696. ASSERT( (F)->FullFileName.Length != 0 ); \
  1697. ASSERT( (F)->FinalNameLength != 0 ); \
  1698. ASSERT( (F)->FullFileName.Length > (F)->FinalNameLength ); \
  1699. ASSERT( (F)->FullFileName.Buffer[((F)->FullFileName.Length - (F)->FinalNameLength)/sizeof(WCHAR) - 1] == L'\\' ); \
  1700. FsRtlNotifyFullReportChange( (V)->NotifySync, \
  1701. &(V)->DirNotifyList, \
  1702. (PSTRING)&(F)->FullFileName, \
  1703. (USHORT) ((F)->FullFileName.Length - \
  1704. (F)->FinalNameLength), \
  1705. (PSTRING)NULL, \
  1706. (PSTRING)NULL, \
  1707. (ULONG)FL, \
  1708. (ULONG)A, \
  1709. (PVOID)NULL ); \
  1710. }
  1711. //
  1712. // The FSD Level dispatch routines. These routines are called by the
  1713. // I/O system via the dispatch table in the Driver Object.
  1714. //
  1715. // They each accept as input a pointer to a device object (actually most
  1716. // expect a volume device object, with the exception of the file system
  1717. // control function which can also take a file system device object), and
  1718. // a pointer to the IRP. They either perform the function at the FSD level
  1719. // or post the request to the FSP work queue for FSP level processing.
  1720. //
  1721. NTSTATUS
  1722. FatFsdCleanup ( // implemented in Cleanup.c
  1723. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1724. IN PIRP Irp
  1725. );
  1726. NTSTATUS
  1727. FatFsdClose ( // implemented in Close.c
  1728. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1729. IN PIRP Irp
  1730. );
  1731. NTSTATUS
  1732. FatFsdCreate ( // implemented in Create.c
  1733. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1734. IN PIRP Irp
  1735. );
  1736. NTSTATUS
  1737. FatFsdDeviceControl ( // implemented in DevCtrl.c
  1738. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1739. IN PIRP Irp
  1740. );
  1741. NTSTATUS
  1742. FatFsdDirectoryControl ( // implemented in DirCtrl.c
  1743. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1744. IN PIRP Irp
  1745. );
  1746. NTSTATUS
  1747. FatFsdQueryEa ( // implemented in Ea.c
  1748. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1749. IN PIRP Irp
  1750. );
  1751. NTSTATUS
  1752. FatFsdSetEa ( // implemented in Ea.c
  1753. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1754. IN PIRP Irp
  1755. );
  1756. NTSTATUS
  1757. FatFsdQueryInformation ( // implemented in FileInfo.c
  1758. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1759. IN PIRP Irp
  1760. );
  1761. NTSTATUS
  1762. FatFsdSetInformation ( // implemented in FileInfo.c
  1763. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1764. IN PIRP Irp
  1765. );
  1766. NTSTATUS
  1767. FatFsdFlushBuffers ( // implemented in Flush.c
  1768. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1769. IN PIRP Irp
  1770. );
  1771. NTSTATUS
  1772. FatFsdFileSystemControl ( // implemented in FsCtrl.c
  1773. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1774. IN PIRP Irp
  1775. );
  1776. NTSTATUS
  1777. FatFsdLockControl ( // implemented in LockCtrl.c
  1778. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1779. IN PIRP Irp
  1780. );
  1781. NTSTATUS
  1782. FatFsdPnp ( // implemented in Pnp.c
  1783. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1784. IN PIRP Irp
  1785. );
  1786. NTSTATUS
  1787. FatFsdRead ( // implemented in Read.c
  1788. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1789. IN PIRP Irp
  1790. );
  1791. NTSTATUS
  1792. FatFsdShutdown ( // implemented in Shutdown.c
  1793. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1794. IN PIRP Irp
  1795. );
  1796. NTSTATUS
  1797. FatFsdQueryVolumeInformation ( // implemented in VolInfo.c
  1798. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1799. IN PIRP Irp
  1800. );
  1801. NTSTATUS
  1802. FatFsdSetVolumeInformation ( // implemented in VolInfo.c
  1803. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1804. IN PIRP Irp
  1805. );
  1806. NTSTATUS
  1807. FatFsdWrite ( // implemented in Write.c
  1808. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  1809. IN PIRP Irp
  1810. );
  1811. //
  1812. // The following macro is used to determine if an FSD thread can block
  1813. // for I/O or wait for a resource. It returns TRUE if the thread can
  1814. // block and FALSE otherwise. This attribute can then be used to call
  1815. // the FSD & FSP common work routine with the proper wait value.
  1816. //
  1817. #define CanFsdWait(IRP) IoIsOperationSynchronous(Irp)
  1818. //
  1819. // The FSP level dispatch/main routine. This is the routine that takes
  1820. // IRP's off of the work queue and calls the appropriate FSP level
  1821. // work routine.
  1822. //
  1823. VOID
  1824. FatFspDispatch ( // implemented in FspDisp.c
  1825. IN PVOID Context
  1826. );
  1827. //
  1828. // The following routines are the FSP work routines that are called
  1829. // by the preceding FatFspDispath routine. Each takes as input a pointer
  1830. // to the IRP, perform the function, and return a pointer to the volume
  1831. // device object that they just finished servicing (if any). The return
  1832. // pointer is then used by the main Fsp dispatch routine to check for
  1833. // additional IRPs in the volume's overflow queue.
  1834. //
  1835. // Each of the following routines is also responsible for completing the IRP.
  1836. // We moved this responsibility from the main loop to the individual routines
  1837. // to allow them the ability to complete the IRP and continue post processing
  1838. // actions.
  1839. //
  1840. NTSTATUS
  1841. FatCommonCleanup ( // implemented in Cleanup.c
  1842. IN PIRP_CONTEXT IrpContext,
  1843. IN PIRP Irp
  1844. );
  1845. NTSTATUS
  1846. FatCommonClose ( // implemented in Close.c
  1847. IN PVCB Vcb,
  1848. IN PFCB Fcb,
  1849. IN PCCB Ccb,
  1850. IN TYPE_OF_OPEN TypeOfOpen,
  1851. IN BOOLEAN Wait,
  1852. IN OPTIONAL PBOOLEAN VolumeTornDown
  1853. );
  1854. VOID
  1855. FatFspClose ( // implemented in Close.c
  1856. IN PVCB Vcb OPTIONAL
  1857. );
  1858. NTSTATUS
  1859. FatCommonCreate ( // implemented in Create.c
  1860. IN PIRP_CONTEXT IrpContext,
  1861. IN PIRP Irp
  1862. );
  1863. NTSTATUS
  1864. FatCommonDirectoryControl ( // implemented in DirCtrl.c
  1865. IN PIRP_CONTEXT IrpContext,
  1866. IN PIRP Irp
  1867. );
  1868. NTSTATUS
  1869. FatCommonDeviceControl ( // implemented in DevCtrl.c
  1870. IN PIRP_CONTEXT IrpContext,
  1871. IN PIRP Irp
  1872. );
  1873. NTSTATUS
  1874. FatCommonQueryEa ( // implemented in Ea.c
  1875. IN PIRP_CONTEXT IrpContext,
  1876. IN PIRP Irp
  1877. );
  1878. NTSTATUS
  1879. FatCommonSetEa ( // implemented in Ea.c
  1880. IN PIRP_CONTEXT IrpContext,
  1881. IN PIRP Irp
  1882. );
  1883. NTSTATUS
  1884. FatCommonQueryInformation ( // implemented in FileInfo.c
  1885. IN PIRP_CONTEXT IrpContext,
  1886. IN PIRP Irp
  1887. );
  1888. NTSTATUS
  1889. FatCommonSetInformation ( // implemented in FileInfo.c
  1890. IN PIRP_CONTEXT IrpContext,
  1891. IN PIRP Irp
  1892. );
  1893. NTSTATUS
  1894. FatCommonFlushBuffers ( // implemented in Flush.c
  1895. IN PIRP_CONTEXT IrpContext,
  1896. IN PIRP Irp
  1897. );
  1898. NTSTATUS
  1899. FatCommonFileSystemControl ( // implemented in FsCtrl.c
  1900. IN PIRP_CONTEXT IrpContext,
  1901. IN PIRP Irp
  1902. );
  1903. NTSTATUS
  1904. FatCommonLockControl ( // implemented in LockCtrl.c
  1905. IN PIRP_CONTEXT IrpContext,
  1906. IN PIRP Irp
  1907. );
  1908. NTSTATUS
  1909. FatCommonPnp ( // implemented in Pnp.c
  1910. IN PIRP_CONTEXT IrpContext,
  1911. IN PIRP Irp
  1912. );
  1913. NTSTATUS
  1914. FatCommonRead ( // implemented in Read.c
  1915. IN PIRP_CONTEXT IrpContext,
  1916. IN PIRP Irp
  1917. );
  1918. NTSTATUS
  1919. FatCommonShutdown ( // implemented in Shutdown.c
  1920. IN PIRP_CONTEXT IrpContext,
  1921. IN PIRP Irp
  1922. );
  1923. NTSTATUS
  1924. FatCommonQueryVolumeInfo ( // implemented in VolInfo.c
  1925. IN PIRP_CONTEXT IrpContext,
  1926. IN PIRP Irp
  1927. );
  1928. NTSTATUS
  1929. FatCommonSetVolumeInfo ( // implemented in VolInfo.c
  1930. IN PIRP_CONTEXT IrpContext,
  1931. IN PIRP Irp
  1932. );
  1933. NTSTATUS
  1934. FatCommonWrite ( // implemented in Write.c
  1935. IN PIRP_CONTEXT IrpContext,
  1936. IN PIRP Irp
  1937. );
  1938. //
  1939. // The following is implemented in Flush.c, and does what is says.
  1940. //
  1941. NTSTATUS
  1942. FatFlushFile (
  1943. IN PIRP_CONTEXT IrpContext,
  1944. IN PFCB Fcb,
  1945. IN FAT_FLUSH_TYPE FlushType
  1946. );
  1947. NTSTATUS
  1948. FatFlushDirectory (
  1949. IN PIRP_CONTEXT IrpContext,
  1950. IN PDCB Dcb,
  1951. IN FAT_FLUSH_TYPE FlushType
  1952. );
  1953. NTSTATUS
  1954. FatFlushFat (
  1955. IN PIRP_CONTEXT IrpContext,
  1956. IN PVCB Vcb
  1957. );
  1958. NTSTATUS
  1959. FatFlushVolume (
  1960. IN PIRP_CONTEXT IrpContext,
  1961. IN PVCB Vcb,
  1962. IN FAT_FLUSH_TYPE FlushType
  1963. );
  1964. NTSTATUS
  1965. FatHijackIrpAndFlushDevice (
  1966. IN PIRP_CONTEXT IrpContext,
  1967. IN PIRP Irp,
  1968. IN PDEVICE_OBJECT TargetDeviceObject
  1969. );
  1970. VOID
  1971. FatFlushFatEntries (
  1972. IN PIRP_CONTEXT IrpContext,
  1973. IN PVCB Vcb,
  1974. IN ULONG Cluster,
  1975. IN ULONG Count
  1976. );
  1977. VOID
  1978. FatFlushDirentForFile (
  1979. IN PIRP_CONTEXT IrpContext,
  1980. IN PFCB Fcb
  1981. );
  1982. //
  1983. // The following procedure is used by the FSP and FSD routines to complete
  1984. // an IRP.
  1985. //
  1986. // Note that this macro allows either the Irp or the IrpContext to be
  1987. // null, however the only legal order to do this in is:
  1988. //
  1989. // FatCompleteRequest( NULL, Irp, Status ); // completes Irp & preserves context
  1990. // ...
  1991. // FatCompleteRequest( IrpContext, NULL, DontCare ); // deallocates context
  1992. //
  1993. // This would typically be done in order to pass a "naked" IrpContext off to
  1994. // the Fsp for post processing, such as read ahead.
  1995. //
  1996. VOID
  1997. FatCompleteRequest_Real (
  1998. IN PIRP_CONTEXT IrpContext,
  1999. IN PIRP Irp,
  2000. IN NTSTATUS Status
  2001. );
  2002. #define FatCompleteRequest(IRPCONTEXT,IRP,STATUS) { \
  2003. FatCompleteRequest_Real(IRPCONTEXT,IRP,STATUS); \
  2004. }
  2005. BOOLEAN
  2006. FatIsIrpTopLevel (
  2007. IN PIRP Irp
  2008. );
  2009. //
  2010. // The Following routine makes a popup
  2011. //
  2012. VOID
  2013. FatPopUpFileCorrupt (
  2014. IN PIRP_CONTEXT IrpContext,
  2015. IN PFCB Fcb
  2016. );
  2017. //
  2018. // Here are the callbacks used by the I/O system for checking for fast I/O or
  2019. // doing a fast query info call, or doing fast lock calls.
  2020. //
  2021. BOOLEAN
  2022. FatFastIoCheckIfPossible (
  2023. IN PFILE_OBJECT FileObject,
  2024. IN PLARGE_INTEGER FileOffset,
  2025. IN ULONG Length,
  2026. IN BOOLEAN Wait,
  2027. IN ULONG LockKey,
  2028. IN BOOLEAN CheckForReadOperation,
  2029. OUT PIO_STATUS_BLOCK IoStatus,
  2030. IN PDEVICE_OBJECT DeviceObject
  2031. );
  2032. BOOLEAN
  2033. FatFastQueryBasicInfo (
  2034. IN PFILE_OBJECT FileObject,
  2035. IN BOOLEAN Wait,
  2036. IN OUT PFILE_BASIC_INFORMATION Buffer,
  2037. OUT PIO_STATUS_BLOCK IoStatus,
  2038. IN PDEVICE_OBJECT DeviceObject
  2039. );
  2040. BOOLEAN
  2041. FatFastQueryStdInfo (
  2042. IN PFILE_OBJECT FileObject,
  2043. IN BOOLEAN Wait,
  2044. IN OUT PFILE_STANDARD_INFORMATION Buffer,
  2045. OUT PIO_STATUS_BLOCK IoStatus,
  2046. IN PDEVICE_OBJECT DeviceObject
  2047. );
  2048. BOOLEAN
  2049. FatFastQueryNetworkOpenInfo (
  2050. IN PFILE_OBJECT FileObject,
  2051. IN BOOLEAN Wait,
  2052. IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
  2053. OUT PIO_STATUS_BLOCK IoStatus,
  2054. IN PDEVICE_OBJECT DeviceObject
  2055. );
  2056. BOOLEAN
  2057. FatFastLock (
  2058. IN PFILE_OBJECT FileObject,
  2059. IN PLARGE_INTEGER FileOffset,
  2060. IN PLARGE_INTEGER Length,
  2061. PEPROCESS ProcessId,
  2062. ULONG Key,
  2063. BOOLEAN FailImmediately,
  2064. BOOLEAN ExclusiveLock,
  2065. OUT PIO_STATUS_BLOCK IoStatus,
  2066. IN PDEVICE_OBJECT DeviceObject
  2067. );
  2068. BOOLEAN
  2069. FatFastUnlockSingle (
  2070. IN PFILE_OBJECT FileObject,
  2071. IN PLARGE_INTEGER FileOffset,
  2072. IN PLARGE_INTEGER Length,
  2073. PEPROCESS ProcessId,
  2074. ULONG Key,
  2075. OUT PIO_STATUS_BLOCK IoStatus,
  2076. IN PDEVICE_OBJECT DeviceObject
  2077. );
  2078. BOOLEAN
  2079. FatFastUnlockAll (
  2080. IN PFILE_OBJECT FileObject,
  2081. PEPROCESS ProcessId,
  2082. OUT PIO_STATUS_BLOCK IoStatus,
  2083. IN PDEVICE_OBJECT DeviceObject
  2084. );
  2085. BOOLEAN
  2086. FatFastUnlockAllByKey (
  2087. IN PFILE_OBJECT FileObject,
  2088. PVOID ProcessId,
  2089. ULONG Key,
  2090. OUT PIO_STATUS_BLOCK IoStatus,
  2091. IN PDEVICE_OBJECT DeviceObject
  2092. );
  2093. VOID
  2094. FatExamineFatEntries(
  2095. IN PIRP_CONTEXT IrpContext,
  2096. IN PVCB Vcb,
  2097. IN ULONG StartIndex OPTIONAL,
  2098. IN ULONG EndIndex OPTIONAL,
  2099. IN BOOLEAN SetupWindows,
  2100. IN PFAT_WINDOW SwitchToWindow OPTIONAL,
  2101. IN PULONG BitMapBuffer OPTIONAL
  2102. );
  2103. BOOLEAN
  2104. FatScanForDataTrack(
  2105. IN PIRP_CONTEXT IrpContext,
  2106. IN PDEVICE_OBJECT TargetDeviceObject
  2107. );
  2108. //
  2109. // The following macro is used to determine is a file has been deleted.
  2110. //
  2111. // BOOLEAN
  2112. // IsFileDeleted (
  2113. // IN PIRP_CONTEXT IrpContext,
  2114. // IN PFCB Fcb
  2115. // );
  2116. //
  2117. #define IsFileDeleted(IRPCONTEXT,FCB) \
  2118. (FlagOn((FCB)->FcbState, FCB_STATE_DELETE_ON_CLOSE) && \
  2119. ((FCB)->UncleanCount == 0))
  2120. //
  2121. // The following macro is used by the dispatch routines to determine if
  2122. // an operation is to be done with or without Write Through.
  2123. //
  2124. // BOOLEAN
  2125. // IsFileWriteThrough (
  2126. // IN PFILE_OBJECT FileObject,
  2127. // IN PVCB Vcb
  2128. // );
  2129. //
  2130. #define IsFileWriteThrough(FO,VCB) ( \
  2131. BooleanFlagOn((FO)->Flags, FO_WRITE_THROUGH) \
  2132. )
  2133. //
  2134. // The following macro is used to set the is fast i/o possible field in
  2135. // the common part of the nonpaged fcb
  2136. //
  2137. //
  2138. // BOOLEAN
  2139. // FatIsFastIoPossible (
  2140. // IN PFCB Fcb
  2141. // );
  2142. //
  2143. #define FatIsFastIoPossible(FCB) ((BOOLEAN) \
  2144. (((FCB)->FcbCondition != FcbGood || !FsRtlOplockIsFastIoPossible( &(FCB)->Specific.Fcb.Oplock )) ? \
  2145. FastIoIsNotPossible \
  2146. : \
  2147. (!FsRtlAreThereCurrentFileLocks( &(FCB)->Specific.Fcb.FileLock ) && \
  2148. ((FCB)->NonPaged->OutstandingAsyncWrites == 0) && \
  2149. !FlagOn( (FCB)->Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED ) ? \
  2150. FastIoIsPossible \
  2151. : \
  2152. FastIoIsQuestionable \
  2153. ) \
  2154. ) \
  2155. )
  2156. //
  2157. // The following macro is used to detemine if the file object is opened
  2158. // for read only access (i.e., it is not also opened for write access or
  2159. // delete access).
  2160. //
  2161. // BOOLEAN
  2162. // IsFileObjectReadOnly (
  2163. // IN PFILE_OBJECT FileObject
  2164. // );
  2165. //
  2166. #define IsFileObjectReadOnly(FO) (!((FO)->WriteAccess | (FO)->DeleteAccess))
  2167. //
  2168. // The following two macro are used by the Fsd/Fsp exception handlers to
  2169. // process an exception. The first macro is the exception filter used in the
  2170. // Fsd/Fsp to decide if an exception should be handled at this level.
  2171. // The second macro decides if the exception is to be finished off by
  2172. // completing the IRP, and cleaning up the Irp Context, or if we should
  2173. // bugcheck. Exception values such as STATUS_FILE_INVALID (raised by
  2174. // VerfySup.c) cause us to complete the Irp and cleanup, while exceptions
  2175. // such as accvio cause us to bugcheck.
  2176. //
  2177. // The basic structure for fsd/fsp exception handling is as follows:
  2178. //
  2179. // FatFsdXxx(...)
  2180. // {
  2181. // try {
  2182. //
  2183. // ...
  2184. //
  2185. // } except(FatExceptionFilter( IrpContext, GetExceptionCode() )) {
  2186. //
  2187. // Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
  2188. // }
  2189. //
  2190. // Return Status;
  2191. // }
  2192. //
  2193. // To explicitly raise an exception that we expect, such as
  2194. // STATUS_FILE_INVALID, use the below macro FatRaiseStatus(). To raise a
  2195. // status from an unknown origin (such as CcFlushCache()), use the macro
  2196. // FatNormalizeAndRaiseStatus. This will raise the status if it is expected,
  2197. // or raise STATUS_UNEXPECTED_IO_ERROR if it is not.
  2198. //
  2199. // If we are vicariously handling exceptions without using FatProcessException(),
  2200. // if there is the possibility that we raised that exception, one *must*
  2201. // reset the IrpContext so a subsequent raise in the course of handling this
  2202. // request that is *not* explicit, i.e. like a pagein error, does not get
  2203. // spoofed into believing that the first raise status is the reason the second
  2204. // occured. This could have really nasty consequences.
  2205. //
  2206. // It is an excellent idea to always FatResetExceptionState in these cases.
  2207. //
  2208. // Note that when using these two macros, the original status is placed in
  2209. // IrpContext->ExceptionStatus, signaling FatExceptionFilter and
  2210. // FatProcessException that the status we actually raise is by definition
  2211. // expected.
  2212. //
  2213. ULONG
  2214. FatExceptionFilter (
  2215. IN PIRP_CONTEXT IrpContext,
  2216. IN PEXCEPTION_POINTERS ExceptionPointer
  2217. );
  2218. #if DBG
  2219. ULONG
  2220. FatBugCheckExceptionFilter (
  2221. IN PEXCEPTION_POINTERS ExceptionPointer
  2222. );
  2223. #endif
  2224. NTSTATUS
  2225. FatProcessException (
  2226. IN PIRP_CONTEXT IrpContext,
  2227. IN PIRP Irp,
  2228. IN NTSTATUS ExceptionCode
  2229. );
  2230. //
  2231. // VOID
  2232. // FatRaiseStatus (
  2233. // IN PRIP_CONTEXT IrpContext,
  2234. // IN NT_STATUS Status
  2235. // );
  2236. //
  2237. //
  2238. #if DBG
  2239. #define DebugBreakOnStatus(S) { \
  2240. if (FatTestRaisedStatus) { \
  2241. if ((S) == STATUS_DISK_CORRUPT_ERROR || (S) == STATUS_FILE_CORRUPT_ERROR) { \
  2242. DbgPrint( "FAT: Breaking on interesting raised status (%08x)\n", (S) ); \
  2243. DbgPrint( "FAT: Set FatTestRaisedStatus @ %08x to 0 to disable\n", \
  2244. &FatTestRaisedStatus ); \
  2245. DbgBreakPoint(); \
  2246. } \
  2247. } \
  2248. }
  2249. #else
  2250. #define DebugBreakOnStatus(S)
  2251. #endif
  2252. #define FatRaiseStatus(IRPCONTEXT,STATUS) { \
  2253. (IRPCONTEXT)->ExceptionStatus = (STATUS); \
  2254. DebugBreakOnStatus( (STATUS) ) \
  2255. ExRaiseStatus( (STATUS) ); \
  2256. }
  2257. #define FatResetExceptionState( IRPCONTEXT ) { \
  2258. (IRPCONTEXT)->ExceptionStatus = STATUS_SUCCESS; \
  2259. }
  2260. //
  2261. // VOID
  2262. // FatNormalAndRaiseStatus (
  2263. // IN PRIP_CONTEXT IrpContext,
  2264. // IN NT_STATUS Status
  2265. // );
  2266. //
  2267. #define FatNormalizeAndRaiseStatus(IRPCONTEXT,STATUS) { \
  2268. (IRPCONTEXT)->ExceptionStatus = (STATUS); \
  2269. ExRaiseStatus(FsRtlNormalizeNtstatus((STATUS),STATUS_UNEXPECTED_IO_ERROR)); \
  2270. }
  2271. //
  2272. // The following macros are used to establish the semantics needed
  2273. // to do a return from within a try-finally clause. As a rule every
  2274. // try clause must end with a label call try_exit. For example,
  2275. //
  2276. // try {
  2277. // :
  2278. // :
  2279. //
  2280. // try_exit: NOTHING;
  2281. // } finally {
  2282. //
  2283. // :
  2284. // :
  2285. // }
  2286. //
  2287. // Every return statement executed inside of a try clause should use the
  2288. // try_return macro. If the compiler fully supports the try-finally construct
  2289. // then the macro should be
  2290. //
  2291. // #define try_return(S) { return(S); }
  2292. //
  2293. // If the compiler does not support the try-finally construct then the macro
  2294. // should be
  2295. //
  2296. // #define try_return(S) { S; goto try_exit; }
  2297. //
  2298. #define try_return(S) { S; goto try_exit; }
  2299. #define try_leave(S) { S; leave; }
  2300. CLUSTER_TYPE
  2301. FatInterpretClusterType (
  2302. IN PVCB Vcb,
  2303. IN FAT_ENTRY Entry
  2304. );
  2305. //
  2306. // These routines define the FileId for FAT. Lacking a fixed/uniquifiable
  2307. // notion, we simply come up with one which is unique in a given snapshot
  2308. // of the volume. As long as the parent directory is not moved or compacted,
  2309. // it may even be permanent.
  2310. //
  2311. //
  2312. // The internal information used to identify the fcb/dcb on the
  2313. // volume is the byte offset of the dirent of the file on disc.
  2314. // Our root always has fileid 0. FAT32 roots are chains and can
  2315. // use the LBO of the cluster, 12/16 roots use the lbo in the Vcb.
  2316. //
  2317. #define FatGenerateFileIdFromDirentOffset(ParentDcb,DirentOffset) \
  2318. ((ParentDcb) ? ((NodeType(ParentDcb) != FAT_NTC_ROOT_DCB || FatIsFat32((ParentDcb)->Vcb)) ? \
  2319. FatGetLboFromIndex( (ParentDcb)->Vcb, \
  2320. (ParentDcb)->FirstClusterOfFile ) : \
  2321. (ParentDcb)->Vcb->AllocationSupport.RootDirectoryLbo) + \
  2322. (DirentOffset) \
  2323. : \
  2324. 0)
  2325. //
  2326. //
  2327. #define FatGenerateFileIdFromFcb(Fcb) \
  2328. FatGenerateFileIdFromDirentOffset( (Fcb)->ParentDcb, (Fcb)->DirentOffsetWithinDirectory )
  2329. //
  2330. // Wrap to handle the ./.. cases appropriately. Note that we commute NULL parent to 0. This would
  2331. // only occur in an illegal root ".." entry.
  2332. //
  2333. #define FATDOT ((ULONG)0x2020202E)
  2334. #define FATDOTDOT ((ULONG)0x20202E2E)
  2335. #define FatGenerateFileIdFromDirentAndOffset(Dcb,Dirent,DirentOffset) \
  2336. ((*((PULONG)(Dirent)->FileName)) == FATDOT ? FatGenerateFileIdFromFcb(Dcb) : \
  2337. ((*((PULONG)(Dirent)->FileName)) == FATDOTDOT ? ((Dcb)->ParentDcb ? \
  2338. FatGenerateFileIdFromFcb((Dcb)->ParentDcb) : \
  2339. 0) : \
  2340. FatGenerateFileIdFromDirentOffset(Dcb,DirentOffset)))
  2341. //
  2342. // BOOLEAN
  2343. // FatDeviceIsFatFsdo(
  2344. // IN PDEVICE_OBJECT D
  2345. // );
  2346. //
  2347. // Evaluates to TRUE if the supplied device object is one of the file system devices
  2348. // we created at initialisation.
  2349. //
  2350. #define FatDeviceIsFatFsdo( D) (((D) == FatData.DiskFileSystemDeviceObject) || ((D) == FatData.CdromFileSystemDeviceObject))
  2351. #endif // _FATPROCS_