Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

lfsprocs.h

Go to the documentation of this file.
00001 /*++ BUILD Version: 0000 // Increment this if a change has global effects 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 LfsProcs.h 00008 00009 Abstract: 00010 00011 This module defines all of the globally used procedures in the Log 00012 File Service. 00013 00014 Author: 00015 00016 Brian Andrew [BrianAn] 20-June-1991 00017 00018 Revision History: 00019 00020 --*/ 00021 00022 #ifndef _LFSPROCS_ 00023 #define _LFSPROCS_ 00024 00025 #include <ntos.h> 00026 #include <string.h> 00027 #include <zwapi.h> 00028 #include <lfs.h> 00029 #include <fsrtl.h> 00030 00031 #include "nodetype.h" 00032 #include "LfsDisk.h" 00033 #include "LfsStruc.h" 00034 #include "LfsData.h" 00035 00036 // 00037 // Tag all of our allocations if tagging is turned on 00038 // 00039 00040 #undef FsRtlAllocatePool 00041 #undef FsRtlAllocatePoolWithQuota 00042 00043 #define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,' sfL') 00044 #define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,' sfL') 00045 00046 #define LfsAllocatePoolNoRaise(a,b) ExAllocatePoolWithTag((a),(b),MODULE_POOL_TAG) 00047 #define LfsAllocatePool(a,b) ExAllocatePoolWithTag(((a) | POOL_RAISE_IF_ALLOCATION_FAILURE),(b),MODULE_POOL_TAG) 00048 #define LfsFreePool(pv) ExFreePool(pv) 00049 00050 00051 // 00052 // The following routines provide an interface with the cache package. 00053 // They are contained in 'CacheSup.c'. 00054 // 00055 00056 NTSTATUS 00057 LfsPinOrMapData ( 00058 IN PLFCB Lfcb, 00059 IN LONGLONG FileOffset, 00060 IN ULONG Length, 00061 IN BOOLEAN PinData, 00062 IN BOOLEAN AllowErrors, 00063 IN BOOLEAN IgnoreUsaErrors, 00064 OUT PBOOLEAN UsaError, 00065 OUT PVOID *Buffer, 00066 OUT PBCB *Bcb 00067 ); 00068 00069 // 00070 // VOID 00071 // LfsPreparePinWriteData ( 00072 // IN PLFCB Lfcb, 00073 // IN LONGLONG FileOffset, 00074 // IN ULONG Length, 00075 // OUT PVOID *Buffer, 00076 // OUT PBCB *Bcb 00077 // ); 00078 // 00079 00080 #define LfsPreparePinWriteData(L,FO,LEN,BUF,B) { \ 00081 LONGLONG _LocalFileOffset = (FO); \ 00082 CcPreparePinWrite( (L)->FileObject, \ 00083 (PLARGE_INTEGER)&_LocalFileOffset, \ 00084 (LEN), \ 00085 FALSE, \ 00086 TRUE, \ 00087 (B), \ 00088 (BUF) ); \ 00089 } 00090 00091 VOID 00092 LfsPinOrMapLogRecordHeader ( 00093 IN PLFCB Lfcb, 00094 IN LSN Lsn, 00095 IN BOOLEAN PinData, 00096 IN BOOLEAN IgnoreUsaErrors, 00097 OUT PBOOLEAN UsaError, 00098 OUT PLFS_RECORD_HEADER *RecordHeader, 00099 OUT PBCB *Bcb 00100 ); 00101 00102 VOID 00103 LfsCopyReadLogRecord ( 00104 IN PLFCB Lfcb, 00105 IN PLFS_RECORD_HEADER RecordHeader, 00106 OUT PVOID Buffer 00107 ); 00108 00109 VOID 00110 LfsFlushLfcb ( 00111 IN PLFCB Lfcb, 00112 IN PLBCB Lbcb 00113 ); 00114 00115 BOOLEAN 00116 LfsReadRestart ( 00117 IN PLFCB Lfcb, 00118 IN LONGLONG FileSize, 00119 IN BOOLEAN FirstRestart, 00120 OUT PLONGLONG RestartPageOffset, 00121 OUT PLFS_RESTART_PAGE_HEADER *RestartPage, 00122 OUT PBCB *RestartPageBcb, 00123 OUT PBOOLEAN ChkdskWasRun, 00124 OUT PBOOLEAN ValidPage, 00125 OUT PBOOLEAN UninitializedFile, 00126 OUT PBOOLEAN LogPacked, 00127 OUT PLSN LastLsn 00128 ); 00129 00130 00131 // 00132 // The following routines manipulate buffer control blocks. They are 00133 // contained in 'LbcbSup.c' 00134 // 00135 00136 VOID 00137 LfsFlushLbcb ( 00138 IN PLFCB Lfcb, 00139 IN PLBCB Lbcb 00140 ); 00141 00142 VOID 00143 LfsFlushToLsnPriv ( 00144 IN PLFCB Lfcb, 00145 IN LSN Lsn 00146 ); 00147 00148 PLBCB 00149 LfsGetLbcb ( 00150 IN PLFCB Lfcb 00151 ); 00152 00153 00154 // 00155 // The following routines are in LfsData.c 00156 // 00157 00158 LONG 00159 LfsExceptionFilter ( 00160 IN PEXCEPTION_POINTERS ExceptionPointer 00161 ); 00162 00163 00164 // 00165 // Log page support routines. The following routines manipulate and 00166 // modify log pages. They are contained in 'LogPgSup.c' 00167 // 00168 00169 // 00170 // VOID 00171 // LfsTruncateOffsetToLogPage ( 00172 // IN PLFCB Lfcb, 00173 // IN LONGLONG LargeInt, 00174 // OUT PLONGLONG Result 00175 // ); 00176 // 00177 // ULONG 00178 // LfsLogPageOffset ( 00179 // IN PLFCB Lfcb, 00180 // IN ULONG Integer 00181 // ); 00182 // 00183 00184 #define LfsTruncateOffsetToLogPage(LFCB,LI,OUTLI) \ 00185 *(OUTLI) = LI; \ 00186 *((PULONG)(OUTLI)) &= (LFCB)->SystemPageInverseMask 00187 00188 #define LfsLogPageOffset(LFCB,INT) \ 00189 (INT & (LFCB)->LogPageMask) 00190 00191 VOID 00192 LfsNextLogPageOffset ( 00193 IN PLFCB Lfcb, 00194 IN LONGLONG CurrentLogPageOffset, 00195 OUT PLONGLONG NextLogPageOffset, 00196 OUT PBOOLEAN Wrapped 00197 ); 00198 00199 PVOID 00200 LfsAllocateSpanningBuffer ( 00201 IN PLFCB Lfcb, 00202 IN ULONG Length 00203 ); 00204 00205 VOID 00206 LfsFreeSpanningBuffer ( 00207 IN PVOID Buffer 00208 ); 00209 00210 00211 // 00212 // The following routines provide support for dealing with log records. They 00213 // are contained in 'LogRcSup.c' 00214 // 00215 00216 BOOLEAN 00217 LfsWriteLogRecordIntoLogPage ( 00218 IN PLFCB Lfcb, 00219 IN PLCH Lch, 00220 IN ULONG NumberOfWriteEntries, 00221 IN PLFS_WRITE_ENTRY WriteEntries, 00222 IN LFS_RECORD_TYPE RecordType, 00223 IN TRANSACTION_ID *TransactionId OPTIONAL, 00224 IN LSN ClientUndoNextLsn OPTIONAL, 00225 IN LSN ClientPreviousLsn OPTIONAL, 00226 IN LONG UndoRequirement, 00227 IN BOOLEAN ForceToDisk, 00228 OUT PLSN Lsn 00229 ); 00230 00231 00232 // 00233 // Lsn support routines. The following routines provide support for 00234 // manipulating Lsn values. They are contained in 'LsnSup.c' 00235 // 00236 00237 // 00238 // LSN 00239 // LfsFileOffsetToLsn ( 00240 // IN PLFCB Lfcb, 00241 // IN LONGLONG FileOffset, 00242 // IN LONGLONG SequenceNumber 00243 // ); 00244 // 00245 // BOOLEAN 00246 // LfsIsLsnInFile ( 00247 // IN PLFCB Lfcb, 00248 // IN LSN Lsn 00249 // ); 00250 // 00251 // LSN 00252 // LfsComputeLsnFromLbcb ( 00253 // IN PLFCB Lfcb, 00254 // IN PLBCB Lbcb 00255 // ); 00256 // 00257 // VOID 00258 // LfsTruncateLsnToLogPage ( 00259 // IN PLFCB Lfcb, 00260 // IN LSN Lsn, 00261 // OUT PLONGLONG FileOffset 00262 // ); 00263 // 00264 // LONGLONG 00265 // LfsLsnToFileOffset ( 00266 // IN PLFCB Lfcb, 00267 // IN LSN Lsn 00268 // ); 00269 // 00270 // LONGLONG 00271 // LfsLsnToSeqNumber ( 00272 // IN PLFCB Lfcb, 00273 // IN LSN Lsn 00274 // ); 00275 // 00276 // ULONG 00277 // LfsLsnToPageOffset ( 00278 // IN PLFCB Lfcb, 00279 // IN LSN Lsn 00280 // ); 00281 // 00282 00283 #define LfsFileOffsetToLsn(LFCB,FO,SN) ( \ 00284 (((ULONGLONG)(FO)) >> 3) + Int64ShllMod32((SN), (LFCB)->FileDataBits) \ 00285 ) 00286 00287 #define LfsIsLsnInFile(LFCB,LSN) \ 00288 (/*xxGeq*/( (LSN).QuadPart >= ((LFCB)->OldestLsn).QuadPart ) \ 00289 && /*xxLeq*/( (LSN).QuadPart <= ((LFCB)->RestartArea->CurrentLsn).QuadPart )) 00290 00291 #define LfsComputeLsnFromLbcb(LFCB,LBCB) ( \ 00292 LfsFileOffsetToLsn( LFCB, \ 00293 (LBCB)->FileOffset + (LBCB)->BufferOffset, \ 00294 (LBCB)->SeqNumber ) \ 00295 ) 00296 00297 #define LfsTruncateLsnToLogPage(LFCB,LSN,FO) { \ 00298 *(FO) = LfsLsnToFileOffset( LFCB, LSN ); \ 00299 *((PULONG)(FO)) &= (LFCB)->LogPageInverseMask; \ 00300 } 00301 00302 #define LfsLsnToFileOffset(LFCB,LSN) \ 00303 /*xxShr*/( ((ULONGLONG)/*xxShl*/( (LSN).QuadPart << (LFCB)->SeqNumberBits )) >> ((LFCB)->SeqNumberBits - 3) ) 00304 00305 #define LfsLsnToSeqNumber(LFCB,LSN) \ 00306 /*xxShr*/Int64ShrlMod32( ((ULONGLONG)(LSN).QuadPart), (LFCB)->FileDataBits ) 00307 00308 #define LfsLsnToPageOffset(LFCB,LSN) \ 00309 LfsLogPageOffset( LFCB, (LSN).LowPart << 3 ) 00310 00311 VOID 00312 LfsLsnFinalOffset ( 00313 IN PLFCB Lfcb, 00314 IN LSN Lsn, 00315 IN ULONG DataLength, 00316 OUT PLONGLONG FinalOffset 00317 ); 00318 00319 BOOLEAN 00320 LfsFindNextLsn ( 00321 IN PLFCB Lfcb, 00322 IN PLFS_RECORD_HEADER RecordHeader, 00323 OUT PLSN Lsn 00324 ); 00325 00326 00327 // 00328 // The following routines support the Lfs restart areas. They are contained 00329 // in 'RstrtSup.c' 00330 // 00331 00332 VOID 00333 LfsWriteLfsRestart ( 00334 IN PLFCB Lfcb, 00335 IN ULONG ThisRestartSize, 00336 IN BOOLEAN WaitForIo 00337 ); 00338 00339 VOID 00340 LfsFindOldestClientLsn ( 00341 IN PLFS_RESTART_AREA RestartArea, 00342 IN PLFS_CLIENT_RECORD ClientArray, 00343 OUT PLSN OldestLsn 00344 ); 00345 00346 00347 // 00348 // The following routines are used for managing the structures allocated 00349 // by us. They are contained in 'StrucSup.c' 00350 // 00351 00352 PLFCB 00353 LfsAllocateLfcb ( 00354 ); 00355 00356 00357 VOID 00358 LfsDeallocateLfcb ( 00359 IN PLFCB Lfcb, 00360 IN BOOLEAN CompleteTeardown 00361 ); 00362 00363 VOID 00364 LfsAllocateLbcb ( 00365 IN PLFCB Lfcb, 00366 OUT PLBCB *Lbcb 00367 ); 00368 00369 VOID 00370 LfsDeallocateLbcb ( 00371 IN PLFCB Lfcb, 00372 IN PLBCB Lbcb 00373 ); 00374 00375 VOID 00376 LfsAllocateLcb ( 00377 IN PLFCB Lfcb, 00378 OUT PLCB *NewLcb 00379 ); 00380 00381 VOID 00382 LfsDeallocateLcb ( 00383 IN PLFCB Lfcb, 00384 IN PLCB Lcb 00385 ); 00386 00387 // 00388 // VOID 00389 // LfsInitializeLcb ( 00390 // IN PLCB Lcb, 00391 // IN LFS_CLIENT_ID ClientId, 00392 // IN LFS_CONTEXT_MODE ContextMode 00393 // ); 00394 // 00395 // 00396 // VOID 00397 // LfsAllocateLch ( 00398 // OUT PLCH *Lch 00399 // ); 00400 // 00401 // VOID 00402 // LfsDeallocateLch ( 00403 // IN PLCH Lch 00404 // ); 00405 // 00406 // VOID 00407 // LfsAllocateRestartArea ( 00408 // OUT PLFS_RESTART_AREA *RestartArea, 00409 // ULONG Size 00410 // ); 00411 // 00412 // VOID 00413 // LfsDeallocateRestartArea ( 00414 // IN PLFS_RESTART_AREA RestartArea 00415 // ); 00416 // 00417 // BOOLEAN 00418 // LfsLbcbIsRestart ( 00419 // IN PLBCB Lbcb 00420 // ); 00421 // 00422 00423 #define LfsInitializeLcb(LCB,ID,MODE) \ 00424 (LCB)->ClientId = ID; \ 00425 (LCB)->ContextMode = MODE 00426 00427 00428 #define LfsAllocateLch(NEW) { \ 00429 *(NEW) = FsRtlAllocatePool( PagedPool, sizeof( LCH )); \ 00430 RtlZeroMemory( (*NEW), sizeof( LCH )); \ 00431 (*(NEW))->NodeTypeCode = LFS_NTC_LCH; \ 00432 (*(NEW))->NodeByteSize = sizeof( LCH ); \ 00433 } 00434 00435 #define LfsDeallocateLch(LCH) \ 00436 ExFreePool( LCH ) 00437 00438 #define LfsAllocateRestartArea(RS,SIZE) \ 00439 *(RS) = FsRtlAllocatePool( PagedPool, (SIZE) ); \ 00440 RtlZeroMemory( *(RS), (SIZE) ) 00441 00442 #define LfsDeallocateRestartArea(RS) \ 00443 ExFreePool( RS ) 00444 00445 #define LfsLbcbIsRestart(LBCB) \ 00446 (FlagOn( (LBCB)->LbcbFlags, LBCB_RESTART_LBCB )) 00447 00448 00449 // 00450 // The following routines provide synchronization support for the Lfs 00451 // shared structures. They are contained in 'SyncSup.c' 00452 // 00453 00454 // 00455 // VOID 00456 // LfsAcquireLfsData ( 00457 // ); 00458 // 00459 // VOID 00460 // LfsReleaseLfsData ( 00461 // ); 00462 // 00463 // VOID 00464 // LfsAcquireLfcb ( 00465 // IN PLFCB Lfcb 00466 // ); 00467 // 00468 // VOID 00469 // LfsReleaseLfcb ( 00470 // IN PLFCB Lfcb 00471 // ); 00472 // 00473 // VOID 00474 // LfsAcquireLch ( 00475 // IN PLCH Lch 00476 // ); 00477 // 00478 // VOID 00479 // LfsReleaseLfcb ( 00480 // IN PLCH Lch 00481 // ); 00482 // 00483 00484 #define LfsAcquireLfsData() \ 00485 ExAcquireFastMutex( &LfsData.LfsDataLock ) 00486 00487 #define LfsReleaseLfsData() \ 00488 ExReleaseFastMutex( &LfsData.LfsDataLock ) 00489 00490 #define LfsAcquireBufferLock() \ 00491 ExAcquireFastMutex( &LfsData.BufferLock ) 00492 00493 #define LfsReleaseBufferLock() \ 00494 ExReleaseFastMutex( &LfsData.BufferLock ) 00495 00496 #define LfsWaitForBufferNotification() \ 00497 KeWaitForSingleObject( &LfsData.BufferNotification, \ 00498 Executive, \ 00499 KernelMode, \ 00500 FALSE, \ 00501 NULL ) 00502 00503 #define LfsNotifyBufferWaiters() \ 00504 KeSetEvent( &LfsData.BufferNotification, 0, FALSE ) 00505 00506 #define LfsBlockBufferWaiters() \ 00507 KeClearEvent( &LfsData.BufferNotification ) 00508 00509 #define LfsAcquireLfcb(LFCB) \ 00510 ExAcquireResourceExclusive( &(LFCB)->Sync->Resource, TRUE ) 00511 00512 #define LfsReleaseLfcb(LFCB) \ 00513 if ((LFCB)->Sync->Resource.OwnerThreads[0].OwnerThread == ExGetCurrentResourceThread()) {\ 00514 ExReleaseResource( &(LFCB)->Sync->Resource ); \ 00515 } 00516 00517 #define LfsAcquireLch(LCH) \ 00518 ExAcquireResourceExclusive( &(LCH)->Sync->Resource, TRUE ) 00519 00520 #define LfsReleaseLch(LCH) \ 00521 if ((LCH)->Sync->Resource.OwnerThreads[0].OwnerThread == ExGetCurrentResourceThread()) { \ 00522 ExReleaseResource( &(LCH)->Sync->Resource ); \ 00523 } 00524 00525 00526 // 00527 // The following routines are used to check various structures for validity 00528 // and comparability. They are contained in 'VerfySup.c'. 00529 // 00530 00531 VOID 00532 LfsCurrentAvailSpace ( 00533 IN PLFCB Lfcb, 00534 OUT PLONGLONG CurrentAvailSpace, 00535 OUT PULONG CurrentPageBytes 00536 ); 00537 00538 BOOLEAN 00539 LfsVerifyLogSpaceAvail ( 00540 IN PLFCB Lfcb, 00541 IN PLCH Lch, 00542 IN ULONG RemainingLogBytes, 00543 IN LONG UndoRequirement, 00544 IN BOOLEAN ForceToDisk 00545 ); 00546 00547 VOID 00548 LfsFindCurrentAvail ( 00549 IN PLFCB Lfcb 00550 ); 00551 00552 // 00553 // VOID 00554 // LfsValidateLch ( 00555 // IN PLCH Lch 00556 // ); 00557 // 00558 // VOID 00559 // LfsValidateClientId ( 00560 // IN PLFCB Lfcb, 00561 // IN PLCH Lch 00562 // ); 00563 // 00564 // BOOLEAN 00565 // LfsVerifyClientLsnInRange ( 00566 // IN PLFCB Lfcb, 00567 // IN PLFS_CLIENT_RECORD ClientRecord, 00568 // IN LSN Lsn 00569 // ); 00570 // 00571 // BOOLEAN 00572 // LfsClientIdMatch ( 00573 // IN PLFS_CLIENT_ID ClientA, 00574 // IN PLFS_CLIENT_ID ClientB 00575 // ) 00576 // 00577 // VOID 00578 // LfsValidateLcb ( 00579 // IN PLFS_CONTEXT_BLOCK Lcb, 00580 // IN PLCH Lch 00581 // ) 00582 // 00583 00584 #define LfsValidateLch(LCH) \ 00585 if ((LCH) == NULL \ 00586 || (LCH)->NodeTypeCode != LFS_NTC_LCH \ 00587 || ((LCH)->Lfcb != NULL \ 00588 && (LCH)->Lfcb->NodeTypeCode != LFS_NTC_LFCB)) { \ 00589 \ 00590 ExRaiseStatus( STATUS_ACCESS_DENIED ); \ 00591 } 00592 00593 #define LfsValidateClientId(LFCB,LCH) \ 00594 if ((LCH)->ClientId.ClientIndex >= (LFCB)->RestartArea->LogClients \ 00595 || (LCH)->ClientId.SeqNumber \ 00596 != Add2Ptr( Lfcb->ClientArray, \ 00597 (LCH)->ClientArrayByteOffset, \ 00598 PLFS_CLIENT_RECORD )->SeqNumber) { \ 00599 ExRaiseStatus( STATUS_ACCESS_DENIED ); \ 00600 } 00601 00602 #define LfsVerifyClientLsnInRange(LFCB,CLIENT,LSN) \ 00603 (/*xxGeq*/( (LSN).QuadPart >= ((CLIENT)->OldestLsn).QuadPart ) \ 00604 && /*xxLeq*/( (LSN).QuadPart <= ((LFCB)->RestartArea->CurrentLsn).QuadPart ) \ 00605 && /*xxNeqZero*/( (LSN).QuadPart != 0 )) 00606 00607 #define LfsClientIdMatch(CLIENT_A,CLIENT_B) \ 00608 ((BOOLEAN) ((CLIENT_A)->SeqNumber == (CLIENT_B)->SeqNumber \ 00609 && (CLIENT_A)->ClientIndex == (CLIENT_B)->ClientIndex)) 00610 00611 #define LfsValidateLcb(LCB,LCH) \ 00612 if (LCB == NULL \ 00613 || (LCB)->NodeTypeCode != LFS_NTC_LCB \ 00614 || !LfsClientIdMatch( &(LCB)->ClientId, &(LCH)->ClientId )) { \ 00615 ExRaiseStatus( STATUS_ACCESS_DENIED ); \ 00616 } 00617 00618 00619 // 00620 // Miscellaneous support routines 00621 // 00622 00623 // 00624 // ULONG 00625 // FlagOn ( 00626 // IN ULONG Flags, 00627 // IN ULONG SingleFlag 00628 // ); 00629 // 00630 // BOOLEAN 00631 // BooleanFlagOn ( 00632 // IN ULONG Flags, 00633 // IN ULONG SingleFlag 00634 // ); 00635 // 00636 // VOID 00637 // SetFlag ( 00638 // IN ULONG Flags, 00639 // IN ULONG SingleFlag 00640 // ); 00641 // 00642 // VOID 00643 // ClearFlag ( 00644 // IN ULONG Flags, 00645 // IN ULONG SingleFlag 00646 // ); 00647 // 00648 00649 // 00650 // This macro returns TRUE if a flag in a set of flags is on and FALSE 00651 // otherwise 00652 // 00653 00654 #define FlagOn(F,SF) ( \ 00655 (((F) & (SF))) \ 00656 ) 00657 00658 #define BooleanFlagOn(F,SF) ( \ 00659 (BOOLEAN)(((F) & (SF)) != 0) \ 00660 ) 00661 00662 #define SetFlag(Flags,SingleFlag) { \ 00663 (Flags) |= (SingleFlag); \ 00664 } 00665 00666 #define ClearFlag(Flags,SingleFlag) { \ 00667 (Flags) &= ~(SingleFlag); \ 00668 } 00669 00670 // 00671 // This macro takes a pointer (or ulong) and returns its rounded up word 00672 // value 00673 // 00674 00675 #define WordAlign(Ptr) ( \ 00676 ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \ 00677 ) 00678 00679 // 00680 // This macro takes a pointer (or ulong) and returns its rounded up longword 00681 // value 00682 // 00683 00684 #define LongAlign(Ptr) ( \ 00685 ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \ 00686 ) 00687 00688 // 00689 // This macro takes a pointer (or ulong) and returns its rounded up quadword 00690 // value 00691 // 00692 00693 #define QuadAlign(Ptr) ( \ 00694 ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \ 00695 ) 00696 00697 // 00698 // This macro will up a 64 bit value to the next quad align boundary. 00699 // 00700 00701 #define LiQuadAlign(LI,OUT) { \ 00702 *(OUT) = /*xxAdd*/( (LI) + 7 ); \ 00703 *((PULONG)(OUT)) &= 0xfffffff8; \ 00704 } 00705 00706 // 00707 // CAST 00708 // Add2Ptr ( 00709 // IN PVOID Pointer, 00710 // IN ULONG Increment 00711 // IN (CAST) 00712 // ); 00713 // 00714 // ULONG 00715 // PtrOffset ( 00716 // IN PVOID BasePtr, 00717 // IN PVOID OffsetPtr 00718 // ); 00719 // 00720 00721 #define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC))) 00722 00723 #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE))) 00724 00725 00726 // 00727 // The following macros are used to establish the semantics needed 00728 // to do a return from within a try-finally clause. As a rule every 00729 // try clause must end with a label call try_exit. For example, 00730 // 00731 // try { 00732 // : 00733 // : 00734 // 00735 // try_exit: NOTHING; 00736 // } finally { 00737 // 00738 // : 00739 // : 00740 // } 00741 // 00742 // Every return statement executed inside of a try clause should use the 00743 // try_return macro. If the compiler fully supports the try-finally construct 00744 // then the macro should be 00745 // 00746 // #define try_return(S) { return(S); } 00747 // 00748 // If the compiler does not support the try-finally construct then the macro 00749 // should be 00750 // 00751 // #define try_return(S) { S; goto try_exit; } 00752 // 00753 00754 #define try_return(S) { S; goto try_exit; } 00755 00756 #endif // _LFSPROCS_

Generated on Sat May 15 19:40:38 2004 for test by doxygen 1.3.7