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.

7514 lines
193 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. NtfsProc.h
  5. Abstract:
  6. This module defines all of the globally used procedures in the Ntfs
  7. file system.
  8. Author:
  9. Brian Andrew [BrianAn] 21-May-1991
  10. David Goebel [DavidGoe]
  11. Gary Kimura [GaryKi]
  12. Tom Miller [TomM]
  13. Revision History:
  14. --*/
  15. #ifndef _NTFSPROC_
  16. #define _NTFSPROC_
  17. #pragma warning(error:4100) // Unreferenced formal parameter
  18. #pragma warning(error:4101) // Unreferenced local variable
  19. #pragma warning(error:4705) // Statement has no effect
  20. #pragma warning(disable:4116) // unnamed type definition in parentheses
  21. #define RTL_USE_AVL_TABLES 0
  22. #ifndef KDEXTMODE
  23. #include <ntifs.h>
  24. #else
  25. #include <ntos.h>
  26. #include <zwapi.h>
  27. #include <FsRtl.h>
  28. #include <ntrtl.h>
  29. #endif
  30. #include <string.h>
  31. #include <lfs.h>
  32. #include <ntdddisk.h>
  33. #include <NtIoLogc.h>
  34. #include <elfmsg.h>
  35. #include "nodetype.h"
  36. #include "Ntfs.h"
  37. #ifndef INLINE
  38. // definition of inline
  39. #define INLINE __inline
  40. #endif
  41. #include <ntfsexp.h>
  42. #include "NtfsStru.h"
  43. #include "NtfsData.h"
  44. #include "NtfsLog.h"
  45. //
  46. // Tag all of our allocations if tagging is turned on
  47. //
  48. //
  49. // Default module pool tag
  50. //
  51. #define MODULE_POOL_TAG ('0ftN')
  52. #if 0
  53. #define NtfsVerifySizes(s) (ASSERT( (s)->ValidDataLength.QuadPart <= (s)->FileSize.QuadPart && (s)->FileSize.QuadPart <= (s)->AllocationSize.QuadPart ))
  54. #define NtfsVerifySizesLongLong(s) (ASSERT( (s)->ValidDataLength <= (s)->FileSize && (s)->FileSize <= (s)->AllocationSize ))
  55. #else // !DBG
  56. #define NtfsVerifySizes(s)
  57. #define NtfsVerifySizesLongLong(s)
  58. #endif // !DBG
  59. #if !(DBG && i386 && defined (NTFSPOOLCHECK))
  60. //
  61. // Non-debug allocate and free goes directly to the FsRtl routines
  62. //
  63. #define NtfsAllocatePoolWithTagNoRaise(a,b,c) ExAllocatePoolWithTag((a),(b),(c))
  64. #define NtfsAllocatePoolWithTag(a,b,c) FsRtlAllocatePoolWithTag((a),(b),(c))
  65. #define NtfsAllocatePoolNoRaise(a,b) ExAllocatePoolWithTag((a),(b),MODULE_POOL_TAG)
  66. #define NtfsAllocatePool(a,b) FsRtlAllocatePoolWithTag((a),(b),MODULE_POOL_TAG)
  67. #define NtfsFreePool(pv) ExFreePool(pv)
  68. #else // !DBG
  69. //
  70. // Debugging routines capture the stack backtrace for allocates and frees
  71. //
  72. #define NtfsAllocatePoolWithTagNoRaise(a,b,c) NtfsDebugAllocatePoolWithTagNoRaise((a),(b),(c))
  73. #define NtfsAllocatePoolWithTag(a,b,c) NtfsDebugAllocatePoolWithTag((a),(b),(c))
  74. #define NtfsAllocatePoolNoRaise(a,b) NtfsDebugAllocatePoolWithTagNoRaise((a),(b),MODULE_POOL_TAG)
  75. #define NtfsAllocatePool(a,b) NtfsDebugAllocatePoolWithTag((a),(b),MODULE_POOL_TAG)
  76. #define NtfsFreePool(pv) NtfsDebugFreePool(pv)
  77. PVOID
  78. NtfsDebugAllocatePoolWithTagNoRaise (
  79. POOL_TYPE Pool,
  80. ULONG Length,
  81. ULONG Tag);
  82. PVOID
  83. NtfsDebugAllocatePoolWithTag (
  84. POOL_TYPE Pool,
  85. ULONG Length,
  86. ULONG Tag);
  87. VOID
  88. NtfsDebugFreePool (
  89. PVOID pv);
  90. VOID
  91. NtfsDebugHeapDump (
  92. PUNICODE_STRING UnicodeString );
  93. #endif // !DBG
  94. //
  95. // Local character comparison macros that we might want to later move to ntfsproc
  96. //
  97. #define IsCharZero(C) (((C) & 0x000000ff) == 0x00000000)
  98. #define IsCharMinus1(C) (((C) & 0x000000ff) == 0x000000ff)
  99. #define IsCharLtrZero(C) (((C) & 0x00000080) == 0x00000080)
  100. #define IsCharGtrZero(C) (!IsCharLtrZero(C) && !IsCharZero(C))
  101. //
  102. // The following two macro are used to find the first byte to really store
  103. // in the mapping pairs. They take as input a pointer to the LargeInteger we are
  104. // trying to store and a pointer to a character pointer. The character pointer
  105. // on return points to the first byte that we need to output. That's we skip
  106. // over the high order 0x00 or 0xff bytes.
  107. //
  108. typedef struct _SHORT2 {
  109. USHORT LowPart;
  110. USHORT HighPart;
  111. } SHORT2, *PSHORT2;
  112. typedef struct _CHAR2 {
  113. UCHAR LowPart;
  114. UCHAR HighPart;
  115. } CHAR2, *PCHAR2;
  116. #define GetPositiveByte(LI,CP) { \
  117. *(CP) = (PCHAR)(LI); \
  118. if ((LI)->HighPart != 0) { *(CP) += 4; } \
  119. if (((PSHORT2)(*(CP)))->HighPart != 0) { *(CP) += 2; } \
  120. if (((PCHAR2)(*(CP)))->HighPart != 0) { *(CP) += 1; } \
  121. if (IsCharLtrZero(*(*CP))) { *(CP) += 1; } \
  122. }
  123. #define GetNegativeByte(LI,CP) { \
  124. *(CP) = (PCHAR)(LI); \
  125. if ((LI)->HighPart != 0xffffffff) { *(CP) += 4; } \
  126. if (((PSHORT2)(*(CP)))->HighPart != 0xffff) { *(CP) += 2; } \
  127. if (((PCHAR2)(*(CP)))->HighPart != 0xff) { *(CP) += 1; } \
  128. if (!IsCharLtrZero(*(*CP))) { *(CP) += 1; } \
  129. }
  130. //
  131. // Flag macros
  132. //
  133. // ULONG
  134. // FlagOn (
  135. // IN ULONG Flags,
  136. // IN ULONG SingleFlag
  137. // );
  138. //
  139. // BOOLEAN
  140. // BooleanFlagOn (
  141. // IN ULONG Flags,
  142. // IN ULONG SingleFlag
  143. // );
  144. //
  145. // VOID
  146. // SetFlag (
  147. // IN ULONG Flags,
  148. // IN ULONG SingleFlag
  149. // );
  150. //
  151. // VOID
  152. // ClearFlag (
  153. // IN ULONG Flags,
  154. // IN ULONG SingleFlag
  155. // );
  156. //
  157. #ifdef KDEXTMODE
  158. #ifndef FlagOn
  159. #define FlagOn(F,SF) ( \
  160. (((F) & (SF))) \
  161. )
  162. #endif
  163. #endif
  164. //#ifndef BooleanFlagOn
  165. //#define BooleanFlagOn(F,SF) ( \
  166. // (BOOLEAN)(((F) & (SF)) != 0) \
  167. //)
  168. //#endif
  169. //#ifndef SetFlag
  170. //#define SetFlag(F,SF) { \
  171. // (F) |= (SF); \
  172. //}
  173. //#endif
  174. //#ifndef ClearFlag
  175. //#define ClearFlag(F,SF) { \
  176. // (F) &= ~(SF); \
  177. //}
  178. //#endif
  179. //
  180. // The following two macro are used by the Fsd/Fsp exception handlers to
  181. // process an exception. The first macro is the exception filter used in the
  182. // Fsd/Fsp to decide if an exception should be handled at this level.
  183. // The second macro decides if the exception is to be finished off by
  184. // completing the IRP, and cleaning up the Irp Context, or if we should
  185. // bugcheck. Exception values such as STATUS_FILE_INVALID (raised by
  186. // VerfySup.c) cause us to complete the Irp and cleanup, while exceptions
  187. // such as accvio cause us to bugcheck.
  188. //
  189. // The basic structure for fsd/fsp exception handling is as follows:
  190. //
  191. // NtfsFsdXxx(..)
  192. // {
  193. // try {
  194. //
  195. // ..
  196. //
  197. // } except(NtfsExceptionFilter( IrpContext, GetExceptionRecord() )) {
  198. //
  199. // Status = NtfsProcessException( IrpContext, Irp, GetExceptionCode() );
  200. // }
  201. //
  202. // Return Status;
  203. // }
  204. //
  205. // To explicitly raise an exception that we expect, such as
  206. // STATUS_FILE_INVALID, use the below macro NtfsRaiseStatus). To raise a
  207. // status from an unknown origin (such as CcFlushCache()), use the macro
  208. // NtfsNormalizeAndRaiseStatus. This will raise the status if it is expected,
  209. // or raise STATUS_UNEXPECTED_IO_ERROR if it is not.
  210. //
  211. // Note that when using these two macros, the original status is placed in
  212. // IrpContext->ExceptionStatus, signaling NtfsExceptionFilter and
  213. // NtfsProcessException that the status we actually raise is by definition
  214. // expected.
  215. //
  216. VOID
  217. NtfsCorruptionBreakPointTest (
  218. IN PIRP_CONTEXT IrpContext,
  219. IN ULONG ExceptionCode
  220. );
  221. LONG
  222. NtfsExceptionFilter (
  223. IN PIRP_CONTEXT IrpContext,
  224. IN PEXCEPTION_POINTERS ExceptionPointer
  225. );
  226. NTSTATUS
  227. NtfsProcessException (
  228. IN PIRP_CONTEXT IrpContext,
  229. IN PIRP Irp OPTIONAL,
  230. IN NTSTATUS ExceptionCode
  231. );
  232. VOID
  233. DECLSPEC_NORETURN
  234. NtfsRaiseStatus (
  235. IN PIRP_CONTEXT IrpContext,
  236. IN NTSTATUS Status,
  237. IN PFILE_REFERENCE FileReference OPTIONAL,
  238. IN PFCB Fcb OPTIONAL
  239. );
  240. ULONG
  241. NtfsRaiseStatusFunction (
  242. IN PIRP_CONTEXT IrpContext,
  243. IN NTSTATUS Status
  244. );
  245. //
  246. // VOID
  247. // NtfsNormalAndRaiseStatus (
  248. // IN PRIP_CONTEXT IrpContext,
  249. // IN NT_STATUS Status
  250. // IN NT_STATUS NormalStatus
  251. // );
  252. //
  253. #define NtfsNormalizeAndRaiseStatus(IC,STAT,NOR_STAT) { \
  254. (IC)->ExceptionStatus = (STAT); \
  255. ExRaiseStatus(FsRtlNormalizeNtstatus((STAT),NOR_STAT)); \
  256. }
  257. //
  258. // Informational popup routine.
  259. //
  260. VOID
  261. NtfsRaiseInformationHardError (
  262. IN PIRP_CONTEXT IrpContext,
  263. IN NTSTATUS Status,
  264. IN PFILE_REFERENCE FileReference OPTIONAL,
  265. IN PFCB Fcb OPTIONAL
  266. );
  267. //
  268. // Allocation support routines, implemented in AllocSup.c
  269. //
  270. // These routines are for querying, allocating and truncating clusters
  271. // for individual data streams.
  272. //
  273. //
  274. // Syscache debugging support - Main current define these are triggered on is
  275. // SYSCACHE_DEBUG
  276. //
  277. #if (defined(NTFS_RWCMP_TRACE) || defined(SYSCACHE) || defined(NTFS_RWC_DEBUG) || defined(SYSCACHE_DEBUG) || defined(SYSCACHE_DEBUG_ALLOC))
  278. BOOLEAN
  279. FsRtlIsSyscacheFile (
  280. IN PFILE_OBJECT FileObject
  281. );
  282. //
  283. // Depreciated verification routine leftover from tomm's original debugging code
  284. //
  285. VOID
  286. FsRtlVerifySyscacheData (
  287. IN PFILE_OBJECT FileObject,
  288. IN PVOID Buffer,
  289. IN ULONG Length,
  290. IN ULONG Offset
  291. );
  292. ULONG
  293. FsRtlLogSyscacheEvent (
  294. IN PSCB Scb,
  295. IN ULONG Event,
  296. IN ULONG Flags,
  297. IN LONGLONG Start,
  298. IN LONGLONG Range,
  299. IN LONGLONG Result
  300. );
  301. VOID
  302. FsRtlUpdateSyscacheEvent (
  303. IN PSCB Scb,
  304. IN ULONG EntryNumber,
  305. IN LONGLONG Result,
  306. IN ULONG NewFlag
  307. );
  308. #define ScbIsBeingLogged( S ) (((S)->SyscacheLogEntryCount != 0) && (NtfsSyscacheLogSet[(S)->LogSetNumber].Scb == (S)))
  309. #define FSCTL_ENABLE_SYSCACHE CTL_CODE( FILE_DEVICE_FILE_SYSTEM, 0x4545, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA )
  310. #endif
  311. //
  312. // The following routine takes an Vbo and returns the lbo and size of
  313. // the run corresponding to the Vbo. It function result is TRUE if
  314. // the Vbo has a valid Lbo mapping and FALSE otherwise.
  315. //
  316. ULONG
  317. NtfsPreloadAllocation (
  318. IN PIRP_CONTEXT IrpContext,
  319. IN OUT PSCB Scb,
  320. IN VCN StartingVcn,
  321. IN VCN EndingVcn
  322. );
  323. BOOLEAN
  324. NtfsLookupAllocation (
  325. IN PIRP_CONTEXT IrpContext,
  326. IN OUT PSCB Scb,
  327. IN VCN Vcn,
  328. OUT PLCN Lcn,
  329. OUT PLONGLONG ClusterCount,
  330. OUT PVOID *RangePtr OPTIONAL,
  331. OUT PULONG RunIndex OPTIONAL
  332. );
  333. BOOLEAN
  334. NtfsIsRangeAllocated (
  335. IN PSCB Scb,
  336. IN VCN StartVcn,
  337. IN VCN FinalCluster,
  338. IN BOOLEAN RoundToSparseUnit,
  339. OUT PLONGLONG ClusterCount
  340. );
  341. //
  342. // The following two routines modify the allocation of a data stream
  343. // represented by an Scb.
  344. //
  345. BOOLEAN
  346. NtfsAllocateAttribute (
  347. IN PIRP_CONTEXT IrpContext,
  348. IN PSCB Scb,
  349. IN ATTRIBUTE_TYPE_CODE AttributeTypeCode,
  350. IN PUNICODE_STRING AttributeName OPTIONAL,
  351. IN USHORT AttributeFlags,
  352. IN BOOLEAN AllocateAll,
  353. IN BOOLEAN LogIt,
  354. IN LONGLONG Size,
  355. IN PATTRIBUTE_ENUMERATION_CONTEXT NewLocation OPTIONAL
  356. );
  357. VOID
  358. NtfsAddAllocation (
  359. IN PIRP_CONTEXT IrpContext,
  360. IN PFILE_OBJECT FileObject OPTIONAL,
  361. IN OUT PSCB Scb,
  362. IN VCN StartingVcn,
  363. IN LONGLONG ClusterCount,
  364. IN LOGICAL AskForMore,
  365. IN OUT PCCB CcbForWriteExtend OPTIONAL
  366. );
  367. VOID
  368. NtfsAddSparseAllocation (
  369. IN PIRP_CONTEXT IrpContext,
  370. IN PFILE_OBJECT FileObject OPTIONAL,
  371. IN OUT PSCB Scb,
  372. IN LONGLONG StartingOffset,
  373. IN LONGLONG ByteCount
  374. );
  375. VOID
  376. NtfsDeleteAllocation (
  377. IN PIRP_CONTEXT IrpContext,
  378. IN PFILE_OBJECT FileObject OPTIONAL,
  379. IN OUT PSCB Scb,
  380. IN VCN StartingVcn,
  381. IN VCN EndingVcn,
  382. IN BOOLEAN LogIt,
  383. IN BOOLEAN BreakupAllowed
  384. );
  385. VOID
  386. NtfsReallocateRange (
  387. IN PIRP_CONTEXT IrpContext,
  388. IN OUT PSCB Scb,
  389. IN VCN DeleteVcn,
  390. IN LONGLONG DeleteCount,
  391. IN VCN AllocateVcn,
  392. IN LONGLONG AllocateCount,
  393. IN PLCN TargetLcn OPTIONAL
  394. );
  395. //
  396. // Routines for Mcb to Mapping Pairs operations
  397. //
  398. ULONG
  399. NtfsGetSizeForMappingPairs (
  400. IN PNTFS_MCB Mcb,
  401. IN ULONG BytesAvailable,
  402. IN VCN LowestVcn,
  403. IN PVCN StopOnVcn OPTIONAL,
  404. OUT PVCN StoppedOnVcn
  405. );
  406. BOOLEAN
  407. NtfsBuildMappingPairs (
  408. IN PNTFS_MCB Mcb,
  409. IN VCN LowestVcn,
  410. IN OUT PVCN HighestVcn,
  411. OUT PCHAR MappingPairs
  412. );
  413. VCN
  414. NtfsGetHighestVcn (
  415. IN PIRP_CONTEXT IrpContext,
  416. IN VCN LowestVcn,
  417. IN PCHAR EndOfMappingPairs,
  418. IN PCHAR MappingPairs
  419. );
  420. BOOLEAN
  421. NtfsReserveClusters (
  422. IN PIRP_CONTEXT IrpContext OPTIONAL,
  423. IN PSCB Scb,
  424. IN LONGLONG FileOffset,
  425. IN ULONG ByteCount
  426. );
  427. VOID
  428. NtfsFreeReservedClusters (
  429. IN PSCB Scb,
  430. IN LONGLONG FileOffset,
  431. IN ULONG ByteCount
  432. );
  433. BOOLEAN
  434. NtfsCheckForReservedClusters (
  435. IN PSCB Scb,
  436. IN LONGLONG StartingVcn,
  437. IN OUT PLONGLONG ClusterCount
  438. );
  439. VOID
  440. NtfsDeleteReservedBitmap (
  441. IN PSCB Scb
  442. );
  443. //
  444. // Attribute lookup routines, implemented in AttrSup.c
  445. //
  446. //
  447. // This macro detects if we are enumerating through base or external
  448. // attributes, and calls the appropriate function.
  449. //
  450. // BOOLEAN
  451. // LookupNextAttribute (
  452. // IN PRIP_CONTEXT IrpContext,
  453. // IN PFCB Fcb,
  454. // IN ATTRIBUTE_TYPE_CODE Code,
  455. // IN PUNICODE_STRING Name OPTIONAL,
  456. // IN BOOLEAN IgnoreCase,
  457. // IN PVOID Value OPTIONAL,
  458. // IN ULONG ValueLength,
  459. // IN PVCN Vcn OPTIONAL,
  460. // IN PATTRIBUTE_ENUMERATION_CONTEXT Context
  461. // );
  462. //
  463. #define LookupNextAttribute(IRPCTXT,FCB,CODE,NAME,IC,VALUE,LENGTH,V,CONTEXT) \
  464. ( (CONTEXT)->AttributeList.Bcb == NULL \
  465. ? NtfsLookupInFileRecord( (IRPCTXT), \
  466. (FCB), \
  467. NULL, \
  468. (CODE), \
  469. (NAME), \
  470. (V), \
  471. (IC), \
  472. (VALUE), \
  473. (LENGTH), \
  474. (CONTEXT)) \
  475. : NtfsLookupExternalAttribute((IRPCTXT), \
  476. (FCB), \
  477. (CODE), \
  478. (NAME), \
  479. (V), \
  480. (IC), \
  481. (VALUE), \
  482. (LENGTH), \
  483. (CONTEXT)) )
  484. BOOLEAN
  485. NtfsLookupExternalAttribute (
  486. IN PIRP_CONTEXT IrpContext,
  487. IN PFCB Fcb,
  488. IN ATTRIBUTE_TYPE_CODE QueriedTypeCode,
  489. IN PCUNICODE_STRING QueriedName OPTIONAL,
  490. IN PVCN Vcn OPTIONAL,
  491. IN BOOLEAN IgnoreCase,
  492. IN PVOID QueriedValue OPTIONAL,
  493. IN ULONG QueriedValueLength,
  494. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  495. );
  496. //
  497. // The following two routines do lookups based on the attribute definitions.
  498. //
  499. ATTRIBUTE_TYPE_CODE
  500. NtfsGetAttributeTypeCode (
  501. IN PVCB Vcb,
  502. IN PUNICODE_STRING AttributeTypeName
  503. );
  504. //
  505. // PATTRIBUTE_DEFINITION_COLUMNS
  506. // NtfsGetAttributeDefinition (
  507. // IN PVCB Vcb,
  508. // IN ATTRIBUTE_TYPE_CODE AttributeTypeCode
  509. // )
  510. //
  511. #define NtfsGetAttributeDefinition(Vcb,AttributeTypeCode) \
  512. (&Vcb->AttributeDefinitions[(AttributeTypeCode / 0x10) - 1])
  513. //
  514. // This routine looks up the attribute uniquely-qualified by the specified
  515. // Attribute Code and case-sensitive name. The attribute may not be unique
  516. // if IgnoreCase is specified.
  517. //
  518. BOOLEAN
  519. NtfsLookupInFileRecord (
  520. IN PIRP_CONTEXT IrpContext,
  521. IN PFCB Fcb,
  522. IN PFILE_REFERENCE BaseFileReference OPTIONAL,
  523. IN ATTRIBUTE_TYPE_CODE QueriedTypeCode,
  524. IN PCUNICODE_STRING QueriedName OPTIONAL,
  525. IN PVCN Vcn OPTIONAL,
  526. IN BOOLEAN IgnoreCase,
  527. IN PVOID QueriedValue OPTIONAL,
  528. IN ULONG QueriedValueLength,
  529. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  530. );
  531. //
  532. // This routine attempts to find the fist occurrence of an attribute with
  533. // the specified AttributeTypeCode and the specified QueriedName in the
  534. // specified BaseFileReference. If we find one, its attribute record is
  535. // pinned and returned.
  536. //
  537. // BOOLEAN
  538. // NtfsLookupAttributeByName (
  539. // IN PIRP_CONTEXT IrpContext,
  540. // IN PFCB Fcb,
  541. // IN PFILE_REFERENCE BaseFileReference,
  542. // IN ATTRIBUTE_TYPE_CODE QueriedTypeCode,
  543. // IN PUNICODE_STRING QueriedName OPTIONAL,
  544. // IN PVCN Vcn OPTIONAL,
  545. // IN BOOLEAN IgnoreCase,
  546. // OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  547. // )
  548. //
  549. #define NtfsLookupAttributeByName(IrpContext,Fcb,BaseFileReference,QueriedTypeCode,QueriedName,Vcn,IgnoreCase,Context) \
  550. NtfsLookupInFileRecord( IrpContext, \
  551. Fcb, \
  552. BaseFileReference, \
  553. QueriedTypeCode, \
  554. QueriedName, \
  555. Vcn, \
  556. IgnoreCase, \
  557. NULL, \
  558. 0, \
  559. Context )
  560. //
  561. // This function continues where the prior left off.
  562. //
  563. // BOOLEAN
  564. // NtfsLookupNextAttributeByName (
  565. // IN PIRP_CONTEXT IrpContext,
  566. // IN PFCB Fcb,
  567. // IN ATTRIBUTE_TYPE_CODE QueriedTypeCode,
  568. // IN PUNICODE_STRING QueriedName OPTIONAL,
  569. // IN BOOLEAN IgnoreCase,
  570. // IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  571. // )
  572. //
  573. #define NtfsLookupNextAttributeByName(IrpContext,Fcb,QueriedTypeCode,QueriedName,IgnoreCase,Context) \
  574. LookupNextAttribute( IrpContext, \
  575. Fcb, \
  576. QueriedTypeCode, \
  577. QueriedName, \
  578. IgnoreCase, \
  579. NULL, \
  580. 0, \
  581. NULL, \
  582. Context )
  583. //
  584. // The following does a search based on a VCN.
  585. //
  586. //
  587. // BOOLEAN
  588. // NtfsLookupNextAttributeByVcn (
  589. // IN PIRP_CONTEXT IrpContext,
  590. // IN PFCB Fcb,
  591. // IN PVCN Vcn OPTIONAL,
  592. // OUT PATTRIBUTE_ENUMERATION_CONTEXT
  593. // );
  594. //
  595. #define NtfsLookupNextAttributeByVcn(IC,F,V,C) \
  596. LookupNextAttribute( (IC), \
  597. (F), \
  598. $UNUSED, \
  599. NULL, \
  600. FALSE, \
  601. NULL, \
  602. FALSE, \
  603. (V), \
  604. (C) )
  605. //
  606. // The following routines find the attribute record for a given Scb.
  607. // And also update the scb from the attribute
  608. //
  609. // VOID
  610. // NtfsLookupAttributeForScb (
  611. // IN PIRP_CONTEXT IrpContext,
  612. // IN PSCB Scb,
  613. // IN PVCN Vcn OPTIONAL,
  614. // IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  615. // )
  616. //
  617. #define NtfsLookupAttributeForScb(IrpContext,Scb,Vcn,Context) \
  618. if (!NtfsLookupAttributeByName( IrpContext, \
  619. Scb->Fcb, \
  620. &Scb->Fcb->FileReference, \
  621. Scb->AttributeTypeCode, \
  622. &Scb->AttributeName, \
  623. Vcn, \
  624. FALSE, \
  625. Context ) && \
  626. !FlagOn( Scb->ScbState, SCB_STATE_VIEW_INDEX )) { \
  627. \
  628. DebugTrace( 0, 0, ("Could not find attribute for Scb @ %08lx\n", Scb )); \
  629. ASSERTMSG("Could not find attribute for Scb\n", FALSE); \
  630. NtfsRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR, NULL, Scb->Fcb ); \
  631. }
  632. //
  633. // This routine looks up and returns the next attribute for a given Scb.
  634. //
  635. // BOOLEAN
  636. // NtfsLookupNextAttributeForScb (
  637. // IN PIRP_CONTEXT IrpContext,
  638. // IN PSCB Scb,
  639. // IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  640. // )
  641. //
  642. #define NtfsLookupNextAttributeForScb(IrpContext,Scb,Context) \
  643. NtfsLookupNextAttributeByName( IrpContext, \
  644. Scb->Fcb, \
  645. Scb->AttributeTypeCode, \
  646. &Scb->AttributeName, \
  647. FALSE, \
  648. Context )
  649. VOID
  650. NtfsUpdateScbFromAttribute (
  651. IN PIRP_CONTEXT IrpContext,
  652. IN OUT PSCB Scb,
  653. IN PATTRIBUTE_RECORD_HEADER AttrHeader OPTIONAL
  654. );
  655. //
  656. // The following routines deal with the Fcb and the duplicated information field.
  657. //
  658. BOOLEAN
  659. NtfsUpdateFcbInfoFromDisk (
  660. IN PIRP_CONTEXT IrpContext,
  661. IN BOOLEAN LoadSecurity,
  662. IN OUT PFCB Fcb,
  663. OUT POLD_SCB_SNAPSHOT UnnamedDataSizes OPTIONAL
  664. );
  665. //
  666. // These routines looks up the first/next attribute, i.e., they may be used
  667. // to retrieve all atributes for a file record.
  668. //
  669. // If the Bcb in the Found Attribute structure changes in the Next call, then
  670. // the previous Bcb is autmatically unpinned and the new one pinned.
  671. //
  672. //
  673. // This routine attempts to find the fist occurrence of an attribute with
  674. // the specified AttributeTypeCode in the specified BaseFileReference. If we
  675. // find one, its attribute record is pinned and returned.
  676. //
  677. // BOOLEAN
  678. // NtfsLookupAttribute (
  679. // IN PIRP_CONTEXT IrpContext,
  680. // IN PFCB Fcb,
  681. // IN PFILE_REFERENCE BaseFileReference,
  682. // OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  683. // )
  684. //
  685. #define NtfsLookupAttribute(IrpContext,Fcb,BaseFileReference,Context) \
  686. NtfsLookupInFileRecord( IrpContext, \
  687. Fcb, \
  688. BaseFileReference, \
  689. $UNUSED, \
  690. NULL, \
  691. NULL, \
  692. FALSE, \
  693. NULL, \
  694. 0, \
  695. Context )
  696. //
  697. // This function continues where the prior left off.
  698. //
  699. // BOOLEAN
  700. // NtfsLookupNextAttribute (
  701. // IN PIRP_CONTEXT IrpContext,
  702. // IN PFCB Fcb,
  703. // IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  704. // )
  705. //
  706. #define NtfsLookupNextAttribute(IrpContext,Fcb,Context) \
  707. LookupNextAttribute( IrpContext, \
  708. Fcb, \
  709. $UNUSED, \
  710. NULL, \
  711. FALSE, \
  712. NULL, \
  713. 0, \
  714. NULL, \
  715. Context )
  716. //
  717. // These routines looks up the first/next attribute of the given type code.
  718. //
  719. // If the Bcb in the Found Attribute structure changes in the Next call, then
  720. // the previous Bcb is autmatically unpinned and the new one pinned.
  721. //
  722. //
  723. // This routine attempts to find the fist occurrence of an attribute with
  724. // the specified AttributeTypeCode in the specified BaseFileReference. If we
  725. // find one, its attribute record is pinned and returned.
  726. //
  727. // BOOLEAN
  728. // NtfsLookupAttributeByCode (
  729. // IN PIRP_CONTEXT IrpContext,
  730. // IN PFCB Fcb,
  731. // IN PFILE_REFERENCE BaseFileReference,
  732. // IN ATTRIBUTE_TYPE_CODE QueriedTypeCode,
  733. // OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  734. // )
  735. //
  736. #define NtfsLookupAttributeByCode(IrpContext,Fcb,BaseFileReference,QueriedTypeCode,Context) \
  737. NtfsLookupInFileRecord( IrpContext, \
  738. Fcb, \
  739. BaseFileReference, \
  740. QueriedTypeCode, \
  741. NULL, \
  742. NULL, \
  743. FALSE, \
  744. NULL, \
  745. 0, \
  746. Context )
  747. //
  748. // This function continues where the prior left off.
  749. //
  750. // BOOLEAN
  751. // NtfsLookupNextAttributeByCode (
  752. // IN PIRP_CONTEXT IrpContext,
  753. // IN PFCB Fcb,
  754. // IN ATTRIBUTE_TYPE_CODE QueriedTypeCode,
  755. // IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  756. // )
  757. //
  758. #define NtfsLookupNextAttributeByCode(IC,F,CODE,C) \
  759. LookupNextAttribute( (IC), \
  760. (F), \
  761. (CODE), \
  762. NULL, \
  763. FALSE, \
  764. NULL, \
  765. 0, \
  766. NULL, \
  767. (C) )
  768. //
  769. // These routines looks up the first/next occurrence of an attribute by its
  770. // Attribute Code and exact attribute value (consider using RtlCompareMemory).
  771. // The value contains everything outside of the standard attribute header,
  772. // so for example, to look up the File Name attribute by value, the caller
  773. // must form a record with not only the file name in it, but with the
  774. // ParentDirectory filled in as well. The length should be exact, and not
  775. // include any unused (such as in DOS_NAME) or reserved characters.
  776. //
  777. // If the Bcb changes in the Next call, then the previous Bcb is autmatically
  778. // unpinned and the new one pinned.
  779. //
  780. //
  781. // This routine attempts to find the fist occurrence of an attribute with
  782. // the specified AttributeTypeCode and the specified QueriedValue in the
  783. // specified BaseFileReference. If we find one, its attribute record is
  784. // pinned and returned.
  785. //
  786. // BOOLEAN
  787. // NtfsLookupAttributeByValue (
  788. // IN PIRP_CONTEXT IrpContext,
  789. // IN PFCB Fcb,
  790. // IN PFILE_REFERENCE BaseFileReference,
  791. // IN ATTRIBUTE_TYPE_CODE QueriedTypeCode,
  792. // IN PVOID QueriedValue,
  793. // IN ULONG QueriedValueLength,
  794. // OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  795. // )
  796. //
  797. #define NtfsLookupAttributeByValue(IrpContext,Fcb,BaseFileReference,QueriedTypeCode,QueriedValue,QueriedValueLength,Context) \
  798. NtfsLookupInFileRecord( IrpContext, \
  799. Fcb, \
  800. BaseFileReference, \
  801. QueriedTypeCode, \
  802. NULL, \
  803. NULL, \
  804. FALSE, \
  805. QueriedValue, \
  806. QueriedValueLength, \
  807. Context )
  808. //
  809. // This function continues where the prior left off.
  810. //
  811. // BOOLEAN
  812. // NtfsLookupNextAttributeByValue (
  813. // IN PIRP_CONTEXT IrpContext,
  814. // IN PFCB Fcb,
  815. // IN ATTRIBUTE_TYPE_CODE QueriedTypeCode,
  816. // IN PVOID QueriedValue,
  817. // IN ULONG QueriedValueLength,
  818. // IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  819. // )
  820. //
  821. #define NtfsLookupNextAttributeByValue(IC,F,CODE,V,VL,C) \
  822. LookupNextAttribute( (IC), \
  823. (F), \
  824. (CODE), \
  825. NULL, \
  826. FALSE, \
  827. (V), \
  828. (VL), \
  829. (C) )
  830. VOID
  831. NtfsCleanupAttributeContext(
  832. IN OUT PIRP_CONTEXT IrpContext,
  833. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT AttributeContext
  834. );
  835. //
  836. //
  837. //
  838. // Here are some routines/macros for dealing with Attribute Enumeration
  839. // Contexts.
  840. //
  841. // VOID
  842. // NtfsInitializeAttributeContext(
  843. // OUT PATTRIBUTE_ENUMERATION_CONTEXT AttributeContext
  844. // );
  845. //
  846. // VOID
  847. // NtfsPinMappedAttribute(
  848. // IN PIRP_CONTEXT IrpContext,
  849. // IN PVCB Vcb,
  850. // IN OUT PATTRIBUTE_ENUMERATION_CONTEXT AttributeContext
  851. // );
  852. //
  853. // PATTRIBUTE_RECORD_HEADER
  854. // NtfsFoundAttribute(
  855. // IN PATTRIBUTE_ENUMERATION_CONTEXT AttributeContext
  856. // );
  857. //
  858. // PBCB
  859. // NtfsFoundBcb(
  860. // IN PATTRIBUTE_ENUMERATION_CONTEXT AttributeContext
  861. // );
  862. //
  863. // PFILE_RECORD
  864. // NtfsContainingFileRecord (
  865. // IN PATTRIBUTE_ENUMERATION_CONTEXT AttributeContext
  866. // );
  867. //
  868. // LONGLONG
  869. // NtfsMftOffset (
  870. // IN PATTRIBUTE_ENUMERATION_CONTEXT AttributeContext
  871. // );
  872. //
  873. #define NtfsInitializeAttributeContext(CTX) { \
  874. RtlZeroMemory( (CTX), sizeof(ATTRIBUTE_ENUMERATION_CONTEXT) ); \
  875. }
  876. #define NtfsPinMappedAttribute(IC,V,CTX) { \
  877. NtfsPinMappedData( (IC), \
  878. (V)->MftScb, \
  879. (CTX)->FoundAttribute.MftFileOffset, \
  880. (V)->BytesPerFileRecordSegment, \
  881. &(CTX)->FoundAttribute.Bcb ); \
  882. }
  883. #define NtfsFoundAttribute(CTX) ( \
  884. (CTX)->FoundAttribute.Attribute \
  885. )
  886. #define NtfsFoundBcb(CTX) ( \
  887. (CTX)->FoundAttribute.Bcb \
  888. )
  889. #define NtfsContainingFileRecord(CTX) ( \
  890. (CTX)->FoundAttribute.FileRecord \
  891. )
  892. #define NtfsMftOffset(CTX) ( \
  893. (CTX)->FoundAttribute.MftFileOffset \
  894. )
  895. //
  896. // This routine returns whether an attribute is resident or not.
  897. //
  898. // BOOLEAN
  899. // NtfsIsAttributeResident (
  900. // IN PATTRIBUTE_RECORD_HEADER Attribute
  901. // );
  902. //
  903. // PVOID
  904. // NtfsAttributeValue (
  905. // IN PATTRIBUTE_RECORD_HEADER Attribute
  906. // );
  907. //
  908. #define NtfsIsAttributeResident(ATTR) ( \
  909. ((ATTR)->FormCode == RESIDENT_FORM) \
  910. )
  911. #define NtfsAttributeValue(ATTR) ( \
  912. ((PCHAR)(ATTR) + (ULONG)(ATTR)->Form.Resident.ValueOffset) \
  913. )
  914. //
  915. // This routine modifies the valid data length and file size on disk for
  916. // a given Scb.
  917. //
  918. BOOLEAN
  919. NtfsWriteFileSizes (
  920. IN PIRP_CONTEXT IrpContext,
  921. IN PSCB Scb,
  922. IN PLONGLONG ValidDataLength,
  923. IN BOOLEAN AdvanceOnly,
  924. IN BOOLEAN LogIt,
  925. IN BOOLEAN RollbackMemStructures
  926. );
  927. //
  928. // This routine updates the standard information attribute from the
  929. // information in the Fcb.
  930. //
  931. VOID
  932. NtfsUpdateStandardInformation (
  933. IN PIRP_CONTEXT IrpContext,
  934. IN PFCB Fcb
  935. );
  936. //
  937. // This routine grows and updates the standard information attribute from
  938. // the information in the Fcb.
  939. //
  940. VOID
  941. NtfsGrowStandardInformation (
  942. IN PIRP_CONTEXT IrpContext,
  943. IN PFCB Fcb
  944. );
  945. //
  946. // Attribute FILE_NAME routines. These routines deal with filename attributes.
  947. //
  948. // VOID
  949. // NtfsBuildFileNameAttribute (
  950. // IN PIRP_CONTEXT IrpContext,
  951. // IN PFILE_REFERENCE ParentDirectory,
  952. // IN UNICODE_STRING FileName,
  953. // IN UCHAR Flags,
  954. // OUT PFILE_NAME FileNameValue
  955. // );
  956. //
  957. #define NtfsBuildFileNameAttribute(IC,PD,FN,FL,PFNA) { \
  958. (PFNA)->ParentDirectory = *(PD); \
  959. (PFNA)->FileNameLength = (UCHAR)((FN).Length >> 1); \
  960. (PFNA)->Flags = FL; \
  961. RtlMoveMemory( (PFNA)->FileName, (FN).Buffer, (ULONG)(FN).Length ); \
  962. }
  963. BOOLEAN
  964. NtfsLookupEntry (
  965. IN PIRP_CONTEXT IrpContext,
  966. IN PSCB ParentScb,
  967. IN BOOLEAN IgnoreCase,
  968. IN OUT PUNICODE_STRING Name,
  969. IN OUT PFILE_NAME *FileNameAttr,
  970. IN OUT PUSHORT FileNameAttrLength,
  971. OUT PQUICK_INDEX QuickIndex OPTIONAL,
  972. OUT PINDEX_ENTRY *IndexEntry,
  973. OUT PBCB *IndexEntryBcb,
  974. OUT PINDEX_CONTEXT IndexContext OPTIONAL
  975. );
  976. //
  977. // Macro to decide when to create an attribute resident.
  978. //
  979. // BOOLEAN
  980. // NtfsShouldAttributeBeResident (
  981. // IN PVCB Vcb,
  982. // IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  983. // IN ULONG Size
  984. // );
  985. //
  986. #define RS(S) ((S) + SIZEOF_RESIDENT_ATTRIBUTE_HEADER)
  987. #define NtfsShouldAttributeBeResident(VC,FR,S) ( \
  988. (BOOLEAN)((RS(S) <= ((FR)->BytesAvailable - (FR)->FirstFreeByte)) || \
  989. (RS(S) < (VC)->BigEnoughToMove)) \
  990. )
  991. //
  992. // Attribute creation/modification routines
  993. //
  994. // These three routines do *not* presuppose either the Resident or Nonresident
  995. // form, with the single exception that if the attribute is indexed, then
  996. // it must be Resident.
  997. //
  998. // NtfsMapAttributeValue and NtfsChangeAttributeValue implement transparent
  999. // access to small to medium sized attributes (such as $ACL and $EA), and
  1000. // work whether the attribute is resident or nonresident. The design target
  1001. // is 0-64KB in size. Attributes larger than 256KB (or more accurrately,
  1002. // whatever the virtual mapping granularity is in the Cache Manager) will not
  1003. // work correctly.
  1004. //
  1005. VOID
  1006. NtfsCreateAttributeWithValue (
  1007. IN PIRP_CONTEXT IrpContext,
  1008. IN PFCB Fcb,
  1009. IN ATTRIBUTE_TYPE_CODE AttributeTypeCode,
  1010. IN PUNICODE_STRING AttributeName OPTIONAL,
  1011. IN PVOID Value OPTIONAL,
  1012. IN ULONG ValueLength,
  1013. IN USHORT AttributeFlags,
  1014. IN PFILE_REFERENCE WhereIndexed OPTIONAL,
  1015. IN BOOLEAN LogIt,
  1016. OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  1017. );
  1018. VOID
  1019. NtfsMapAttributeValue (
  1020. IN PIRP_CONTEXT IrpContext,
  1021. IN PFCB Fcb,
  1022. OUT PVOID *Buffer,
  1023. OUT PULONG Length,
  1024. OUT PBCB *Bcb,
  1025. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  1026. );
  1027. VOID
  1028. NtfsChangeAttributeValue (
  1029. IN PIRP_CONTEXT IrpContext,
  1030. IN PFCB Fcb,
  1031. IN ULONG ValueOffset,
  1032. IN PVOID Value OPTIONAL,
  1033. IN ULONG ValueLength,
  1034. IN BOOLEAN SetNewLength,
  1035. IN BOOLEAN LogNonresidentToo,
  1036. IN BOOLEAN CreateSectionUnderway,
  1037. IN BOOLEAN PreserveContext,
  1038. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  1039. );
  1040. VOID
  1041. NtfsConvertToNonresident (
  1042. IN PIRP_CONTEXT IrpContext,
  1043. IN PFCB Fcb,
  1044. IN OUT PATTRIBUTE_RECORD_HEADER Attribute,
  1045. IN BOOLEAN CreateSectionUnderway,
  1046. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context OPTIONAL
  1047. );
  1048. #define DELETE_LOG_OPERATION 0x00000001
  1049. #define DELETE_RELEASE_FILE_RECORD 0x00000002
  1050. #define DELETE_RELEASE_ALLOCATION 0x00000004
  1051. VOID
  1052. NtfsDeleteAttributeRecord (
  1053. IN PIRP_CONTEXT IrpContext,
  1054. IN PFCB Fcb,
  1055. IN ULONG Flags,
  1056. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  1057. );
  1058. VOID
  1059. NtfsDeleteAllocationFromRecord (
  1060. PIRP_CONTEXT IrpContext,
  1061. IN PFCB Fcb,
  1062. IN PATTRIBUTE_ENUMERATION_CONTEXT Context,
  1063. IN BOOLEAN BreakupAllowed,
  1064. IN BOOLEAN LogIt
  1065. );
  1066. BOOLEAN
  1067. NtfsChangeAttributeSize (
  1068. IN PIRP_CONTEXT IrpContext,
  1069. IN PFCB Fcb,
  1070. IN ULONG Length,
  1071. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  1072. );
  1073. VOID
  1074. NtfsAddToAttributeList (
  1075. IN PIRP_CONTEXT IrpContext,
  1076. IN PFCB Fcb,
  1077. IN MFT_SEGMENT_REFERENCE SegmentReference,
  1078. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  1079. );
  1080. VOID
  1081. NtfsDeleteFromAttributeList (
  1082. IN PIRP_CONTEXT IrpContext,
  1083. IN PFCB Fcb,
  1084. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  1085. );
  1086. BOOLEAN
  1087. NtfsRewriteMftMapping (
  1088. IN PIRP_CONTEXT IrpContext,
  1089. IN PVCB Vcb
  1090. );
  1091. VOID
  1092. NtfsSetTotalAllocatedField (
  1093. IN PIRP_CONTEXT IrpContext,
  1094. IN PSCB Scb,
  1095. IN USHORT TotalAllocatedNeeded
  1096. );
  1097. VOID
  1098. NtfsSetSparseStream (
  1099. IN PIRP_CONTEXT IrpContext,
  1100. IN PSCB ParentScb OPTIONAL,
  1101. IN PSCB Scb
  1102. );
  1103. NTSTATUS
  1104. NtfsZeroRangeInStream (
  1105. IN PIRP_CONTEXT IrpContext,
  1106. IN PFILE_OBJECT FileObject OPTIONAL,
  1107. IN PSCB Scb,
  1108. IN PLONGLONG StartingOffset,
  1109. IN LONGLONG FinalZero
  1110. );
  1111. BOOLEAN
  1112. NtfsModifyAttributeFlags (
  1113. IN PIRP_CONTEXT IrpContext,
  1114. IN PSCB Scb,
  1115. IN USHORT NewAttributeFlags
  1116. );
  1117. PFCB
  1118. NtfsInitializeFileInExtendDirectory (
  1119. IN PIRP_CONTEXT IrpContext,
  1120. IN PVCB Vcb,
  1121. IN PCUNICODE_STRING FileName,
  1122. IN BOOLEAN ViewIndex,
  1123. IN ULONG CreateIfNotExist
  1124. );
  1125. //
  1126. // Use common routines to fill the common query buffers.
  1127. //
  1128. VOID
  1129. NtfsFillBasicInfo (
  1130. OUT PFILE_BASIC_INFORMATION Buffer,
  1131. IN PSCB Scb
  1132. );
  1133. VOID
  1134. NtfsFillStandardInfo (
  1135. OUT PFILE_STANDARD_INFORMATION Buffer,
  1136. IN PSCB Scb,
  1137. IN PCCB Ccb OPTIONAL
  1138. );
  1139. VOID
  1140. NtfsFillNetworkOpenInfo (
  1141. OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
  1142. IN PSCB Scb
  1143. );
  1144. //
  1145. // The following three routines dealing with allocation are to be
  1146. // called by allocsup.c only. Other software must call the routines
  1147. // in allocsup.c
  1148. //
  1149. BOOLEAN
  1150. NtfsCreateAttributeWithAllocation (
  1151. IN PIRP_CONTEXT IrpContext,
  1152. IN PSCB Scb,
  1153. IN ATTRIBUTE_TYPE_CODE AttributeTypeCode,
  1154. IN PUNICODE_STRING AttributeName OPTIONAL,
  1155. IN USHORT AttributeFlags,
  1156. IN BOOLEAN LogIt,
  1157. IN BOOLEAN UseContext,
  1158. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context
  1159. );
  1160. VOID
  1161. NtfsAddAttributeAllocation (
  1162. IN PIRP_CONTEXT IrpContext,
  1163. IN PSCB Scb,
  1164. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context,
  1165. IN PVCN StartingVcn OPTIONAL,
  1166. IN PVCN ClusterCount OPTIONAL
  1167. );
  1168. VOID
  1169. NtfsDeleteAttributeAllocation (
  1170. IN PIRP_CONTEXT IrpContext,
  1171. IN PSCB Scb,
  1172. IN BOOLEAN LogIt,
  1173. IN PVCN StopOnVcn,
  1174. IN OUT PATTRIBUTE_ENUMERATION_CONTEXT Context,
  1175. IN BOOLEAN TruncateToVcn
  1176. );
  1177. //
  1178. // To delete a file, you must first ask if it is deleteable from the ParentScb
  1179. // used to get there for your caller, and then you can delete it if it is.
  1180. //
  1181. //
  1182. // BOOLEAN
  1183. // NtfsIsLinkDeleteable (
  1184. // IN PIRP_CONTEXT IrpContext,
  1185. // IN PFCB Fcb,
  1186. // OUT PBOOLEAN NonEmptyIndex,
  1187. // OUT PBOOLEAN LastLink
  1188. // );
  1189. //
  1190. #define NtfsIsLinkDeleteable(IC,FC,NEI,LL) ((BOOLEAN) \
  1191. (((*(LL) = ((BOOLEAN) (FC)->LinkCount == 1)), (FC)->LinkCount > 1) || \
  1192. (NtfsIsFileDeleteable( (IC), (FC), (NEI) ))) \
  1193. )
  1194. BOOLEAN
  1195. NtfsIsFileDeleteable (
  1196. IN PIRP_CONTEXT IrpContext,
  1197. IN PFCB Fcb,
  1198. OUT PBOOLEAN NonEmptyIndex
  1199. );
  1200. VOID
  1201. NtfsDeleteFile (
  1202. IN PIRP_CONTEXT IrpContext,
  1203. IN PFCB Fcb,
  1204. IN PSCB ParentScb,
  1205. IN OUT PBOOLEAN AcquiredParentScb,
  1206. IN OUT PNAME_PAIR NamePair OPTIONAL,
  1207. IN OUT PNTFS_TUNNELED_DATA TunneledData OPTIONAL
  1208. );
  1209. VOID
  1210. NtfsPrepareForUpdateDuplicate (
  1211. IN PIRP_CONTEXT IrpContext,
  1212. IN PFCB Fcb,
  1213. IN OUT PLCB *Lcb,
  1214. IN OUT PSCB *ParentScb,
  1215. IN BOOLEAN AcquireShared
  1216. );
  1217. VOID
  1218. NtfsUpdateDuplicateInfo (
  1219. IN PIRP_CONTEXT IrpContext,
  1220. IN PFCB Fcb,
  1221. IN PLCB Lcb OPTIONAL,
  1222. IN PSCB ParentScb OPTIONAL
  1223. );
  1224. VOID
  1225. NtfsUpdateLcbDuplicateInfo (
  1226. IN PFCB Fcb,
  1227. IN PLCB Lcb
  1228. );
  1229. VOID
  1230. NtfsUpdateFcb (
  1231. IN PFCB Fcb,
  1232. IN ULONG ChangeFlags
  1233. );
  1234. //
  1235. // The following routines add and remove links. They also update the name
  1236. // flags in particular links.
  1237. //
  1238. VOID
  1239. NtfsAddLink (
  1240. IN PIRP_CONTEXT IrpContext,
  1241. IN BOOLEAN CreatePrimaryLink,
  1242. IN PSCB ParentScb,
  1243. IN PFCB Fcb,
  1244. IN PFILE_NAME FileNameAttr,
  1245. IN PBOOLEAN LogIt OPTIONAL,
  1246. OUT PUCHAR FileNameFlags,
  1247. OUT PQUICK_INDEX QuickIndex OPTIONAL,
  1248. IN PNAME_PAIR NamePair OPTIONAL,
  1249. IN PINDEX_CONTEXT IndexContext OPTIONAL
  1250. );
  1251. VOID
  1252. NtfsRemoveLink (
  1253. IN PIRP_CONTEXT IrpContext,
  1254. IN PFCB Fcb,
  1255. IN PSCB ParentScb,
  1256. IN UNICODE_STRING LinkName,
  1257. IN OUT PNAME_PAIR NamePair OPTIONAL,
  1258. IN OUT PNTFS_TUNNELED_DATA TunneledData OPTIONAL
  1259. );
  1260. VOID
  1261. NtfsRemoveLinkViaFlags (
  1262. IN PIRP_CONTEXT IrpContext,
  1263. IN PFCB Fcb,
  1264. IN PSCB Scb,
  1265. IN UCHAR FileNameFlags,
  1266. IN OUT PNAME_PAIR NamePair OPTIONAL,
  1267. OUT PUNICODE_STRING FileName OPTIONAL
  1268. );
  1269. VOID
  1270. NtfsUpdateFileNameFlags (
  1271. IN PIRP_CONTEXT IrpContext,
  1272. IN PFCB Fcb,
  1273. IN PSCB ParentScb,
  1274. IN UCHAR FileNameFlags,
  1275. IN PFILE_NAME FileNameLink
  1276. );
  1277. //
  1278. // These routines are intended for low-level attribute access, such as within
  1279. // attrsup, or for applying update operations from the log during restart.
  1280. //
  1281. VOID
  1282. NtfsRestartInsertAttribute (
  1283. IN PIRP_CONTEXT IrpContext,
  1284. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  1285. IN ULONG RecordOffset,
  1286. IN PATTRIBUTE_RECORD_HEADER Attribute,
  1287. IN PUNICODE_STRING AttributeName OPTIONAL,
  1288. IN PVOID ValueOrMappingPairs OPTIONAL,
  1289. IN ULONG Length
  1290. );
  1291. VOID
  1292. NtfsRestartRemoveAttribute (
  1293. IN PIRP_CONTEXT IrpContext,
  1294. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  1295. IN ULONG RecordOffset
  1296. );
  1297. VOID
  1298. NtfsRestartChangeAttributeSize (
  1299. IN PIRP_CONTEXT IrpContext,
  1300. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  1301. IN PATTRIBUTE_RECORD_HEADER Attribute,
  1302. IN ULONG NewRecordLength
  1303. );
  1304. VOID
  1305. NtfsRestartChangeValue (
  1306. IN PIRP_CONTEXT IrpContext,
  1307. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  1308. IN ULONG RecordOffset,
  1309. IN ULONG AttributeOffset,
  1310. IN PVOID Data OPTIONAL,
  1311. IN ULONG Length,
  1312. IN BOOLEAN SetNewLength
  1313. );
  1314. VOID
  1315. NtfsRestartChangeMapping (
  1316. IN PIRP_CONTEXT IrpContext,
  1317. IN PVCB Vcb,
  1318. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  1319. IN ULONG RecordOffset,
  1320. IN ULONG AttributeOffset,
  1321. IN PVOID Data,
  1322. IN ULONG Length
  1323. );
  1324. VOID
  1325. NtfsRestartWriteEndOfFileRecord (
  1326. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  1327. IN PATTRIBUTE_RECORD_HEADER OldAttribute,
  1328. IN PATTRIBUTE_RECORD_HEADER NewAttributes,
  1329. IN ULONG SizeOfNewAttributes
  1330. );
  1331. //
  1332. // Bitmap support routines. Implemented in BitmpSup.c
  1333. //
  1334. //
  1335. // The following routines are used for allocating and deallocating clusters
  1336. // on the disk. The first routine initializes the allocation support
  1337. // routines and must be called for each newly mounted/verified volume.
  1338. // The next two routines allocate and deallocate clusters via Mcbs.
  1339. // The last three routines are simple query routines.
  1340. //
  1341. VOID
  1342. NtfsInitializeClusterAllocation (
  1343. IN PIRP_CONTEXT IrpContext,
  1344. IN PVCB Vcb
  1345. );
  1346. BOOLEAN
  1347. NtfsAllocateClusters (
  1348. IN PIRP_CONTEXT IrpContext,
  1349. IN PVCB Vcb,
  1350. IN OUT PSCB Scb,
  1351. IN VCN StartingVcn,
  1352. IN BOOLEAN AllocateAll,
  1353. IN LONGLONG ClusterCount,
  1354. IN PLCN TargetLcn OPTIONAL,
  1355. IN OUT PLONGLONG DesiredClusterCount
  1356. );
  1357. VOID
  1358. NtfsAddBadCluster (
  1359. IN PIRP_CONTEXT IrpContext,
  1360. IN PVCB Vcb,
  1361. IN LCN Lcn
  1362. );
  1363. BOOLEAN
  1364. NtfsDeallocateClusters (
  1365. IN PIRP_CONTEXT IrpContext,
  1366. IN PVCB Vcb,
  1367. IN PSCB Scb,
  1368. IN VCN StartingVcn,
  1369. IN VCN EndingVcn,
  1370. OUT PLONGLONG TotalAllocated OPTIONAL
  1371. );
  1372. VOID
  1373. NtfsPreAllocateClusters (
  1374. IN PIRP_CONTEXT IrpContext,
  1375. IN PVCB Vcb,
  1376. IN LCN StartingLcn,
  1377. IN LONGLONG ClusterCount,
  1378. OUT PBOOLEAN AcquiredBitmap,
  1379. OUT PBOOLEAN AcquiredMft
  1380. );
  1381. VOID
  1382. NtfsCleanupClusterAllocationHints (
  1383. IN PIRP_CONTEXT IrpContext,
  1384. IN PVCB Vcb,
  1385. IN PNTFS_MCB Mcb
  1386. );
  1387. VOID
  1388. NtfsScanEntireBitmap (
  1389. IN PIRP_CONTEXT IrpContext,
  1390. IN PVCB Vcb,
  1391. IN LOGICAL CachedRunsOnly
  1392. );
  1393. VOID
  1394. NtfsModifyBitsInBitmap (
  1395. IN PIRP_CONTEXT IrpContext,
  1396. IN PVCB Vcb,
  1397. IN LONGLONG FirstBit,
  1398. IN LONGLONG BeyondFinalBit,
  1399. IN ULONG RedoOperation,
  1400. IN ULONG UndoOperation
  1401. );
  1402. typedef enum _NTFS_RUN_STATE {
  1403. RunStateUnknown = 1,
  1404. RunStateFree,
  1405. RunStateAllocated
  1406. } NTFS_RUN_STATE;
  1407. typedef NTFS_RUN_STATE *PNTFS_RUN_STATE;
  1408. BOOLEAN
  1409. NtfsAddCachedRun (
  1410. IN PIRP_CONTEXT IrpContext,
  1411. IN PVCB Vcb,
  1412. IN LCN StartingLcn,
  1413. IN LONGLONG ClusterCount,
  1414. IN NTFS_RUN_STATE RunState
  1415. );
  1416. //
  1417. // The following two routines are called at Restart to make bitmap
  1418. // operations in the volume bitmap recoverable.
  1419. //
  1420. VOID
  1421. NtfsRestartSetBitsInBitMap (
  1422. IN PIRP_CONTEXT IrpContext,
  1423. IN PRTL_BITMAP Bitmap,
  1424. IN ULONG BitMapOffset,
  1425. IN ULONG NumberOfBits
  1426. );
  1427. VOID
  1428. NtfsRestartClearBitsInBitMap (
  1429. IN PIRP_CONTEXT IrpContext,
  1430. IN PRTL_BITMAP Bitmap,
  1431. IN ULONG BitMapOffset,
  1432. IN ULONG NumberOfBits
  1433. );
  1434. //
  1435. // The following routines are for allocating and deallocating records
  1436. // based on a bitmap attribute (e.g., allocating mft file records based on
  1437. // the bitmap attribute of the mft). If necessary the routines will
  1438. // also extend/truncate the data and bitmap attributes to satisfy the
  1439. // operation.
  1440. //
  1441. VOID
  1442. NtfsInitializeRecordAllocation (
  1443. IN PIRP_CONTEXT IrpContext,
  1444. IN PSCB DataScb,
  1445. IN PATTRIBUTE_ENUMERATION_CONTEXT BitmapAttribute,
  1446. IN ULONG BytesPerRecord,
  1447. IN ULONG ExtendGranularity, // In terms of records
  1448. IN ULONG TruncateGranularity, // In terms of records
  1449. IN OUT PRECORD_ALLOCATION_CONTEXT RecordAllocationContext
  1450. );
  1451. VOID
  1452. NtfsUninitializeRecordAllocation (
  1453. IN PIRP_CONTEXT IrpContext,
  1454. IN OUT PRECORD_ALLOCATION_CONTEXT RecordAllocationContext
  1455. );
  1456. ULONG
  1457. NtfsAllocateRecord (
  1458. IN PIRP_CONTEXT IrpContext,
  1459. IN PRECORD_ALLOCATION_CONTEXT RecordAllocationContext,
  1460. IN PATTRIBUTE_ENUMERATION_CONTEXT BitmapAttribute
  1461. );
  1462. VOID
  1463. NtfsDeallocateRecord (
  1464. IN PIRP_CONTEXT IrpContext,
  1465. IN PRECORD_ALLOCATION_CONTEXT RecordAllocationContext,
  1466. IN ULONG Index,
  1467. IN PATTRIBUTE_ENUMERATION_CONTEXT BitmapAttribute
  1468. );
  1469. VOID
  1470. NtfsReserveMftRecord (
  1471. IN PIRP_CONTEXT IrpContext,
  1472. IN OUT PVCB Vcb,
  1473. IN PATTRIBUTE_ENUMERATION_CONTEXT BitmapAttribute
  1474. );
  1475. ULONG
  1476. NtfsAllocateMftReservedRecord (
  1477. IN OUT PIRP_CONTEXT IrpContext,
  1478. IN OUT PVCB Vcb,
  1479. IN PATTRIBUTE_ENUMERATION_CONTEXT BitmapAttribute
  1480. );
  1481. VOID
  1482. NtfsDeallocateRecordsComplete (
  1483. IN PIRP_CONTEXT IrpContext
  1484. );
  1485. BOOLEAN
  1486. NtfsIsRecordAllocated (
  1487. IN PIRP_CONTEXT IrpContext,
  1488. IN PRECORD_ALLOCATION_CONTEXT RecordAllocationContext,
  1489. IN ULONG Index,
  1490. IN PATTRIBUTE_ENUMERATION_CONTEXT BitmapAttribute
  1491. );
  1492. VOID
  1493. NtfsScanMftBitmap (
  1494. IN PIRP_CONTEXT IrpContext,
  1495. IN OUT PVCB Vcb
  1496. );
  1497. BOOLEAN
  1498. NtfsCreateMftHole (
  1499. IN PIRP_CONTEXT IrpContext,
  1500. IN PVCB Vcb
  1501. );
  1502. BOOLEAN
  1503. NtfsFindMftFreeTail (
  1504. IN PIRP_CONTEXT IrpContext,
  1505. IN PVCB Vcb,
  1506. OUT PLONGLONG FileOffset
  1507. );
  1508. //
  1509. // Routines to handle the cached runs.
  1510. //
  1511. VOID
  1512. NtfsInitializeCachedRuns (
  1513. IN PNTFS_CACHED_RUNS CachedRuns
  1514. );
  1515. VOID
  1516. NtfsReinitializeCachedRuns (
  1517. IN PNTFS_CACHED_RUNS CachedRuns
  1518. );
  1519. VOID
  1520. NtfsUninitializeCachedRuns (
  1521. IN PNTFS_CACHED_RUNS CachedRuns
  1522. );
  1523. //
  1524. // Buffer control routines for data caching using internal attribute
  1525. // streams implemented in CacheSup.c
  1526. //
  1527. #define NtfsCreateInternalAttributeStream(IC,S,U,NM) { \
  1528. NtfsCreateInternalStreamCommon((IC),(S),(U),FALSE,(NM)); \
  1529. }
  1530. #define NtfsCreateInternalCompressedStream(IC,S,U,NM) { \
  1531. NtfsCreateInternalStreamCommon((IC),(S),(U),TRUE,(NM)); \
  1532. }
  1533. #define NtfsClearInternalFilename(_FileObject) { \
  1534. (_FileObject)->FileName.MaximumLength = 0; \
  1535. (_FileObject)->FileName.Length = 0; \
  1536. (_FileObject)->FileName.Buffer = NULL; \
  1537. }
  1538. VOID
  1539. NtfsCreateInternalStreamCommon (
  1540. IN PIRP_CONTEXT IrpContext,
  1541. IN PSCB Scb,
  1542. IN BOOLEAN UpdateScb,
  1543. IN BOOLEAN CompressedStream,
  1544. IN UNICODE_STRING const *StreamName
  1545. );
  1546. BOOLEAN
  1547. NtfsDeleteInternalAttributeStream (
  1548. IN PSCB Scb,
  1549. IN ULONG ForceClose,
  1550. IN ULONG CompressedStreamOnly
  1551. );
  1552. //
  1553. // The following routines provide direct access to data in an attribute.
  1554. //
  1555. VOID
  1556. NtfsMapStream (
  1557. IN PIRP_CONTEXT IrpContext,
  1558. IN PSCB Scb,
  1559. IN LONGLONG FileOffset,
  1560. IN ULONG Length,
  1561. OUT PVOID *Bcb,
  1562. OUT PVOID *Buffer
  1563. );
  1564. VOID
  1565. NtfsPinMappedData (
  1566. IN PIRP_CONTEXT IrpContext,
  1567. IN PSCB Scb,
  1568. IN LONGLONG FileOffset,
  1569. IN ULONG Length,
  1570. IN OUT PVOID *Bcb
  1571. );
  1572. VOID
  1573. NtfsPinStream (
  1574. IN PIRP_CONTEXT IrpContext,
  1575. IN PSCB Scb,
  1576. IN LONGLONG FileOffset,
  1577. IN ULONG Length,
  1578. OUT PVOID *Bcb,
  1579. OUT PVOID *Buffer
  1580. );
  1581. VOID
  1582. NtfsPreparePinWriteStream (
  1583. IN PIRP_CONTEXT IrpContext,
  1584. IN PSCB Scb,
  1585. IN LONGLONG FileOffset,
  1586. IN ULONG Length,
  1587. IN BOOLEAN Zero,
  1588. OUT PVOID *Bcb,
  1589. OUT PVOID *Buffer
  1590. );
  1591. NTSTATUS
  1592. NtfsCompleteMdl (
  1593. IN PIRP_CONTEXT IrpContext,
  1594. IN PIRP Irp
  1595. );
  1596. BOOLEAN
  1597. NtfsZeroData (
  1598. IN PIRP_CONTEXT IrpContext,
  1599. IN PSCB Scb,
  1600. IN PFILE_OBJECT FileObject,
  1601. IN LONGLONG StartingZero,
  1602. IN LONGLONG ByteCount,
  1603. IN OUT PLONGLONG CommittedFileSize OPTIONAL
  1604. );
  1605. //
  1606. // The following is needed when biasing the SetFileSizes call for the Usn Journal.
  1607. //
  1608. // VOID
  1609. // NtfsSetCcFileSizes (
  1610. // IN PFILE_OBJECT FileObject,
  1611. // IN PSCB Scb,
  1612. // IN PCC_FILE_SIZES CcSizes
  1613. // );
  1614. //
  1615. #define NtfsSetCcFileSizes(FO,S,CC) { \
  1616. if (FlagOn( (S)->ScbPersist, SCB_PERSIST_USN_JOURNAL )) { \
  1617. CC_FILE_SIZES _CcSizes; \
  1618. RtlCopyMemory( &_CcSizes, (CC), sizeof( CC_FILE_SIZES )); \
  1619. _CcSizes.AllocationSize.QuadPart -= (S)->Vcb->UsnCacheBias; \
  1620. _CcSizes.FileSize.QuadPart -= (S)->Vcb->UsnCacheBias; \
  1621. CcSetFileSizes( (FO), &_CcSizes ); \
  1622. } else { \
  1623. CcSetFileSizes( (FO), (CC) ); \
  1624. } \
  1625. }
  1626. //
  1627. // VOID
  1628. // NtfsFreeBcb (
  1629. // IN PIRP_CONTEXT IrpContext,
  1630. // IN OUT PBCB *Bcb
  1631. // );
  1632. //
  1633. // VOID
  1634. // NtfsUnpinBcb (
  1635. // IN PIRP_CONTEXT IrpContext,
  1636. // IN OUT PBCB *Bcb,
  1637. // );
  1638. //
  1639. #define NtfsFreeBcb(IC,BC) { \
  1640. ASSERT_IRP_CONTEXT(IC); \
  1641. if (*(BC) != NULL) \
  1642. { \
  1643. CcFreePinnedData(*(BC)); \
  1644. *(BC) = NULL; \
  1645. } \
  1646. }
  1647. #ifdef MAPCOUNT_DBG
  1648. #define NtfsUnpinBcb(IC,BC) { \
  1649. if (*(BC) != NULL) \
  1650. { \
  1651. CcUnpinData(*(BC)); \
  1652. (IC)->MapCount--; \
  1653. *(BC) = NULL; \
  1654. } \
  1655. }
  1656. #else
  1657. #define NtfsUnpinBcb(IC,BC) { \
  1658. if (*(BC) != NULL) \
  1659. { \
  1660. CcUnpinData(*(BC)); \
  1661. *(BC) = NULL; \
  1662. } \
  1663. }
  1664. #endif
  1665. #ifdef MAPCOUNT_DBG
  1666. #define NtfsUnpinBcbForThread(IC,BC,T) { \
  1667. if (*(BC) != NULL) \
  1668. { \
  1669. CcUnpinDataForThread(*(BC), (T)); \
  1670. (IC)->MapCount--; \
  1671. *(BC) = NULL; \
  1672. } \
  1673. }
  1674. #else
  1675. #define NtfsUnpinBcbForThread(IC,BC,T) { \
  1676. if (*(BC) != NULL) \
  1677. { \
  1678. CcUnpinDataForThread(*(BC), (T)); \
  1679. *(BC) = NULL; \
  1680. } \
  1681. }
  1682. #endif
  1683. INLINE
  1684. PBCB
  1685. NtfsRemapBcb (
  1686. IN PIRP_CONTEXT IrpContext,
  1687. IN PBCB Bcb
  1688. )
  1689. {
  1690. UNREFERENCED_PARAMETER( IrpContext );
  1691. #ifdef MAPCOUNT_DBG
  1692. IrpContext->MapCount++;
  1693. #endif
  1694. return CcRemapBcb( Bcb );
  1695. }
  1696. //
  1697. // Ntfs structure check routines in CheckSup.c
  1698. //
  1699. BOOLEAN
  1700. NtfsCheckFileRecord (
  1701. IN PVCB Vcb,
  1702. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  1703. IN PFILE_REFERENCE FileReference OPTIONAL,
  1704. OUT PULONG CorruptionHint
  1705. );
  1706. BOOLEAN
  1707. NtfsCheckAttributeRecord (
  1708. IN PVCB Vcb,
  1709. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  1710. IN PATTRIBUTE_RECORD_HEADER Attribute,
  1711. IN ULONG CheckHeaderOnly,
  1712. OUT PULONG CorruptionHint
  1713. );
  1714. BOOLEAN
  1715. NtfsCheckIndexRoot (
  1716. IN PVCB Vcb,
  1717. IN PINDEX_ROOT IndexRoot,
  1718. IN ULONG AttributeSize
  1719. );
  1720. BOOLEAN
  1721. NtfsCheckIndexBuffer (
  1722. IN PSCB Scb,
  1723. IN PINDEX_ALLOCATION_BUFFER IndexBuffer
  1724. );
  1725. BOOLEAN
  1726. NtfsCheckIndexHeader (
  1727. IN PINDEX_HEADER IndexHeader,
  1728. IN ULONG BytesAvailable
  1729. );
  1730. BOOLEAN
  1731. NtfsCheckLogRecord (
  1732. IN PNTFS_LOG_RECORD_HEADER LogRecord,
  1733. IN ULONG LogRecordLength,
  1734. IN TRANSACTION_ID TransactionId,
  1735. IN ULONG AttributeEntrySize
  1736. );
  1737. BOOLEAN
  1738. NtfsCheckRestartTable (
  1739. IN PRESTART_TABLE RestartTable,
  1740. IN ULONG TableSize
  1741. );
  1742. //
  1743. // Collation routines, implemented in ColatSup.c
  1744. //
  1745. // These routines perform low-level collation operations, primarily
  1746. // for IndexSup. All of these routines are dispatched to via dispatch
  1747. // tables indexed by the collation rule. The dispatch tables are
  1748. // defined here, and the actual implementations are in colatsup.c
  1749. //
  1750. typedef
  1751. FSRTL_COMPARISON_RESULT
  1752. (*PCOMPARE_VALUES) (
  1753. IN PWCH UnicodeTable,
  1754. IN ULONG UnicodeTableSize,
  1755. IN PVOID Value,
  1756. IN PINDEX_ENTRY IndexEntry,
  1757. IN FSRTL_COMPARISON_RESULT WildCardIs,
  1758. IN BOOLEAN IgnoreCase
  1759. );
  1760. typedef
  1761. BOOLEAN
  1762. (*PIS_IN_EXPRESSION) (
  1763. IN PWCH UnicodeTable,
  1764. IN PVOID Value,
  1765. IN PINDEX_ENTRY IndexEntry,
  1766. IN BOOLEAN IgnoreCase
  1767. );
  1768. typedef
  1769. BOOLEAN
  1770. (*PARE_EQUAL) (
  1771. IN PWCH UnicodeTable,
  1772. IN PVOID Value,
  1773. IN PINDEX_ENTRY IndexEntry,
  1774. IN BOOLEAN IgnoreCase
  1775. );
  1776. typedef
  1777. BOOLEAN
  1778. (*PCONTAINS_WILDCARD) (
  1779. IN PVOID Value
  1780. );
  1781. typedef
  1782. VOID
  1783. (*PUPCASE_VALUE) (
  1784. IN PWCH UnicodeTable,
  1785. IN ULONG UnicodeTableSize,
  1786. IN OUT PVOID Value
  1787. );
  1788. extern PCOMPARE_VALUES NtfsCompareValues[COLLATION_NUMBER_RULES];
  1789. extern PIS_IN_EXPRESSION NtfsIsInExpression[COLLATION_NUMBER_RULES];
  1790. extern PARE_EQUAL NtfsIsEqual[COLLATION_NUMBER_RULES];
  1791. extern PCONTAINS_WILDCARD NtfsContainsWildcards[COLLATION_NUMBER_RULES];
  1792. extern PUPCASE_VALUE NtfsUpcaseValue[COLLATION_NUMBER_RULES];
  1793. BOOLEAN
  1794. NtfsFileNameIsInExpression (
  1795. IN PWCH UnicodeTable,
  1796. IN PFILE_NAME ExpressionName,
  1797. IN PFILE_NAME FileName,
  1798. IN BOOLEAN IgnoreCase
  1799. );
  1800. BOOLEAN
  1801. NtfsFileNameIsEqual (
  1802. IN PWCH UnicodeTable,
  1803. IN PFILE_NAME ExpressionName,
  1804. IN PFILE_NAME FileName,
  1805. IN BOOLEAN IgnoreCase
  1806. );
  1807. //
  1808. // Compression on the wire routines in CowSup.c
  1809. //
  1810. BOOLEAN
  1811. NtfsCopyReadC (
  1812. IN PFILE_OBJECT FileObject,
  1813. IN PLARGE_INTEGER FileOffset,
  1814. IN ULONG Length,
  1815. IN ULONG LockKey,
  1816. OUT PVOID Buffer,
  1817. OUT PMDL *MdlChain,
  1818. OUT PIO_STATUS_BLOCK IoStatus,
  1819. OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
  1820. IN ULONG CompressedDataInfoLength,
  1821. IN PDEVICE_OBJECT DeviceObject
  1822. );
  1823. NTSTATUS
  1824. NtfsCompressedCopyRead (
  1825. IN PFILE_OBJECT FileObject,
  1826. IN PLARGE_INTEGER FileOffset,
  1827. IN ULONG Length,
  1828. OUT PVOID Buffer,
  1829. OUT PMDL *MdlChain,
  1830. OUT PCOMPRESSED_DATA_INFO CompressedDataInfo,
  1831. IN ULONG CompressedDataInfoLength,
  1832. IN PDEVICE_OBJECT DeviceObject,
  1833. IN PNTFS_ADVANCED_FCB_HEADER Header,
  1834. IN ULONG CompressionUnitSize,
  1835. IN ULONG ChunkSize
  1836. );
  1837. BOOLEAN
  1838. NtfsMdlReadCompleteCompressed (
  1839. IN struct _FILE_OBJECT *FileObject,
  1840. IN PMDL MdlChain,
  1841. IN struct _DEVICE_OBJECT *DeviceObject
  1842. );
  1843. BOOLEAN
  1844. NtfsCopyWriteC (
  1845. IN PFILE_OBJECT FileObject,
  1846. IN PLARGE_INTEGER FileOffset,
  1847. IN ULONG Length,
  1848. IN ULONG LockKey,
  1849. IN PVOID Buffer,
  1850. OUT PMDL *MdlChain,
  1851. OUT PIO_STATUS_BLOCK IoStatus,
  1852. IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
  1853. IN ULONG CompressedDataInfoLength,
  1854. IN PDEVICE_OBJECT DeviceObject
  1855. );
  1856. NTSTATUS
  1857. NtfsCompressedCopyWrite (
  1858. IN PFILE_OBJECT FileObject,
  1859. IN PLARGE_INTEGER FileOffset,
  1860. IN ULONG Length,
  1861. IN PVOID Buffer,
  1862. OUT PMDL *MdlChain,
  1863. IN PCOMPRESSED_DATA_INFO CompressedDataInfo,
  1864. IN PDEVICE_OBJECT DeviceObject,
  1865. IN PNTFS_ADVANCED_FCB_HEADER Header,
  1866. IN ULONG CompressionUnitSize,
  1867. IN ULONG ChunkSize,
  1868. IN ULONG EngineMatches
  1869. );
  1870. BOOLEAN
  1871. NtfsMdlWriteCompleteCompressed (
  1872. IN struct _FILE_OBJECT *FileObject,
  1873. IN PLARGE_INTEGER FileOffset,
  1874. IN PMDL MdlChain,
  1875. IN struct _DEVICE_OBJECT *DeviceObject
  1876. );
  1877. NTSTATUS
  1878. NtfsSynchronizeUncompressedIo (
  1879. IN PSCB Scb,
  1880. IN PLONGLONG FileOffset OPTIONAL,
  1881. IN ULONG Length,
  1882. IN ULONG WriteAccess,
  1883. IN OUT PCOMPRESSION_SYNC *CompressionSync
  1884. );
  1885. NTSTATUS
  1886. NtfsSynchronizeCompressedIo (
  1887. IN PSCB Scb,
  1888. IN PLONGLONG FileOffset,
  1889. IN ULONG Length,
  1890. IN ULONG WriteAccess,
  1891. IN OUT PCOMPRESSION_SYNC *CompressionSync
  1892. );
  1893. PCOMPRESSION_SYNC
  1894. NtfsAcquireCompressionSync (
  1895. IN LONGLONG FileOffset,
  1896. IN PSCB Scb,
  1897. IN ULONG WriteAccess
  1898. );
  1899. VOID
  1900. NtfsReleaseCompressionSync (
  1901. IN PCOMPRESSION_SYNC CompressionSync
  1902. );
  1903. INLINE
  1904. VOID
  1905. NtfsSetBothCacheSizes (
  1906. IN PFILE_OBJECT FileObject,
  1907. IN PCC_FILE_SIZES FileSizes,
  1908. IN PSCB Scb
  1909. )
  1910. {
  1911. if (Scb->NonpagedScb->SegmentObject.SharedCacheMap != NULL) {
  1912. NtfsSetCcFileSizes( FileObject, Scb, FileSizes );
  1913. }
  1914. #ifdef COMPRESS_ON_WIRE
  1915. if (Scb->Header.FileObjectC != NULL) {
  1916. CcSetFileSizes( Scb->Header.FileObjectC, FileSizes );
  1917. }
  1918. #endif
  1919. }
  1920. //
  1921. // Device I/O routines, implemented in DevIoSup.c
  1922. //
  1923. // These routines perform the actual device read and writes. They only affect
  1924. // the on disk structure and do not alter any other data structures.
  1925. //
  1926. VOID
  1927. NtfsLockUserBuffer (
  1928. IN PIRP_CONTEXT IrpContext,
  1929. IN OUT PIRP Irp,
  1930. IN LOCK_OPERATION Operation,
  1931. IN ULONG BufferLength
  1932. );
  1933. PVOID
  1934. NtfsMapUserBuffer (
  1935. IN OUT PIRP Irp,
  1936. IN MM_PAGE_PRIORITY Priority
  1937. );
  1938. PVOID
  1939. NtfsMapUserBufferNoRaise (
  1940. IN OUT PIRP Irp,
  1941. IN MM_PAGE_PRIORITY Priority
  1942. );
  1943. VOID
  1944. NtfsFillIrpBuffer (
  1945. IN PIRP_CONTEXT IrpContext,
  1946. IN PIRP Irp,
  1947. IN ULONG ByteCount,
  1948. IN ULONG Offset,
  1949. IN UCHAR Pattern
  1950. );
  1951. VOID
  1952. NtfsZeroEndOfSector (
  1953. IN PIRP_CONTEXT IrpContext,
  1954. IN PIRP Irp,
  1955. IN PSCB Scb,
  1956. IN LONGLONG Offset,
  1957. IN BOOLEAN Cached
  1958. );
  1959. NTSTATUS
  1960. NtfsVolumeDasdIo (
  1961. IN PIRP_CONTEXT IrpContext,
  1962. IN PIRP Irp,
  1963. IN PSCB DasdScb,
  1964. IN PCCB Ccb,
  1965. IN VBO StartingVbo,
  1966. IN ULONG ByteCount
  1967. );
  1968. VOID
  1969. NtfsPagingFileIo (
  1970. IN PIRP_CONTEXT IrpContext,
  1971. IN PIRP Irp,
  1972. IN PSCB Scb,
  1973. IN VBO StartingVbo,
  1974. IN ULONG ByteCount
  1975. );
  1976. BOOLEAN
  1977. NtfsIsReadAheadThread (
  1978. );
  1979. //
  1980. // Values for StreamFlags passed to NtfsNonCachedIo, etc.
  1981. //
  1982. #define COMPRESSED_STREAM 0x00000001
  1983. #define ENCRYPTED_STREAM 0x00000002
  1984. NTSTATUS
  1985. NtfsNonCachedIo (
  1986. IN PIRP_CONTEXT IrpContext,
  1987. IN PIRP Irp,
  1988. IN PSCB Scb,
  1989. IN VBO StartingVbo,
  1990. IN ULONG ByteCount,
  1991. IN ULONG StreamFlags
  1992. );
  1993. VOID
  1994. NtfsNonCachedNonAlignedIo (
  1995. IN PIRP_CONTEXT IrpContext,
  1996. IN PIRP Irp,
  1997. IN PSCB Scb,
  1998. IN VBO StartingVbo,
  1999. IN ULONG ByteCount
  2000. );
  2001. #ifdef EFSDBG
  2002. NTSTATUS
  2003. NtfsDummyEfsRead (
  2004. IN OUT PUCHAR InOutBuffer,
  2005. IN PLARGE_INTEGER Offset,
  2006. IN ULONG BufferSize,
  2007. IN PVOID Context
  2008. );
  2009. NTSTATUS
  2010. NtfsDummyEfsWrite (
  2011. IN PUCHAR InBuffer,
  2012. OUT PUCHAR OutBuffer,
  2013. IN PLARGE_INTEGER Offset,
  2014. IN ULONG BufferSize,
  2015. IN PUCHAR Context
  2016. );
  2017. #endif
  2018. VOID
  2019. NtfsTransformUsaBlock (
  2020. IN PSCB Scb,
  2021. IN OUT PVOID SystemBuffer,
  2022. IN OUT PVOID Buffer,
  2023. IN ULONG Length
  2024. );
  2025. VOID
  2026. NtfsCreateMdlAndBuffer (
  2027. IN PIRP_CONTEXT IrpContext,
  2028. IN PSCB ThisScb,
  2029. IN UCHAR NeedTwoBuffers,
  2030. IN OUT PULONG Length,
  2031. OUT PMDL *Mdl OPTIONAL,
  2032. OUT PVOID *Buffer
  2033. );
  2034. VOID
  2035. NtfsDeleteMdlAndBuffer (
  2036. IN PMDL Mdl OPTIONAL,
  2037. IN PVOID Buffer OPTIONAL
  2038. );
  2039. VOID
  2040. NtfsWriteClusters (
  2041. IN PIRP_CONTEXT IrpContext,
  2042. IN PVCB Vcb,
  2043. IN PSCB Scb,
  2044. IN VBO StartingVbo,
  2045. IN PVOID Buffer,
  2046. IN ULONG ClusterCount
  2047. );
  2048. BOOLEAN
  2049. NtfsVerifyAndRevertUsaBlock (
  2050. IN PIRP_CONTEXT IrpContext,
  2051. IN PSCB Scb,
  2052. IN PIRP Irp OPTIONAL,
  2053. IN PVOID SystemBuffer OPTIONAL,
  2054. IN ULONG Offset,
  2055. IN ULONG Length,
  2056. IN LONGLONG FileOffset
  2057. );
  2058. NTSTATUS
  2059. NtfsDefragFile (
  2060. IN PIRP_CONTEXT IrpContext,
  2061. IN PIRP Irp
  2062. );
  2063. NTSTATUS
  2064. NtfsReadFromPlex(
  2065. IN PIRP_CONTEXT IrpContext,
  2066. IN PIRP Irp
  2067. );
  2068. //
  2069. // The following support routines are contained int Ea.c
  2070. //
  2071. PFILE_FULL_EA_INFORMATION
  2072. NtfsMapExistingEas (
  2073. IN PIRP_CONTEXT IrpContext,
  2074. IN PFCB Fcb,
  2075. OUT PBCB *EaBcb,
  2076. OUT PULONG EaLength
  2077. );
  2078. NTSTATUS
  2079. NtfsBuildEaList (
  2080. IN PIRP_CONTEXT IrpContext,
  2081. IN PVCB Vcb,
  2082. IN OUT PEA_LIST_HEADER EaListHeader,
  2083. IN PFILE_FULL_EA_INFORMATION UserEaList,
  2084. OUT PULONG_PTR ErrorOffset
  2085. );
  2086. VOID
  2087. NtfsReplaceFileEas (
  2088. IN PIRP_CONTEXT IrpContext,
  2089. IN PFCB Fcb,
  2090. IN PEA_LIST_HEADER EaList
  2091. );
  2092. //
  2093. // The following routines are used to manipulate the fscontext fields
  2094. // of the file object, implemented in FilObSup.c
  2095. //
  2096. typedef enum _TYPE_OF_OPEN {
  2097. UnopenedFileObject = 1,
  2098. UserFileOpen,
  2099. UserDirectoryOpen,
  2100. UserVolumeOpen,
  2101. StreamFileOpen,
  2102. UserViewIndexOpen
  2103. } TYPE_OF_OPEN;
  2104. VOID
  2105. NtfsSetFileObject (
  2106. IN PFILE_OBJECT FileObject,
  2107. IN TYPE_OF_OPEN TypeOfOpen,
  2108. IN PSCB Scb,
  2109. IN PCCB Ccb OPTIONAL
  2110. );
  2111. //
  2112. // TYPE_OF_OPEN
  2113. // NtfsDecodeFileObject (
  2114. // IN PIRP_CONTEXT IrpContext,
  2115. // IN PFILE_OBJECT FileObject,
  2116. // OUT PVCB *Vcb,
  2117. // OUT PFCB *Fcb,
  2118. // OUT PSCB *Scb,
  2119. // OUT PCCB *Ccb,
  2120. // IN BOOLEAN RaiseOnError
  2121. // );
  2122. //
  2123. #ifdef _DECODE_MACRO_
  2124. #define NtfsDecodeFileObject(IC,FO,V,F,S,C,R) ( \
  2125. ( *(S) = (PSCB)(FO)->FsContext), \
  2126. ((*(S) != NULL) \
  2127. ? ((*(V) = (*(S))->Vcb), \
  2128. (*(C) = (PCCB)(FO)->FsContext2), \
  2129. (*(F) = (*(S))->Fcb), \
  2130. ((R) \
  2131. && !FlagOn((*(V))->VcbState, VCB_STATE_VOLUME_MOUNTED) \
  2132. && ((*(C) == NULL) \
  2133. || ((*(C))->TypeOfOpen != UserVolumeOpen) \
  2134. || !FlagOn((*(V))->VcbState, VCB_STATE_LOCKED)) \
  2135. && NtfsRaiseStatusFunction((IC), (STATUS_VOLUME_DISMOUNTED))), \
  2136. ((*(C) == NULL) \
  2137. ? StreamFileOpen \
  2138. : (*(C))->TypeOfOpen)) \
  2139. : (*(C) = NULL, \
  2140. UnopenedFileObject)) \
  2141. )
  2142. #else // _DECODE_MACRO_
  2143. INLINE TYPE_OF_OPEN
  2144. NtfsDecodeFileObject (
  2145. IN PIRP_CONTEXT IrpContext,
  2146. IN PFILE_OBJECT FileObject,
  2147. OUT PVCB *Vcb,
  2148. OUT PFCB *Fcb,
  2149. OUT PSCB *Scb,
  2150. OUT PCCB *Ccb,
  2151. IN BOOLEAN RaiseOnError
  2152. )
  2153. /*++
  2154. Routine Description:
  2155. This routine decodes a file object into a Vcb, Fcb, Scb, and Ccb.
  2156. Arguments:
  2157. IrpContext - The Irp context to use for raising on an error.
  2158. FileObject - The file object to decode.
  2159. Vcb - Where to store the Vcb.
  2160. Fcb - Where to store the Fcb.
  2161. Scb - Where to store the Scb.
  2162. Ccb - Where to store the Ccb.
  2163. RaiseOnError - If FALSE, we do not raise if we encounter an error.
  2164. Otherwise we do raise if we encounter an error.
  2165. Return Value:
  2166. Type of open
  2167. --*/
  2168. {
  2169. *Scb = (PSCB)FileObject->FsContext;
  2170. if (*Scb != NULL) {
  2171. *Vcb = (*Scb)->Vcb;
  2172. *Ccb = (PCCB)FileObject->FsContext2;
  2173. *Fcb = (*Scb)->Fcb;
  2174. //
  2175. // If the caller wants us to raise, let's see if there's anything
  2176. // we should raise.
  2177. //
  2178. if (RaiseOnError &&
  2179. !FlagOn((*Vcb)->VcbState, VCB_STATE_VOLUME_MOUNTED) &&
  2180. ((*Ccb == NULL) ||
  2181. ((*Ccb)->TypeOfOpen != UserVolumeOpen) ||
  2182. !FlagOn((*Vcb)->VcbState, VCB_STATE_LOCKED))) {
  2183. NtfsRaiseStatusFunction( IrpContext, STATUS_VOLUME_DISMOUNTED );
  2184. }
  2185. //
  2186. // Every open except a StreamFileOpen has a Ccb.
  2187. //
  2188. if (*Ccb == NULL) {
  2189. return StreamFileOpen;
  2190. } else {
  2191. return (*Ccb)->TypeOfOpen;
  2192. }
  2193. } else {
  2194. //
  2195. // No Scb, we assume the file wasn't open.
  2196. //
  2197. *Ccb = NULL;
  2198. return UnopenedFileObject;
  2199. }
  2200. }
  2201. #endif // _DECODE_MACRO_
  2202. //
  2203. // PSCB
  2204. // NtfsFastDecodeUserFileOpen (
  2205. // IN PFILE_OBJECT FileObject
  2206. // );
  2207. //
  2208. #define NtfsFastDecodeUserFileOpen(FO) ( \
  2209. (((FO)->FsContext2 != NULL) && (((PCCB)(FO)->FsContext2)->TypeOfOpen == UserFileOpen)) ? \
  2210. (PSCB)(FO)->FsContext : NULL \
  2211. )
  2212. VOID
  2213. NtfsUpdateScbFromFileObject (
  2214. IN PIRP_CONTEXT IrpContext,
  2215. IN PFILE_OBJECT FileObject,
  2216. IN PSCB Scb,
  2217. IN BOOLEAN CheckTimeStamps
  2218. );
  2219. //
  2220. // Ntfs-private FastIo routines.
  2221. //
  2222. BOOLEAN
  2223. NtfsCopyReadA (
  2224. IN PFILE_OBJECT FileObject,
  2225. IN PLARGE_INTEGER FileOffset,
  2226. IN ULONG Length,
  2227. IN BOOLEAN Wait,
  2228. IN ULONG LockKey,
  2229. OUT PVOID Buffer,
  2230. OUT PIO_STATUS_BLOCK IoStatus,
  2231. IN PDEVICE_OBJECT DeviceObject
  2232. );
  2233. BOOLEAN
  2234. NtfsCopyWriteA (
  2235. IN PFILE_OBJECT FileObject,
  2236. IN PLARGE_INTEGER FileOffset,
  2237. IN ULONG Length,
  2238. IN BOOLEAN Wait,
  2239. IN ULONG LockKey,
  2240. IN PVOID Buffer,
  2241. OUT PIO_STATUS_BLOCK IoStatus,
  2242. IN PDEVICE_OBJECT DeviceObject
  2243. );
  2244. BOOLEAN
  2245. NtfsMdlReadA (
  2246. IN PFILE_OBJECT FileObject,
  2247. IN PLARGE_INTEGER FileOffset,
  2248. IN ULONG Length,
  2249. IN ULONG LockKey,
  2250. OUT PMDL *MdlChain,
  2251. OUT PIO_STATUS_BLOCK IoStatus,
  2252. IN PDEVICE_OBJECT DeviceObject
  2253. );
  2254. BOOLEAN
  2255. NtfsPrepareMdlWriteA (
  2256. IN PFILE_OBJECT FileObject,
  2257. IN PLARGE_INTEGER FileOffset,
  2258. IN ULONG Length,
  2259. IN ULONG LockKey,
  2260. OUT PMDL *MdlChain,
  2261. OUT PIO_STATUS_BLOCK IoStatus,
  2262. IN PDEVICE_OBJECT DeviceObject
  2263. );
  2264. BOOLEAN
  2265. NtfsWaitForIoAtEof (
  2266. IN PNTFS_ADVANCED_FCB_HEADER Header,
  2267. IN OUT PLARGE_INTEGER FileOffset,
  2268. IN ULONG Length
  2269. );
  2270. VOID
  2271. NtfsFinishIoAtEof (
  2272. IN PNTFS_ADVANCED_FCB_HEADER Header
  2273. );
  2274. //
  2275. // VOID
  2276. // FsRtlLockFsRtlHeader (
  2277. // IN PNTFS_ADVANCED_FCB_HEADER FsRtlHeader
  2278. // );
  2279. //
  2280. // VOID
  2281. // FsRtlUnlockFsRtlHeader (
  2282. // IN PNTFS_ADVANCED_FCB_HEADER FsRtlHeader
  2283. // );
  2284. //
  2285. #define FsRtlLockFsRtlHeader(H) { \
  2286. ExAcquireFastMutex( (H)->FastMutex ); \
  2287. if (((H)->Flags & FSRTL_FLAG_EOF_ADVANCE_ACTIVE)) { \
  2288. NtfsWaitForIoAtEof( (H), &LiEof, 0 ); \
  2289. } \
  2290. (H)->Flags |= FSRTL_FLAG_EOF_ADVANCE_ACTIVE; \
  2291. ExReleaseFastMutex( (H)->FastMutex ); \
  2292. }
  2293. #define FsRtlUnlockFsRtlHeader(H) { \
  2294. ExAcquireFastMutex( (H)->FastMutex ); \
  2295. NtfsFinishIoAtEof( (H) ); \
  2296. ExReleaseFastMutex( (H)->FastMutex ); \
  2297. }
  2298. //
  2299. // Volume locking/unlocking routines, implemented in FsCtrl.c.
  2300. //
  2301. NTSTATUS
  2302. NtfsLockVolumeInternal (
  2303. IN PIRP_CONTEXT IrpContext,
  2304. IN PVCB Vcb,
  2305. IN PFILE_OBJECT FileObjectWithVcbLocked,
  2306. IN OUT PULONG Retrying
  2307. );
  2308. NTSTATUS
  2309. NtfsUnlockVolumeInternal (
  2310. IN PIRP_CONTEXT IrpContext,
  2311. IN PVCB Vcb
  2312. );
  2313. //
  2314. // Indexing routine interfaces, implemented in IndexSup.c.
  2315. //
  2316. VOID
  2317. NtfsCreateIndex (
  2318. IN PIRP_CONTEXT IrpContext,
  2319. IN OUT PFCB Fcb,
  2320. IN ATTRIBUTE_TYPE_CODE IndexedAttributeType,
  2321. IN COLLATION_RULE CollationRule,
  2322. IN ULONG BytesPerIndexBuffer,
  2323. IN UCHAR BlocksPerIndexBuffer,
  2324. IN PATTRIBUTE_ENUMERATION_CONTEXT Context OPTIONAL,
  2325. IN USHORT AttributeFlags,
  2326. IN BOOLEAN NewIndex,
  2327. IN BOOLEAN LogIt
  2328. );
  2329. VOID
  2330. NtfsUpdateIndexScbFromAttribute (
  2331. IN PIRP_CONTEXT IrpContext,
  2332. IN PSCB Scb,
  2333. IN PATTRIBUTE_RECORD_HEADER IndexRootAttr,
  2334. IN ULONG MustBeFileName
  2335. );
  2336. BOOLEAN
  2337. NtfsFindIndexEntry (
  2338. IN PIRP_CONTEXT IrpContext,
  2339. IN PSCB Scb,
  2340. IN PVOID Value,
  2341. IN BOOLEAN IgnoreCase,
  2342. OUT PQUICK_INDEX QuickIndex OPTIONAL,
  2343. OUT PBCB *Bcb,
  2344. OUT PINDEX_ENTRY *IndexEntry,
  2345. OUT PINDEX_CONTEXT IndexContext OPTIONAL
  2346. );
  2347. VOID
  2348. NtfsUpdateFileNameInIndex (
  2349. IN PIRP_CONTEXT IrpContext,
  2350. IN PSCB Scb,
  2351. IN PFILE_NAME FileName,
  2352. IN PDUPLICATED_INFORMATION Info,
  2353. IN OUT PQUICK_INDEX QuickIndex OPTIONAL
  2354. );
  2355. VOID
  2356. NtfsAddIndexEntry (
  2357. IN PIRP_CONTEXT IrpContext,
  2358. IN PSCB Scb,
  2359. IN PVOID Value,
  2360. IN ULONG ValueLength,
  2361. IN PFILE_REFERENCE FileReference,
  2362. IN PINDEX_CONTEXT IndexContext OPTIONAL,
  2363. OUT PQUICK_INDEX QuickIndex OPTIONAL
  2364. );
  2365. VOID
  2366. NtfsDeleteIndexEntry (
  2367. IN PIRP_CONTEXT IrpContext,
  2368. IN PSCB Scb,
  2369. IN PVOID Value,
  2370. IN PFILE_REFERENCE FileReference
  2371. );
  2372. VOID
  2373. NtfsPushIndexRoot (
  2374. IN PIRP_CONTEXT IrpContext,
  2375. IN PSCB Scb
  2376. );
  2377. BOOLEAN
  2378. NtfsRestartIndexEnumeration (
  2379. IN PIRP_CONTEXT IrpContext,
  2380. IN PCCB Ccb,
  2381. IN PSCB Scb,
  2382. IN PVOID Value,
  2383. IN BOOLEAN IgnoreCase,
  2384. IN BOOLEAN NextFlag,
  2385. OUT PINDEX_ENTRY *IndexEntry,
  2386. IN PFCB AcquiredFcb OPTIONAL
  2387. );
  2388. BOOLEAN
  2389. NtfsContinueIndexEnumeration (
  2390. IN PIRP_CONTEXT IrpContext,
  2391. IN PCCB Ccb,
  2392. IN PSCB Scb,
  2393. IN BOOLEAN NextFlag,
  2394. OUT PINDEX_ENTRY *IndexEntry
  2395. );
  2396. PFILE_NAME
  2397. NtfsRetrieveOtherFileName (
  2398. IN PIRP_CONTEXT IrpContext,
  2399. IN PCCB Ccb,
  2400. IN PSCB Scb,
  2401. IN PINDEX_ENTRY IndexEntry,
  2402. IN OUT PINDEX_CONTEXT OtherContext,
  2403. IN PFCB AcquiredFcb OPTIONAL,
  2404. OUT PBOOLEAN SynchronizationError
  2405. );
  2406. VOID
  2407. NtfsCleanupAfterEnumeration (
  2408. IN PIRP_CONTEXT IrpContext,
  2409. IN PCCB Ccb
  2410. );
  2411. BOOLEAN
  2412. NtfsIsIndexEmpty (
  2413. IN PIRP_CONTEXT IrpContext,
  2414. IN PATTRIBUTE_RECORD_HEADER Attribute
  2415. );
  2416. VOID
  2417. NtfsDeleteIndex (
  2418. IN PIRP_CONTEXT IrpContext,
  2419. IN PFCB Fcb,
  2420. IN PUNICODE_STRING AttributeName
  2421. );
  2422. VOID
  2423. NtfsInitializeIndexContext (
  2424. OUT PINDEX_CONTEXT IndexContext
  2425. );
  2426. VOID
  2427. NtfsCleanupIndexContext (
  2428. IN PIRP_CONTEXT IrpContext,
  2429. OUT PINDEX_CONTEXT IndexContext
  2430. );
  2431. VOID
  2432. NtfsReinitializeIndexContext (
  2433. IN PIRP_CONTEXT IrpContext,
  2434. OUT PINDEX_CONTEXT IndexContext
  2435. );
  2436. //
  2437. // PVOID
  2438. // NtfsFoundIndexEntry (
  2439. // IN PIRP_CONTEXT IrpContext,
  2440. // IN PINDEX_ENTRY IndexEntry
  2441. // );
  2442. //
  2443. #define NtfsFoundIndexEntry(IE) ((PVOID) \
  2444. ((PUCHAR) (IE) + sizeof( INDEX_ENTRY )) \
  2445. )
  2446. //
  2447. // Restart routines for IndexSup
  2448. //
  2449. VOID
  2450. NtfsRestartInsertSimpleRoot (
  2451. IN PIRP_CONTEXT IrpContext,
  2452. IN PINDEX_ENTRY InsertIndexEntry,
  2453. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  2454. IN PATTRIBUTE_RECORD_HEADER Attribute,
  2455. IN PINDEX_ENTRY BeforeIndexEntry
  2456. );
  2457. VOID
  2458. NtfsRestartInsertSimpleAllocation (
  2459. IN PINDEX_ENTRY InsertIndexEntry,
  2460. IN PINDEX_ALLOCATION_BUFFER IndexBuffer,
  2461. IN PINDEX_ENTRY BeforeIndexEntry
  2462. );
  2463. VOID
  2464. NtfsRestartWriteEndOfIndex (
  2465. IN PINDEX_HEADER IndexHeader,
  2466. IN PINDEX_ENTRY OverwriteIndexEntry,
  2467. IN PINDEX_ENTRY FirstNewIndexEntry,
  2468. IN ULONG Length
  2469. );
  2470. VOID
  2471. NtfsRestartSetIndexBlock(
  2472. IN PINDEX_ENTRY IndexEntry,
  2473. IN LONGLONG IndexBlock
  2474. );
  2475. VOID
  2476. NtfsRestartUpdateFileName(
  2477. IN PINDEX_ENTRY IndexEntry,
  2478. IN PDUPLICATED_INFORMATION Info
  2479. );
  2480. VOID
  2481. NtfsRestartDeleteSimpleRoot (
  2482. IN PIRP_CONTEXT IrpContext,
  2483. IN PINDEX_ENTRY IndexEntry,
  2484. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  2485. IN PATTRIBUTE_RECORD_HEADER Attribute
  2486. );
  2487. VOID
  2488. NtfsRestartDeleteSimpleAllocation (
  2489. IN PINDEX_ENTRY IndexEntry,
  2490. IN PINDEX_ALLOCATION_BUFFER IndexBuffer
  2491. );
  2492. VOID
  2493. NtOfsRestartUpdateDataInIndex(
  2494. IN PINDEX_ENTRY IndexEntry,
  2495. IN PVOID IndexData,
  2496. IN ULONG Length );
  2497. //
  2498. // Ntfs hashing routines, implemented in HashSup.c
  2499. //
  2500. VOID
  2501. NtfsInitializeHashTable (
  2502. IN OUT PNTFS_HASH_TABLE Table
  2503. );
  2504. VOID
  2505. NtfsUninitializeHashTable (
  2506. IN OUT PNTFS_HASH_TABLE Table
  2507. );
  2508. PLCB
  2509. NtfsFindPrefixHashEntry (
  2510. IN PIRP_CONTEXT IrpContext,
  2511. IN PNTFS_HASH_TABLE Table,
  2512. IN PSCB ParentScb,
  2513. IN OUT PULONG CreateFlags,
  2514. IN OUT PFCB *CurrentFcb,
  2515. OUT PULONG FileHashValue,
  2516. OUT PULONG FileNameLength,
  2517. OUT PULONG ParentHashValue,
  2518. OUT PULONG ParentNameLength,
  2519. IN OUT PUNICODE_STRING RemainingName
  2520. );
  2521. VOID
  2522. NtfsInsertHashEntry (
  2523. IN PNTFS_HASH_TABLE Table,
  2524. IN PLCB HashLcb,
  2525. IN ULONG NameLength,
  2526. IN ULONG HashValue
  2527. );
  2528. VOID
  2529. NtfsRemoveHashEntry (
  2530. IN PNTFS_HASH_TABLE Table,
  2531. IN PLCB HashLcb
  2532. );
  2533. //
  2534. // VOID
  2535. // NtfsRemoveHashEntriesForLcb (
  2536. // IN PLCB Lcb
  2537. // );
  2538. //
  2539. #define NtfsRemoveHashEntriesForLcb(L) { \
  2540. if (FlagOn( (L)->LcbState, LCB_STATE_VALID_HASH_VALUE )) { \
  2541. NtfsRemoveHashEntry( &(L)->Fcb->Vcb->HashTable, \
  2542. (L) ); \
  2543. } \
  2544. }
  2545. //
  2546. // Ntfs Logging Routine interfaces in LogSup.c
  2547. //
  2548. LSN
  2549. NtfsWriteLog (
  2550. IN PIRP_CONTEXT IrpContext,
  2551. IN PSCB Scb,
  2552. IN PBCB Bcb OPTIONAL,
  2553. IN NTFS_LOG_OPERATION RedoOperation,
  2554. IN PVOID RedoBuffer OPTIONAL,
  2555. IN ULONG RedoLength,
  2556. IN NTFS_LOG_OPERATION UndoOperation,
  2557. IN PVOID UndoBuffer OPTIONAL,
  2558. IN ULONG UndoLength,
  2559. IN LONGLONG StreamOffset,
  2560. IN ULONG RecordOffset,
  2561. IN ULONG AttributeOffset,
  2562. IN ULONG StructureSize
  2563. );
  2564. VOID
  2565. NtfsCheckpointVolume (
  2566. IN PIRP_CONTEXT IrpContext,
  2567. IN PVCB Vcb,
  2568. IN BOOLEAN OwnsCheckpoint,
  2569. IN BOOLEAN CleanVolume,
  2570. IN BOOLEAN FlushVolume,
  2571. IN ULONG LfsFlags,
  2572. IN LSN LastKnownLsn
  2573. );
  2574. VOID
  2575. NtfsCheckpointForLogFileFull (
  2576. IN PIRP_CONTEXT IrpContext
  2577. );
  2578. NTSTATUS
  2579. NtfsCheckpointForVolumeSnapshot (
  2580. IN PIRP_CONTEXT IrpContext
  2581. );
  2582. VOID
  2583. NtfsCleanCheckpoint (
  2584. IN PVCB Vcb
  2585. );
  2586. VOID
  2587. NtfsCommitCurrentTransaction (
  2588. IN PIRP_CONTEXT IrpContext
  2589. );
  2590. VOID
  2591. NtfsCheckpointCurrentTransaction (
  2592. IN PIRP_CONTEXT IrpContext
  2593. );
  2594. VOID
  2595. NtfsInitializeLogging (
  2596. );
  2597. VOID
  2598. NtfsStartLogFile (
  2599. IN PSCB LogFileScb,
  2600. IN PVCB Vcb
  2601. );
  2602. VOID
  2603. NtfsStopLogFile (
  2604. IN PVCB Vcb
  2605. );
  2606. VOID
  2607. NtfsInitializeRestartTable (
  2608. IN ULONG EntrySize,
  2609. IN ULONG NumberEntries,
  2610. OUT PRESTART_POINTERS TablePointer
  2611. );
  2612. VOID
  2613. InitializeNewTable (
  2614. IN ULONG EntrySize,
  2615. IN ULONG NumberEntries,
  2616. OUT PRESTART_POINTERS TablePointer
  2617. );
  2618. VOID
  2619. NtfsFreeRestartTable (
  2620. IN PRESTART_POINTERS TablePointer
  2621. );
  2622. VOID
  2623. NtfsExtendRestartTable (
  2624. IN PRESTART_POINTERS TablePointer,
  2625. IN ULONG NumberNewEntries,
  2626. IN ULONG FreeGoal
  2627. );
  2628. ULONG
  2629. NtfsAllocateRestartTableIndex (
  2630. IN PRESTART_POINTERS TablePointer,
  2631. IN ULONG Exclusive
  2632. );
  2633. PVOID
  2634. NtfsAllocateRestartTableFromIndex (
  2635. IN PRESTART_POINTERS TablePointer,
  2636. IN ULONG Index
  2637. );
  2638. VOID
  2639. NtfsFreeRestartTableIndex (
  2640. IN PRESTART_POINTERS TablePointer,
  2641. IN ULONG Index
  2642. );
  2643. PVOID
  2644. NtfsGetFirstRestartTable (
  2645. IN PRESTART_POINTERS TablePointer
  2646. );
  2647. PVOID
  2648. NtfsGetNextRestartTable (
  2649. IN PRESTART_POINTERS TablePointer,
  2650. IN PVOID Current
  2651. );
  2652. VOID
  2653. NtfsUpdateOatVersion (
  2654. IN PVCB Vcb,
  2655. IN ULONG NewRestartVersion
  2656. );
  2657. VOID
  2658. NtfsFreeRecentlyDeallocated (
  2659. IN PIRP_CONTEXT IrpContext,
  2660. IN PVCB Vcb,
  2661. IN PLSN BaseLsn,
  2662. IN ULONG CleanVolume
  2663. );
  2664. //
  2665. //
  2666. // VOID
  2667. // NtfsFreeOpenAttributeData (
  2668. // IN POPEN_ATTRIBUTE_DATA Entry
  2669. // );
  2670. //
  2671. #define NtfsFreeOpenAttributeData(E) { \
  2672. RemoveEntryList( &(E)->Links ); \
  2673. NtfsFreePool( E ); \
  2674. }
  2675. VOID
  2676. NtfsFreeAttributeEntry (
  2677. IN PVCB Vcb,
  2678. IN POPEN_ATTRIBUTE_ENTRY AttributeEntry
  2679. );
  2680. //
  2681. // VOID
  2682. // NtfsNormalizeAndCleanupTransaction (
  2683. // IN PIRP_CONTEXT IrpContext,
  2684. // IN NTSTATUS *Status,
  2685. // IN BOOLEAN AlwaysRaise,
  2686. // IN NTSTATUS NormalizeStatus
  2687. // );
  2688. //
  2689. #define NtfsNormalizeAndCleanupTransaction(IC,PSTAT,RAISE,NORM_STAT) { \
  2690. if (!NT_SUCCESS( (IC)->TopLevelIrpContext->ExceptionStatus )) { \
  2691. NtfsRaiseStatus( (IC), (IC)->TopLevelIrpContext->ExceptionStatus, NULL, NULL ); \
  2692. } else if (!NT_SUCCESS( *(PSTAT) )) { \
  2693. *(PSTAT) = FsRtlNormalizeNtstatus( *(PSTAT), (NORM_STAT) ); \
  2694. if ((RAISE) || ((IC)->TopLevelIrpContext->TransactionId != 0)) { \
  2695. NtfsRaiseStatus( (IC), *(PSTAT), NULL, NULL ); \
  2696. } \
  2697. } \
  2698. }
  2699. //
  2700. // VOID
  2701. // NtfsCleanupTransaction (
  2702. // IN PIRP_CONTEXT IrpContext,
  2703. // IN NTSTATUS Status,
  2704. // IN BOOLEAN AlwaysRaise
  2705. // );
  2706. //
  2707. #define NtfsCleanupTransaction(IC,STAT,RAISE) { \
  2708. if (!NT_SUCCESS( (IC)->TopLevelIrpContext->ExceptionStatus )) { \
  2709. NtfsRaiseStatus( (IC), (IC)->TopLevelIrpContext->ExceptionStatus, NULL, NULL ); \
  2710. } else if (!NT_SUCCESS( STAT ) && \
  2711. ((RAISE) || ((IC)->TopLevelIrpContext->TransactionId != 0))) { \
  2712. NtfsRaiseStatus( (IC), (STAT), NULL, NULL ); \
  2713. } else if (((IC)->Usn.NewReasons != 0) || ((IC)->Usn.RemovedSourceInfo != 0)) { \
  2714. NtfsWriteUsnJournalChanges( (IC) ); \
  2715. NtfsCommitCurrentTransaction( (IC) ); \
  2716. } \
  2717. }
  2718. //
  2719. // VOID
  2720. // NtfsCleanupTransactionAndCommit (
  2721. // IN PIRP_CONTEXT IrpContext,
  2722. // IN NTSTATUS Status,
  2723. // IN BOOLEAN AlwaysRaise
  2724. // );
  2725. //
  2726. #define NtfsCleanupTransactionAndCommit(IC,STAT,RAISE) { \
  2727. if (!NT_SUCCESS( (IC)->TopLevelIrpContext->ExceptionStatus )) { \
  2728. NtfsRaiseStatus( (IC), (IC)->TopLevelIrpContext->ExceptionStatus, NULL, NULL ); \
  2729. } else if (!NT_SUCCESS( STAT ) && \
  2730. ((RAISE) || ((IC)->TopLevelIrpContext->TransactionId != 0))) { \
  2731. NtfsRaiseStatus( (IC), (STAT), NULL, NULL ); \
  2732. } else if (((IC)->Usn.NewReasons != 0) || ((IC)->Usn.RemovedSourceInfo != 0)) { \
  2733. NtfsWriteUsnJournalChanges( (IC) ); \
  2734. NtfsCheckpointCurrentTransaction( (IC) ); \
  2735. } else { \
  2736. NtfsCheckpointCurrentTransaction( (IC) ); \
  2737. } \
  2738. }
  2739. VOID
  2740. NtfsCleanupFailedTransaction (
  2741. IN PIRP_CONTEXT IrpContext
  2742. );
  2743. //
  2744. // NTFS MCB support routine, implemented in McbSup.c
  2745. //
  2746. //
  2747. // An Ntfs Mcb is a superset of the regular mcb package. In
  2748. // addition to the regular Mcb functions it will unload mapping
  2749. // information to keep it overall memory usage down
  2750. //
  2751. VOID
  2752. NtfsInitializeNtfsMcb (
  2753. IN PNTFS_MCB Mcb,
  2754. IN PNTFS_ADVANCED_FCB_HEADER FcbHeader,
  2755. IN PNTFS_MCB_INITIAL_STRUCTS McbStructs,
  2756. IN POOL_TYPE PoolType
  2757. );
  2758. VOID
  2759. NtfsUninitializeNtfsMcb (
  2760. IN PNTFS_MCB Mcb
  2761. );
  2762. VOID
  2763. NtfsRemoveNtfsMcbEntry (
  2764. IN PNTFS_MCB Mcb,
  2765. IN LONGLONG Vcn,
  2766. IN LONGLONG Count
  2767. );
  2768. VOID
  2769. NtfsUnloadNtfsMcbRange (
  2770. IN PNTFS_MCB Mcb,
  2771. IN LONGLONG StartingVcn,
  2772. IN LONGLONG EndingVcn,
  2773. IN BOOLEAN TruncateOnly,
  2774. IN BOOLEAN AlreadySynchronized
  2775. );
  2776. ULONG
  2777. NtfsNumberOfRangesInNtfsMcb (
  2778. IN PNTFS_MCB Mcb
  2779. );
  2780. BOOLEAN
  2781. NtfsNumberOfRunsInRange(
  2782. IN PNTFS_MCB Mcb,
  2783. IN PVOID RangePtr,
  2784. OUT PULONG NumberOfRuns
  2785. );
  2786. BOOLEAN
  2787. NtfsLookupLastNtfsMcbEntry (
  2788. IN PNTFS_MCB Mcb,
  2789. OUT PLONGLONG Vcn,
  2790. OUT PLONGLONG Lcn
  2791. );
  2792. ULONG
  2793. NtfsMcbLookupArrayIndex (
  2794. IN PNTFS_MCB Mcb,
  2795. IN VCN Vcn
  2796. );
  2797. BOOLEAN
  2798. NtfsSplitNtfsMcb (
  2799. IN PNTFS_MCB Mcb,
  2800. IN LONGLONG Vcn,
  2801. IN LONGLONG Amount
  2802. );
  2803. BOOLEAN
  2804. NtfsAddNtfsMcbEntry (
  2805. IN PNTFS_MCB Mcb,
  2806. IN LONGLONG Vcn,
  2807. IN LONGLONG Lcn,
  2808. IN LONGLONG RunCount,
  2809. IN BOOLEAN AlreadySynchronized
  2810. );
  2811. BOOLEAN
  2812. NtfsLookupNtfsMcbEntry (
  2813. IN PNTFS_MCB Mcb,
  2814. IN LONGLONG Vcn,
  2815. OUT PLONGLONG Lcn OPTIONAL,
  2816. OUT PLONGLONG CountFromLcn OPTIONAL,
  2817. OUT PLONGLONG StartingLcn OPTIONAL,
  2818. OUT PLONGLONG CountFromStartingLcn OPTIONAL,
  2819. OUT PVOID *RangePtr OPTIONAL,
  2820. OUT PULONG RunIndex OPTIONAL
  2821. );
  2822. BOOLEAN
  2823. NtfsGetNextNtfsMcbEntry (
  2824. IN PNTFS_MCB Mcb,
  2825. IN PVOID *RangePtr,
  2826. IN ULONG RunIndex,
  2827. OUT PLONGLONG Vcn,
  2828. OUT PLONGLONG Lcn,
  2829. OUT PLONGLONG Count
  2830. );
  2831. //
  2832. // BOOLEAN
  2833. // NtfsGetSequentialMcbEntry (
  2834. // IN PNTFS_MCB Mcb,
  2835. // IN PVOID *RangePtr,
  2836. // IN ULONG RunIndex,
  2837. // OUT PLONGLONG Vcn,
  2838. // OUT PLONGLONG Lcn,
  2839. // OUT PLONGLONG Count
  2840. // );
  2841. //
  2842. #define NtfsGetSequentialMcbEntry(MC,RGI,RNI,V,L,C) ( \
  2843. NtfsGetNextNtfsMcbEntry(MC,RGI,RNI,V,L,C) || \
  2844. (RNI = 0) || \
  2845. NtfsGetNextNtfsMcbEntry(MC,RGI,MAXULONG,V,L,C) || \
  2846. ((RNI = MAXULONG) == 0) \
  2847. )
  2848. VOID
  2849. NtfsDefineNtfsMcbRange (
  2850. IN PNTFS_MCB Mcb,
  2851. IN LONGLONG StartingVcn,
  2852. IN LONGLONG EndingVcn,
  2853. IN BOOLEAN AlreadySynchronized
  2854. );
  2855. VOID
  2856. NtfsSwapMcbs (
  2857. IN PNTFS_MCB McbTarget,
  2858. IN PNTFS_MCB McbSource
  2859. );
  2860. //
  2861. // VOID
  2862. // NtfsAcquireNtfsMcbMutex (
  2863. // IN PNTFS_MCB Mcb
  2864. // );
  2865. //
  2866. // VOID
  2867. // NtfsReleaseNtfsMcbMutex (
  2868. // IN PNTFS_MCB Mcb
  2869. // );
  2870. //
  2871. #define NtfsAcquireNtfsMcbMutex(M) { \
  2872. ExAcquireFastMutex((M)->FastMutex); \
  2873. }
  2874. #define NtfsReleaseNtfsMcbMutex(M) { \
  2875. ExReleaseFastMutex((M)->FastMutex); \
  2876. }
  2877. //
  2878. // MFT access routines, implemented in MftSup.c
  2879. //
  2880. //
  2881. // Mft map cache routines. We maintain a cache of active maps in the
  2882. // IRP_CONTEXT and consult this if we need to map a file record.
  2883. //
  2884. INLINE
  2885. PIRP_FILE_RECORD_CACHE_ENTRY
  2886. NtfsFindFileRecordCacheEntry (
  2887. IN PIRP_CONTEXT IrpContext,
  2888. IN ULONG UnsafeSegmentNumber
  2889. )
  2890. {
  2891. #if (IRP_FILE_RECORD_MAP_CACHE_SIZE <= 4)
  2892. #define PROBECACHE(ic,sn,i) \
  2893. ASSERT((ic)->FileRecordCache[(i)].FileRecordBcb != NULL); \
  2894. if ((ic)->FileRecordCache[(i)].UnsafeSegmentNumber == (sn)) \
  2895. { \
  2896. return IrpContext->FileRecordCache + (i); \
  2897. }
  2898. // DebugTrace( 0, 0, ("Context %08x finding %x\n", IrpContext, UnsafeSegmentNumber ));
  2899. ASSERT(IrpContext->CacheCount <= 4);
  2900. switch (IrpContext->CacheCount) {
  2901. case 4:
  2902. PROBECACHE( IrpContext, UnsafeSegmentNumber, 3 );
  2903. // Fallthru
  2904. case 3:
  2905. PROBECACHE( IrpContext, UnsafeSegmentNumber, 2 );
  2906. // Fallthru
  2907. case 2:
  2908. PROBECACHE( IrpContext, UnsafeSegmentNumber, 1 );
  2909. // Fallthru
  2910. case 1:
  2911. PROBECACHE( IrpContext, UnsafeSegmentNumber, 0 );
  2912. // Fallthru
  2913. case 0:
  2914. //
  2915. // redundant default case (and matching assert above) added to quiet
  2916. // warning 4715:
  2917. //
  2918. // "not all control paths return a value."
  2919. //
  2920. default:
  2921. return NULL;
  2922. }
  2923. #else
  2924. PIRP_FILE_RECORD_CACHE_ENTRY Entry;
  2925. for (Entry = IrpContext->FileRecordCache;
  2926. Entry < IrpContext->FileRecordCache + IrpContext->CacheCount;
  2927. Entry++) {
  2928. ASSERT( Entry->FileRecordBcb != NULL);
  2929. if (Entry->UnsafeSegmentNumber == UnsafeSegmentNumber) {
  2930. return Entry;
  2931. }
  2932. }
  2933. return NULL;
  2934. #endif
  2935. }
  2936. INLINE
  2937. VOID
  2938. NtfsRemoveFromFileRecordCache (
  2939. IN PIRP_CONTEXT IrpContext,
  2940. IN ULONG UnsafeSegmentNumber
  2941. )
  2942. {
  2943. PIRP_FILE_RECORD_CACHE_ENTRY Entry =
  2944. NtfsFindFileRecordCacheEntry( IrpContext, UnsafeSegmentNumber );
  2945. // DebugTrace( 0, 0, ("Context %08x removing %x\n", IrpContext, Entry ));
  2946. if (Entry != NULL) {
  2947. ASSERT( Entry->FileRecordBcb != NULL );
  2948. //
  2949. // We delete the entry at position [i] by dereferencing the Bcb and
  2950. // copying the entire structure from [IrpContext->CacheCount]
  2951. //
  2952. NtfsUnpinBcb( IrpContext, &Entry->FileRecordBcb );
  2953. //
  2954. // Decrement the active count. If there are no more cache entries,
  2955. // then we're done.
  2956. //
  2957. IrpContext->CacheCount--;
  2958. if (IrpContext->FileRecordCache + IrpContext->CacheCount != Entry) {
  2959. *Entry = IrpContext->FileRecordCache[IrpContext->CacheCount];
  2960. }
  2961. }
  2962. }
  2963. #ifndef KDEXT
  2964. INLINE
  2965. VOID
  2966. NtfsAddToFileRecordCache (
  2967. IN PIRP_CONTEXT IrpContext,
  2968. IN ULONG UnsafeSegmentNumber,
  2969. IN PBCB FileRecordBcb,
  2970. IN PFILE_RECORD_SEGMENT_HEADER FileRecord
  2971. )
  2972. {
  2973. PAGED_CODE( );
  2974. if (IrpContext->CacheCount < IRP_FILE_RECORD_MAP_CACHE_SIZE) {
  2975. // DebugTrace( 0, 0, ("Context %08x adding %x at %x\n", IrpContext, UnsafeSegmentNumber,
  2976. // IrpContext->FileRecordCache + IrpContext->CacheCount ));
  2977. IrpContext->FileRecordCache[IrpContext->CacheCount].UnsafeSegmentNumber =
  2978. UnsafeSegmentNumber;
  2979. IrpContext->FileRecordCache[IrpContext->CacheCount].FileRecordBcb =
  2980. NtfsRemapBcb( IrpContext, FileRecordBcb );
  2981. IrpContext->FileRecordCache[IrpContext->CacheCount].FileRecord = FileRecord;
  2982. IrpContext->CacheCount++;
  2983. }
  2984. }
  2985. #endif
  2986. INLINE
  2987. VOID
  2988. NtfsPurgeFileRecordCache (
  2989. IN PIRP_CONTEXT IrpContext
  2990. )
  2991. {
  2992. while (IrpContext->CacheCount) {
  2993. IrpContext->CacheCount --;
  2994. // DebugTrace( 0, 0, ("Context %08x purging %x\n", IrpContext, IrpContext->FileRecordCache + IrpContext->CacheCount ));
  2995. NtfsUnpinBcb( IrpContext, &IrpContext->FileRecordCache[IrpContext->CacheCount].FileRecordBcb );
  2996. }
  2997. }
  2998. #if DBG
  2999. extern ULONG FileRecordCacheHitArray[IRP_FILE_RECORD_MAP_CACHE_SIZE];
  3000. #endif // DBG
  3001. INLINE
  3002. BOOLEAN
  3003. NtfsFindCachedFileRecord (
  3004. IN PIRP_CONTEXT IrpContext,
  3005. IN ULONG UnsafeSegmentNumber,
  3006. OUT PBCB *Bcb,
  3007. OUT PFILE_RECORD_SEGMENT_HEADER *FileRecord
  3008. )
  3009. {
  3010. PIRP_FILE_RECORD_CACHE_ENTRY Entry =
  3011. NtfsFindFileRecordCacheEntry( IrpContext, UnsafeSegmentNumber );
  3012. // DebugTrace( 0, 0, ("Context %x finding %x = %x\n", IrpContext, UnsafeSegmentNumber, Entry ));
  3013. if (Entry == NULL) {
  3014. return FALSE;
  3015. }
  3016. *Bcb = NtfsRemapBcb( IrpContext, Entry->FileRecordBcb );
  3017. *FileRecord = Entry->FileRecord;
  3018. return TRUE;
  3019. }
  3020. //
  3021. // This routine may only be used to read the Base file record segment, and
  3022. // it checks that this is true.
  3023. //
  3024. VOID
  3025. NtfsReadFileRecord (
  3026. IN PIRP_CONTEXT IrpContext,
  3027. IN PVCB Vcb,
  3028. IN PFILE_REFERENCE FileReference,
  3029. OUT PBCB *Bcb,
  3030. OUT PFILE_RECORD_SEGMENT_HEADER *BaseFileRecord,
  3031. OUT PATTRIBUTE_RECORD_HEADER *FirstAttribute,
  3032. OUT PLONGLONG MftFileOffset OPTIONAL
  3033. );
  3034. //
  3035. // These routines can read/pin any record in the MFT.
  3036. //
  3037. VOID
  3038. NtfsReadMftRecord (
  3039. IN PIRP_CONTEXT IrpContext,
  3040. IN PVCB Vcb,
  3041. IN PMFT_SEGMENT_REFERENCE SegmentReference,
  3042. IN BOOLEAN CheckRecord,
  3043. OUT PBCB *Bcb,
  3044. OUT PFILE_RECORD_SEGMENT_HEADER *FileRecord,
  3045. OUT PLONGLONG MftFileOffset OPTIONAL
  3046. );
  3047. VOID
  3048. NtfsPinMftRecord (
  3049. IN PIRP_CONTEXT IrpContext,
  3050. IN PVCB Vcb,
  3051. IN PMFT_SEGMENT_REFERENCE SegmentReference,
  3052. IN BOOLEAN PreparingToWrite,
  3053. OUT PBCB *Bcb,
  3054. OUT PFILE_RECORD_SEGMENT_HEADER *FileRecord,
  3055. OUT PLONGLONG MftFileOffset OPTIONAL
  3056. );
  3057. //
  3058. // The following routines are used to setup, allocate, and deallocate
  3059. // file records in the Mft.
  3060. //
  3061. MFT_SEGMENT_REFERENCE
  3062. NtfsAllocateMftRecord (
  3063. IN PIRP_CONTEXT IrpContext,
  3064. IN PVCB Vcb,
  3065. IN BOOLEAN MftData
  3066. );
  3067. VOID
  3068. NtfsInitializeMftRecord (
  3069. IN PIRP_CONTEXT IrpContext,
  3070. IN PVCB Vcb,
  3071. IN OUT PMFT_SEGMENT_REFERENCE MftSegment,
  3072. IN OUT PFILE_RECORD_SEGMENT_HEADER FileRecord,
  3073. IN PBCB Bcb,
  3074. IN BOOLEAN Directory
  3075. );
  3076. VOID
  3077. NtfsDeallocateMftRecord (
  3078. IN PIRP_CONTEXT IrpContext,
  3079. IN PVCB Vcb,
  3080. IN ULONG FileNumber
  3081. );
  3082. BOOLEAN
  3083. NtfsIsMftIndexInHole (
  3084. IN PIRP_CONTEXT IrpContext,
  3085. IN PVCB Vcb,
  3086. IN ULONG Index,
  3087. OUT PULONG HoleLength OPTIONAL
  3088. );
  3089. VOID
  3090. NtfsFillMftHole (
  3091. IN PIRP_CONTEXT IrpContext,
  3092. IN PVCB Vcb,
  3093. IN ULONG Index
  3094. );
  3095. VOID
  3096. NtfsLogMftFileRecord (
  3097. IN PIRP_CONTEXT IrpContext,
  3098. IN PVCB Vcb,
  3099. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  3100. IN LONGLONG MftOffset,
  3101. IN PBCB FileRecordBcb,
  3102. IN BOOLEAN RedoOperation
  3103. );
  3104. BOOLEAN
  3105. NtfsDefragMft (
  3106. IN PDEFRAG_MFT DefragMft
  3107. );
  3108. VOID
  3109. NtfsCheckForDefrag (
  3110. IN OUT PVCB Vcb
  3111. );
  3112. VOID
  3113. NtfsInitializeMftHoleRecords (
  3114. IN PIRP_CONTEXT IrpContext,
  3115. IN PVCB Vcb,
  3116. IN ULONG FirstIndex,
  3117. IN ULONG RecordCount
  3118. );
  3119. //
  3120. // Name support routines, implemented in NameSup.c
  3121. //
  3122. typedef enum _PARSE_TERMINATION_REASON {
  3123. EndOfPathReached,
  3124. NonSimpleName,
  3125. IllegalCharacterInName,
  3126. MalFormedName,
  3127. AttributeOnly,
  3128. VersionNumberPresent
  3129. } PARSE_TERMINATION_REASON;
  3130. INLINE
  3131. NTSTATUS
  3132. NtfsDissectName(
  3133. IN UNICODE_STRING Path,
  3134. OUT PUNICODE_STRING FirstName,
  3135. OUT PUNICODE_STRING RemainingName
  3136. )
  3137. {
  3138. FsRtlDissectName( Path, FirstName, RemainingName );
  3139. //
  3140. // Remaining name cannot start with a slash
  3141. //
  3142. if ((RemainingName->Length != 0) && (RemainingName->Buffer[0] == L'\\')) {
  3143. return STATUS_OBJECT_NAME_INVALID;
  3144. } else {
  3145. return STATUS_SUCCESS;
  3146. }
  3147. }
  3148. BOOLEAN
  3149. NtfsParseName (
  3150. IN const UNICODE_STRING Name,
  3151. IN BOOLEAN WildCardsPermissible,
  3152. OUT PBOOLEAN FoundIllegalCharacter,
  3153. OUT PNTFS_NAME_DESCRIPTOR ParsedName
  3154. );
  3155. PARSE_TERMINATION_REASON
  3156. NtfsParsePath (
  3157. IN UNICODE_STRING Path,
  3158. IN BOOLEAN WildCardsPermissible,
  3159. OUT PUNICODE_STRING FirstPart,
  3160. OUT PNTFS_NAME_DESCRIPTOR Name,
  3161. OUT PUNICODE_STRING RemainingPart
  3162. );
  3163. VOID
  3164. NtfsPreprocessName (
  3165. IN UNICODE_STRING InputString,
  3166. OUT PUNICODE_STRING FirstPart,
  3167. OUT PUNICODE_STRING AttributeCode,
  3168. OUT PUNICODE_STRING AttributeName,
  3169. OUT PBOOLEAN TrailingBackslash
  3170. );
  3171. VOID
  3172. NtfsUpcaseName (
  3173. IN PWCH UpcaseTable,
  3174. IN ULONG UpcaseTableSize,
  3175. IN OUT PUNICODE_STRING InputString
  3176. );
  3177. FSRTL_COMPARISON_RESULT
  3178. NtfsCollateNames (
  3179. IN PCWCH UpcaseTable,
  3180. IN ULONG UpcaseTableSize,
  3181. IN PCUNICODE_STRING Expression,
  3182. IN PCUNICODE_STRING Name,
  3183. IN FSRTL_COMPARISON_RESULT WildIs,
  3184. IN BOOLEAN IgnoreCase
  3185. );
  3186. #define NtfsIsNameInExpression(UC,EX,NM,IC) \
  3187. FsRtlIsNameInExpression( (EX), (NM), (IC), (UC) )
  3188. BOOLEAN
  3189. NtfsIsFileNameValid (
  3190. IN PUNICODE_STRING FileName,
  3191. IN BOOLEAN WildCardsPermissible
  3192. );
  3193. BOOLEAN
  3194. NtfsIsFatNameValid (
  3195. IN PUNICODE_STRING FileName,
  3196. IN BOOLEAN WildCardsPermissible
  3197. );
  3198. //
  3199. // Ntfs works very hard to make sure that all names are kept in upper case
  3200. // so that most comparisons are done case SENSITIVE. Name testing for
  3201. // case SENSITIVE can be very quick since RtlEqualMemory is an inline operation
  3202. // on several processors.
  3203. //
  3204. // NtfsAreNamesEqual is used when the caller does not know for sure whether
  3205. // or not case is important. In the case where IgnoreCase is a known value,
  3206. // the compiler can easily optimize the relevant clause.
  3207. //
  3208. #define NtfsAreNamesEqual(UpcaseTable,Name1,Name2,IgnoreCase) \
  3209. ((IgnoreCase) ? FsRtlAreNamesEqual( (Name1), (Name2), (IgnoreCase), (UpcaseTable) ) \
  3210. : ((Name1)->Length == (Name2)->Length && \
  3211. RtlEqualMemory( (Name1)->Buffer, (Name2)->Buffer, (Name1)->Length )))
  3212. //
  3213. // Object id support routines, implemented in ObjIdSup.c
  3214. //
  3215. VOID
  3216. NtfsInitializeObjectIdIndex (
  3217. IN PIRP_CONTEXT IrpContext,
  3218. IN PFCB Fcb,
  3219. IN PVCB Vcb
  3220. );
  3221. NTSTATUS
  3222. NtfsSetObjectId (
  3223. IN PIRP_CONTEXT IrpContext,
  3224. IN PIRP Irp
  3225. );
  3226. NTSTATUS
  3227. NtfsSetObjectIdExtendedInfo (
  3228. IN PIRP_CONTEXT IrpContext,
  3229. IN PIRP Irp
  3230. );
  3231. NTSTATUS
  3232. NtfsSetObjectIdInternal (
  3233. IN PIRP_CONTEXT IrpContext,
  3234. IN PFCB Fcb,
  3235. IN PVCB Vcb,
  3236. IN PFILE_OBJECTID_BUFFER ObjectIdBuffer
  3237. );
  3238. NTSTATUS
  3239. NtfsCreateOrGetObjectId (
  3240. IN PIRP_CONTEXT IrpContext,
  3241. IN PIRP Irp
  3242. );
  3243. NTSTATUS
  3244. NtfsGetObjectId (
  3245. IN PIRP_CONTEXT IrpContext,
  3246. IN PIRP Irp
  3247. );
  3248. NTSTATUS
  3249. NtfsGetObjectIdInternal (
  3250. IN PIRP_CONTEXT IrpContext,
  3251. IN PFCB Fcb,
  3252. IN BOOLEAN GetExtendedInfo,
  3253. OUT FILE_OBJECTID_BUFFER *OutputBuffer
  3254. );
  3255. NTSTATUS
  3256. NtfsGetObjectIdExtendedInfo (
  3257. IN PIRP_CONTEXT IrpContext,
  3258. IN PVCB Vcb,
  3259. IN UCHAR *ObjectId,
  3260. IN OUT UCHAR *ExtendedInfo
  3261. );
  3262. NTSTATUS
  3263. NtfsDeleteObjectId (
  3264. IN PIRP_CONTEXT IrpContext,
  3265. IN PIRP Irp
  3266. );
  3267. NTSTATUS
  3268. NtfsDeleteObjectIdInternal (
  3269. IN PIRP_CONTEXT IrpContext,
  3270. IN PFCB Fcb,
  3271. IN PVCB Vcb,
  3272. IN BOOLEAN DeleteFileAttribute
  3273. );
  3274. VOID
  3275. NtfsRepairObjectId (
  3276. IN PIRP_CONTEXT IrpContext,
  3277. IN PVOID Context
  3278. );
  3279. //
  3280. // Mount point support routines, implemented in MountSup.c
  3281. //
  3282. VOID
  3283. NtfsInitializeReparsePointIndex (
  3284. IN PIRP_CONTEXT IrpContext,
  3285. IN PFCB Fcb,
  3286. IN PVCB Vcb
  3287. );
  3288. NTSTATUS
  3289. NtfsValidateReparsePointBuffer (
  3290. IN ULONG BufferLength,
  3291. IN PREPARSE_DATA_BUFFER ReparseBuffer
  3292. );
  3293. //
  3294. // Largest matching prefix searching routines, implemented in PrefxSup.c
  3295. //
  3296. VOID
  3297. NtfsInsertPrefix (
  3298. IN PLCB Lcb,
  3299. IN ULONG CreateFlags
  3300. );
  3301. VOID
  3302. NtfsRemovePrefix (
  3303. IN PLCB Lcb
  3304. );
  3305. PLCB
  3306. NtfsFindPrefix (
  3307. IN PIRP_CONTEXT IrpContext,
  3308. IN PSCB StartingScb,
  3309. OUT PFCB *CurrentFcb,
  3310. OUT PLCB *LcbForTeardown,
  3311. IN OUT UNICODE_STRING FullFileName,
  3312. IN OUT PULONG CreateFlags,
  3313. OUT PUNICODE_STRING RemainingName
  3314. );
  3315. BOOLEAN
  3316. NtfsInsertNameLink (
  3317. IN PRTL_SPLAY_LINKS *RootNode,
  3318. IN PNAME_LINK NameLink
  3319. );
  3320. //
  3321. // VOID
  3322. // NtfsRemoveNameLink (
  3323. // IN PRTL_SPLAY_LINKS *RootNode,
  3324. // IN PNAME_LINK NameLink
  3325. // );
  3326. //
  3327. #define NtfsRemoveNameLink(RN,NL) { \
  3328. *(RN) = RtlDelete( &(NL)->Links ); \
  3329. }
  3330. PNAME_LINK
  3331. NtfsFindNameLink (
  3332. IN PRTL_SPLAY_LINKS *RootNode,
  3333. IN PUNICODE_STRING Name
  3334. );
  3335. //
  3336. // The following macro is useful for traversing the queue of Prefixes
  3337. // attached to a given Lcb
  3338. //
  3339. // PPREFIX_ENTRY
  3340. // NtfsGetNextPrefix (
  3341. // IN PIRP_CONTEXT IrpContext,
  3342. // IN PLCB Lcb,
  3343. // IN PPREFIX_ENTRY PreviousPrefixEntry
  3344. // );
  3345. //
  3346. #define NtfsGetNextPrefix(IC,LC,PPE) ((PPREFIX_ENTRY) \
  3347. ((PPE) == NULL ? \
  3348. (IsListEmpty(&(LC)->PrefixQueue) ? \
  3349. NULL \
  3350. : \
  3351. CONTAINING_RECORD((LC)->PrefixQueue.Flink, PREFIX_ENTRY, LcbLinks.Flink) \
  3352. ) \
  3353. : \
  3354. ((PVOID)((PPREFIX_ENTRY)(PPE))->LcbLinks.Flink == &(LC)->PrefixQueue.Flink ? \
  3355. NULL \
  3356. : \
  3357. CONTAINING_RECORD(((PPREFIX_ENTRY)(PPE))->LcbLinks.Flink, PREFIX_ENTRY, LcbLinks.Flink) \
  3358. ) \
  3359. ) \
  3360. )
  3361. //
  3362. // Resources support routines/macros, implemented in ResrcSup.c
  3363. //
  3364. //
  3365. // Flags used in the acquire routines
  3366. //
  3367. #define ACQUIRE_NO_DELETE_CHECK (0x00000001)
  3368. #define ACQUIRE_DONT_WAIT (0x00000002)
  3369. #define ACQUIRE_HOLD_BITMAP (0x00000004)
  3370. #define ACQUIRE_WAIT (0x00000008)
  3371. //
  3372. // VOID
  3373. // NtfsAcquireExclusiveGlobal (
  3374. // IN PIRP_CONTEXT IrpContext,
  3375. // IN BOOLEAN Wait
  3376. // );
  3377. //
  3378. // BOOLEAN
  3379. // NtfsAcquireSharedGlobal (
  3380. // IN PIRP_CONTEXT IrpContext,
  3381. // IN BOOLEAN Wait
  3382. // );
  3383. //
  3384. #define NtfsAcquireSharedGlobal( I, W ) ExAcquireResourceSharedLite( &NtfsData.Resource, (W) )
  3385. #define NtfsAcquireExclusiveGlobal( I, W ) ExAcquireResourceExclusiveLite( &NtfsData.Resource, (W) )
  3386. VOID
  3387. NtfsAcquireCheckpointSynchronization (
  3388. IN PIRP_CONTEXT IrpContext,
  3389. IN PVCB Vcb
  3390. );
  3391. VOID
  3392. NtfsReleaseCheckpointSynchronization (
  3393. IN PIRP_CONTEXT IrpContext,
  3394. IN PVCB Vcb
  3395. );
  3396. //
  3397. // VOID
  3398. // NtfsLockNtfsData (
  3399. // );
  3400. //
  3401. // VOID
  3402. // NtfsUnlockNtfsData (
  3403. // );
  3404. //
  3405. #define NtfsLockNtfsData() { \
  3406. ExAcquireFastMutex( &NtfsData.NtfsDataLock ); \
  3407. }
  3408. #define NtfsUnlockNtfsData() { \
  3409. ExReleaseFastMutex( &NtfsData.NtfsDataLock ); \
  3410. }
  3411. VOID
  3412. NtfsAcquireAllFiles (
  3413. IN PIRP_CONTEXT IrpContext,
  3414. IN PVCB Vcb,
  3415. IN ULONG Exclusive,
  3416. IN ULONG AcquirePagingIo,
  3417. IN ULONG AcquireAndDrop
  3418. );
  3419. VOID
  3420. NtfsReleaseAllFiles (
  3421. IN PIRP_CONTEXT IrpContext,
  3422. IN PVCB Vcb,
  3423. IN BOOLEAN ReleasePagingIo
  3424. );
  3425. BOOLEAN
  3426. NtfsAcquireExclusiveVcb (
  3427. IN PIRP_CONTEXT IrpContext,
  3428. IN PVCB Vcb,
  3429. IN BOOLEAN RaiseOnCantWait
  3430. );
  3431. BOOLEAN
  3432. NtfsAcquireSharedVcb (
  3433. IN PIRP_CONTEXT IrpContext,
  3434. IN PVCB Vcb,
  3435. IN BOOLEAN RaiseOnCantWait
  3436. );
  3437. #define NtfsAcquireExclusivePagingIo(IC,FCB) { \
  3438. ASSERT((IC)->CleanupStructure == NULL); \
  3439. NtfsAcquirePagingResourceExclusive( IC, FCB, TRUE ); \
  3440. (IC)->CleanupStructure = (FCB); \
  3441. }
  3442. #define NtfsReleasePagingIo(IC,FCB) { \
  3443. ASSERT((IC)->CleanupStructure == (FCB)); \
  3444. NtfsReleasePagingResource( IC, FCB ); \
  3445. (IC)->CleanupStructure = NULL; \
  3446. }
  3447. BOOLEAN
  3448. NtfsAcquireFcbWithPaging (
  3449. IN PIRP_CONTEXT IrpContext,
  3450. IN PFCB Fcb,
  3451. IN ULONG AcquireFlags
  3452. );
  3453. VOID
  3454. NtfsReleaseFcbWithPaging (
  3455. IN PIRP_CONTEXT IrpContext,
  3456. IN PFCB Fcb
  3457. );
  3458. VOID
  3459. NtfsReleaseScbWithPaging (
  3460. IN PIRP_CONTEXT IrpContext,
  3461. IN PSCB Scb
  3462. );
  3463. BOOLEAN
  3464. NtfsAcquireExclusiveFcb (
  3465. IN PIRP_CONTEXT IrpContext,
  3466. IN PFCB Fcb,
  3467. IN PSCB Scb OPTIONAL,
  3468. IN ULONG AcquireFlags
  3469. );
  3470. VOID
  3471. NtfsAcquireSharedFcb (
  3472. IN PIRP_CONTEXT IrpContext,
  3473. IN PFCB Fcb,
  3474. IN PSCB Scb OPTIONAL,
  3475. IN ULONG AcquireFlags
  3476. );
  3477. BOOLEAN
  3478. NtfsAcquireSharedFcbCheckWait (
  3479. IN PIRP_CONTEXT IrpContext,
  3480. IN PFCB Fcb,
  3481. IN ULONG AcquireFlags
  3482. );
  3483. VOID
  3484. NtfsReleaseFcb (
  3485. IN PIRP_CONTEXT IrpContext,
  3486. IN PFCB Fcb
  3487. );
  3488. VOID
  3489. NtfsAcquireExclusiveScb (
  3490. IN PIRP_CONTEXT IrpContext,
  3491. IN PSCB Scb
  3492. );
  3493. #ifdef NTFSDBG
  3494. BOOLEAN
  3495. NtfsAcquireResourceExclusive (
  3496. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3497. IN PVOID FcbOrScb,
  3498. IN BOOLEAN Wait
  3499. );
  3500. #else
  3501. INLINE
  3502. BOOLEAN
  3503. NtfsAcquireResourceExclusive (
  3504. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3505. IN PVOID FcbOrScb,
  3506. IN BOOLEAN Wait
  3507. )
  3508. {
  3509. BOOLEAN Result;
  3510. UNREFERENCED_PARAMETER( IrpContext );
  3511. if (NTFS_NTC_FCB == ((PFCB)FcbOrScb)->NodeTypeCode) {
  3512. Result = ExAcquireResourceExclusiveLite( ((PFCB)FcbOrScb)->Resource, Wait );
  3513. } else {
  3514. Result = ExAcquireResourceExclusiveLite( ((PSCB)(FcbOrScb))->Header.Resource, Wait );
  3515. }
  3516. return Result;
  3517. }
  3518. #endif
  3519. INLINE
  3520. BOOLEAN
  3521. NtfsAcquirePagingResourceExclusive (
  3522. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3523. IN PVOID FcbOrScb,
  3524. IN BOOLEAN Wait
  3525. )
  3526. {
  3527. UNREFERENCED_PARAMETER( IrpContext );
  3528. if (NTFS_NTC_FCB == ((PFCB)FcbOrScb)->NodeTypeCode) {
  3529. return ExAcquireResourceExclusive( ((PFCB)FcbOrScb)->PagingIoResource, Wait );
  3530. } else {
  3531. return ExAcquireResourceExclusive( ((PSCB)(FcbOrScb))->Header.PagingIoResource, Wait );
  3532. }
  3533. }
  3534. INLINE
  3535. BOOLEAN
  3536. NtfsAcquirePagingResourceSharedWaitForExclusive (
  3537. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3538. IN PVOID FcbOrScb,
  3539. IN BOOLEAN Wait
  3540. )
  3541. {
  3542. BOOLEAN Result;
  3543. UNREFERENCED_PARAMETER( IrpContext );
  3544. if (NTFS_NTC_FCB == ((PFCB)FcbOrScb)->NodeTypeCode) {
  3545. Result = ExAcquireSharedWaitForExclusive( ((PFCB)FcbOrScb)->PagingIoResource, Wait );
  3546. } else {
  3547. Result = ExAcquireSharedWaitForExclusive( ((PSCB)(FcbOrScb))->Header.PagingIoResource, Wait );
  3548. }
  3549. return Result;
  3550. }
  3551. INLINE
  3552. BOOLEAN
  3553. NtfsAcquirePagingResourceSharedStarveExclusive (
  3554. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3555. IN PVOID FcbOrScb,
  3556. IN BOOLEAN Wait
  3557. )
  3558. {
  3559. BOOLEAN Result;
  3560. UNREFERENCED_PARAMETER( IrpContext );
  3561. if (NTFS_NTC_FCB == ((PFCB)FcbOrScb)->NodeTypeCode) {
  3562. Result = ExAcquireSharedStarveExclusive( ((PFCB)FcbOrScb)->PagingIoResource, Wait );
  3563. } else {
  3564. Result = ExAcquireSharedStarveExclusive( ((PSCB)(FcbOrScb))->Header.PagingIoResource, Wait );
  3565. }
  3566. return Result;
  3567. }
  3568. #ifdef NTFSDBG
  3569. BOOLEAN
  3570. NtfsAcquireResourceShared (
  3571. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3572. IN PVOID FcbOrScb,
  3573. IN BOOLEAN Wait
  3574. );
  3575. BOOLEAN
  3576. NtfsAcquireResourceSharedWaitForEx (
  3577. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3578. IN PVOID FcbOrScb,
  3579. IN BOOLEAN Wait
  3580. );
  3581. #else
  3582. INLINE
  3583. BOOLEAN
  3584. NtfsAcquireResourceShared (
  3585. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3586. IN PVOID FcbOrScb,
  3587. IN BOOLEAN Wait
  3588. )
  3589. {
  3590. PFCB Fcb;
  3591. if (NTFS_NTC_FCB == ((PFCB)FcbOrScb)->NodeTypeCode) {
  3592. Fcb = (PFCB)FcbOrScb;
  3593. } else {
  3594. ASSERT_SCB( FcbOrScb );
  3595. Fcb = ((PSCB)FcbOrScb)->Fcb;
  3596. }
  3597. return ExAcquireResourceSharedLite( Fcb->Resource, Wait );
  3598. UNREFERENCED_PARAMETER( IrpContext );
  3599. }
  3600. INLINE
  3601. BOOLEAN
  3602. NtfsAcquireResourceSharedWaitForEx (
  3603. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3604. IN PVOID FcbOrScb,
  3605. IN BOOLEAN Wait
  3606. )
  3607. {
  3608. PFCB Fcb;
  3609. if (NTFS_NTC_FCB == ((PFCB)FcbOrScb)->NodeTypeCode) {
  3610. Fcb = (PFCB)FcbOrScb;
  3611. } else {
  3612. ASSERT_SCB( FcbOrScb );
  3613. Fcb = ((PSCB)FcbOrScb)->Fcb;
  3614. ASSERT( ((PSCB)FcbOrScb)->Header.Resource == Fcb->Resource );
  3615. }
  3616. return ExAcquireSharedWaitForExclusive( Fcb->Resource, Wait );
  3617. UNREFERENCED_PARAMETER( IrpContext );
  3618. }
  3619. #endif
  3620. INLINE
  3621. BOOLEAN
  3622. NtfsAcquirePagingResourceShared (
  3623. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3624. IN PVOID FcbOrScb,
  3625. IN BOOLEAN Wait
  3626. )
  3627. {
  3628. BOOLEAN Result;
  3629. UNREFERENCED_PARAMETER( IrpContext );
  3630. if (NTFS_NTC_FCB == ((PFCB)FcbOrScb)->NodeTypeCode) {
  3631. Result = ExAcquireResourceShared( ((PFCB)FcbOrScb)->PagingIoResource, Wait );
  3632. } else {
  3633. ASSERT_SCB( FcbOrScb );
  3634. Result = ExAcquireResourceShared( ((PSCB)(FcbOrScb))->Header.PagingIoResource, Wait );
  3635. }
  3636. return Result;
  3637. }
  3638. //
  3639. // VOID
  3640. // NtfsReleaseResource(
  3641. // IN PIRP_CONTEXT IrpContext OPTIONAL,
  3642. // IN PVOID FcbOrScb
  3643. // };
  3644. //
  3645. #ifdef NTFSDBG
  3646. VOID
  3647. NtfsReleaseResource (
  3648. IN PIRP_CONTEXT IrpContext OPTIONAL,
  3649. IN PVOID FcbOrScb
  3650. );
  3651. #else
  3652. #define NtfsReleaseResource( IC, F ) { \
  3653. if (NTFS_NTC_FCB == ((PFCB)(F))->NodeTypeCode) { \
  3654. ExReleaseResourceLite( ((PFCB)(F))->Resource ); \
  3655. } else { \
  3656. ExReleaseResourceLite( ((PSCB)(F))->Header.Resource ); \
  3657. } \
  3658. }
  3659. #endif
  3660. #define NtfsReleasePagingResource( IC, F ) { \
  3661. if (NTFS_NTC_FCB == ((PFCB)(F))->NodeTypeCode) { \
  3662. ExReleaseResource( ((PFCB)(F))->PagingIoResource ); \
  3663. } else { \
  3664. ExReleaseResource( ((PSCB)(F))->Header.PagingIoResource ); \
  3665. } \
  3666. }
  3667. VOID
  3668. NtfsAcquireSharedScbForTransaction (
  3669. IN PIRP_CONTEXT IrpContext,
  3670. IN PSCB Scb
  3671. );
  3672. VOID
  3673. NtfsReleaseSharedResources (
  3674. IN PIRP_CONTEXT IrpContext
  3675. );
  3676. VOID
  3677. NtfsReleaseAllResources (
  3678. IN PIRP_CONTEXT IrpContext
  3679. );
  3680. VOID
  3681. NtfsAcquireIndexCcb (
  3682. IN PSCB Scb,
  3683. IN PCCB Ccb,
  3684. IN PEOF_WAIT_BLOCK EofWaitBlock
  3685. );
  3686. VOID
  3687. NtfsReleaseIndexCcb (
  3688. IN PSCB Scb,
  3689. IN PCCB Ccb
  3690. );
  3691. //
  3692. // VOID
  3693. // NtfsAcquireSharedScb (
  3694. // IN PIRP_CONTEXT IrpContext,
  3695. // IN PSCB Scb
  3696. // );
  3697. //
  3698. // VOID
  3699. // NtfsReleaseScb (
  3700. // IN PIRP_CONTEXT IrpContext,
  3701. // IN PSCB Scb
  3702. // );
  3703. //
  3704. // VOID
  3705. // NtfsReleaseGlobal (
  3706. // IN PIRP_CONTEXT IrpContext
  3707. // );
  3708. //
  3709. // VOID
  3710. // NtfsAcquireFcbTable (
  3711. // IN PIRP_CONTEXT IrpContext,
  3712. // IN PVCB Vcb,
  3713. // );
  3714. //
  3715. // VOID
  3716. // NtfsReleaseFcbTable (
  3717. // IN PIRP_CONTEXT IrpContext,
  3718. // IN PVCB Vcb
  3719. // );
  3720. //
  3721. // VOID
  3722. // NtfsLockVcb (
  3723. // IN PIRP_CONTEXT IrpContext,
  3724. // IN PVCB Vcb
  3725. // );
  3726. //
  3727. // VOID
  3728. // NtfsUnlockVcb (
  3729. // IN PIRP_CONTEXT IrpContext,
  3730. // IN PVCB Vcb
  3731. // );
  3732. //
  3733. // VOID
  3734. // NtfsLockFcb (
  3735. // IN PIRP_CONTEXT IrpContext,
  3736. // IN PFCB Fcb
  3737. // );
  3738. //
  3739. // VOID
  3740. // NtfsUnlockFcb (
  3741. // IN PIRP_CONTEXT IrpContext,
  3742. // IN PFCB Fcb
  3743. // );
  3744. //
  3745. // VOID
  3746. // NtfsAcquireFcbSecurity (
  3747. // IN PIRP_CONTEXT IrpContext,
  3748. // IN PVCB Vcb,
  3749. // );
  3750. //
  3751. // VOID
  3752. // NtfsReleaseFcbSecurity (
  3753. // IN PIRP_CONTEXT IrpContext,
  3754. // IN PVCB Vcb
  3755. // );
  3756. //
  3757. // VOID
  3758. // NtfsAcquireHashTable (
  3759. // IN PVCB Vcb
  3760. // );
  3761. //
  3762. // VOID
  3763. // NtfsReleaseHashTable (
  3764. // IN PVCB Vcb
  3765. // );
  3766. //
  3767. // VOID
  3768. // NtfsAcquireCheckpoint (
  3769. // IN PIRP_CONTEXT IrpContext,
  3770. // IN PVCB Vcb,
  3771. // );
  3772. //
  3773. // VOID
  3774. // NtfsReleaseCheckpoint (
  3775. // IN PIRP_CONTEXT IrpContext,
  3776. // IN PVCB Vcb
  3777. // );
  3778. //
  3779. // VOID
  3780. // NtfsWaitOnCheckpointNotify (
  3781. // IN PIRP_CONTEXT IrpContext,
  3782. // IN PVCB Vcb
  3783. // );
  3784. //
  3785. // VOID
  3786. // NtfsSetCheckpointNotify (
  3787. // IN PIRP_CONTEXT IrpContext,
  3788. // IN PVCB Vcb
  3789. // );
  3790. //
  3791. // VOID
  3792. // NtfsResetCheckpointNotify (
  3793. // IN PIRP_CONTEXT IrpContext,
  3794. // IN PVCB Vcb
  3795. // );
  3796. //
  3797. // VOID
  3798. // NtfsAcquireReservedClusters (
  3799. // IN PIRP_CONTEXT IrpContext,
  3800. // IN PVCB Vcb
  3801. // );
  3802. //
  3803. // VOID
  3804. // NtfsReleaseReservedClusters (
  3805. // IN PIRP_CONTEXT IrpContext,
  3806. // IN PVCB Vcb
  3807. // );
  3808. //
  3809. // VOID
  3810. // NtfsAcquireUsnNotify (
  3811. // IN PVCB Vcb
  3812. // );
  3813. //
  3814. // VOID
  3815. // NtfsDeleteUsnNotify (
  3816. // IN PVCB Vcb
  3817. // );
  3818. //
  3819. // VOID NtfsAcquireFsrtlHeader (
  3820. // IN PSCB Scb
  3821. // );
  3822. //
  3823. // VOID NtfsReleaseFsrtlHeader (
  3824. // IN PSCB Scb
  3825. // );
  3826. //
  3827. // VOID
  3828. // NtfsReleaseVcb (
  3829. // IN PIRP_CONTEXT IrpContext,
  3830. // IN PVCB Vcb
  3831. // );
  3832. //
  3833. VOID
  3834. NtfsReleaseVcbCheckDelete (
  3835. IN PIRP_CONTEXT IrpContext,
  3836. IN PVCB Vcb,
  3837. IN UCHAR MajorCode,
  3838. IN PFILE_OBJECT FileObject OPTIONAL
  3839. );
  3840. #define NtfsAcquireSharedScb(IC,S) { \
  3841. NtfsAcquireSharedFcb((IC),(S)->Fcb, S, 0); \
  3842. }
  3843. #define NtfsAcquireSharedScbWaitForEx(IC,S) \
  3844. NtfsAcquireResourceSharedWaitForEx( IC, S, BooleanFlagOn( (IC)->State, IRP_CONTEXT_STATE_WAIT ) )
  3845. #define NtfsReleaseScb(IC,S) { \
  3846. NtfsReleaseFcb((IC),(S)->Fcb); \
  3847. }
  3848. #define NtfsReleaseGlobal(IC) { \
  3849. ExReleaseResourceLite( &NtfsData.Resource ); \
  3850. }
  3851. #define NtfsAcquireFcbTable(IC,V) { \
  3852. ExAcquireFastMutexUnsafe( &(V)->FcbTableMutex ); \
  3853. }
  3854. #define NtfsReleaseFcbTable(IC,V) { \
  3855. ExReleaseFastMutexUnsafe( &(V)->FcbTableMutex ); \
  3856. }
  3857. #define NtfsLockVcb(IC,V) { \
  3858. ExAcquireFastMutexUnsafe( &(V)->FcbSecurityMutex ); \
  3859. }
  3860. #define NtfsUnlockVcb(IC,V) { \
  3861. ExReleaseFastMutexUnsafe( &(V)->FcbSecurityMutex ); \
  3862. }
  3863. #define NtfsLockFcb(IC,F) { \
  3864. ExAcquireFastMutex( (F)->FcbMutex ); \
  3865. }
  3866. #define NtfsUnlockFcb(IC,F) { \
  3867. ExReleaseFastMutex( (F)->FcbMutex ); \
  3868. }
  3869. #define NtfsAcquireFcbSecurity(V) { \
  3870. ExAcquireFastMutexUnsafe( &(V)->FcbSecurityMutex ); \
  3871. }
  3872. #define NtfsReleaseFcbSecurity(V) { \
  3873. ExReleaseFastMutexUnsafe( &(V)->FcbSecurityMutex ); \
  3874. }
  3875. #define NtfsAcquireHashTable(V) { \
  3876. ExAcquireFastMutexUnsafe( &(V)->HashTableMutex ); \
  3877. }
  3878. #define NtfsReleaseHashTable(V) { \
  3879. ExReleaseFastMutexUnsafe( &(V)->HashTableMutex ); \
  3880. }
  3881. #define NtfsAcquireCheckpoint(IC,V) { \
  3882. ExAcquireFastMutexUnsafe( &(V)->CheckpointMutex ); \
  3883. }
  3884. #define NtfsReleaseCheckpoint(IC,V) { \
  3885. ExReleaseFastMutexUnsafe( &(V)->CheckpointMutex ); \
  3886. }
  3887. #define NtfsWaitOnCheckpointNotify(IC,V) { \
  3888. NTSTATUS _Status; \
  3889. _Status = KeWaitForSingleObject( &(V)->CheckpointNotifyEvent, \
  3890. Executive, \
  3891. KernelMode, \
  3892. FALSE, \
  3893. NULL ); \
  3894. if (!NT_SUCCESS( _Status )) { \
  3895. NtfsRaiseStatus( IrpContext, _Status, NULL, NULL ); \
  3896. } \
  3897. }
  3898. #define NtfsSetCheckpointNotify(IC,V) { \
  3899. (V)->CheckpointOwnerThread = NULL; \
  3900. KeSetEvent( &(V)->CheckpointNotifyEvent, 0, FALSE ); \
  3901. }
  3902. #define NtfsResetCheckpointNotify(IC,V) { \
  3903. (V)->CheckpointOwnerThread = (PVOID) PsGetCurrentThread(); \
  3904. KeClearEvent( &(V)->CheckpointNotifyEvent ); \
  3905. }
  3906. #define NtfsAcquireUsnNotify(V) { \
  3907. ExAcquireFastMutex( &(V)->CheckpointMutex ); \
  3908. }
  3909. #define NtfsReleaseUsnNotify(V) { \
  3910. ExReleaseFastMutex( &(V)->CheckpointMutex ); \
  3911. }
  3912. #define NtfsAcquireReservedClusters(V) { \
  3913. ExAcquireFastMutexUnsafe( &(V)->ReservedClustersMutex );\
  3914. }
  3915. #define NtfsReleaseReservedClusters(V) { \
  3916. ExReleaseFastMutexUnsafe( &(V)->ReservedClustersMutex );\
  3917. }
  3918. #define NtfsAcquireFsrtlHeader(S) { \
  3919. ExAcquireFastMutex((S)->Header.FastMutex); \
  3920. }
  3921. #define NtfsReleaseFsrtlHeader(S) { \
  3922. ExReleaseFastMutex((S)->Header.FastMutex); \
  3923. }
  3924. #ifdef NTFSDBG
  3925. VOID NtfsReleaseVcb(
  3926. IN PIRP_CONTEXT IrpContext,
  3927. IN PVCB Vcb
  3928. );
  3929. #else
  3930. #define NtfsReleaseVcb(IC,V) { \
  3931. ExReleaseResourceLite( &(V)->Resource ); \
  3932. }
  3933. #endif
  3934. //
  3935. // Macros to test resources for exclusivity.
  3936. //
  3937. #define NtfsIsExclusiveResource(R) ( \
  3938. ExIsResourceAcquiredExclusiveLite(R) \
  3939. )
  3940. #define NtfsIsExclusiveFcb(F) ( \
  3941. (NtfsIsExclusiveResource((F)->Resource)) \
  3942. )
  3943. #define NtfsIsExclusiveFcbPagingIo(F) ( \
  3944. (NtfsIsExclusiveResource((F)->PagingIoResource)) \
  3945. )
  3946. #define NtfsIsExclusiveScbPagingIo(S) ( \
  3947. (NtfsIsExclusiveFcbPagingIo((S)->Fcb)) \
  3948. )
  3949. #define NtfsIsExclusiveScb(S) ( \
  3950. (NtfsIsExclusiveFcb((S)->Fcb)) \
  3951. )
  3952. #define NtfsIsExclusiveVcb(V) ( \
  3953. (NtfsIsExclusiveResource(&(V)->Resource)) \
  3954. )
  3955. //
  3956. // Macros to test resources for shared acquire
  3957. //
  3958. #define NtfsIsSharedResource(R) ( \
  3959. ExIsResourceAcquiredSharedLite(R) \
  3960. )
  3961. #define NtfsIsSharedFcb(F) ( \
  3962. (NtfsIsSharedResource((F)->Resource)) \
  3963. )
  3964. #define NtfsIsSharedFcbPagingIo(F) ( \
  3965. (NtfsIsSharedResource((F)->PagingIoResource)) \
  3966. )
  3967. #define NtfsIsSharedScbPagingIo(S) ( \
  3968. (NtfsIsSharedFcbPagingIo((S)->Fcb)) \
  3969. )
  3970. #define NtfsIsSharedScb(S) ( \
  3971. (NtfsIsSharedFcb((S)->Fcb)) \
  3972. )
  3973. #define NtfsIsSharedVcb(V) ( \
  3974. (NtfsIsSharedResource(&(V)->Resource)) \
  3975. )
  3976. __inline
  3977. VOID
  3978. NtfsReleaseExclusiveScbIfOwned(
  3979. IN PIRP_CONTEXT IrpContext,
  3980. IN PSCB Scb
  3981. )
  3982. /*++
  3983. Routine Description:
  3984. This routine is called release an Scb that may or may not be currently
  3985. owned exclusive.
  3986. Arguments:
  3987. IrpContext - Context of call
  3988. Scb - Scb to be released
  3989. Return Value:
  3990. None.
  3991. --*/
  3992. {
  3993. if (Scb->Fcb->ExclusiveFcbLinks.Flink != NULL &&
  3994. NtfsIsExclusiveScb( Scb )) {
  3995. NtfsReleaseScb( IrpContext, Scb );
  3996. }
  3997. }
  3998. //
  3999. // The following are cache manager call backs. They return FALSE
  4000. // if the resource cannot be acquired with waiting and wait is false.
  4001. //
  4002. BOOLEAN
  4003. NtfsAcquireScbForLazyWrite (
  4004. IN PVOID Null,
  4005. IN BOOLEAN Wait
  4006. );
  4007. VOID
  4008. NtfsReleaseScbFromLazyWrite (
  4009. IN PVOID Null
  4010. );
  4011. NTSTATUS
  4012. NtfsAcquireFileForModWrite (
  4013. IN PFILE_OBJECT FileObject,
  4014. IN PLARGE_INTEGER EndingOffset,
  4015. OUT PERESOURCE *ResourceToRelease,
  4016. IN PDEVICE_OBJECT DeviceObject
  4017. );
  4018. NTSTATUS
  4019. NtfsAcquireFileForCcFlush (
  4020. IN PFILE_OBJECT FileObject,
  4021. IN PDEVICE_OBJECT DeviceObject
  4022. );
  4023. NTSTATUS
  4024. NtfsReleaseFileForCcFlush (
  4025. IN PFILE_OBJECT FileObject,
  4026. IN PDEVICE_OBJECT DeviceObject
  4027. );
  4028. VOID
  4029. NtfsAcquireForCreateSection (
  4030. IN PFILE_OBJECT FileObject
  4031. );
  4032. VOID
  4033. NtfsReleaseForCreateSection (
  4034. IN PFILE_OBJECT FileObject
  4035. );
  4036. BOOLEAN
  4037. NtfsAcquireScbForReadAhead (
  4038. IN PVOID Null,
  4039. IN BOOLEAN Wait
  4040. );
  4041. VOID
  4042. NtfsReleaseScbFromReadAhead (
  4043. IN PVOID Null
  4044. );
  4045. BOOLEAN
  4046. NtfsAcquireVolumeFileForLazyWrite (
  4047. IN PVOID Vcb,
  4048. IN BOOLEAN Wait
  4049. );
  4050. VOID
  4051. NtfsReleaseVolumeFileFromLazyWrite (
  4052. IN PVOID Vcb
  4053. );
  4054. //
  4055. // Ntfs Logging Routine interfaces in RestrSup.c
  4056. //
  4057. BOOLEAN
  4058. NtfsRestartVolume (
  4059. IN PIRP_CONTEXT IrpContext,
  4060. IN PVCB Vcb,
  4061. OUT PBOOLEAN UnrecognizedRestart
  4062. );
  4063. VOID
  4064. NtfsAbortTransaction (
  4065. IN PIRP_CONTEXT IrpContext,
  4066. IN PVCB Vcb,
  4067. IN PTRANSACTION_ENTRY Transaction OPTIONAL
  4068. );
  4069. NTSTATUS
  4070. NtfsCloseAttributesFromRestart (
  4071. IN PIRP_CONTEXT IrpContext,
  4072. IN PVCB Vcb
  4073. );
  4074. //
  4075. // Security support routines, implemented in SecurSup.c
  4076. //
  4077. //
  4078. // VOID
  4079. // NtfsTraverseCheck (
  4080. // IN PIRP_CONTEXT IrpContext,
  4081. // IN PFCB ParentFcb,
  4082. // IN PIRP Irp
  4083. // );
  4084. //
  4085. // VOID
  4086. // NtfsOpenCheck (
  4087. // IN PIRP_CONTEXT IrpContext,
  4088. // IN PFCB Fcb,
  4089. // IN PFCB ParentFcb OPTIONAL,
  4090. // IN PIRP Irp
  4091. // );
  4092. //
  4093. // VOID
  4094. // NtfsCreateCheck (
  4095. // IN PIRP_CONTEXT IrpContext,
  4096. // IN PFCB ParentFcb,
  4097. // IN PIRP Irp
  4098. // );
  4099. //
  4100. #define NtfsTraverseCheck(IC,F,IR) { \
  4101. NtfsAccessCheck( IC, \
  4102. F, \
  4103. NULL, \
  4104. IR, \
  4105. FILE_TRAVERSE, \
  4106. TRUE ); \
  4107. }
  4108. #define NtfsOpenCheck(IC,F,PF,IR) { \
  4109. NtfsAccessCheck( IC, \
  4110. F, \
  4111. PF, \
  4112. IR, \
  4113. IoGetCurrentIrpStackLocation(IR)->Parameters.Create.SecurityContext->DesiredAccess, \
  4114. FALSE ); \
  4115. }
  4116. #define NtfsCreateCheck(IC,PF,IR) { \
  4117. NtfsAccessCheck( IC, \
  4118. PF, \
  4119. NULL, \
  4120. IR, \
  4121. (FlagOn(IoGetCurrentIrpStackLocation(IR)->Parameters.Create.Options, FILE_DIRECTORY_FILE) ? \
  4122. FILE_ADD_SUBDIRECTORY : FILE_ADD_FILE), \
  4123. TRUE ); \
  4124. }
  4125. VOID
  4126. NtfsAssignSecurity (
  4127. IN PIRP_CONTEXT IrpContext,
  4128. IN PFCB ParentFcb,
  4129. IN PIRP Irp,
  4130. IN PFCB NewFcb,
  4131. IN PFILE_RECORD_SEGMENT_HEADER FileRecord,
  4132. IN PBCB FileRecordBcb,
  4133. IN LONGLONG FileOffset,
  4134. IN OUT PBOOLEAN LogIt
  4135. );
  4136. NTSTATUS
  4137. NtfsModifySecurity (
  4138. IN PIRP_CONTEXT IrpContext,
  4139. IN PFCB Fcb,
  4140. IN PSECURITY_INFORMATION SecurityInformation,
  4141. OUT PSECURITY_DESCRIPTOR SecurityDescriptor
  4142. );
  4143. NTSTATUS
  4144. NtfsQuerySecurity (
  4145. IN PIRP_CONTEXT IrpContext,
  4146. IN PFCB Fcb,
  4147. IN PSECURITY_INFORMATION SecurityInformation,
  4148. OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
  4149. IN OUT PULONG SecurityDescriptorLength
  4150. );
  4151. VOID
  4152. NtfsAccessCheck (
  4153. PIRP_CONTEXT IrpContext,
  4154. IN PFCB Fcb,
  4155. IN PFCB ParentFcb OPTIONAL,
  4156. IN PIRP Irp,
  4157. IN ACCESS_MASK DesiredAccess,
  4158. IN BOOLEAN CheckOnly
  4159. );
  4160. BOOLEAN
  4161. NtfsCanAdministerVolume (
  4162. IN PIRP_CONTEXT IrpContext,
  4163. IN PIRP Irp,
  4164. IN PFCB Fcb,
  4165. IN PSECURITY_DESCRIPTOR TestSecurityDescriptor OPTIONAL,
  4166. IN PULONG TestDesiredAccess OPTIONAL
  4167. );
  4168. NTSTATUS
  4169. NtfsCheckFileForDelete (
  4170. IN PIRP_CONTEXT IrpContext,
  4171. IN PSCB ParentScb,
  4172. IN PFCB ThisFcb,
  4173. IN BOOLEAN FcbExisted,
  4174. IN PINDEX_ENTRY IndexEntry
  4175. );
  4176. VOID
  4177. NtfsCheckIndexForAddOrDelete (
  4178. IN PIRP_CONTEXT IrpContext,
  4179. IN PFCB ParentFcb,
  4180. IN ACCESS_MASK DesiredAccess,
  4181. IN ULONG CreatePrivileges
  4182. );
  4183. VOID
  4184. NtfsSetFcbSecurityFromDescriptor (
  4185. IN PIRP_CONTEXT IrpContext,
  4186. IN OUT PFCB Fcb,
  4187. IN PSECURITY_DESCRIPTOR SecurityDescriptor,
  4188. IN ULONG SecurityDescriptorLength,
  4189. IN BOOLEAN RaiseIfInvalid
  4190. );
  4191. INLINE
  4192. VOID
  4193. RemoveReferenceSharedSecurityUnsafe (
  4194. IN OUT PSHARED_SECURITY *SharedSecurity
  4195. )
  4196. /*++
  4197. Routine Description:
  4198. This routine is called to manage the reference count on a shared security
  4199. descriptor. If the reference count goes to zero, the shared security is
  4200. freed.
  4201. Arguments:
  4202. SharedSecurity - security that is being dereferenced.
  4203. Return Value:
  4204. None.
  4205. --*/
  4206. {
  4207. DebugTrace( 0, (DEBUG_TRACE_SECURSUP | DEBUG_TRACE_ACLINDEX),
  4208. ( "RemoveReferenceSharedSecurityUnsafe( %08x )\n", *SharedSecurity ));
  4209. //
  4210. // Note that there will be one less reference shortly
  4211. //
  4212. ASSERT( (*SharedSecurity)->ReferenceCount != 0 );
  4213. (*SharedSecurity)->ReferenceCount--;
  4214. if ((*SharedSecurity)->ReferenceCount == 0) {
  4215. DebugTrace( 0, (DEBUG_TRACE_SECURSUP | DEBUG_TRACE_ACLINDEX),
  4216. ( "RemoveReferenceSharedSecurityUnsafe freeing\n" ));
  4217. NtfsFreePool( *SharedSecurity );
  4218. }
  4219. *SharedSecurity = NULL;
  4220. }
  4221. BOOLEAN
  4222. NtfsNotifyTraverseCheck (
  4223. IN PCCB Ccb,
  4224. IN PFCB Fcb,
  4225. IN PSECURITY_SUBJECT_CONTEXT SubjectContext
  4226. );
  4227. VOID
  4228. NtfsLoadSecurityDescriptor (
  4229. PIRP_CONTEXT IrpContext,
  4230. IN PFCB Fcb
  4231. );
  4232. VOID
  4233. NtfsStoreSecurityDescriptor (
  4234. PIRP_CONTEXT IrpContext,
  4235. IN PFCB Fcb,
  4236. IN BOOLEAN LogIt
  4237. );
  4238. VOID
  4239. NtfsInitializeSecurity (
  4240. IN PIRP_CONTEXT IrpContext,
  4241. IN PVCB Vcb,
  4242. IN PFCB Fcb
  4243. );
  4244. VOID
  4245. NtOfsPurgeSecurityCache (
  4246. IN PVCB Vcb
  4247. );
  4248. PSHARED_SECURITY
  4249. NtfsCacheSharedSecurityBySecurityId (
  4250. IN PIRP_CONTEXT IrpContext,
  4251. IN PVCB Vcb,
  4252. IN SECURITY_ID SecurityId
  4253. );
  4254. PSHARED_SECURITY
  4255. NtfsCacheSharedSecurityForCreate (
  4256. IN PIRP_CONTEXT IrpContext,
  4257. IN PFCB ParentFcb
  4258. );
  4259. SECURITY_ID
  4260. GetSecurityIdFromSecurityDescriptorUnsafe (
  4261. PIRP_CONTEXT IrpContext,
  4262. IN OUT PSHARED_SECURITY SharedSecurity
  4263. );
  4264. FSRTL_COMPARISON_RESULT
  4265. NtOfsCollateSecurityHash (
  4266. IN PINDEX_KEY Key1,
  4267. IN PINDEX_KEY Key2,
  4268. IN PVOID CollationData
  4269. );
  4270. #ifdef NTFS_CACHE_RIGHTS
  4271. VOID
  4272. NtfsGetCachedRightsById (
  4273. IN PVCB Vcb,
  4274. IN PLUID TokenId,
  4275. IN PLUID ModifiedId,
  4276. IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
  4277. IN PSHARED_SECURITY SharedSecurity,
  4278. OUT PBOOLEAN EntryCached OPTIONAL,
  4279. OUT PACCESS_MASK Rights
  4280. );
  4281. NTSTATUS
  4282. NtfsGetCachedRights (
  4283. IN PVCB Vcb,
  4284. IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
  4285. IN PSHARED_SECURITY SharedSecurity,
  4286. OUT PACCESS_MASK Rights,
  4287. OUT PBOOLEAN EntryCached OPTIONAL,
  4288. OUT PLUID TokenId OPTIONAL,
  4289. OUT PLUID ModifiedId OPTIONAL
  4290. );
  4291. #endif
  4292. //
  4293. // In-memory structure support routine, implemented in StrucSup.c
  4294. //
  4295. //
  4296. // Routines to create and destroy the Vcb
  4297. //
  4298. VOID
  4299. NtfsInitializeVcb (
  4300. IN PIRP_CONTEXT IrpContext,
  4301. IN OUT PVCB Vcb,
  4302. IN PDEVICE_OBJECT TargetDeviceObject,
  4303. IN PVPB Vpb
  4304. );
  4305. BOOLEAN
  4306. NtfsDeleteVcb (
  4307. IN PIRP_CONTEXT IrpContext,
  4308. IN OUT PVCB *Vcb
  4309. );
  4310. //
  4311. // Routines to create and destroy the Fcb
  4312. //
  4313. PFCB
  4314. NtfsCreateRootFcb ( // also creates the root lcb
  4315. IN PIRP_CONTEXT IrpContext,
  4316. IN PVCB Vcb
  4317. );
  4318. PFCB
  4319. NtfsCreateFcb (
  4320. IN PIRP_CONTEXT IrpContext,
  4321. IN PVCB Vcb,
  4322. IN FILE_REFERENCE FileReference,
  4323. IN BOOLEAN IsPagingFile,
  4324. IN BOOLEAN LargeFcb,
  4325. OUT PBOOLEAN ReturnedExistingFcb OPTIONAL
  4326. );
  4327. VOID
  4328. NtfsDeleteFcb (
  4329. IN PIRP_CONTEXT IrpContext,
  4330. IN OUT PFCB *Fcb,
  4331. OUT PBOOLEAN AcquiredFcbTable
  4332. );
  4333. PFCB
  4334. NtfsGetNextFcbTableEntry (
  4335. IN PVCB Vcb,
  4336. IN PVOID *RestartKey
  4337. );
  4338. //
  4339. // Routines to create and destroy the Scb
  4340. //
  4341. PSCB
  4342. NtfsCreateScb (
  4343. IN PIRP_CONTEXT IrpContext,
  4344. IN PFCB Fcb,
  4345. IN ATTRIBUTE_TYPE_CODE AttributeTypeCode,
  4346. IN PCUNICODE_STRING AttributeName,
  4347. IN BOOLEAN ReturnExistingOnly,
  4348. OUT PBOOLEAN ReturnedExistingScb OPTIONAL
  4349. );
  4350. PSCB
  4351. NtfsCreatePrerestartScb (
  4352. IN PIRP_CONTEXT IrpContext,
  4353. IN PVCB Vcb,
  4354. IN PFILE_REFERENCE FileReference,
  4355. IN ATTRIBUTE_TYPE_CODE AttributeTypeCode,
  4356. IN PUNICODE_STRING AttributeName OPTIONAL,
  4357. IN ULONG BytesPerIndexBuffer
  4358. );
  4359. VOID
  4360. NtfsFreeScbAttributeName (
  4361. IN PWSTR AttributeNameBuffer
  4362. );
  4363. VOID
  4364. NtfsDeleteScb (
  4365. IN PIRP_CONTEXT IrpContext,
  4366. IN OUT PSCB *Scb
  4367. );
  4368. BOOLEAN
  4369. NtfsUpdateNormalizedName (
  4370. IN PIRP_CONTEXT IrpContext,
  4371. IN PSCB ParentScb,
  4372. IN PSCB Scb,
  4373. IN PFILE_NAME FileName OPTIONAL,
  4374. IN BOOLEAN CheckBufferSizeOnly,
  4375. IN BOOLEAN NewDirectory
  4376. );
  4377. VOID
  4378. NtfsDeleteNormalizedName (
  4379. IN PSCB Scb
  4380. );
  4381. typedef
  4382. NTSTATUS
  4383. (*NTFSWALKUPFUNCTION)(
  4384. PIRP_CONTEXT IrpContext,
  4385. PFCB Fcb,
  4386. PSCB Scb,
  4387. PFILE_NAME FileName,
  4388. PVOID Context );
  4389. NTSTATUS
  4390. NtfsWalkUpTree (
  4391. IN PIRP_CONTEXT IrpContext,
  4392. IN PFCB Fcb,
  4393. IN NTFSWALKUPFUNCTION WalkUpFunction,
  4394. IN OUT PVOID Context
  4395. );
  4396. typedef struct {
  4397. UNICODE_STRING Name;
  4398. FILE_REFERENCE Scope;
  4399. BOOLEAN IsRoot;
  4400. #ifdef BENL_DBG
  4401. PFCB StartFcb;
  4402. #endif
  4403. } SCOPE_CONTEXT, *PSCOPE_CONTEXT;
  4404. NTSTATUS
  4405. NtfsBuildRelativeName (
  4406. IN PIRP_CONTEXT IrpContext,
  4407. IN PFCB Fcb,
  4408. IN PSCB Scb,
  4409. IN PFILE_NAME FileName,
  4410. IN OUT PVOID Context
  4411. );
  4412. VOID
  4413. NtfsBuildNormalizedName (
  4414. IN PIRP_CONTEXT IrpContext,
  4415. IN PFCB Fcb,
  4416. IN PSCB IndexScb OPTIONAL,
  4417. OUT PUNICODE_STRING FileName
  4418. );
  4419. VOID
  4420. NtfsSnapshotScb (
  4421. IN PIRP_CONTEXT IrpContext,
  4422. IN PSCB Scb
  4423. );
  4424. VOID
  4425. NtfsUpdateScbSnapshots (
  4426. IN PIRP_CONTEXT IrpContext
  4427. );
  4428. VOID
  4429. NtfsRestoreScbSnapshots (
  4430. IN PIRP_CONTEXT IrpContext,
  4431. IN BOOLEAN Higher
  4432. );
  4433. VOID
  4434. NtfsMungeScbSnapshot (
  4435. IN PIRP_CONTEXT IrpContext,
  4436. IN PSCB Scb,
  4437. IN LONGLONG FileSize
  4438. );
  4439. VOID
  4440. NtfsFreeSnapshotsForFcb (
  4441. IN PIRP_CONTEXT IrpContext,
  4442. IN PFCB Fcb
  4443. );
  4444. BOOLEAN
  4445. NtfsCreateFileLock (
  4446. IN PSCB Scb,
  4447. IN BOOLEAN RaiseOnError
  4448. );
  4449. //
  4450. //
  4451. // A general purpose teardown routine that helps cleanup the
  4452. // the Fcb/Scb structures
  4453. //
  4454. VOID
  4455. NtfsTeardownStructures (
  4456. IN PIRP_CONTEXT IrpContext,
  4457. IN PVOID FcbOrScb,
  4458. IN PLCB Lcb OPTIONAL,
  4459. IN BOOLEAN CheckForAttributeTable,
  4460. IN ULONG AcquireFlags,
  4461. OUT PBOOLEAN RemovedFcb OPTIONAL
  4462. );
  4463. //
  4464. // Routines to create, destroy and walk through the Lcbs
  4465. //
  4466. PLCB
  4467. NtfsCreateLcb (
  4468. IN PIRP_CONTEXT IrpContext,
  4469. IN PSCB Scb,
  4470. IN PFCB Fcb,
  4471. IN UNICODE_STRING LastComponentFileName,
  4472. IN UCHAR FileNameFlags,
  4473. IN OUT PBOOLEAN ReturnedExistingLcb OPTIONAL
  4474. );
  4475. VOID
  4476. NtfsDeleteLcb (
  4477. IN PIRP_CONTEXT IrpContext,
  4478. IN OUT PLCB *Lcb
  4479. );
  4480. VOID
  4481. NtfsMoveLcb ( // also munges the ccb and fileobjects filenames
  4482. IN PIRP_CONTEXT IrpContext,
  4483. IN PLCB Lcb,
  4484. IN PSCB Scb,
  4485. IN PFCB Fcb,
  4486. IN PUNICODE_STRING TargetDirectoryName,
  4487. IN PUNICODE_STRING LastComponentName,
  4488. IN UCHAR FileNameFlags,
  4489. IN BOOLEAN CheckBufferSizeOnly
  4490. );
  4491. VOID
  4492. NtfsRenameLcb ( // also munges the ccb and fileobjects filenames
  4493. IN PIRP_CONTEXT IrpContext,
  4494. IN PLCB Lcb,
  4495. IN PUNICODE_STRING LastComponentFileName,
  4496. IN UCHAR FileNameFlags,
  4497. IN BOOLEAN CheckBufferSizeOnly
  4498. );
  4499. VOID
  4500. NtfsCombineLcbs (
  4501. IN PIRP_CONTEXT IrpContext,
  4502. IN PLCB PrimaryLcb,
  4503. IN PLCB AuxLcb
  4504. );
  4505. PLCB
  4506. NtfsLookupLcbByFlags (
  4507. IN PFCB Fcb,
  4508. IN UCHAR FileNameFlags
  4509. );
  4510. ULONG
  4511. NtfsLookupNameLengthViaLcb (
  4512. IN PFCB Fcb,
  4513. OUT PBOOLEAN LeadingBackslash
  4514. );
  4515. VOID
  4516. NtfsFileNameViaLcb (
  4517. IN PFCB Fcb,
  4518. IN PWCHAR FileName,
  4519. ULONG Length,
  4520. ULONG BytesToCopy
  4521. );
  4522. //
  4523. // VOID
  4524. // NtfsLinkCcbToLcb (
  4525. // IN PIRP_CONTEXT IrpContext OPTIONAL,
  4526. // IN PFCB Fcb,
  4527. // IN PCCB Ccb,
  4528. // IN PLCB Lcb
  4529. // );
  4530. //
  4531. #define NtfsLinkCcbToLcb(IC,F,C,L) { \
  4532. NtfsLockFcb( IC, F ); \
  4533. InsertTailList( &(L)->CcbQueue, &(C)->LcbLinks ); \
  4534. (C)->Lcb = (L); \
  4535. NtfsUnlockFcb( IC, F ); \
  4536. }
  4537. //
  4538. // VOID
  4539. // NtfsUnlinkCcbFromLcb (
  4540. // IN PIRP_CONTEXT IrpContext OPTIONAL,
  4541. // IN PFCB Fcb,
  4542. // IN PCCB Ccb
  4543. // );
  4544. //
  4545. #define NtfsUnlinkCcbFromLcb(IC,F,C) { \
  4546. NtfsLockFcb( IC, F ); \
  4547. if ((C)->Lcb != NULL) { \
  4548. RemoveEntryList( &(C)->LcbLinks ); \
  4549. (C)->Lcb = NULL; \
  4550. } \
  4551. NtfsUnlockFcb( IC, F ); \
  4552. }
  4553. //
  4554. // Routines to create and destroy the Ccb
  4555. //
  4556. PCCB
  4557. NtfsCreateCcb (
  4558. IN PIRP_CONTEXT IrpContext,
  4559. IN PFCB Fcb,
  4560. IN PSCB Scb,
  4561. IN BOOLEAN Indexed,
  4562. IN USHORT EaModificationCount,
  4563. IN ULONG Flags,
  4564. IN PFILE_OBJECT FileObject,
  4565. IN ULONG LastFileNameOffset
  4566. );
  4567. VOID
  4568. NtfsDeleteCcb (
  4569. IN PFCB Fcb,
  4570. IN OUT PCCB *Ccb
  4571. );
  4572. //
  4573. // Routines to create and destroy the IrpContext
  4574. //
  4575. VOID
  4576. NtfsInitializeIrpContext (
  4577. IN PIRP Irp OPTIONAL,
  4578. IN BOOLEAN Wait,
  4579. IN OUT PIRP_CONTEXT *IrpContext
  4580. );
  4581. VOID
  4582. NtfsCleanupIrpContext (
  4583. IN OUT PIRP_CONTEXT IrpContext,
  4584. IN ULONG Retry
  4585. );
  4586. //
  4587. // Routines to initialize and change the ntfs_io_context
  4588. //
  4589. VOID
  4590. NtfsInitializeIoContext (
  4591. IN PIRP_CONTEXT IrpContext,
  4592. IN PNTFS_IO_CONTEXT IoContext,
  4593. IN BOOLEAN PagingIo
  4594. );
  4595. VOID
  4596. NtfsSetIoContextAsync (
  4597. IN PIRP_CONTEXT IrpContext,
  4598. IN PERESOURCE ResourceToRelease,
  4599. IN ULONG ByteCount
  4600. );
  4601. //
  4602. // Routine for scanning the Fcbs within the graph hierarchy
  4603. //
  4604. PSCB
  4605. NtfsGetNextScb (
  4606. IN PSCB Scb,
  4607. IN PSCB TerminationScb
  4608. );
  4609. //
  4610. // The following macros are useful for traversing the queues interconnecting
  4611. // fcbs, scb, and lcbs.
  4612. //
  4613. // PSCB
  4614. // NtfsGetNextChildScb (
  4615. // IN PFCB Fcb,
  4616. // IN PSCB PreviousChildScb
  4617. // );
  4618. //
  4619. // PLCB
  4620. // NtfsGetNextParentLcb (
  4621. // IN PIRP_CONTEXT IrpContext,
  4622. // IN PFCB Fcb,
  4623. // IN PLCB PreviousParentLcb
  4624. // );
  4625. //
  4626. // PLCB
  4627. // NtfsGetNextChildLcb (
  4628. // IN PIRP_CONTEXT IrpContext,
  4629. // IN PSCB Scb,
  4630. // IN PLCB PreviousChildLcb
  4631. // );
  4632. //
  4633. // PLCB
  4634. // NtfsGetPrevChildLcb (
  4635. // IN PIRP_CONTEXT IrpContext,
  4636. // IN PSCB Scb,
  4637. // IN PLCB PreviousChildLcb
  4638. // );
  4639. //
  4640. // PLCB
  4641. // NtfsGetNextParentLcb (
  4642. // IN PIRP_CONTEXT IrpContext,
  4643. // IN PFCB Fcb,
  4644. // IN PLCB PreviousChildLcb
  4645. // );
  4646. //
  4647. // PCCB
  4648. // NtfsGetNextCcb (
  4649. // IN PIRP_CONTEXT IrpContext,
  4650. // IN PLCB Lcb,
  4651. // IN PCCB PreviousCcb
  4652. // );
  4653. //
  4654. #define NtfsGetNextChildScb(F,P) ((PSCB) \
  4655. ((P) == NULL ? \
  4656. (IsListEmpty(&(F)->ScbQueue) ? \
  4657. NULL \
  4658. : \
  4659. CONTAINING_RECORD((F)->ScbQueue.Flink, SCB, FcbLinks.Flink) \
  4660. ) \
  4661. : \
  4662. ((PVOID)((PSCB)(P))->FcbLinks.Flink == &(F)->ScbQueue.Flink ? \
  4663. NULL \
  4664. : \
  4665. CONTAINING_RECORD(((PSCB)(P))->FcbLinks.Flink, SCB, FcbLinks.Flink) \
  4666. ) \
  4667. ) \
  4668. )
  4669. #define NtfsGetNextParentLcb(F,P) ((PLCB) \
  4670. ((P) == NULL ? \
  4671. (IsListEmpty(&(F)->LcbQueue) ? \
  4672. NULL \
  4673. : \
  4674. CONTAINING_RECORD((F)->LcbQueue.Flink, LCB, FcbLinks.Flink) \
  4675. ) \
  4676. : \
  4677. ((PVOID)((PLCB)(P))->FcbLinks.Flink == &(F)->LcbQueue.Flink ? \
  4678. NULL \
  4679. : \
  4680. CONTAINING_RECORD(((PLCB)(P))->FcbLinks.Flink, LCB, FcbLinks.Flink) \
  4681. ) \
  4682. ) \
  4683. )
  4684. #define NtfsGetNextChildLcb(S,P) ((PLCB) \
  4685. ((P) == NULL ? \
  4686. ((((NodeType(S) == NTFS_NTC_SCB_DATA) || (NodeType(S) == NTFS_NTC_SCB_MFT)) \
  4687. || IsListEmpty(&(S)->ScbType.Index.LcbQueue)) ? \
  4688. NULL \
  4689. : \
  4690. CONTAINING_RECORD((S)->ScbType.Index.LcbQueue.Flink, LCB, ScbLinks.Flink) \
  4691. ) \
  4692. : \
  4693. ((PVOID)((PLCB)(P))->ScbLinks.Flink == &(S)->ScbType.Index.LcbQueue.Flink ? \
  4694. NULL \
  4695. : \
  4696. CONTAINING_RECORD(((PLCB)(P))->ScbLinks.Flink, LCB, ScbLinks.Flink) \
  4697. ) \
  4698. ) \
  4699. )
  4700. #define NtfsGetPrevChildLcb(S,P) ((PLCB) \
  4701. ((P) == NULL ? \
  4702. ((((NodeType(S) == NTFS_NTC_SCB_DATA) || (NodeType(S) == NTFS_NTC_SCB_MFT)) \
  4703. || IsListEmpty(&(S)->ScbType.Index.LcbQueue)) ? \
  4704. NULL \
  4705. : \
  4706. CONTAINING_RECORD((S)->ScbType.Index.LcbQueue.Blink, LCB, ScbLinks.Flink) \
  4707. ) \
  4708. : \
  4709. ((PVOID)((PLCB)(P))->ScbLinks.Blink == &(S)->ScbType.Index.LcbQueue.Flink ? \
  4710. NULL \
  4711. : \
  4712. CONTAINING_RECORD(((PLCB)(P))->ScbLinks.Blink, LCB, ScbLinks.Flink) \
  4713. ) \
  4714. ) \
  4715. )
  4716. #define NtfsGetNextParentLcb(F,P) ((PLCB) \
  4717. ((P) == NULL ? \
  4718. (IsListEmpty(&(F)->LcbQueue) ? \
  4719. NULL \
  4720. : \
  4721. CONTAINING_RECORD((F)->LcbQueue.Flink, LCB, FcbLinks.Flink) \
  4722. ) \
  4723. : \
  4724. ((PVOID)((PLCB)(P))->FcbLinks.Flink == &(F)->LcbQueue.Flink ? \
  4725. NULL \
  4726. : \
  4727. CONTAINING_RECORD(((PLCB)(P))->FcbLinks.Flink, LCB, FcbLinks.Flink) \
  4728. ) \
  4729. ) \
  4730. )
  4731. #define NtfsGetNextCcb(L,P) ((PCCB) \
  4732. ((P) == NULL ? \
  4733. (IsListEmpty(&(L)->CcbQueue) ? \
  4734. NULL \
  4735. : \
  4736. CONTAINING_RECORD((L)->CcbQueue.Flink, CCB, LcbLinks.Flink) \
  4737. ) \
  4738. : \
  4739. ((PVOID)((PCCB)(P))->LcbLinks.Flink == &(L)->CcbQueue.Flink ? \
  4740. NULL \
  4741. : \
  4742. CONTAINING_RECORD(((PCCB)(P))->LcbLinks.Flink, CCB, LcbLinks.Flink) \
  4743. ) \
  4744. ) \
  4745. )
  4746. #define NtfsGetFirstCcbEntry(S) \
  4747. (IsListEmpty( &(S)->CcbQueue ) \
  4748. ? NULL \
  4749. : CONTAINING_RECORD( (S)->CcbQueue.Flink, CCB, CcbLinks.Flink ))
  4750. #define NtfsGetNextCcbEntry(S,C) \
  4751. ( (PVOID)&(S)->CcbQueue.Flink == (PVOID)(C)->CcbLinks.Flink \
  4752. ? NULL \
  4753. : CONTAINING_RECORD( (C)->CcbLinks.Flink, CCB, CcbLinks.Flink ))
  4754. //
  4755. // VOID
  4756. // NtfsDeleteFcbTableEntry (
  4757. // IN PVCB Vcb,
  4758. // IN FILE_REFERENCE FileReference
  4759. // );
  4760. //
  4761. #if (defined( NTFS_FREE_ASSERTS ))
  4762. #define NtfsDeleteFcbTableEntry(V,FR) { \
  4763. FCB_TABLE_ELEMENT _Key; \
  4764. BOOLEAN _RemovedEntry; \
  4765. _Key.FileReference = FR; \
  4766. _RemovedEntry = RtlDeleteElementGenericTable( &(V)->FcbTable, &_Key ); \
  4767. ASSERT( _RemovedEntry ); \
  4768. }
  4769. #else
  4770. #define NtfsDeleteFcbTableEntry(V,FR) { \
  4771. FCB_TABLE_ELEMENT _Key; \
  4772. _Key.FileReference = FR; \
  4773. RtlDeleteElementGenericTable( &(V)->FcbTable, &_Key ); \
  4774. }
  4775. #endif
  4776. //
  4777. // Routines for allocating and deallocating the compression synchronization structures.
  4778. //
  4779. PVOID
  4780. NtfsAllocateCompressionSync (
  4781. IN POOL_TYPE PoolType,
  4782. IN SIZE_T NumberOfBytes,
  4783. IN ULONG Tag
  4784. );
  4785. VOID
  4786. NtfsDeallocateCompressionSync (
  4787. IN PVOID CompressionSync
  4788. );
  4789. //
  4790. // The following four routines are for incrementing and decrementing the cleanup
  4791. // counts and the close counts. In all of the structures
  4792. //
  4793. VOID
  4794. NtfsIncrementCleanupCounts (
  4795. IN PSCB Scb,
  4796. IN PLCB Lcb OPTIONAL,
  4797. IN BOOLEAN NonCachedHandle
  4798. );
  4799. VOID
  4800. NtfsIncrementCloseCounts (
  4801. IN PSCB Scb,
  4802. IN BOOLEAN SystemFile,
  4803. IN BOOLEAN ReadOnly
  4804. );
  4805. VOID
  4806. NtfsDecrementCleanupCounts (
  4807. IN PSCB Scb,
  4808. IN PLCB Lcb OPTIONAL,
  4809. IN BOOLEAN NonCachedHandle
  4810. );
  4811. VOID
  4812. NtfsDecrementCloseCounts (
  4813. IN PIRP_CONTEXT IrpContext,
  4814. IN PSCB Scb,
  4815. IN PLCB Lcb OPTIONAL,
  4816. IN BOOLEAN SystemFile,
  4817. IN BOOLEAN ReadOnly,
  4818. IN BOOLEAN DecrementCountsOnly,
  4819. IN OUT PBOOLEAN RemovedFcb OPTIONAL
  4820. );
  4821. PERESOURCE
  4822. NtfsAllocateEresource (
  4823. );
  4824. VOID
  4825. NtfsFreeEresource (
  4826. IN PERESOURCE Eresource
  4827. );
  4828. PVOID
  4829. NtfsAllocateFcbTableEntry (
  4830. IN PRTL_GENERIC_TABLE FcbTable,
  4831. IN CLONG ByteSize
  4832. );
  4833. VOID
  4834. NtfsFreeFcbTableEntry (
  4835. IN PRTL_GENERIC_TABLE FcbTable,
  4836. IN PVOID Buffer
  4837. );
  4838. VOID
  4839. NtfsPostToNewLengthQueue (
  4840. IN PIRP_CONTEXT IrpContext,
  4841. IN PSCB Scb
  4842. );
  4843. VOID
  4844. NtfsProcessNewLengthQueue (
  4845. IN PIRP_CONTEXT IrpContext,
  4846. IN BOOLEAN CleanupOnly
  4847. );
  4848. //
  4849. // Useful debug routines
  4850. //
  4851. VOID
  4852. NtfsTestStatusProc (
  4853. );
  4854. //
  4855. // Usn Support routines in UsnSup.c
  4856. //
  4857. NTSTATUS
  4858. NtfsReadUsnJournal (
  4859. IN PIRP_CONTEXT IrpContext,
  4860. IN PIRP Irp,
  4861. IN BOOLEAN ProbeInput
  4862. );
  4863. ULONG
  4864. NtfsPostUsnChange (
  4865. IN PIRP_CONTEXT IrpContext,
  4866. IN PVOID ScborFcb,
  4867. IN ULONG Reason
  4868. );
  4869. VOID
  4870. NtfsWriteUsnJournalChanges (
  4871. PIRP_CONTEXT IrpContext
  4872. );
  4873. VOID
  4874. NtfsSetupUsnJournal (
  4875. IN PIRP_CONTEXT IrpContext,
  4876. IN PVCB Vcb,
  4877. IN PFCB Fcb,
  4878. IN ULONG CreateIfNotExist,
  4879. IN ULONG Restamp,
  4880. IN PCREATE_USN_JOURNAL_DATA JournalData
  4881. );
  4882. VOID
  4883. NtfsTrimUsnJournal (
  4884. IN PIRP_CONTEXT IrpContext,
  4885. IN PVCB Vcb
  4886. );
  4887. NTSTATUS
  4888. NtfsQueryUsnJournal (
  4889. IN PIRP_CONTEXT IrpContext,
  4890. IN PIRP Irp
  4891. );
  4892. NTSTATUS
  4893. NtfsDeleteUsnJournal (
  4894. IN PIRP_CONTEXT IrpContext,
  4895. IN PIRP Irp
  4896. );
  4897. VOID
  4898. NtfsDeleteUsnSpecial (
  4899. IN PIRP_CONTEXT IrpContext,
  4900. IN PVOID Context
  4901. );
  4902. //
  4903. // NtOfs support routines in vattrsup.c
  4904. //
  4905. NTFSAPI
  4906. NTSTATUS
  4907. NtfsHoldIrpForNewLength (
  4908. IN PIRP_CONTEXT IrpContext,
  4909. IN PSCB Scb,
  4910. IN PIRP Irp,
  4911. IN LONGLONG Length,
  4912. IN PDRIVER_CANCEL CancelRoutine,
  4913. IN PVOID CapturedData OPTIONAL,
  4914. OUT PVOID *CopyCapturedData OPTIONAL,
  4915. IN ULONG CapturedDataLength
  4916. );
  4917. //
  4918. // Time conversion support routines, implemented as a macro
  4919. //
  4920. // VOID
  4921. // NtfsGetCurrentTime (
  4922. // IN PIRP_CONTEXT IrpContext,
  4923. // IN LONGLONG Time
  4924. // );
  4925. //
  4926. #define NtfsGetCurrentTime(_IC,_T) { \
  4927. ASSERT_IRP_CONTEXT(_IC); \
  4928. KeQuerySystemTime((PLARGE_INTEGER)&(_T)); \
  4929. }
  4930. //
  4931. // Time routine to check if last access should be updated.
  4932. //
  4933. // BOOLEAN
  4934. // NtfsCheckLastAccess (
  4935. // IN PIRP_CONTEXT IrpContext,
  4936. // IN OUT PFCB Fcb
  4937. // );
  4938. //
  4939. #define NtfsCheckLastAccess(_IC,_FCB) ( \
  4940. ((NtfsLastAccess + (_FCB)->Info.LastAccessTime) < (_FCB)->CurrentLastAccess) || \
  4941. ((_FCB)->CurrentLastAccess < (_FCB)->Info.LastAccessTime) \
  4942. )
  4943. //
  4944. // Macro and #defines to decide whether a given feature is supported on a
  4945. // given volume version. Currently, all features either work on all Ntfs
  4946. // volumes, or work on all volumes with major version greater than 1. In
  4947. // some future version, some features may require version 4.x volumes, etc.
  4948. //
  4949. // This macro is used to decide whether to fail a user request with
  4950. // STATUS_VOLUME_NOT_UPGRADED, and also helps us set the FILE_SUPPORTS_xxx
  4951. // flags correctly in NtfsQueryFsAttributeInfo.
  4952. //
  4953. #define NTFS_ENCRYPTION_VERSION 2
  4954. #define NTFS_OBJECT_ID_VERSION 2
  4955. #define NTFS_QUOTA_VERSION 2
  4956. #define NTFS_REPARSE_POINT_VERSION 2
  4957. #define NTFS_SPARSE_FILE_VERSION 2
  4958. #define NtfsVolumeVersionCheck(VCB,VERSION) ( \
  4959. ((VCB)->MajorVersion >= VERSION) \
  4960. )
  4961. //
  4962. // Low level verification routines, implemented in VerfySup.c
  4963. //
  4964. BOOLEAN
  4965. NtfsPerformVerifyOperation (
  4966. IN PIRP_CONTEXT IrpContext,
  4967. IN PVCB Vcb
  4968. );
  4969. VOID
  4970. NtfsPerformDismountOnVcb (
  4971. IN PIRP_CONTEXT IrpContext,
  4972. IN PVCB Vcb,
  4973. IN BOOLEAN DoCompleteDismount,
  4974. OUT PVPB *NewVpbReturn OPTIONAL
  4975. );
  4976. BOOLEAN
  4977. NtfsPingVolume (
  4978. IN PIRP_CONTEXT IrpContext,
  4979. IN PVCB Vcb,
  4980. IN OUT PBOOLEAN OwnsVcb OPTIONAL
  4981. );
  4982. VOID
  4983. NtfsVolumeCheckpointDpc (
  4984. IN PKDPC Dpc,
  4985. IN PVOID DeferredContext,
  4986. IN PVOID SystemArgument1,
  4987. IN PVOID SystemArgument2
  4988. );
  4989. VOID
  4990. NtfsCheckpointAllVolumes (
  4991. PVOID Parameter
  4992. );
  4993. VOID
  4994. NtfsUsnTimeOutDpc (
  4995. IN PKDPC Dpc,
  4996. IN PVOID DeferredContext,
  4997. IN PVOID SystemArgument1,
  4998. IN PVOID SystemArgument2
  4999. );
  5000. VOID
  5001. NtfsCheckUsnTimeOut (
  5002. PVOID Parameter
  5003. );
  5004. NTSTATUS
  5005. NtfsIoCallSelf (
  5006. IN PIRP_CONTEXT IrpContext,
  5007. IN PFILE_OBJECT FileObject,
  5008. IN UCHAR MajorFunction
  5009. );
  5010. BOOLEAN
  5011. NtfsLogEvent (
  5012. IN PIRP_CONTEXT IrpContext,
  5013. IN PQUOTA_USER_DATA UserData OPTIONAL,
  5014. IN NTSTATUS LogCode,
  5015. IN NTSTATUS FinalStatus
  5016. );
  5017. VOID
  5018. NtfsMarkVolumeDirty (
  5019. IN PIRP_CONTEXT IrpContext,
  5020. IN PVCB Vcb
  5021. );
  5022. VOID
  5023. NtfsSetVolumeInfoFlagState (
  5024. IN PIRP_CONTEXT IrpContext,
  5025. IN PVCB Vcb,
  5026. IN ULONG FlagsToSet,
  5027. IN BOOLEAN NewState,
  5028. IN BOOLEAN UpdateWithinTransaction
  5029. );
  5030. BOOLEAN
  5031. NtfsUpdateVolumeInfo (
  5032. IN PIRP_CONTEXT IrpContext,
  5033. IN PVCB Vcb,
  5034. IN UCHAR DiskMajorVersion,
  5035. IN UCHAR DiskMinorVersion
  5036. );
  5037. VOID
  5038. NtfsPostVcbIsCorrupt (
  5039. IN PIRP_CONTEXT IrpContext,
  5040. IN NTSTATUS Status OPTIONAL,
  5041. IN PFILE_REFERENCE FileReference OPTIONAL,
  5042. IN PFCB Fcb OPTIONAL
  5043. );
  5044. VOID
  5045. NtOfsCloseAttributeSafe (
  5046. IN PIRP_CONTEXT IrpContext,
  5047. IN PSCB Scb
  5048. );
  5049. NTSTATUS
  5050. NtfsDeviceIoControlAsync (
  5051. IN PIRP_CONTEXT IrpContext,
  5052. IN PDEVICE_OBJECT DeviceObject,
  5053. IN ULONG IoCtl,
  5054. IN OUT PVOID Buffer OPTIONAL,
  5055. IN ULONG BufferSize
  5056. );
  5057. //
  5058. // Work queue routines for posting and retrieving an Irp, implemented in
  5059. // workque.c
  5060. //
  5061. VOID
  5062. NtfsOplockComplete (
  5063. IN PVOID Context,
  5064. IN PIRP Irp
  5065. );
  5066. VOID
  5067. NtfsPrePostIrp (
  5068. IN PVOID Context,
  5069. IN PIRP Irp OPTIONAL
  5070. );
  5071. VOID
  5072. NtfsWriteOplockPrePostIrp (
  5073. IN PVOID Context,
  5074. IN PIRP Irp OPTIONAL
  5075. );
  5076. VOID
  5077. NtfsPrePostIrpInternal (
  5078. IN PVOID Context,
  5079. IN PIRP Irp OPTIONAL,
  5080. IN BOOLEAN PendIrp,
  5081. IN BOOLEAN SaveContext
  5082. );
  5083. VOID
  5084. NtfsAddToWorkque (
  5085. IN PIRP_CONTEXT IrpContext,
  5086. IN PIRP Irp OPTIONAL
  5087. );
  5088. NTSTATUS
  5089. NtfsPostRequest (
  5090. IN PIRP_CONTEXT IrpContext,
  5091. IN PIRP Irp OPTIONAL
  5092. );
  5093. //
  5094. // Miscellaneous support macros.
  5095. //
  5096. // ULONG_PTR
  5097. // WordAlign (
  5098. // IN ULONG_PTR Pointer
  5099. // );
  5100. //
  5101. // ULONG_PTR
  5102. // LongAlign (
  5103. // IN ULONG_PTR Pointer
  5104. // );
  5105. //
  5106. // ULONG_PTR
  5107. // QuadAlign (
  5108. // IN ULONG_PTR Pointer
  5109. // );
  5110. //
  5111. // UCHAR
  5112. // CopyUchar1 (
  5113. // IN PUCHAR Destination,
  5114. // IN PUCHAR Source
  5115. // );
  5116. //
  5117. // UCHAR
  5118. // CopyUchar2 (
  5119. // IN PUSHORT Destination,
  5120. // IN PUCHAR Source
  5121. // );
  5122. //
  5123. // UCHAR
  5124. // CopyUchar4 (
  5125. // IN PULONG Destination,
  5126. // IN PUCHAR Source
  5127. // );
  5128. //
  5129. // PVOID
  5130. // Add2Ptr (
  5131. // IN PVOID Pointer,
  5132. // IN ULONG Increment
  5133. // );
  5134. //
  5135. // ULONG
  5136. // PtrOffset (
  5137. // IN PVOID BasePtr,
  5138. // IN PVOID OffsetPtr
  5139. // );
  5140. //
  5141. #define WordAlignPtr(P) ( \
  5142. (PVOID)((((ULONG_PTR)(P)) + 1) & (-2)) \
  5143. )
  5144. #define LongAlignPtr(P) ( \
  5145. (PVOID)((((ULONG_PTR)(P)) + 3) & (-4)) \
  5146. )
  5147. #define QuadAlignPtr(P) ( \
  5148. (PVOID)((((ULONG_PTR)(P)) + 7) & (-8)) \
  5149. )
  5150. #define WordAlign(P) ( \
  5151. ((((P)) + 1) & (-2)) \
  5152. )
  5153. #define LongAlign(P) ( \
  5154. ((((P)) + 3) & (-4)) \
  5155. )
  5156. #define QuadAlign(P) ( \
  5157. ((((P)) + 7) & (-8)) \
  5158. )
  5159. #define IsWordAligned(P) ((ULONG_PTR)(P) == WordAlign( (ULONG_PTR)(P) ))
  5160. #define IsLongAligned(P) ((ULONG_PTR)(P) == LongAlign( (ULONG_PTR)(P) ))
  5161. #define IsQuadAligned(P) ((ULONG_PTR)(P) == QuadAlign( (ULONG_PTR)(P) ))
  5162. //
  5163. // A note on structure alignment checking:
  5164. //
  5165. // In a perfect world, we would just use TYPE_ALIGNMENT straight out of the box
  5166. // to check the alignment requirements for a given structure.
  5167. //
  5168. // On 32-bit platforms including Alpha, alignment faults are handled by the
  5169. // OS. There are many places in the NTFS code where a structure requires
  5170. // quadword alignment (on Alpha) but only dword alignment is enforced. To
  5171. // change this on Alpha32 would introduce compatibility problems, so on 32-bit
  5172. // platforms we do not want to use an alignment value greater than 4.
  5173. //
  5174. // In other places, enforcing ULONG alignment is more restrictive than
  5175. // necessary. For example, a structure that contains nothing bigger than a
  5176. // USHORT can get by with 16-bit alignment. However, there is no reason to
  5177. // relax these alignment restrictions, so on all platforms we do not want to
  5178. // use an alignment value of less than 4.
  5179. //
  5180. // This means that NTFS_TYPE_ALIGNMENT always resolves to 4 on 32-bit platforms,
  5181. // and to at least four on 64-bit platforms.
  5182. //
  5183. #ifdef _WIN64
  5184. #define NTFS_TYPE_ALIGNMENT(T) \
  5185. ((TYPE_ALIGNMENT( T ) < TYPE_ALIGNMENT(ULONG)) ? TYPE_ALIGNMENT( ULONG ) : TYPE_ALIGNMENT( T ))
  5186. #else
  5187. #define NTFS_TYPE_ALIGNMENT(T) TYPE_ALIGNMENT( ULONG )
  5188. #endif
  5189. //
  5190. // BlockAlign(): Aligns P on the next V boundary.
  5191. // BlockAlignTruncate(): Aligns P on the prev V boundary.
  5192. //
  5193. #define BlockAlign(P,V) ((ASSERT( V != 0)), (((P)) + (V-1) & (-(V))))
  5194. #define BlockAlignTruncate(P,V) ((P) & (-(V)))
  5195. //
  5196. // BlockOffset(): Calculates offset within V of P
  5197. //
  5198. #define BlockOffset(P,V) ((P) & (V-1))
  5199. //
  5200. // TypeAlign(): Aligns P according to the alignment requirements of type T
  5201. //
  5202. #define TypeAlign(P,T) BlockAlign( P, NTFS_TYPE_ALIGNMENT(T) )
  5203. //
  5204. // IsTypeAligned(): Determines whether P is aligned according to the
  5205. // requirements of type T
  5206. //
  5207. #define IsTypeAligned(P,T) \
  5208. ((ULONG_PTR)(P) == TypeAlign( (ULONG_PTR)(P), T ))
  5209. //
  5210. // Conversions between bytes and clusters. Typically we will round up to the
  5211. // next cluster unless the macro specifies trucate.
  5212. //
  5213. #define ClusterAlign(V,P) ( \
  5214. ((((ULONG)(P)) + (V)->ClusterMask) & (V)->InverseClusterMask) \
  5215. )
  5216. #define ClusterOffset(V,P) ( \
  5217. (((ULONG)(P)) & (V)->ClusterMask) \
  5218. )
  5219. #define ClustersFromBytes(V,P) ( \
  5220. (((ULONG)(P)) + (V)->ClusterMask) >> (V)->ClusterShift \
  5221. )
  5222. #define ClustersFromBytesTruncate(V,P) ( \
  5223. ((ULONG)(P)) >> (V)->ClusterShift \
  5224. )
  5225. #define BytesFromClusters(V,P) ( \
  5226. ((ULONG)(P)) << (V)->ClusterShift \
  5227. )
  5228. #define LlClustersFromBytes(V,L) ( \
  5229. Int64ShraMod32(((L) + (LONGLONG) (V)->ClusterMask), (CCHAR)(V)->ClusterShift) \
  5230. )
  5231. #define LlClustersFromBytesTruncate(V,L) ( \
  5232. Int64ShraMod32((L), (CCHAR)(V)->ClusterShift) \
  5233. )
  5234. #define LlBytesFromClusters(V,C) ( \
  5235. Int64ShllMod32((C), (CCHAR)(V)->ClusterShift) \
  5236. )
  5237. //
  5238. // Conversions between bytes and file records
  5239. //
  5240. #define BytesFromFileRecords(V,B) ( \
  5241. ((ULONG)(B)) << (V)->MftShift \
  5242. )
  5243. #define FileRecordsFromBytes(V,F) ( \
  5244. ((ULONG)(F)) >> (V)->MftShift \
  5245. )
  5246. #define LlBytesFromFileRecords(V,F) ( \
  5247. Int64ShllMod32((F), (CCHAR)(V)->MftShift) \
  5248. )
  5249. #define LlFileRecordsFromBytes(V,B) ( \
  5250. Int64ShraMod32((B), (CCHAR)(V)->MftShift) \
  5251. )
  5252. //
  5253. // Conversions between bytes and index blocks
  5254. //
  5255. #define BytesFromIndexBlocks(B,S) ( \
  5256. ((ULONG)(B)) << (S) \
  5257. )
  5258. #define LlBytesFromIndexBlocks(B,S) ( \
  5259. Int64ShllMod32((B), (S)) \
  5260. )
  5261. //
  5262. // Conversions between bytes and log blocks (512 byte blocks)
  5263. //
  5264. #define BytesFromLogBlocks(B) ( \
  5265. ((ULONG) (B)) << DEFAULT_INDEX_BLOCK_BYTE_SHIFT \
  5266. )
  5267. #define LogBlocksFromBytesTruncate(B) ( \
  5268. ((ULONG) (B)) >> DEFAULT_INDEX_BLOCK_BYTE_SHIFT \
  5269. )
  5270. #define Add2Ptr(P,I) ((PVOID)((PUCHAR)(P) + (I)))
  5271. #define PtrOffset(B,O) ((ULONG)((ULONG_PTR)(O) - (ULONG_PTR)(B)))
  5272. //
  5273. // The following support macros deal with dir notify support.
  5274. //
  5275. // ULONG
  5276. // NtfsBuildDirNotifyFilter (
  5277. // IN PIRP_CONTEXT IrpContext,
  5278. // IN ULONG Flags
  5279. // );
  5280. //
  5281. // VOID
  5282. // NtfsReportDirNotify (
  5283. // IN PIRP_CONTEXT IrpContext,
  5284. // IN PVCB Vcb,
  5285. // IN PUNICODE_STRING FullFileName,
  5286. // IN USHORT TargetNameOffset,
  5287. // IN PUNICODE_STRING StreamName OPTIONAL,
  5288. // IN PUNICODE_STRING NormalizedParentName OPTIONAL,
  5289. // IN ULONG Filter,
  5290. // IN ULONG Action,
  5291. // IN PFCB ParentFcb OPTIONAL
  5292. // );
  5293. //
  5294. // VOID
  5295. // NtfsUnsafeReportDirNotify (
  5296. // IN PIRP_CONTEXT IrpContext,
  5297. // IN PVCB Vcb,
  5298. // IN PUNICODE_STRING FullFileName,
  5299. // IN USHORT TargetNameOffset,
  5300. // IN PUNICODE_STRING StreamName OPTIONAL,
  5301. // IN PUNICODE_STRING NormalizedParentName OPTIONAL,
  5302. // IN ULONG Filter,
  5303. // IN ULONG Action,
  5304. // IN PFCB ParentFcb OPTIONAL
  5305. // );
  5306. //
  5307. #define NtfsBuildDirNotifyFilter(IC,F) ( \
  5308. FlagOn( (F), FCB_INFO_CHANGED_ALLOC_SIZE ) ? \
  5309. (FlagOn( (F), FCB_INFO_VALID_NOTIFY_FLAGS ) | FILE_NOTIFY_CHANGE_SIZE) : \
  5310. FlagOn( (F), FCB_INFO_VALID_NOTIFY_FLAGS ) \
  5311. )
  5312. #define NtfsReportDirNotify(IC,V,FN,O,SN,NPN,F,A,PF) { \
  5313. try { \
  5314. FsRtlNotifyFilterReportChange( (V)->NotifySync, \
  5315. &(V)->DirNotifyList, \
  5316. (PSTRING) (FN), \
  5317. (USHORT) (O), \
  5318. (PSTRING) (SN), \
  5319. (PSTRING) (NPN), \
  5320. F, \
  5321. A, \
  5322. PF, \
  5323. NULL ); \
  5324. } except (FsRtlIsNtstatusExpected( GetExceptionCode() ) ? \
  5325. EXCEPTION_EXECUTE_HANDLER : \
  5326. EXCEPTION_CONTINUE_SEARCH) { \
  5327. NOTHING; \
  5328. } \
  5329. }
  5330. #define NtfsUnsafeReportDirNotify(IC,V,FN,O,SN,NPN,F,A,PF) { \
  5331. FsRtlNotifyFilterReportChange( (V)->NotifySync, \
  5332. &(V)->DirNotifyList, \
  5333. (PSTRING) (FN), \
  5334. (USHORT) (O), \
  5335. (PSTRING) (SN), \
  5336. (PSTRING) (NPN), \
  5337. F, \
  5338. A, \
  5339. PF, \
  5340. NULL ); \
  5341. }
  5342. //
  5343. // The following types and macros are used to help unpack the packed and
  5344. // misaligned fields found in the Bios parameter block
  5345. //
  5346. typedef union _UCHAR1 {
  5347. UCHAR Uchar[1];
  5348. UCHAR ForceAlignment;
  5349. } UCHAR1, *PUCHAR1;
  5350. typedef union _UCHAR2 {
  5351. UCHAR Uchar[2];
  5352. USHORT ForceAlignment;
  5353. } UCHAR2, *PUCHAR2;
  5354. typedef union _UCHAR4 {
  5355. UCHAR Uchar[4];
  5356. ULONG ForceAlignment;
  5357. } UCHAR4, *PUCHAR4;
  5358. #define CopyUchar1(D,S) { \
  5359. *((UCHAR1 *)(D)) = *((UNALIGNED UCHAR1 *)(S)); \
  5360. }
  5361. #define CopyUchar2(D,S) { \
  5362. *((UCHAR2 *)(D)) = *((UNALIGNED UCHAR2 *)(S)); \
  5363. }
  5364. #define CopyUchar4(D,S) { \
  5365. *((UCHAR4 *)(D)) = *((UNALIGNED UCHAR4 *)(S)); \
  5366. }
  5367. //
  5368. // The following routines are used to set up and restore the top level
  5369. // irp field in the local thread. They are contained in ntfsdata.c
  5370. //
  5371. PTOP_LEVEL_CONTEXT
  5372. NtfsInitializeTopLevelIrp (
  5373. IN PTOP_LEVEL_CONTEXT TopLevelContext,
  5374. IN BOOLEAN ForceTopLevel,
  5375. IN BOOLEAN SetTopLevel
  5376. );
  5377. //
  5378. // BOOLEAN
  5379. // NtfsIsTopLevelRequest (
  5380. // IN PIRP_CONTEXT IrpContext
  5381. // );
  5382. //
  5383. // BOOLEAN
  5384. // NtfsIsTopLevelNtfs (
  5385. // IN PIRP_CONTEXT IrpContext
  5386. // );
  5387. //
  5388. // VOID
  5389. // NtfsRestoreTopLevelIrp (
  5390. // );
  5391. //
  5392. // PTOP_LEVEL_CONTEXT
  5393. // NtfsGetTopLevelContext (
  5394. // );
  5395. //
  5396. // PSCB
  5397. // NtfsGetTopLevelHotFixScb (
  5398. // );
  5399. //
  5400. // VCN
  5401. // NtfsGetTopLevelHotFixVcn (
  5402. // );
  5403. //
  5404. // BOOLEAN
  5405. // NtfsIsTopLevelHotFixScb (
  5406. // IN PSCB Scb
  5407. // );
  5408. //
  5409. // VOID
  5410. // NtfsUpdateIrpContextWithTopLevel (
  5411. // IN PIRP_CONTEXT IrpContext,
  5412. // IN PTOP_LEVEL_CONTEXT TopLevelContext
  5413. // );
  5414. //
  5415. #define NtfsRestoreTopLevelIrp() { \
  5416. PTOP_LEVEL_CONTEXT TLC; \
  5417. TLC = (PTOP_LEVEL_CONTEXT) IoGetTopLevelIrp(); \
  5418. ASSERT( (TLC)->ThreadIrpContext != NULL ); \
  5419. (TLC)->Ntfs = 0; \
  5420. (TLC)->ThreadIrpContext = NULL; \
  5421. IoSetTopLevelIrp( (PIRP) (TLC)->SavedTopLevelIrp ); \
  5422. }
  5423. #define NtfsGetTopLevelContext() ( \
  5424. (PTOP_LEVEL_CONTEXT) IoGetTopLevelIrp() \
  5425. )
  5426. #define NtfsIsTopLevelRequest(IC) ( \
  5427. ((IC) == (IC)->TopLevelIrpContext) && \
  5428. NtfsGetTopLevelContext()->TopLevelRequest \
  5429. )
  5430. #define NtfsIsTopLevelNtfs(IC) ( \
  5431. (IC) == (IC)->TopLevelIrpContext \
  5432. )
  5433. #define NtfsGetTopLevelHotFixScb() ( \
  5434. (NtfsGetTopLevelContext())->ScbBeingHotFixed \
  5435. )
  5436. #define NtfsGetTopLevelHotFixVcn() ( \
  5437. (NtfsGetTopLevelContext())->VboBeingHotFixed \
  5438. )
  5439. #define NtfsIsTopLevelHotFixScb(S) ( \
  5440. ((BOOLEAN) (NtfsGetTopLevelHotFixScb() == (S))) \
  5441. )
  5442. #define NtfsUpdateIrpContextWithTopLevel(IC,TLC) { \
  5443. if ((TLC)->ThreadIrpContext == NULL) { \
  5444. (TLC)->Ntfs = 0x5346544e; \
  5445. (TLC)->ThreadIrpContext = (IC); \
  5446. SetFlag( (IC)->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL ); \
  5447. IoSetTopLevelIrp( (PIRP) (TLC) ); \
  5448. } \
  5449. (IC)->TopLevelIrpContext = (TLC)->ThreadIrpContext; \
  5450. }
  5451. BOOLEAN
  5452. NtfsSetCancelRoutine (
  5453. IN PIRP Irp,
  5454. IN PDRIVER_CANCEL CancelRoutine,
  5455. IN ULONG_PTR IrpInformation,
  5456. IN ULONG Async
  5457. );
  5458. BOOLEAN
  5459. NtfsClearCancelRoutine (
  5460. IN PIRP Irp
  5461. );
  5462. #ifdef NTFS_CHECK_BITMAP
  5463. VOID
  5464. NtfsBadBitmapCopy (
  5465. IN PIRP_CONTEXT IrpContext,
  5466. IN ULONG BadBit,
  5467. IN ULONG Length
  5468. );
  5469. BOOLEAN
  5470. NtfsCheckBitmap (
  5471. IN PVCB Vcb,
  5472. IN ULONG Lcn,
  5473. IN ULONG Count,
  5474. IN BOOLEAN Set
  5475. );
  5476. #endif
  5477. //
  5478. // The FSD Level dispatch routines. These routines are called by the
  5479. // I/O system via the dispatch table in the Driver Object.
  5480. //
  5481. // They each accept as input a pointer to a device object (actually most
  5482. // expect a volume device object, with the exception of the file system
  5483. // control function which can also take a file system device object), and
  5484. // a pointer to the IRP. They either perform the function at the FSD level
  5485. // or post the request to the FSP work queue for FSP level processing.
  5486. //
  5487. NTSTATUS
  5488. NtfsFsdDispatch ( // implemented in ntfsdata.c
  5489. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5490. IN PIRP Irp
  5491. );
  5492. NTSTATUS
  5493. NtfsFsdDispatchWait ( // implemented in ntfsdata.c
  5494. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5495. IN PIRP Irp
  5496. );
  5497. NTSTATUS
  5498. NtfsFsdCleanup ( // implemented in Cleanup.c
  5499. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5500. IN PIRP Irp
  5501. );
  5502. NTSTATUS
  5503. NtfsFsdClose ( // implemented in Close.c
  5504. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5505. IN PIRP Irp
  5506. );
  5507. NTSTATUS
  5508. NtfsFsdCreate ( // implemented in Create.c
  5509. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5510. IN PIRP Irp
  5511. );
  5512. NTSTATUS
  5513. NtfsDeviceIoControl ( // implemented in FsCtrl.c
  5514. IN PIRP_CONTEXT IrpContext,
  5515. IN PDEVICE_OBJECT DeviceObject,
  5516. IN ULONG IoCtl,
  5517. IN PVOID InputBuffer OPTIONAL,
  5518. IN ULONG InputBufferLength,
  5519. IN PVOID OutputBuffer OPTIONAL,
  5520. IN ULONG OutputBufferLength,
  5521. OUT PULONG_PTR IosbInformation OPTIONAL
  5522. );
  5523. NTSTATUS
  5524. NtfsFsdDirectoryControl ( // implemented in DirCtrl.c
  5525. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5526. IN PIRP Irp
  5527. );
  5528. NTSTATUS
  5529. NtfsFsdPnp ( // implemented in Pnp.c
  5530. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5531. IN PIRP Irp
  5532. );
  5533. NTSTATUS
  5534. NtfsFsdFlushBuffers ( // implemented in Flush.c
  5535. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5536. IN PIRP Irp
  5537. );
  5538. NTSTATUS
  5539. NtfsFlushUserStream ( // implemented in Flush.c
  5540. IN PIRP_CONTEXT IrpContext,
  5541. IN PSCB Scb,
  5542. IN PLONGLONG FileOffset OPTIONAL,
  5543. IN ULONG Length
  5544. );
  5545. NTSTATUS
  5546. NtfsFlushVolume ( // implemented in Flush.c
  5547. IN PIRP_CONTEXT IrpContext,
  5548. IN PVCB Vcb,
  5549. IN BOOLEAN FlushCache,
  5550. IN BOOLEAN PurgeFromCache,
  5551. IN BOOLEAN ReleaseAllFiles,
  5552. IN BOOLEAN MarkFilesForDismount
  5553. );
  5554. NTSTATUS
  5555. NtfsFlushLsnStreams ( // implemented in Flush.c
  5556. IN PIRP_CONTEXT IrpContext,
  5557. IN PVCB Vcb,
  5558. IN BOOLEAN ForceRemove,
  5559. IN BOOLEAN Partial
  5560. );
  5561. VOID
  5562. NtfsFlushAndPurgeFcb ( // implemented in Flush.c
  5563. IN PIRP_CONTEXT IrpContext,
  5564. IN PFCB Fcb
  5565. );
  5566. VOID
  5567. NtfsFlushAndPurgeScb ( // implemented in Flush.c
  5568. IN PIRP_CONTEXT IrpContext,
  5569. IN PSCB Scb,
  5570. IN PSCB ParentScb OPTIONAL
  5571. );
  5572. NTSTATUS
  5573. NtfsFsdFileSystemControl ( // implemented in FsCtrl.c
  5574. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5575. IN PIRP Irp
  5576. );
  5577. NTSTATUS
  5578. NtfsFsdLockControl ( // implemented in LockCtrl.c
  5579. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5580. IN PIRP Irp
  5581. );
  5582. NTSTATUS
  5583. NtfsFsdRead ( // implemented in Read.c
  5584. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5585. IN PIRP Irp
  5586. );
  5587. NTSTATUS
  5588. NtfsFsdSetInformation ( // implemented in FileInfo.c
  5589. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5590. IN PIRP Irp
  5591. );
  5592. NTSTATUS
  5593. NtfsFsdShutdown ( // implemented in Shutdown.c
  5594. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5595. IN PIRP Irp
  5596. );
  5597. NTSTATUS
  5598. NtfsFsdQueryVolumeInformation ( // implemented in VolInfo.c
  5599. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5600. IN PIRP Irp
  5601. );
  5602. NTSTATUS
  5603. NtfsFsdSetVolumeInformation ( // implemented in VolInfo.c
  5604. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5605. IN PIRP Irp
  5606. );
  5607. NTSTATUS
  5608. NtfsFsdWrite ( // implemented in Write.c
  5609. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  5610. IN PIRP Irp
  5611. );
  5612. //
  5613. // The following macro is used to determine if an FSD thread can block
  5614. // for I/O or wait for a resource. It returns TRUE if the thread can
  5615. // block and FALSE otherwise. This attribute can then be used to call
  5616. // the FSD & FSP common work routine with the proper wait value.
  5617. //
  5618. //
  5619. // BOOLEAN
  5620. // CanFsdWait (
  5621. // IN PIRP Irp
  5622. // );
  5623. //
  5624. #define CanFsdWait(I) IoIsOperationSynchronous(I)
  5625. //
  5626. // The FSP level dispatch/main routine. This is the routine that takes
  5627. // IRP's off of the work queue and calls the appropriate FSP level
  5628. // work routine.
  5629. //
  5630. VOID
  5631. NtfsFspDispatch ( // implemented in FspDisp.c
  5632. IN PVOID Context
  5633. );
  5634. //
  5635. // The following routines are the FSP work routines that are called
  5636. // by the preceding NtfsFspDispath routine. Each takes as input a pointer
  5637. // to the IRP, perform the function, and return a pointer to the volume
  5638. // device object that they just finished servicing (if any). The return
  5639. // pointer is then used by the main Fsp dispatch routine to check for
  5640. // additional IRPs in the volume's overflow queue.
  5641. //
  5642. // Each of the following routines is also responsible for completing the IRP.
  5643. // We moved this responsibility from the main loop to the individual routines
  5644. // to allow them the ability to complete the IRP and continue post processing
  5645. // actions.
  5646. //
  5647. NTSTATUS
  5648. NtfsCommonCleanup ( // implemented in Cleanup.c
  5649. IN PIRP_CONTEXT IrpContext,
  5650. IN PIRP Irp
  5651. );
  5652. LONG
  5653. NtfsCleanupExceptionFilter ( // implemented in Cleanup.c
  5654. IN PIRP_CONTEXT IrpContext,
  5655. IN PEXCEPTION_POINTERS ExceptionPointer,
  5656. OUT PNTSTATUS Status
  5657. );
  5658. VOID
  5659. NtfsFspClose ( // implemented in Close.c
  5660. IN PVCB ThisVcb OPTIONAL
  5661. );
  5662. BOOLEAN
  5663. NtfsAddScbToFspClose ( // implemented in Close.c
  5664. IN PIRP_CONTEXT IrpContext,
  5665. IN PSCB Scb,
  5666. IN BOOLEAN DelayClose
  5667. );
  5668. BOOLEAN
  5669. NtfsNetworkOpenCreate ( // implemented in Create.c
  5670. IN PIRP Irp,
  5671. OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
  5672. IN PDEVICE_OBJECT VolumeDeviceObject
  5673. );
  5674. NTSTATUS
  5675. NtfsCommonCreate ( // implemented in Create.c
  5676. IN PIRP_CONTEXT IrpContext,
  5677. IN PIRP Irp,
  5678. IN PCREATE_CONTEXT CreateContext
  5679. );
  5680. VOID
  5681. NtfsInitializeFcbAndStdInfo (
  5682. IN PIRP_CONTEXT IrpContext,
  5683. IN PFCB ThisFcb,
  5684. IN BOOLEAN Directory,
  5685. IN BOOLEAN ViewIndex,
  5686. IN BOOLEAN Compressed,
  5687. IN ULONG FileAttributes,
  5688. IN PNTFS_TUNNELED_DATA SetTunnelData OPTIONAL
  5689. );
  5690. NTSTATUS
  5691. NtfsCommonVolumeOpen ( // implemented in Create.c
  5692. IN PIRP_CONTEXT IrpContext,
  5693. IN PIRP Irp
  5694. );
  5695. NTSTATUS
  5696. NtfsCommonDeviceControl ( // implemented in DevCtrl.c
  5697. IN PIRP_CONTEXT IrpContext,
  5698. IN PIRP Irp
  5699. );
  5700. NTSTATUS
  5701. NtfsCommonDirectoryControl ( // implemented in DirCtrl.c
  5702. IN PIRP_CONTEXT IrpContext,
  5703. IN PIRP Irp
  5704. );
  5705. VOID
  5706. NtfsReportViewIndexNotify ( // implemented in DirCtrl.c
  5707. IN PVCB Vcb,
  5708. IN PFCB Fcb,
  5709. IN ULONG FilterMatch,
  5710. IN ULONG Action,
  5711. IN PVOID ChangeInfoBuffer,
  5712. IN USHORT ChangeInfoBufferLength
  5713. );
  5714. NTSTATUS
  5715. NtfsCommonQueryEa ( // implemented in Ea.c
  5716. IN PIRP_CONTEXT IrpContext,
  5717. IN PIRP Irp
  5718. );
  5719. NTSTATUS
  5720. NtfsCommonSetEa ( // implemented in Ea.c
  5721. IN PIRP_CONTEXT IrpContext,
  5722. IN PIRP Irp
  5723. );
  5724. NTSTATUS
  5725. NtfsCommonQueryInformation ( // implemented in FileInfo.c
  5726. IN PIRP_CONTEXT IrpContext,
  5727. IN PIRP Irp
  5728. );
  5729. NTSTATUS
  5730. NtfsCommonSetInformation ( // implemented in FileInfo.c
  5731. IN PIRP_CONTEXT IrpContext,
  5732. IN PIRP Irp
  5733. );
  5734. NTSTATUS // implemented in FsCtrl.c
  5735. NtfsGetTunneledData (
  5736. IN PIRP_CONTEXT IrpContext,
  5737. IN PFCB Fcb,
  5738. IN OUT PNTFS_TUNNELED_DATA TunneledData
  5739. );
  5740. NTSTATUS // implemented in FsCtrl.c
  5741. NtfsSetTunneledData (
  5742. IN PIRP_CONTEXT IrpContext,
  5743. IN PFCB Fcb,
  5744. IN PNTFS_TUNNELED_DATA TunneledData
  5745. );
  5746. NTSTATUS
  5747. NtfsCommonQueryQuota ( // implemented in Quota.c
  5748. IN PIRP_CONTEXT IrpContext,
  5749. IN PIRP Irp
  5750. );
  5751. NTSTATUS
  5752. NtfsCommonSetQuota ( // implemented in Quota.c
  5753. IN PIRP_CONTEXT IrpContext,
  5754. IN PIRP Irp
  5755. );
  5756. NTSTATUS
  5757. NtfsCommonFlushBuffers ( // implemented in Flush.c
  5758. IN PIRP_CONTEXT IrpContext,
  5759. IN PIRP Irp
  5760. );
  5761. NTSTATUS
  5762. NtfsCommonFileSystemControl ( // implemented in FsCtrl.c
  5763. IN PIRP_CONTEXT IrpContext,
  5764. IN PIRP Irp
  5765. );
  5766. NTSTATUS
  5767. NtfsCommonLockControl ( // implemented in LockCtrl.c
  5768. IN PIRP_CONTEXT IrpContext,
  5769. IN PIRP Irp
  5770. );
  5771. NTSTATUS
  5772. NtfsCommonRead ( // implemented in Read.c
  5773. IN PIRP_CONTEXT IrpContext,
  5774. IN PIRP Irp,
  5775. IN BOOLEAN AcquireScb
  5776. );
  5777. NTSTATUS
  5778. NtfsCommonQuerySecurityInfo ( // implemented in SeInfo.c
  5779. IN PIRP_CONTEXT IrpContext,
  5780. IN PIRP Irp
  5781. );
  5782. NTSTATUS
  5783. NtfsCommonSetSecurityInfo ( // implemented in SeInfo.c
  5784. IN PIRP_CONTEXT IrpContext,
  5785. IN PIRP Irp
  5786. );
  5787. NTSTATUS
  5788. NtfsQueryViewIndex ( // implemented in ViewSup.c
  5789. IN PIRP_CONTEXT IrpContext,
  5790. IN PIRP Irp,
  5791. IN PVCB Vcb,
  5792. IN PSCB Scb,
  5793. IN PCCB Ccb
  5794. );
  5795. NTSTATUS
  5796. NtfsCommonQueryVolumeInfo ( // implemented in VolInfo.c
  5797. IN PIRP_CONTEXT IrpContext,
  5798. IN PIRP Irp
  5799. );
  5800. NTSTATUS
  5801. NtfsCommonSetVolumeInfo ( // implemented in VolInfo.c
  5802. IN PIRP_CONTEXT IrpContext,
  5803. IN PIRP Irp
  5804. );
  5805. NTSTATUS
  5806. NtfsCommonWrite ( // implemented in Write.c
  5807. IN PIRP_CONTEXT IrpContext,
  5808. IN PIRP Irp
  5809. );
  5810. //
  5811. // The following procedure is used by the FSP and FSD routines to complete
  5812. // an IRP. Either the Irp or IrpContext may be NULL depending on whether
  5813. // this is being done for a user or for a FS service.
  5814. //
  5815. // This would typically be done in order to pass a "naked" IrpContext off to
  5816. // the Fsp for post processing, such as read ahead.
  5817. //
  5818. VOID
  5819. NtfsCompleteRequest (
  5820. IN OUT PIRP_CONTEXT IrpContext OPTIONAL,
  5821. IN OUT PIRP Irp OPTIONAL,
  5822. IN NTSTATUS Status
  5823. );
  5824. //
  5825. // Here are the callbacks used by the I/O system for checking for fast I/O or
  5826. // doing a fast query info call, or doing fast lock calls.
  5827. //
  5828. BOOLEAN
  5829. NtfsFastIoCheckIfPossible (
  5830. IN PFILE_OBJECT FileObject,
  5831. IN PLARGE_INTEGER FileOffset,
  5832. IN ULONG Length,
  5833. IN BOOLEAN Wait,
  5834. IN ULONG LockKey,
  5835. IN BOOLEAN CheckForReadOperation,
  5836. OUT PIO_STATUS_BLOCK IoStatus,
  5837. IN PDEVICE_OBJECT DeviceObject
  5838. );
  5839. BOOLEAN
  5840. NtfsFastQueryBasicInfo (
  5841. IN PFILE_OBJECT FileObject,
  5842. IN BOOLEAN Wait,
  5843. IN OUT PFILE_BASIC_INFORMATION Buffer,
  5844. OUT PIO_STATUS_BLOCK IoStatus,
  5845. IN PDEVICE_OBJECT DeviceObject
  5846. );
  5847. BOOLEAN
  5848. NtfsFastQueryStdInfo (
  5849. IN PFILE_OBJECT FileObject,
  5850. IN BOOLEAN Wait,
  5851. IN OUT PFILE_STANDARD_INFORMATION Buffer,
  5852. OUT PIO_STATUS_BLOCK IoStatus,
  5853. IN PDEVICE_OBJECT DeviceObject
  5854. );
  5855. BOOLEAN
  5856. NtfsFastLock (
  5857. IN PFILE_OBJECT FileObject,
  5858. IN PLARGE_INTEGER FileOffset,
  5859. IN PLARGE_INTEGER Length,
  5860. PEPROCESS ProcessId,
  5861. ULONG Key,
  5862. BOOLEAN FailImmediately,
  5863. BOOLEAN ExclusiveLock,
  5864. OUT PIO_STATUS_BLOCK IoStatus,
  5865. IN PDEVICE_OBJECT DeviceObject
  5866. );
  5867. BOOLEAN
  5868. NtfsFastUnlockSingle (
  5869. IN PFILE_OBJECT FileObject,
  5870. IN PLARGE_INTEGER FileOffset,
  5871. IN PLARGE_INTEGER Length,
  5872. PEPROCESS ProcessId,
  5873. ULONG Key,
  5874. OUT PIO_STATUS_BLOCK IoStatus,
  5875. IN PDEVICE_OBJECT DeviceObject
  5876. );
  5877. BOOLEAN
  5878. NtfsFastUnlockAll (
  5879. IN PFILE_OBJECT FileObject,
  5880. PEPROCESS ProcessId,
  5881. OUT PIO_STATUS_BLOCK IoStatus,
  5882. IN PDEVICE_OBJECT DeviceObject
  5883. );
  5884. BOOLEAN
  5885. NtfsFastUnlockAllByKey (
  5886. IN PFILE_OBJECT FileObject,
  5887. PVOID ProcessId,
  5888. ULONG Key,
  5889. OUT PIO_STATUS_BLOCK IoStatus,
  5890. IN PDEVICE_OBJECT DeviceObject
  5891. );
  5892. BOOLEAN
  5893. NtfsFastQueryNetworkOpenInfo (
  5894. IN struct _FILE_OBJECT *FileObject,
  5895. IN BOOLEAN Wait,
  5896. OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer,
  5897. OUT struct _IO_STATUS_BLOCK *IoStatus,
  5898. IN struct _DEVICE_OBJECT *DeviceObject
  5899. );
  5900. VOID
  5901. NtfsFastIoQueryCompressionInfo (
  5902. IN PFILE_OBJECT FileObject,
  5903. OUT PFILE_COMPRESSION_INFORMATION Buffer,
  5904. OUT PIO_STATUS_BLOCK IoStatus
  5905. );
  5906. VOID
  5907. NtfsFastIoQueryCompressedSize (
  5908. IN PFILE_OBJECT FileObject,
  5909. IN PLARGE_INTEGER FileOffset,
  5910. OUT PULONG CompressedSize
  5911. );
  5912. //
  5913. // The following macro is used by the dispatch routines to determine if
  5914. // an operation is to be done with or without WriteThrough.
  5915. //
  5916. // BOOLEAN
  5917. // IsFileWriteThrough (
  5918. // IN PFILE_OBJECT FileObject,
  5919. // IN PVCB Vcb
  5920. // );
  5921. //
  5922. #define IsFileWriteThrough(FO,V) ( \
  5923. FlagOn((FO)->Flags, FO_WRITE_THROUGH) \
  5924. )
  5925. //
  5926. // The following macro is used to set the is fast i/o possible field in
  5927. // the common part of the non paged fcb
  5928. //
  5929. // NotPossible - Volume not mounted
  5930. // - Oplock state prevents it
  5931. //
  5932. // Possible - Not compressed or sparse
  5933. // - No file locks
  5934. // - Not a read only volume
  5935. // - No Usn journal for this volume
  5936. //
  5937. // Questionable - All other cases
  5938. //
  5939. //
  5940. // BOOLEAN
  5941. // NtfsIsFastIoPossible (
  5942. // IN PSCB Scb
  5943. // );
  5944. //
  5945. #define NtfsIsFastIoPossible(S) (BOOLEAN) ( \
  5946. (!FlagOn((S)->Vcb->VcbState, VCB_STATE_VOLUME_MOUNTED) || \
  5947. !FsRtlOplockIsFastIoPossible( &(S)->ScbType.Data.Oplock )) ? \
  5948. \
  5949. FastIoIsNotPossible : \
  5950. \
  5951. ((((S)->CompressionUnit == 0) && \
  5952. (((S)->ScbType.Data.FileLock == NULL) || \
  5953. !FsRtlAreThereCurrentFileLocks( (S)->ScbType.Data.FileLock )) && \
  5954. !NtfsIsVolumeReadOnly( (S)->Vcb ) && \
  5955. ((S)->Vcb->UsnJournal == NULL)) ? \
  5956. \
  5957. FastIoIsPossible : \
  5958. \
  5959. FastIoIsQuestionable) \
  5960. )
  5961. //
  5962. // The following macro is used to detemine if the file object is opened
  5963. // for read only access (i.e., it is not also opened for write access or
  5964. // delete access).
  5965. //
  5966. // BOOLEAN
  5967. // IsFileObjectReadOnly (
  5968. // IN PFILE_OBJECT FileObject
  5969. // );
  5970. //
  5971. #define IsFileObjectReadOnly(FO) (!((FO)->WriteAccess | (FO)->DeleteAccess))
  5972. //
  5973. // The following macros are used to establish the semantics needed
  5974. // to do a return from within a try-finally clause. As a rule every
  5975. // try clause must end with a label call try_exit. For example,
  5976. //
  5977. // try {
  5978. // :
  5979. // :
  5980. //
  5981. // try_exit: NOTHING;
  5982. // } finally {
  5983. //
  5984. // :
  5985. // :
  5986. // }
  5987. //
  5988. // Every return statement executed inside of a try clause should use the
  5989. // try_return macro. If the compiler fully supports the try-finally construct
  5990. // then the macro should be
  5991. //
  5992. // #define try_return(S) { return(S); }
  5993. //
  5994. // If the compiler does not support the try-finally construct then the macro
  5995. // should be
  5996. //
  5997. // #define try_return(S) { S; goto try_exit; }
  5998. //
  5999. #define try_return(S) { S; goto try_exit; }
  6000. //
  6001. // Simple initialization for a name pair
  6002. //
  6003. // VOID
  6004. // NtfsInitializeNamePair(PNAME_PAIR PNp);
  6005. //
  6006. #define NtfsInitializeNamePair(PNp) { \
  6007. (PNp)->Short.Buffer = (PNp)->ShortBuffer; \
  6008. (PNp)->Long.Buffer = (PNp)->LongBuffer; \
  6009. (PNp)->Short.Length = 0; \
  6010. (PNp)->Long.Length = 0; \
  6011. (PNp)->Short.MaximumLength = sizeof((PNp)->ShortBuffer); \
  6012. (PNp)->Long.MaximumLength = sizeof((PNp)->LongBuffer); \
  6013. }
  6014. //
  6015. // Copy a length of WCHARs into a side of a name pair. Only copy the first name
  6016. // that fits to avoid useless work if more than three links are encountered (per
  6017. // BrianAn), very rare case. We use the filename flags to figure out what kind of
  6018. // name we have.
  6019. //
  6020. // VOID
  6021. // NtfsCopyNameToNamePair(
  6022. // PNAME_PAIR PNp,
  6023. // WCHAR Source,
  6024. // ULONG SourceLen,
  6025. // UCHAR NameFlags);
  6026. //
  6027. #define NtfsCopyNameToNamePair(PNp, Source, SourceLen, NameFlags) { \
  6028. if (!FlagOn((NameFlags), FILE_NAME_DOS)) { \
  6029. if ((PNp)->Long.Length == 0) { \
  6030. if ((PNp)->Long.MaximumLength < ((SourceLen)*sizeof(WCHAR))) { \
  6031. if ((PNp)->Long.Buffer != (PNp)->LongBuffer) { \
  6032. NtfsFreePool((PNp)->Long.Buffer); \
  6033. (PNp)->Long.Buffer = (PNp)->LongBuffer; \
  6034. (PNp)->Long.MaximumLength = sizeof((PNp)->LongBuffer); \
  6035. } \
  6036. (PNp)->Long.Buffer = NtfsAllocatePool(PagedPool,(SourceLen)*sizeof(WCHAR)); \
  6037. (PNp)->Long.MaximumLength = (SourceLen)*sizeof(WCHAR); \
  6038. } \
  6039. RtlCopyMemory((PNp)->Long.Buffer, (Source), (SourceLen)*sizeof(WCHAR)); \
  6040. (PNp)->Long.Length = (SourceLen)*sizeof(WCHAR); \
  6041. } \
  6042. } else { \
  6043. ASSERT((PNp)->Short.Buffer == (PNp)->ShortBuffer); \
  6044. if ((PNp)->Short.Length == 0) { \
  6045. RtlCopyMemory((PNp)->Short.Buffer, (Source), (SourceLen)*sizeof(WCHAR)); \
  6046. (PNp)->Short.Length = (SourceLen)*sizeof(WCHAR); \
  6047. } \
  6048. } \
  6049. }
  6050. //
  6051. // Set up a previously used name pair for reuse.
  6052. //
  6053. // VOID
  6054. // NtfsResetNamePair(PNAME_PAIR PNp);
  6055. //
  6056. #define NtfsResetNamePair(PNp) { \
  6057. if ((PNp)->Long.Buffer != (PNp)->LongBuffer) { \
  6058. NtfsFreePool((PNp)->Long.Buffer); \
  6059. } \
  6060. NtfsInitializeNamePair(PNp); \
  6061. }
  6062. //
  6063. // Cairo support stuff.
  6064. //
  6065. typedef NTSTATUS
  6066. (*FILE_RECORD_WALK) (
  6067. IN PIRP_CONTEXT IrpContext,
  6068. IN PFCB Fcb,
  6069. IN OUT PVOID Context
  6070. );
  6071. NTSTATUS
  6072. NtfsIterateMft (
  6073. IN PIRP_CONTEXT IrpContext,
  6074. IN PVCB Vcb,
  6075. IN OUT PFILE_REFERENCE FileReference,
  6076. IN FILE_RECORD_WALK FileRecordFunction,
  6077. IN PVOID Context
  6078. );
  6079. VOID
  6080. NtfsPostSpecial (
  6081. IN PIRP_CONTEXT IrpContext,
  6082. IN PVCB Vcb,
  6083. IN POST_SPECIAL_CALLOUT PostSpecialCallout,
  6084. IN PVOID Context
  6085. );
  6086. VOID
  6087. NtfsSpecialDispatch (
  6088. PVOID Context
  6089. );
  6090. VOID
  6091. NtfsLoadAddOns (
  6092. IN struct _DRIVER_OBJECT *DriverObject,
  6093. IN PVOID Context,
  6094. IN ULONG Count
  6095. );
  6096. NTSTATUS
  6097. NtfsTryOpenFcb (
  6098. IN PIRP_CONTEXT IrpContext,
  6099. IN PVCB Vcb,
  6100. OUT PFCB *CurrentFcb,
  6101. IN FILE_REFERENCE FileReference
  6102. );
  6103. //
  6104. // The following define controls whether quota operations are done
  6105. // on this FCB.
  6106. //
  6107. #define NtfsPerformQuotaOperation(FCB) ((FCB)->QuotaControl != NULL)
  6108. VOID
  6109. NtfsAcquireQuotaControl (
  6110. IN PIRP_CONTEXT IrpContext,
  6111. IN PQUOTA_CONTROL_BLOCK QuotaControl
  6112. );
  6113. VOID
  6114. NtfsCalculateQuotaAdjustment (
  6115. IN PIRP_CONTEXT IrpContext,
  6116. IN PFCB Fcb,
  6117. OUT PLONGLONG Delta
  6118. );
  6119. VOID
  6120. NtfsDereferenceQuotaControlBlock (
  6121. IN PVCB Vcb,
  6122. IN PQUOTA_CONTROL_BLOCK *QuotaControl
  6123. );
  6124. VOID
  6125. NtfsFixupQuota (
  6126. IN PIRP_CONTEXT IrpContext,
  6127. IN PFCB Fcb
  6128. );
  6129. NTSTATUS
  6130. NtfsFsQuotaQueryInfo (
  6131. IN PIRP_CONTEXT IrpContext,
  6132. IN PVCB Vcb,
  6133. IN ULONG StartingId,
  6134. IN BOOLEAN ReturnSingleEntry,
  6135. IN PFILE_QUOTA_INFORMATION *FileQuotaInfo,
  6136. IN OUT PULONG Length,
  6137. IN OUT PCCB Ccb OPTIONAL
  6138. );
  6139. NTSTATUS
  6140. NtfsFsQuotaSetInfo (
  6141. IN PIRP_CONTEXT IrpContext,
  6142. IN PVCB Vcb,
  6143. IN PFILE_QUOTA_INFORMATION FileQuotaInfo,
  6144. IN ULONG Length
  6145. );
  6146. VOID
  6147. NtfsGetRemainingQuota (
  6148. IN PIRP_CONTEXT IrpContext,
  6149. IN ULONG OwnerId,
  6150. OUT PULONGLONG RemainingQuota,
  6151. OUT PULONGLONG TotalQuota,
  6152. IN OUT PQUICK_INDEX_HINT QuickIndexHint OPTIONAL
  6153. );
  6154. ULONG
  6155. NtfsGetCallersUserId (
  6156. IN PIRP_CONTEXT IrpContext
  6157. );
  6158. ULONG
  6159. NtfsGetOwnerId (
  6160. IN PIRP_CONTEXT IrpContext,
  6161. IN PSID Sid,
  6162. IN BOOLEAN CreateNew,
  6163. IN PFILE_QUOTA_INFORMATION FileQuotaInfo OPTIONAL
  6164. );
  6165. PQUOTA_CONTROL_BLOCK
  6166. NtfsInitializeQuotaControlBlock (
  6167. IN PVCB Vcb,
  6168. IN ULONG OwnerId
  6169. );
  6170. VOID
  6171. NtfsInitializeQuotaIndex (
  6172. IN PIRP_CONTEXT IrpContext,
  6173. IN PFCB Fcb,
  6174. IN PVCB Vcb
  6175. );
  6176. VOID
  6177. NtfsMarkQuotaCorrupt (
  6178. IN PIRP_CONTEXT IrpContext,
  6179. IN PVCB Vcb
  6180. );
  6181. VOID
  6182. NtfsRepairQuotaIndex (
  6183. IN PIRP_CONTEXT IrpContext,
  6184. IN PVOID Context
  6185. );
  6186. VOID
  6187. NtfsMoveQuotaOwner (
  6188. IN PIRP_CONTEXT IrpContext,
  6189. IN PFCB Fcb,
  6190. IN PSECURITY_DESCRIPTOR Security
  6191. );
  6192. VOID
  6193. NtfsPostRepairQuotaIndex (
  6194. IN PIRP_CONTEXT IrpContext,
  6195. IN PVCB Vcb
  6196. );
  6197. NTSTATUS
  6198. NtfsQueryQuotaUserSidList (
  6199. IN PIRP_CONTEXT IrpContext,
  6200. IN PVCB Vcb,
  6201. IN PFILE_GET_QUOTA_INFORMATION SidList,
  6202. OUT PFILE_QUOTA_INFORMATION QuotaBuffer,
  6203. IN OUT PULONG BufferLength,
  6204. IN BOOLEAN ReturnSingleEntry
  6205. );
  6206. VOID
  6207. NtfsReleaseQuotaControl (
  6208. IN PIRP_CONTEXT IrpContext,
  6209. IN PQUOTA_CONTROL_BLOCK QuotaControl
  6210. );
  6211. VOID
  6212. NtfsUpdateFileQuota (
  6213. IN PIRP_CONTEXT IrpContext,
  6214. IN PFCB Fcb,
  6215. IN PLONGLONG Delta,
  6216. IN LOGICAL LogIt,
  6217. IN LOGICAL CheckQuota
  6218. );
  6219. VOID
  6220. NtfsUpdateQuotaDefaults (
  6221. IN PIRP_CONTEXT IrpContext,
  6222. IN PVCB Vcb,
  6223. IN PFILE_FS_CONTROL_INFORMATION FileQuotaInfo
  6224. );
  6225. INLINE
  6226. VOID
  6227. NtfsConditionallyFixupQuota (
  6228. IN PIRP_CONTEXT IrpContext,
  6229. IN PFCB Fcb
  6230. )
  6231. {
  6232. if (FlagOn( Fcb->Vcb->QuotaFlags, QUOTA_FLAG_TRACKING_ENABLED )) {
  6233. NtfsFixupQuota ( IrpContext, Fcb );
  6234. }
  6235. }
  6236. INLINE
  6237. VOID
  6238. NtfsConditionallyUpdateQuota (
  6239. IN PIRP_CONTEXT IrpContext,
  6240. IN PFCB Fcb,
  6241. IN PLONGLONG Delta,
  6242. IN LOGICAL LogIt,
  6243. IN LOGICAL CheckQuota
  6244. )
  6245. {
  6246. if (NtfsPerformQuotaOperation( Fcb ) &&
  6247. !FlagOn( IrpContext->State, IRP_CONTEXT_STATE_QUOTA_DISABLE )) {
  6248. NtfsUpdateFileQuota( IrpContext, Fcb, Delta, LogIt, CheckQuota );
  6249. }
  6250. }
  6251. extern BOOLEAN NtfsAllowFixups;
  6252. INLINE
  6253. VOID
  6254. NtfsReleaseQuotaIndex (
  6255. IN PIRP_CONTEXT IrpContext,
  6256. IN PVCB Vcb,
  6257. IN BOOLEAN Acquired
  6258. )
  6259. {
  6260. if (Acquired) {
  6261. NtfsReleaseScb( IrpContext, Vcb->QuotaTableScb );
  6262. }
  6263. }
  6264. //
  6265. // Define the quota charge for resident streams.
  6266. //
  6267. #define NtfsResidentStreamQuota( Vcb ) ((LONG) Vcb->BytesPerFileRecordSegment)
  6268. //
  6269. // The following macro tests to see if it is ok for an internal routine to
  6270. // write to the volume.
  6271. //
  6272. #define NtfsIsVcbAvailable( Vcb ) (FlagOn( Vcb->VcbState, \
  6273. VCB_STATE_VOLUME_MOUNTED | \
  6274. VCB_STATE_FLAG_SHUTDOWN | \
  6275. VCB_STATE_PERFORMED_DISMOUNT | \
  6276. VCB_STATE_LOCKED) == VCB_STATE_VOLUME_MOUNTED)
  6277. //
  6278. // Test to see if the volume is mounted read only.
  6279. //
  6280. #define NtfsIsVolumeReadOnly( Vcb ) (FlagOn( (Vcb)->VcbState, VCB_STATE_MOUNT_READ_ONLY ))
  6281. //
  6282. // Processing required so reg. exception filter works if another one is being used
  6283. // to handle an exception that could be raise via NtfsRaiseStatus. If its always
  6284. // rethrown this is not necc.
  6285. //
  6286. #define NtfsMinimumExceptionProcessing(I) { \
  6287. if((I) != NULL) { \
  6288. ClearFlag( (I)->Flags, IRP_CONTEXT_FLAG_RAISED_STATUS ); \
  6289. } \
  6290. }
  6291. #ifdef NTFSDBG
  6292. BOOLEAN
  6293. NtfsChangeResourceOrderState(
  6294. IN PIRP_CONTEXT IrpContext,
  6295. IN NTFS_RESOURCE_NAME NewResource,
  6296. IN BOOLEAN Release,
  6297. IN ULONG UnsafeTransition
  6298. );
  6299. NTFS_RESOURCE_NAME
  6300. NtfsIdentifyFcb (
  6301. IN PVCB Vcb,
  6302. IN PFCB Fcb
  6303. );
  6304. #endif
  6305. //
  6306. // Size of a normalized name which is long enough to be freed at cleanup
  6307. //
  6308. #define LONGNAME_THRESHOLD 0x200
  6309. VOID
  6310. NtfsTrimNormalizedNames (
  6311. IN PIRP_CONTEXT IrpContext,
  6312. IN PFCB Fcb,
  6313. IN PSCB ParentScb
  6314. );
  6315. #define NtfsSnapshotFileSizesTest( I, S ) (FlagOn( (S)->ScbState, SCB_STATE_MODIFIED_NO_WRITE | SCB_STATE_CONVERT_UNDERWAY ) || \
  6316. ((S) == (I)->CleanupStructure) || \
  6317. ((S)->Fcb == (I)->CleanupStructure))
  6318. //
  6319. // Reservation needed = AllocationSize
  6320. // largest transfer size - this is because in a single transfer we cannot reuse clusters we freed from the totalallocated piece of the calculation
  6321. // metadata charge for new clusters
  6322. // minus the already allocated space
  6323. //
  6324. //
  6325. // One problem with the reservation strategy, is that we cannot precisely reserve
  6326. // for metadata. If we reserve too much, we will return premature disk full, if
  6327. // we reserve too little, the Lazy Writer can get an error. As we add compression
  6328. // units to a file, large files will eventually require additional File Records.
  6329. // If each compression unit required 0x20 bytes of run information (fairly pessimistic)
  6330. // then a 0x400 size file record would fill up with less than 0x20 runs requiring
  6331. // (worst case) two additional clusters for another file record. So each 0x20
  6332. // compression units require 0x200 reserved clusters, and a separate 2 cluster
  6333. // file record. 0x200/2 = 0x100. So the calculations below tack a 1/0x100 (about
  6334. // .4% "surcharge" on the amount reserved both in the Scb and the Vcb, to solve
  6335. // the Lazy Writer popups like the ones Alan Morris gets in the print lab.
  6336. //
  6337. #define NtfsCalculateNeededReservedSpace( S ) \
  6338. ((S)->Header.AllocationSize.QuadPart + \
  6339. MM_MAXIMUM_DISK_IO_SIZE + \
  6340. (S)->CompressionUnit - \
  6341. (FlagOn( (S)->Vcb->VcbState, VCB_STATE_RESTART_IN_PROGRESS ) ? \
  6342. (S)->Header.AllocationSize.QuadPart : \
  6343. (S)->TotalAllocated) + \
  6344. (Int64ShraMod32( (S)->ScbType.Data.TotalReserved, 8 )))
  6345. PDEALLOCATED_CLUSTERS
  6346. NtfsGetDeallocatedClusters (
  6347. IN PIRP_CONTEXT IrpContext,
  6348. IN PVCB Vcb
  6349. );
  6350. //
  6351. // Dynamically allocate stack space for local variables.
  6352. //
  6353. #define NtfsAllocateFromStack(S) _alloca(S)
  6354. //
  6355. // Common Create Flag definitions
  6356. //
  6357. #define CREATE_FLAG_DOS_ONLY_COMPONENT (0x00000001)
  6358. #define CREATE_FLAG_CREATE_FILE_CASE (0x00000002)
  6359. #define CREATE_FLAG_DELETE_ON_CLOSE (0x00000004)
  6360. #define CREATE_FLAG_TRAILING_BACKSLASH (0x00000008)
  6361. #define CREATE_FLAG_TRAVERSE_CHECK (0x00000010)
  6362. #define CREATE_FLAG_IGNORE_CASE (0x00000020)
  6363. #define CREATE_FLAG_OPEN_BY_ID (0x00000040)
  6364. #define CREATE_FLAG_ACQUIRED_OBJECT_ID_INDEX (0x00000080)
  6365. #define CREATE_FLAG_BACKOUT_FAILED_OPENS (0x00000100)
  6366. #define CREATE_FLAG_INSPECT_NAME_FOR_REPARSE (0x00000200)
  6367. #define CREATE_FLAG_SHARED_PARENT_FCB (0x00000400)
  6368. #define CREATE_FLAG_ACQUIRED_VCB (0x00000800)
  6369. #define CREATE_FLAG_FIRST_PASS (0x00002000)
  6370. #define CREATE_FLAG_FOUND_ENTRY (0x00004000)
  6371. #define CREATE_FLAG_EXPLICIT_ATTRIBUTE_CODE (0x00008000)
  6372. //
  6373. // The following macro gives the effective mode to do security related checks based on the irp
  6374. // If the irp is for a create request: The force_check flag only is defined for creates
  6375. //
  6376. //
  6377. // KPROCESSOR_MODE
  6378. // NtfsEffectiveMode (
  6379. // IN PIRP Irp,
  6380. // IN PIO_STACK_LOCATION IrpSp
  6381. // );
  6382. //
  6383. #define NtfsEffectiveMode( I, IS ) (ASSERT( (IS)->MajorFunction == IRP_MJ_CREATE), (FlagOn( (IS)->Flags, SL_FORCE_ACCESS_CHECK )) ? UserMode : (I)->RequestorMode )
  6384. #endif // _NTFSPROC_