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

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