Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

853 lines
20 KiB

  1. /*++ BUILD Version: 0000 // Increment this if a change has global effects
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. LfsProcs.h
  5. Abstract:
  6. This module defines all of the globally used procedures in the Log
  7. File Service.
  8. Author:
  9. Brian Andrew [BrianAn] 20-June-1991
  10. Revision History:
  11. --*/
  12. #ifndef _LFSPROCS_
  13. #define _LFSPROCS_
  14. #include <ntifs.h>
  15. #include <string.h>
  16. #include <lfs.h>
  17. #include "nodetype.h"
  18. #include "LfsDisk.h"
  19. #include "LfsStruc.h"
  20. #include "LfsData.h"
  21. //
  22. // Tag all of our allocations if tagging is turned on
  23. //
  24. #undef FsRtlAllocatePool
  25. #undef FsRtlAllocatePoolWithQuota
  26. #define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,' sfL')
  27. #define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,' sfL')
  28. #define LfsAllocatePoolNoRaise(a,b) ExAllocatePoolWithTag((a),(b),MODULE_POOL_TAG)
  29. #define LfsAllocatePool(a,b) ExAllocatePoolWithTag(((a) | POOL_RAISE_IF_ALLOCATION_FAILURE),(b),MODULE_POOL_TAG)
  30. #define LfsFreePool(pv) ExFreePool(pv)
  31. #ifndef INLINE
  32. // definition of inline
  33. #define INLINE __inline
  34. #endif
  35. //
  36. // The following routines provide an interface with the cache package.
  37. // They are contained in 'CacheSup.c'.
  38. //
  39. NTSTATUS
  40. LfsPinOrMapData (
  41. IN PLFCB Lfcb,
  42. IN LONGLONG FileOffset,
  43. IN ULONG Length,
  44. IN BOOLEAN PinData,
  45. IN BOOLEAN AllowErrors,
  46. IN BOOLEAN IgnoreUsaErrors,
  47. OUT PBOOLEAN UsaError,
  48. OUT PVOID *Buffer,
  49. OUT PBCB *Bcb
  50. );
  51. //
  52. // VOID
  53. // LfsPreparePinWriteData (
  54. // IN PLFCB Lfcb,
  55. // IN LONGLONG FileOffset,
  56. // IN ULONG Length,
  57. // IN LOGICAL ReadFromDisk,
  58. // OUT PVOID *Buffer,
  59. // OUT PBCB *Bcb
  60. // );
  61. //
  62. #ifdef LFS_CLUSTER_CHECK
  63. #define LfsPreparePinWriteData(L,FO,LEN,R,BUF,B) { \
  64. LONGLONG _LocalFileOffset = (FO); \
  65. CcPinRead( (L)->FileObject, \
  66. (PLARGE_INTEGER)&_LocalFileOffset, \
  67. (LEN), \
  68. TRUE, \
  69. (B), \
  70. (BUF) ); \
  71. }
  72. #else
  73. #define LfsPreparePinWriteData(L,FO,LEN,R,BUF,B) { \
  74. LONGLONG _LocalFileOffset = (FO); \
  75. if (R) { \
  76. CcPinRead( (L)->FileObject, \
  77. (PLARGE_INTEGER)&_LocalFileOffset, \
  78. (LEN), \
  79. TRUE, \
  80. (B), \
  81. (BUF) ); \
  82. } else { \
  83. CcPreparePinWrite( (L)->FileObject, \
  84. (PLARGE_INTEGER)&_LocalFileOffset, \
  85. (LEN), \
  86. FALSE, \
  87. TRUE, \
  88. (B), \
  89. (BUF) ); \
  90. } \
  91. }
  92. #endif
  93. VOID
  94. LfsPinOrMapLogRecordHeader (
  95. IN PLFCB Lfcb,
  96. IN LSN Lsn,
  97. IN BOOLEAN PinData,
  98. IN BOOLEAN IgnoreUsaErrors,
  99. OUT PBOOLEAN UsaError,
  100. OUT PLFS_RECORD_HEADER *RecordHeader,
  101. OUT PBCB *Bcb
  102. );
  103. VOID
  104. LfsCopyReadLogRecord (
  105. IN PLFCB Lfcb,
  106. IN PLFS_RECORD_HEADER RecordHeader,
  107. OUT PVOID Buffer
  108. );
  109. VOID
  110. LfsFlushLfcb (
  111. IN PLFCB Lfcb,
  112. IN LSN TargetLsn,
  113. IN BOOLEAN RestartLsn
  114. );
  115. BOOLEAN
  116. LfsReadRestart (
  117. IN PLFCB Lfcb,
  118. IN LONGLONG FileSize,
  119. IN BOOLEAN FirstRestart,
  120. OUT PLONGLONG RestartPageOffset,
  121. OUT PLFS_RESTART_PAGE_HEADER *RestartPage,
  122. OUT PBCB *RestartPageBcb,
  123. OUT PBOOLEAN ChkdskWasRun,
  124. OUT PBOOLEAN ValidPage,
  125. OUT PBOOLEAN UninitializedFile,
  126. OUT PBOOLEAN LogPacked,
  127. OUT PLSN LastLsn
  128. );
  129. //
  130. // The following routines manipulate buffer control blocks. They are
  131. // contained in 'LbcbSup.c'
  132. //
  133. VOID
  134. LfsFlushLbcb (
  135. IN PLFCB Lfcb,
  136. IN PLBCB Lbcb
  137. );
  138. VOID
  139. LfsFlushToLsnPriv (
  140. IN PLFCB Lfcb,
  141. IN LSN Lsn,
  142. IN BOOLEAN RestartLsn
  143. );
  144. PLBCB
  145. LfsGetLbcb (
  146. IN PLFCB Lfcb
  147. );
  148. //
  149. // The following routines are in LfsData.c
  150. //
  151. LONG
  152. LfsExceptionFilter (
  153. IN PEXCEPTION_POINTERS ExceptionPointer
  154. );
  155. //
  156. // Log page support routines. The following routines manipulate and
  157. // modify log pages. They are contained in 'LogPgSup.c'
  158. //
  159. //
  160. // VOID
  161. // LfsTruncateOffsetToLogPage (
  162. // IN PLFCB Lfcb,
  163. // IN LONGLONG LargeInt,
  164. // OUT PLONGLONG Result
  165. // );
  166. //
  167. // ULONG
  168. // LfsLogPageOffset (
  169. // IN PLFCB Lfcb,
  170. // IN ULONG Integer
  171. // );
  172. //
  173. #define LfsTruncateOffsetToLogPage(LFCB,LI,OUTLI) \
  174. *(OUTLI) = LI; \
  175. *((PULONG)(OUTLI)) &= (LFCB)->LogPageInverseMask
  176. #define LfsLogPageOffset(LFCB,INT) \
  177. (INT & (LFCB)->LogPageMask)
  178. VOID
  179. LfsNextLogPageOffset (
  180. IN PLFCB Lfcb,
  181. IN LONGLONG CurrentLogPageOffset,
  182. OUT PLONGLONG NextLogPageOffset,
  183. OUT PBOOLEAN Wrapped
  184. );
  185. PVOID
  186. LfsAllocateSpanningBuffer (
  187. IN PLFCB Lfcb,
  188. IN ULONG Length
  189. );
  190. VOID
  191. LfsFreeSpanningBuffer (
  192. IN PVOID Buffer
  193. );
  194. //
  195. // The following routines provide support for dealing with log records. They
  196. // are contained in 'LogRcSup.c'
  197. //
  198. BOOLEAN
  199. LfsWriteLogRecordIntoLogPage (
  200. IN PLFCB Lfcb,
  201. IN PLCH Lch,
  202. IN ULONG NumberOfWriteEntries,
  203. IN PLFS_WRITE_ENTRY WriteEntries,
  204. IN LFS_RECORD_TYPE RecordType,
  205. IN TRANSACTION_ID *TransactionId OPTIONAL,
  206. IN LSN ClientUndoNextLsn OPTIONAL,
  207. IN LSN ClientPreviousLsn OPTIONAL,
  208. IN LONG UndoRequirement,
  209. IN BOOLEAN ForceToDisk,
  210. OUT PLSN Lsn
  211. );
  212. //
  213. // Lsn support routines. The following routines provide support for
  214. // manipulating Lsn values. They are contained in 'LsnSup.c'
  215. //
  216. //
  217. // LSN
  218. // LfsFileOffsetToLsn (
  219. // IN PLFCB Lfcb,
  220. // IN LONGLONG FileOffset,
  221. // IN LONGLONG SequenceNumber
  222. // );
  223. //
  224. // BOOLEAN
  225. // LfsIsLsnInFile (
  226. // IN PLFCB Lfcb,
  227. // IN LSN Lsn
  228. // );
  229. //
  230. // LSN
  231. // LfsComputeLsnFromLbcb (
  232. // IN PLFCB Lfcb,
  233. // IN PLBCB Lbcb
  234. // );
  235. //
  236. // VOID
  237. // LfsTruncateLsnToLogPage (
  238. // IN PLFCB Lfcb,
  239. // IN LSN Lsn,
  240. // OUT PLONGLONG FileOffset
  241. // );
  242. //
  243. // LONGLONG
  244. // LfsLsnToFileOffset (
  245. // IN PLFCB Lfcb,
  246. // IN LSN Lsn
  247. // );
  248. //
  249. // LONGLONG
  250. // LfsLsnToSeqNumber (
  251. // IN PLFCB Lfcb,
  252. // IN LSN Lsn
  253. // );
  254. //
  255. // ULONG
  256. // LfsLsnToPageOffset (
  257. // IN PLFCB Lfcb,
  258. // IN LSN Lsn
  259. // );
  260. //
  261. #define LfsFileOffsetToLsn(LFCB,FO,SN) ( \
  262. (((ULONGLONG)(FO)) >> 3) + Int64ShllMod32((SN), (LFCB)->FileDataBits) \
  263. )
  264. #define LfsIsLsnInFile(LFCB,LSN) \
  265. (/*xxGeq*/( (LSN).QuadPart >= ((LFCB)->OldestLsn).QuadPart ) \
  266. && /*xxLeq*/( (LSN).QuadPart <= ((LFCB)->RestartArea->CurrentLsn).QuadPart ))
  267. #define LfsComputeLsnFromLbcb(LFCB,LBCB) ( \
  268. LfsFileOffsetToLsn( LFCB, \
  269. (LBCB)->FileOffset + (LBCB)->BufferOffset, \
  270. (LBCB)->SeqNumber ) \
  271. )
  272. #define LfsTruncateLsnToLogPage(LFCB,LSN,FO) { \
  273. *(FO) = LfsLsnToFileOffset( LFCB, LSN ); \
  274. *((PULONG)(FO)) &= (LFCB)->LogPageInverseMask; \
  275. }
  276. #define LfsLsnToFileOffset(LFCB,LSN) \
  277. /*xxShr*/( ((ULONGLONG)/*xxShl*/( (LSN).QuadPart << (LFCB)->SeqNumberBits )) >> ((LFCB)->SeqNumberBits - 3) )
  278. #define LfsLsnToSeqNumber(LFCB,LSN) \
  279. /*xxShr*/Int64ShrlMod32( ((ULONGLONG)(LSN).QuadPart), (LFCB)->FileDataBits )
  280. #define LfsLsnToPageOffset(LFCB,LSN) \
  281. LfsLogPageOffset( LFCB, (LSN).LowPart << 3 )
  282. VOID
  283. LfsLsnFinalOffset (
  284. IN PLFCB Lfcb,
  285. IN LSN Lsn,
  286. IN ULONG DataLength,
  287. OUT PLONGLONG FinalOffset
  288. );
  289. BOOLEAN
  290. LfsFindNextLsn (
  291. IN PLFCB Lfcb,
  292. IN PLFS_RECORD_HEADER RecordHeader,
  293. OUT PLSN Lsn
  294. );
  295. //
  296. // The following routines support the Lfs restart areas. They are contained
  297. // in 'RstrtSup.c'
  298. //
  299. VOID
  300. LfsWriteLfsRestart (
  301. IN PLFCB Lfcb,
  302. IN ULONG ThisRestartSize,
  303. IN BOOLEAN WaitForIo
  304. );
  305. VOID
  306. LfsFindOldestClientLsn (
  307. IN PLFS_RESTART_AREA RestartArea,
  308. IN PLFS_CLIENT_RECORD ClientArray,
  309. OUT PLSN OldestLsn
  310. );
  311. //
  312. // The following routines are used for managing the structures allocated
  313. // by us. They are contained in 'StrucSup.c'
  314. //
  315. PLFCB
  316. LfsAllocateLfcb (
  317. IN ULONG LogPageSize,
  318. IN LONGLONG FileSize
  319. );
  320. VOID
  321. LfsDeallocateLfcb (
  322. IN PLFCB Lfcb,
  323. IN BOOLEAN CompleteTeardown
  324. );
  325. VOID
  326. LfsAllocateLbcb (
  327. IN PLFCB Lfcb,
  328. OUT PLBCB *Lbcb
  329. );
  330. VOID
  331. LfsDeallocateLbcb (
  332. IN PLFCB Lfcb,
  333. IN PLBCB Lbcb
  334. );
  335. VOID
  336. LfsAllocateLeb (
  337. IN PLFCB Lfcb,
  338. OUT PLEB *NewLeb
  339. );
  340. VOID
  341. LfsDeallocateLeb (
  342. IN PLFCB Lfcb,
  343. IN PLEB Leb
  344. );
  345. VOID
  346. LfsReadPage (
  347. IN PLFCB Lfcb,
  348. IN PLARGE_INTEGER Offset,
  349. OUT PMDL *Mdl,
  350. OUT PVOID *Buffer
  351. );
  352. //
  353. // VOID
  354. // LfsInitializeLeb (
  355. // IN PLEB Leb,
  356. // IN LFS_CLIENT_ID ClientId,
  357. // IN LFS_CONTEXT_MODE ContextMode
  358. // );
  359. //
  360. //
  361. // VOID
  362. // LfsAllocateLch (
  363. // OUT PLCH *Lch
  364. // );
  365. //
  366. // VOID
  367. // LfsDeallocateLch (
  368. // IN PLCH Lch
  369. // );
  370. //
  371. // VOID
  372. // LfsAllocateRestartArea (
  373. // OUT PLFS_RESTART_AREA *RestartArea,
  374. // ULONG Size
  375. // );
  376. //
  377. // VOID
  378. // LfsDeallocateRestartArea (
  379. // IN PLFS_RESTART_AREA RestartArea
  380. // );
  381. //
  382. // BOOLEAN
  383. // LfsLbcbIsRestart (
  384. // IN PLBCB Lbcb
  385. // );
  386. //
  387. #define LfsInitializeLeb(LEB,ID,MODE) \
  388. (LEB)->ClientId = ID; \
  389. (LEB)->ContextMode = MODE
  390. #define LfsAllocateLch(NEW) { \
  391. *(NEW) = FsRtlAllocatePool( PagedPool, sizeof( LCH )); \
  392. RtlZeroMemory( (*NEW), sizeof( LCH )); \
  393. (*(NEW))->NodeTypeCode = LFS_NTC_LCH; \
  394. (*(NEW))->NodeByteSize = sizeof( LCH ); \
  395. }
  396. #define LfsDeallocateLch(LCH) \
  397. ExFreePool( LCH )
  398. #define LfsAllocateRestartArea(RS,SIZE) \
  399. *(RS) = FsRtlAllocatePool( PagedPool, (SIZE) ); \
  400. RtlZeroMemory( *(RS), (SIZE) )
  401. #define LfsDeallocateRestartArea(RS) \
  402. ExFreePool( RS )
  403. #define LfsLbcbIsRestart(LBCB) \
  404. (FlagOn( (LBCB)->LbcbFlags, LBCB_RESTART_LBCB ))
  405. //
  406. // The following routines provide synchronization support for the Lfs
  407. // shared structures. They are contained in 'SyncSup.c'
  408. //
  409. //
  410. // VOID
  411. // LfsAcquireLfsData (
  412. // );
  413. //
  414. // VOID
  415. // LfsReleaseLfsData (
  416. // );
  417. //
  418. // VOID
  419. // LfsAcquireLfcb (
  420. // IN PLFCB Lfcb
  421. // );
  422. //
  423. // VOID
  424. // LfsReleaseLfcb (
  425. // IN PLFCB Lfcb
  426. // );
  427. //
  428. // VOID
  429. // LfsAcquireLchExclusive (
  430. // IN PLCH Lch
  431. // );
  432. //
  433. // VOID
  434. // LfsAcquireLchShared (
  435. // IN PLCH Lch
  436. // );
  437. //
  438. // VOID
  439. // LfsReleaseLfcb (
  440. // IN PLCH Lch
  441. // );
  442. //
  443. #define LfsAcquireLfsData() \
  444. ExAcquireFastMutex( &LfsData.LfsDataLock )
  445. #define LfsReleaseLfsData() \
  446. ExReleaseFastMutex( &LfsData.LfsDataLock )
  447. #define LfsAcquireBufferLock() \
  448. ExAcquireFastMutex( &LfsData.BufferLock )
  449. #define LfsReleaseBufferLock() \
  450. ExReleaseFastMutex( &LfsData.BufferLock )
  451. #define LfsWaitForBufferNotification() \
  452. KeWaitForSingleObject( &LfsData.BufferNotification, \
  453. Executive, \
  454. KernelMode, \
  455. FALSE, \
  456. NULL )
  457. #define LfsNotifyBufferWaiters() \
  458. KeSetEvent( &LfsData.BufferNotification, 0, FALSE )
  459. #define LfsBlockBufferWaiters() \
  460. KeClearEvent( &LfsData.BufferNotification )
  461. INLINE
  462. VOID
  463. LfsAcquireLfcbExclusive (
  464. IN PLFCB Lfcb
  465. )
  466. {
  467. ExAcquireResourceExclusiveLite( &Lfcb->Sync->Resource, TRUE );
  468. }
  469. INLINE
  470. VOID
  471. LfsAcquireLfcbShared (
  472. IN PLFCB Lfcb
  473. )
  474. {
  475. ExAcquireResourceSharedLite( &Lfcb->Sync->Resource, TRUE );
  476. }
  477. INLINE
  478. VOID
  479. LfsReleaseLfcb (
  480. IN PLFCB Lfcb
  481. )
  482. {
  483. //
  484. // If the resource is owned either shared or exlcusive release it
  485. //
  486. if (ExIsResourceAcquiredSharedLite( &Lfcb->Sync->Resource )) {
  487. ExReleaseResourceLite( &Lfcb->Sync->Resource );
  488. }
  489. }
  490. INLINE
  491. VOID
  492. LfsAcquireLchExclusive (
  493. IN PLCH Lch
  494. )
  495. {
  496. ExAcquireResourceExclusiveLite( &(Lch->Sync->Resource), TRUE );
  497. }
  498. INLINE
  499. VOID
  500. LfsAcquireLchShared (
  501. IN PLCH Lch
  502. )
  503. {
  504. ExAcquireResourceSharedLite( &(Lch->Sync->Resource), TRUE );
  505. }
  506. INLINE
  507. VOID
  508. LfsReleaseLch (
  509. IN PLCH Lch
  510. )
  511. {
  512. if (ExIsResourceAcquiredSharedLite( &Lch->Sync->Resource )) {
  513. ExReleaseResourceLite( &Lch->Sync->Resource );
  514. }
  515. }
  516. //
  517. // The following routines are used to check various structures for validity
  518. // and comparability. They are contained in 'VerfySup.c'.
  519. //
  520. VOID
  521. LfsCurrentAvailSpace (
  522. IN PLFCB Lfcb,
  523. OUT PLONGLONG CurrentAvailSpace,
  524. OUT PULONG CurrentPageBytes
  525. );
  526. BOOLEAN
  527. LfsVerifyLogSpaceAvail (
  528. IN PLFCB Lfcb,
  529. IN PLCH Lch,
  530. IN ULONG RemainingLogBytes,
  531. IN LONG UndoRequirement,
  532. IN BOOLEAN ForceToDisk
  533. );
  534. VOID
  535. LfsFindCurrentAvail (
  536. IN PLFCB Lfcb
  537. );
  538. BOOLEAN
  539. LfsCheckSubsequentLogPage (
  540. IN PLFCB Lfcb,
  541. IN PLFS_RECORD_PAGE_HEADER RecordPageHeader,
  542. IN LONGLONG LogFileOffset,
  543. IN LONGLONG SequenceNumber
  544. );
  545. //
  546. // VOID
  547. // LfsValidateLch (
  548. // IN PLCH Lch
  549. // );
  550. //
  551. // VOID
  552. // LfsValidateClientId (
  553. // IN PLFCB Lfcb,
  554. // IN PLCH Lch
  555. // );
  556. //
  557. // BOOLEAN
  558. // LfsVerifyClientLsnInRange (
  559. // IN PLFCB Lfcb,
  560. // IN PLFS_CLIENT_RECORD ClientRecord,
  561. // IN LSN Lsn
  562. // );
  563. //
  564. // BOOLEAN
  565. // LfsClientIdMatch (
  566. // IN PLFS_CLIENT_ID ClientA,
  567. // IN PLFS_CLIENT_ID ClientB
  568. // )
  569. //
  570. // VOID
  571. // LfsValidateLeb (
  572. // IN PLFS_CONTEXT_BLOCK Leb,
  573. // IN PLCH Lch
  574. // )
  575. //
  576. #define LfsValidateLch(LCH) \
  577. if ((LCH) == NULL \
  578. || (LCH)->NodeTypeCode != LFS_NTC_LCH \
  579. || ((LCH)->Lfcb != NULL \
  580. && (LCH)->Lfcb->NodeTypeCode != LFS_NTC_LFCB)) { \
  581. \
  582. ExRaiseStatus( STATUS_ACCESS_DENIED ); \
  583. }
  584. #define LfsValidateClientId(LFCB,LCH) \
  585. if ((LCH)->ClientId.ClientIndex >= (LFCB)->RestartArea->LogClients \
  586. || (LCH)->ClientId.SeqNumber \
  587. != Add2Ptr( Lfcb->ClientArray, \
  588. (LCH)->ClientArrayByteOffset, \
  589. PLFS_CLIENT_RECORD )->SeqNumber) { \
  590. ExRaiseStatus( STATUS_ACCESS_DENIED ); \
  591. }
  592. #define LfsVerifyClientLsnInRange(LFCB,CLIENT,LSN) \
  593. (/*xxGeq*/( (LSN).QuadPart >= ((CLIENT)->OldestLsn).QuadPart ) \
  594. && /*xxLeq*/( (LSN).QuadPart <= ((LFCB)->RestartArea->CurrentLsn).QuadPart ) \
  595. && /*xxNeqZero*/( (LSN).QuadPart != 0 ))
  596. #define LfsClientIdMatch(CLIENT_A,CLIENT_B) \
  597. ((BOOLEAN) ((CLIENT_A)->SeqNumber == (CLIENT_B)->SeqNumber \
  598. && (CLIENT_A)->ClientIndex == (CLIENT_B)->ClientIndex))
  599. #define LfsValidateLeb(LEB,LCH) \
  600. if (LEB == NULL \
  601. || (LEB)->NodeTypeCode != LFS_NTC_LEB \
  602. || !LfsClientIdMatch( &(LEB)->ClientId, &(LCH)->ClientId )) { \
  603. ExRaiseStatus( STATUS_ACCESS_DENIED ); \
  604. }
  605. //
  606. // Miscellaneous support routines
  607. //
  608. //
  609. // ULONG
  610. // FlagOn (
  611. // IN ULONG Flags,
  612. // IN ULONG SingleFlag
  613. // );
  614. //
  615. // BOOLEAN
  616. // BooleanFlagOn (
  617. // IN ULONG Flags,
  618. // IN ULONG SingleFlag
  619. // );
  620. //
  621. // VOID
  622. // SetFlag (
  623. // IN ULONG Flags,
  624. // IN ULONG SingleFlag
  625. // );
  626. //
  627. // VOID
  628. // ClearFlag (
  629. // IN ULONG Flags,
  630. // IN ULONG SingleFlag
  631. // );
  632. //
  633. //#ifndef BooleanFlagOn
  634. //#define BooleanFlagOn(F,SF) ( \
  635. // (BOOLEAN)(((F) & (SF)) != 0) \
  636. //)
  637. //#endif
  638. //#ifndef SetFlag
  639. //#define SetFlag(Flags,SingleFlag) { \
  640. // (Flags) |= (SingleFlag); \
  641. //}
  642. //#endif
  643. //#ifndef ClearFlag
  644. //#define ClearFlag(Flags,SingleFlag) { \
  645. // (Flags) &= ~(SingleFlag); \
  646. //}
  647. //#endif
  648. //
  649. // This macro takes a pointer (or ulong) and returns its rounded up word
  650. // value
  651. //
  652. #define WordAlign(Ptr) ( \
  653. ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
  654. )
  655. //
  656. // This macro takes a pointer (or ulong) and returns its rounded up longword
  657. // value
  658. //
  659. #define LongAlign(Ptr) ( \
  660. ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
  661. )
  662. //
  663. // This macro takes a pointer (or ulong) and returns its rounded up quadword
  664. // value
  665. //
  666. #define QuadAlign(Ptr) ( \
  667. ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
  668. )
  669. //
  670. // This macro will up a 64 bit value to the next quad align boundary.
  671. //
  672. #define LiQuadAlign(LI,OUT) { \
  673. *(OUT) = /*xxAdd*/( (LI) + 7 ); \
  674. *((PULONG)(OUT)) &= 0xfffffff8; \
  675. }
  676. //
  677. // CAST
  678. // Add2Ptr (
  679. // IN PVOID Pointer,
  680. // IN ULONG Increment
  681. // IN (CAST)
  682. // );
  683. //
  684. // ULONG
  685. // PtrOffset (
  686. // IN PVOID BasePtr,
  687. // IN PVOID OffsetPtr
  688. // );
  689. //
  690. #define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC)))
  691. #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
  692. //
  693. // The following macros are used to establish the semantics needed
  694. // to do a return from within a try-finally clause. As a rule every
  695. // try clause must end with a label call try_exit. For example,
  696. //
  697. // try {
  698. // :
  699. // :
  700. //
  701. // try_exit: NOTHING;
  702. // } finally {
  703. //
  704. // :
  705. // :
  706. // }
  707. //
  708. // Every return statement executed inside of a try clause should use the
  709. // try_return macro. If the compiler fully supports the try-finally construct
  710. // then the macro should be
  711. //
  712. // #define try_return(S) { return(S); }
  713. //
  714. // If the compiler does not support the try-finally construct then the macro
  715. // should be
  716. //
  717. // #define try_return(S) { S; goto try_exit; }
  718. //
  719. #define try_return(S) { S; goto try_exit; }
  720. #endif // _LFSPROCS_