Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenex.h
Go to the documentation of this file.
00001 #pragma once 00002 00003 /* GLOBAL VARIABLES *********************************************************/ 00004 00005 extern TIME_ZONE_INFORMATION ExpTimeZoneInfo; 00006 extern LARGE_INTEGER ExpTimeZoneBias; 00007 extern ULONG ExpTimeZoneId; 00008 extern ULONG ExpTickCountMultiplier; 00009 extern ULONG ExpLastTimeZoneBias; 00010 extern POBJECT_TYPE ExEventPairObjectType; 00011 extern POBJECT_TYPE _ExEventObjectType, _ExSemaphoreObjectType; 00012 extern ULONG NtBuildNumber; 00013 extern ULONG NtMajorVersion; 00014 extern ULONG NtMinorVersion; 00015 extern FAST_MUTEX ExpEnvironmentLock; 00016 extern ERESOURCE ExpFirmwareTableResource; 00017 extern LIST_ENTRY ExpFirmwareTableProviderListHead; 00018 extern BOOLEAN ExpIsWinPEMode; 00019 extern LIST_ENTRY ExpSystemResourcesList; 00020 extern ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset; 00021 extern ULONG ExpUnicodeCaseTableDataOffset; 00022 extern PVOID ExpNlsSectionPointer; 00023 extern CHAR NtBuildLab[]; 00024 extern ULONG CmNtCSDVersion; 00025 extern ULONG NtGlobalFlag; 00026 extern ULONG ExpInitializationPhase; 00027 extern ULONG ExpAltTimeZoneBias; 00028 extern LIST_ENTRY ExSystemLookasideListHead; 00029 extern PCALLBACK_OBJECT PowerStateCallback; 00030 00031 typedef struct _EXHANDLE 00032 { 00033 union 00034 { 00035 struct 00036 { 00037 ULONG TagBits:2; 00038 ULONG Index:30; 00039 }; 00040 HANDLE GenericHandleOverlay; 00041 ULONG_PTR Value; 00042 }; 00043 } EXHANDLE, *PEXHANDLE; 00044 00045 typedef struct _ETIMER 00046 { 00047 KTIMER KeTimer; 00048 KAPC TimerApc; 00049 KDPC TimerDpc; 00050 LIST_ENTRY ActiveTimerListEntry; 00051 KSPIN_LOCK Lock; 00052 LONG Period; 00053 BOOLEAN ApcAssociated; 00054 BOOLEAN WakeTimer; 00055 LIST_ENTRY WakeTimerListEntry; 00056 } ETIMER, *PETIMER; 00057 00058 typedef struct 00059 { 00060 PCALLBACK_OBJECT *CallbackObject; 00061 PWSTR Name; 00062 } SYSTEM_CALLBACKS; 00063 00064 typedef struct _HARDERROR_USER_PARAMETERS 00065 { 00066 ULONG_PTR Parameters[MAXIMUM_HARDERROR_PARAMETERS]; 00067 UNICODE_STRING Strings[MAXIMUM_HARDERROR_PARAMETERS]; 00068 WCHAR Buffer[ANYSIZE_ARRAY]; 00069 } HARDERROR_USER_PARAMETERS, *PHARDERROR_USER_PARAMETERS; 00070 00071 #define MAX_FAST_REFS 7 00072 00073 #define ExAcquireRundownProtection _ExAcquireRundownProtection 00074 #define ExReleaseRundownProtection _ExReleaseRundownProtection 00075 #define ExInitializeRundownProtection _ExInitializeRundownProtection 00076 #define ExWaitForRundownProtectionRelease _ExWaitForRundownProtectionRelease 00077 #define ExRundownCompleted _ExRundownCompleted 00078 #define ExGetPreviousMode KeGetPreviousMode 00079 00080 00081 // 00082 // Various bits tagged on the handle or handle table 00083 // 00084 #define EXHANDLE_TABLE_ENTRY_LOCK_BIT 1 00085 #define FREE_HANDLE_MASK -1 00086 00087 // 00088 // Number of entries in each table level 00089 // 00090 #define LOW_LEVEL_ENTRIES (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)) 00091 #define MID_LEVEL_ENTRIES (PAGE_SIZE / sizeof(PHANDLE_TABLE_ENTRY)) 00092 #define HIGH_LEVEL_ENTRIES (16777216 / (LOW_LEVEL_ENTRIES * MID_LEVEL_ENTRIES)) 00093 00094 // 00095 // Maximum index in each table level before we need another table 00096 // 00097 #define MAX_LOW_INDEX LOW_LEVEL_ENTRIES 00098 #define MAX_MID_INDEX (MID_LEVEL_ENTRIES * LOW_LEVEL_ENTRIES) 00099 #define MAX_HIGH_INDEX (MID_LEVEL_ENTRIES * MID_LEVEL_ENTRIES * LOW_LEVEL_ENTRIES) 00100 00101 // 00102 // Detect old GCC 00103 // 00104 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40300) || \ 00105 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ == 40303) 00106 00107 #define DEFINE_WAIT_BLOCK(x) \ 00108 struct _AlignHack \ 00109 { \ 00110 UCHAR Hack[15]; \ 00111 EX_PUSH_LOCK_WAIT_BLOCK UnalignedBlock; \ 00112 } WaitBlockBuffer; \ 00113 PEX_PUSH_LOCK_WAIT_BLOCK x = (PEX_PUSH_LOCK_WAIT_BLOCK) \ 00114 ((ULONG_PTR)&WaitBlockBuffer.UnalignedBlock &~ 0xF); 00115 00116 #else 00117 00118 // 00119 // This is only for compatibility; the compiler will optimize the extra 00120 // local variable (the actual pointer) away, so we don't take any perf hit 00121 // by doing this. 00122 // 00123 #define DEFINE_WAIT_BLOCK(x) \ 00124 EX_PUSH_LOCK_WAIT_BLOCK WaitBlockBuffer; \ 00125 PEX_PUSH_LOCK_WAIT_BLOCK x = &WaitBlockBuffer; 00126 00127 #endif 00128 00129 #define ExpChangeRundown(x, y, z) (ULONG_PTR)InterlockedCompareExchangePointer(&x->Ptr, (PVOID)y, (PVOID)z) 00130 #define ExpChangePushlock(x, y, z) InterlockedCompareExchangePointer((PVOID*)x, (PVOID)y, (PVOID)z) 00131 #define ExpSetRundown(x, y) InterlockedExchangePointer(&x->Ptr, (PVOID)y) 00132 00133 NTSTATUS 00134 NTAPI 00135 ExGetPoolTagInfo( 00136 IN PSYSTEM_POOLTAG_INFORMATION SystemInformation, 00137 IN ULONG SystemInformationLength, 00138 IN OUT PULONG ReturnLength OPTIONAL 00139 ); 00140 00141 /* INITIALIZATION FUNCTIONS *************************************************/ 00142 00143 VOID 00144 NTAPI 00145 ExpWin32kInit(VOID); 00146 00147 VOID 00148 NTAPI 00149 ExInit2(VOID); 00150 00151 VOID 00152 NTAPI 00153 Phase1Initialization( 00154 IN PVOID Context 00155 ); 00156 00157 VOID 00158 NTAPI 00159 ExpInitializePushLocks(VOID); 00160 00161 BOOLEAN 00162 NTAPI 00163 ExRefreshTimeZoneInformation( 00164 IN PLARGE_INTEGER SystemBootTime 00165 ); 00166 00167 VOID 00168 NTAPI 00169 ExpInitializeWorkerThreads(VOID); 00170 00171 VOID 00172 NTAPI 00173 ExSwapinWorkerThreads(IN BOOLEAN AllowSwap); 00174 00175 VOID 00176 NTAPI 00177 ExpInitLookasideLists(VOID); 00178 00179 VOID 00180 NTAPI 00181 ExInitializeSystemLookasideList( 00182 IN PGENERAL_LOOKASIDE List, 00183 IN POOL_TYPE Type, 00184 IN ULONG Size, 00185 IN ULONG Tag, 00186 IN USHORT MaximumDepth, 00187 IN PLIST_ENTRY ListHead 00188 ); 00189 00190 BOOLEAN 00191 NTAPI 00192 ExpInitializeCallbacks(VOID); 00193 00194 VOID 00195 NTAPI 00196 ExpInitUuids(VOID); 00197 00198 VOID 00199 NTAPI 00200 ExpInitializeExecutive( 00201 IN ULONG Cpu, 00202 IN PLOADER_PARAMETER_BLOCK LoaderBlock 00203 ); 00204 00205 VOID 00206 NTAPI 00207 ExpInitializeEventImplementation(VOID); 00208 00209 VOID 00210 NTAPI 00211 ExpInitializeKeyedEventImplementation(VOID); 00212 00213 VOID 00214 NTAPI 00215 ExpInitializeEventPairImplementation(VOID); 00216 00217 VOID 00218 NTAPI 00219 ExpInitializeSemaphoreImplementation(VOID); 00220 00221 VOID 00222 NTAPI 00223 ExpInitializeMutantImplementation(VOID); 00224 00225 VOID 00226 NTAPI 00227 ExpInitializeTimerImplementation(VOID); 00228 00229 VOID 00230 NTAPI 00231 ExpInitializeProfileImplementation(VOID); 00232 00233 VOID 00234 NTAPI 00235 ExpResourceInitialization(VOID); 00236 00237 VOID 00238 NTAPI 00239 ExInitPoolLookasidePointers(VOID); 00240 00241 /* Callback Functions ********************************************************/ 00242 00243 VOID 00244 NTAPI 00245 ExInitializeCallBack( 00246 IN OUT PEX_CALLBACK Callback 00247 ); 00248 00249 PEX_CALLBACK_ROUTINE_BLOCK 00250 NTAPI 00251 ExAllocateCallBack( 00252 IN PEX_CALLBACK_FUNCTION Function, 00253 IN PVOID Context 00254 ); 00255 00256 VOID 00257 NTAPI 00258 ExFreeCallBack( 00259 IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock 00260 ); 00261 00262 BOOLEAN 00263 NTAPI 00264 ExCompareExchangeCallBack ( 00265 IN OUT PEX_CALLBACK CallBack, 00266 IN PEX_CALLBACK_ROUTINE_BLOCK NewBlock, 00267 IN PEX_CALLBACK_ROUTINE_BLOCK OldBlock 00268 ); 00269 00270 PEX_CALLBACK_ROUTINE_BLOCK 00271 NTAPI 00272 ExReferenceCallBackBlock( 00273 IN OUT PEX_CALLBACK CallBack 00274 ); 00275 00276 VOID 00277 NTAPI 00278 ExDereferenceCallBackBlock( 00279 IN OUT PEX_CALLBACK CallBack, 00280 IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock 00281 ); 00282 00283 PEX_CALLBACK_FUNCTION 00284 NTAPI 00285 ExGetCallBackBlockRoutine( 00286 IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock 00287 ); 00288 00289 PVOID 00290 NTAPI 00291 ExGetCallBackBlockContext( 00292 IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock 00293 ); 00294 00295 VOID 00296 NTAPI 00297 ExWaitForCallBacks( 00298 IN PEX_CALLBACK_ROUTINE_BLOCK CallbackRoutineBlock 00299 ); 00300 00301 /* Rundown Functions ********************************************************/ 00302 00303 VOID 00304 FASTCALL 00305 ExfInitializeRundownProtection( 00306 OUT PEX_RUNDOWN_REF RunRef 00307 ); 00308 00309 VOID 00310 FASTCALL 00311 ExfReInitializeRundownProtection( 00312 OUT PEX_RUNDOWN_REF RunRef 00313 ); 00314 00315 BOOLEAN 00316 FASTCALL 00317 ExfAcquireRundownProtection( 00318 IN OUT PEX_RUNDOWN_REF RunRef 00319 ); 00320 00321 BOOLEAN 00322 FASTCALL 00323 ExfAcquireRundownProtectionEx( 00324 IN OUT PEX_RUNDOWN_REF RunRef, 00325 IN ULONG Count 00326 ); 00327 00328 VOID 00329 FASTCALL 00330 ExfReleaseRundownProtection( 00331 IN OUT PEX_RUNDOWN_REF RunRef 00332 ); 00333 00334 VOID 00335 FASTCALL 00336 ExfReleaseRundownProtectionEx( 00337 IN OUT PEX_RUNDOWN_REF RunRef, 00338 IN ULONG Count 00339 ); 00340 00341 VOID 00342 FASTCALL 00343 ExfRundownCompleted( 00344 OUT PEX_RUNDOWN_REF RunRef 00345 ); 00346 00347 VOID 00348 FASTCALL 00349 ExfWaitForRundownProtectionRelease( 00350 IN OUT PEX_RUNDOWN_REF RunRef 00351 ); 00352 00353 /* HANDLE TABLE FUNCTIONS ***************************************************/ 00354 00355 typedef BOOLEAN 00356 (NTAPI *PEX_SWEEP_HANDLE_CALLBACK)( 00357 PHANDLE_TABLE_ENTRY HandleTableEntry, 00358 HANDLE Handle, 00359 PVOID Context 00360 ); 00361 00362 typedef BOOLEAN 00363 (NTAPI *PEX_DUPLICATE_HANDLE_CALLBACK)( 00364 IN PEPROCESS Process, 00365 IN PHANDLE_TABLE HandleTable, 00366 IN PHANDLE_TABLE_ENTRY HandleTableEntry, 00367 IN PHANDLE_TABLE_ENTRY NewEntry 00368 ); 00369 00370 typedef BOOLEAN 00371 (NTAPI *PEX_CHANGE_HANDLE_CALLBACK)( 00372 PHANDLE_TABLE_ENTRY HandleTableEntry, 00373 ULONG_PTR Context 00374 ); 00375 00376 VOID 00377 NTAPI 00378 ExpInitializeHandleTables( 00379 VOID 00380 ); 00381 00382 PHANDLE_TABLE 00383 NTAPI 00384 ExCreateHandleTable( 00385 IN PEPROCESS Process OPTIONAL 00386 ); 00387 00388 VOID 00389 NTAPI 00390 ExUnlockHandleTableEntry( 00391 IN PHANDLE_TABLE HandleTable, 00392 IN PHANDLE_TABLE_ENTRY HandleTableEntry 00393 ); 00394 00395 HANDLE 00396 NTAPI 00397 ExCreateHandle( 00398 IN PHANDLE_TABLE HandleTable, 00399 IN PHANDLE_TABLE_ENTRY HandleTableEntry 00400 ); 00401 00402 VOID 00403 NTAPI 00404 ExDestroyHandleTable( 00405 IN PHANDLE_TABLE HandleTable, 00406 IN PVOID DestroyHandleProcedure OPTIONAL 00407 ); 00408 00409 BOOLEAN 00410 NTAPI 00411 ExDestroyHandle( 00412 IN PHANDLE_TABLE HandleTable, 00413 IN HANDLE Handle, 00414 IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL 00415 ); 00416 00417 PHANDLE_TABLE_ENTRY 00418 NTAPI 00419 ExMapHandleToPointer( 00420 IN PHANDLE_TABLE HandleTable, 00421 IN HANDLE Handle 00422 ); 00423 00424 PHANDLE_TABLE 00425 NTAPI 00426 ExDupHandleTable( 00427 IN PEPROCESS Process, 00428 IN PHANDLE_TABLE HandleTable, 00429 IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, 00430 IN ULONG_PTR Mask 00431 ); 00432 00433 BOOLEAN 00434 NTAPI 00435 ExChangeHandle( 00436 IN PHANDLE_TABLE HandleTable, 00437 IN HANDLE Handle, 00438 IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, 00439 IN ULONG_PTR Context 00440 ); 00441 00442 VOID 00443 NTAPI 00444 ExSweepHandleTable( 00445 IN PHANDLE_TABLE HandleTable, 00446 IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, 00447 IN PVOID Context 00448 ); 00449 00450 /* PSEH EXCEPTION HANDLING **************************************************/ 00451 00452 LONG 00453 NTAPI 00454 ExSystemExceptionFilter(VOID); 00455 00456 /* CALLBACKS *****************************************************************/ 00457 00458 FORCEINLINE 00459 VOID 00460 ExDoCallBack(IN OUT PEX_CALLBACK Callback, 00461 IN PVOID Context, 00462 IN PVOID Argument1, 00463 IN PVOID Argument2) 00464 { 00465 PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock; 00466 PEX_CALLBACK_FUNCTION Function; 00467 00468 /* Reference the block */ 00469 CallbackBlock = ExReferenceCallBackBlock(Callback); 00470 if (CallbackBlock) 00471 { 00472 /* Get the function */ 00473 Function = ExGetCallBackBlockRoutine(CallbackBlock); 00474 00475 /* Do the callback */ 00476 Function(Context, Argument1, Argument2); 00477 00478 /* Now dereference it */ 00479 ExDereferenceCallBackBlock(Callback, CallbackBlock); 00480 } 00481 } 00482 00483 /* FAST REFS ******************************************************************/ 00484 00485 FORCEINLINE 00486 PVOID 00487 ExGetObjectFastReference(IN EX_FAST_REF FastRef) 00488 { 00489 /* Return the unbiased pointer */ 00490 return (PVOID)(FastRef.Value & ~MAX_FAST_REFS); 00491 } 00492 00493 FORCEINLINE 00494 ULONG 00495 ExGetCountFastReference(IN EX_FAST_REF FastRef) 00496 { 00497 /* Return the reference count */ 00498 return (ULONG)FastRef.RefCnt; 00499 } 00500 00501 FORCEINLINE 00502 VOID 00503 ExInitializeFastReference(OUT PEX_FAST_REF FastRef, 00504 IN OPTIONAL PVOID Object) 00505 { 00506 /* Sanity check */ 00507 ASSERT((((ULONG_PTR)Object) & MAX_FAST_REFS) == 0); 00508 00509 /* Check if an object is being set */ 00510 if (!Object) 00511 { 00512 /* Clear the field */ 00513 FastRef->Object = NULL; 00514 } 00515 else 00516 { 00517 /* Otherwise, we assume the object was referenced and is ready */ 00518 FastRef->Value = (ULONG_PTR)Object | MAX_FAST_REFS; 00519 } 00520 } 00521 00522 FORCEINLINE 00523 EX_FAST_REF 00524 ExAcquireFastReference(IN OUT PEX_FAST_REF FastRef) 00525 { 00526 EX_FAST_REF OldValue, NewValue; 00527 00528 /* Start reference loop */ 00529 for (;;) 00530 { 00531 /* Get the current reference count */ 00532 OldValue = *FastRef; 00533 if (OldValue.RefCnt) 00534 { 00535 /* Increase the reference count */ 00536 NewValue.Value = OldValue.Value - 1; 00537 NewValue.Object = ExpChangePushlock(&FastRef->Object, 00538 NewValue.Object, 00539 OldValue.Object); 00540 if (NewValue.Object != OldValue.Object) continue; 00541 } 00542 00543 /* We are done */ 00544 break; 00545 } 00546 00547 /* Return the old value */ 00548 return OldValue; 00549 } 00550 00551 FORCEINLINE 00552 BOOLEAN 00553 ExInsertFastReference(IN OUT PEX_FAST_REF FastRef, 00554 IN PVOID Object) 00555 { 00556 EX_FAST_REF OldValue, NewValue; 00557 00558 /* Sanity checks */ 00559 ASSERT(!(((ULONG_PTR)Object) & MAX_FAST_REFS)); 00560 00561 /* Start update loop */ 00562 for (;;) 00563 { 00564 /* Get the current reference count */ 00565 OldValue = *FastRef; 00566 00567 /* Check if the current count is too high or if the pointer changed */ 00568 if (((OldValue.RefCnt + MAX_FAST_REFS) > MAX_FAST_REFS) || 00569 ((OldValue.Value &~ MAX_FAST_REFS) != (ULONG_PTR)Object)) 00570 { 00571 /* Fail */ 00572 return FALSE; 00573 } 00574 00575 /* Update the reference count */ 00576 NewValue.Value = OldValue.Value + MAX_FAST_REFS; 00577 NewValue.Object = ExpChangePushlock(&FastRef->Object, 00578 NewValue.Object, 00579 OldValue.Object); 00580 if (NewValue.Object != OldValue.Object) continue; 00581 00582 /* We are done */ 00583 break; 00584 } 00585 00586 /* Return success */ 00587 return TRUE; 00588 } 00589 00590 FORCEINLINE 00591 BOOLEAN 00592 ExReleaseFastReference(IN PEX_FAST_REF FastRef, 00593 IN PVOID Object) 00594 { 00595 EX_FAST_REF OldValue, NewValue; 00596 00597 /* Sanity checks */ 00598 ASSERT(Object != NULL); 00599 ASSERT(!(((ULONG_PTR)Object) & MAX_FAST_REFS)); 00600 00601 /* Start reference loop */ 00602 for (;;) 00603 { 00604 /* Get the current reference count */ 00605 OldValue = *FastRef; 00606 00607 /* Check if we're full if if the pointer changed */ 00608 if ((OldValue.Value ^ (ULONG_PTR)Object) >= MAX_FAST_REFS) return FALSE; 00609 00610 /* Decrease the reference count */ 00611 NewValue.Value = OldValue.Value + 1; 00612 NewValue.Object = ExpChangePushlock(&FastRef->Object, 00613 NewValue.Object, 00614 OldValue.Object); 00615 if (NewValue.Object != OldValue.Object) continue; 00616 00617 /* We are done */ 00618 break; 00619 } 00620 00621 /* Return success */ 00622 return TRUE; 00623 } 00624 00625 FORCEINLINE 00626 EX_FAST_REF 00627 ExSwapFastReference(IN PEX_FAST_REF FastRef, 00628 IN PVOID Object) 00629 { 00630 EX_FAST_REF NewValue, OldValue; 00631 00632 /* Sanity check */ 00633 ASSERT((((ULONG_PTR)Object) & MAX_FAST_REFS) == 0); 00634 00635 /* Check if an object is being set */ 00636 if (!Object) 00637 { 00638 /* Clear the field */ 00639 NewValue.Object = NULL; 00640 } 00641 else 00642 { 00643 /* Otherwise, we assume the object was referenced and is ready */ 00644 NewValue.Value = (ULONG_PTR)Object | MAX_FAST_REFS; 00645 } 00646 00647 /* Update the object */ 00648 OldValue.Object = InterlockedExchangePointer(&FastRef->Object, NewValue.Object); 00649 return OldValue; 00650 } 00651 00652 FORCEINLINE 00653 EX_FAST_REF 00654 ExCompareSwapFastReference(IN PEX_FAST_REF FastRef, 00655 IN PVOID Object, 00656 IN PVOID OldObject) 00657 { 00658 EX_FAST_REF OldValue, NewValue; 00659 00660 /* Sanity check and start swap loop */ 00661 ASSERT(!(((ULONG_PTR)Object) & MAX_FAST_REFS)); 00662 for (;;) 00663 { 00664 /* Get the current value */ 00665 OldValue = *FastRef; 00666 00667 /* Make sure there's enough references to swap */ 00668 if (!((OldValue.Value ^ (ULONG_PTR)OldObject) <= MAX_FAST_REFS)) break; 00669 00670 /* Check if we have an object to swap */ 00671 if (Object) 00672 { 00673 /* Set up the value with maximum fast references */ 00674 NewValue.Value = (ULONG_PTR)Object | MAX_FAST_REFS; 00675 } 00676 else 00677 { 00678 /* Write the object address itself (which is empty) */ 00679 NewValue.Value = (ULONG_PTR)Object; 00680 } 00681 00682 /* Do the actual compare exchange */ 00683 NewValue.Object = ExpChangePushlock(&FastRef->Object, 00684 NewValue.Object, 00685 OldValue.Object); 00686 if (NewValue.Object != OldValue.Object) continue; 00687 00688 /* All done */ 00689 break; 00690 } 00691 00692 /* Return the old value */ 00693 return OldValue; 00694 } 00695 00696 /* RUNDOWN *******************************************************************/ 00697 00698 /*++ 00699 * @name ExfAcquireRundownProtection 00700 * INTERNAL MACRO 00701 * 00702 * The ExfAcquireRundownProtection routine acquires rundown protection for 00703 * the specified descriptor. 00704 * 00705 * @param RunRef 00706 * Pointer to a rundown reference descriptor. 00707 * 00708 * @return TRUE if access to the protected structure was granted, FALSE otherwise. 00709 * 00710 * @remarks This is the internal macro for system use only.In case the rundown 00711 * was active, then the slow-path will be called through the exported 00712 * function. 00713 * 00714 *--*/ 00715 FORCEINLINE 00716 BOOLEAN 00717 _ExAcquireRundownProtection(IN PEX_RUNDOWN_REF RunRef) 00718 { 00719 ULONG_PTR Value, NewValue; 00720 00721 /* Get the current value and mask the active bit */ 00722 Value = RunRef->Count &~ EX_RUNDOWN_ACTIVE; 00723 00724 /* Add a reference */ 00725 NewValue = Value + EX_RUNDOWN_COUNT_INC; 00726 00727 /* Change the value */ 00728 NewValue = ExpChangeRundown(RunRef, NewValue, Value); 00729 if (NewValue != Value) 00730 { 00731 /* Rundown was active, use long path */ 00732 return ExfAcquireRundownProtection(RunRef); 00733 } 00734 00735 /* Success */ 00736 return TRUE; 00737 } 00738 00739 /*++ 00740 * @name ExReleaseRundownProtection 00741 * INTERNAL MACRO 00742 * 00743 * The ExReleaseRundownProtection routine releases rundown protection for 00744 * the specified descriptor. 00745 * 00746 * @param RunRef 00747 * Pointer to a rundown reference descriptor. 00748 * 00749 * @return TRUE if access to the protected structure was granted, FALSE otherwise. 00750 * 00751 * @remarks This is the internal macro for system use only.In case the rundown 00752 * was active, then the slow-path will be called through the exported 00753 * function. 00754 * 00755 *--*/ 00756 FORCEINLINE 00757 VOID 00758 _ExReleaseRundownProtection(IN PEX_RUNDOWN_REF RunRef) 00759 { 00760 ULONG_PTR Value, NewValue; 00761 00762 /* Get the current value and mask the active bit */ 00763 Value = RunRef->Count &~ EX_RUNDOWN_ACTIVE; 00764 00765 /* Remove a reference */ 00766 NewValue = Value - EX_RUNDOWN_COUNT_INC; 00767 00768 /* Change the value */ 00769 NewValue = ExpChangeRundown(RunRef, NewValue, Value); 00770 00771 /* Check if the rundown was active */ 00772 if (NewValue != Value) 00773 { 00774 /* Rundown was active, use long path */ 00775 ExfReleaseRundownProtection(RunRef); 00776 } 00777 else 00778 { 00779 /* Sanity check */ 00780 ASSERT((Value >= EX_RUNDOWN_COUNT_INC) || (KeNumberProcessors > 1)); 00781 } 00782 } 00783 00784 /*++ 00785 * @name ExInitializeRundownProtection 00786 * INTERNAL MACRO 00787 * 00788 * The ExInitializeRundownProtection routine initializes a rundown 00789 * protection descriptor. 00790 * 00791 * @param RunRef 00792 * Pointer to a rundown reference descriptor. 00793 * 00794 * @return None. 00795 * 00796 * @remarks This is the internal macro for system use only. 00797 * 00798 *--*/ 00799 FORCEINLINE 00800 VOID 00801 _ExInitializeRundownProtection(IN PEX_RUNDOWN_REF RunRef) 00802 { 00803 /* Set the count to zero */ 00804 RunRef->Count = 0; 00805 } 00806 00807 /*++ 00808 * @name ExWaitForRundownProtectionRelease 00809 * INTERNAL MACRO 00810 * 00811 * The ExWaitForRundownProtectionRelease routine waits until the specified 00812 * rundown descriptor has been released. 00813 * 00814 * @param RunRef 00815 * Pointer to a rundown reference descriptor. 00816 * 00817 * @return None. 00818 * 00819 * @remarks This is the internal macro for system use only. If a wait is actually 00820 * necessary, then the slow path is taken through the exported function. 00821 * 00822 *--*/ 00823 FORCEINLINE 00824 VOID 00825 _ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REF RunRef) 00826 { 00827 ULONG_PTR Value; 00828 00829 /* Set the active bit */ 00830 Value = ExpChangeRundown(RunRef, EX_RUNDOWN_ACTIVE, 0); 00831 if ((Value) && (Value != EX_RUNDOWN_ACTIVE)) 00832 { 00833 /* If the the rundown wasn't already active, then take the long path */ 00834 ExfWaitForRundownProtectionRelease(RunRef); 00835 } 00836 } 00837 00838 /*++ 00839 * @name ExRundownCompleted 00840 * INTERNAL MACRO 00841 * 00842 * The ExRundownCompleted routine completes the rundown of the specified 00843 * descriptor by setting the active bit. 00844 * 00845 * @param RunRef 00846 * Pointer to a rundown reference descriptor. 00847 * 00848 * @return None. 00849 * 00850 * @remarks This is the internal macro for system use only. 00851 * 00852 *--*/ 00853 FORCEINLINE 00854 VOID 00855 _ExRundownCompleted(IN PEX_RUNDOWN_REF RunRef) 00856 { 00857 /* Sanity check */ 00858 ASSERT((RunRef->Count & EX_RUNDOWN_ACTIVE) != 0); 00859 00860 /* Mark the counter as active */ 00861 ExpSetRundown(RunRef, EX_RUNDOWN_ACTIVE); 00862 } 00863 00864 /* PUSHLOCKS *****************************************************************/ 00865 00866 /* FIXME: VERIFY THESE! */ 00867 00868 VOID 00869 FASTCALL 00870 ExBlockPushLock( 00871 IN PEX_PUSH_LOCK PushLock, 00872 IN PVOID WaitBlock 00873 ); 00874 00875 VOID 00876 FASTCALL 00877 ExfUnblockPushLock( 00878 IN PEX_PUSH_LOCK PushLock, 00879 IN PVOID CurrentWaitBlock 00880 ); 00881 00882 VOID 00883 FASTCALL 00884 ExWaitForUnblockPushLock( 00885 IN PEX_PUSH_LOCK PushLock, 00886 IN PVOID WaitBlock 00887 ); 00888 00889 /*++ 00890 * @name _ExInitializePushLock 00891 * INTERNAL MACRO 00892 * 00893 * The _ExInitializePushLock macro initializes a PushLock. 00894 * 00895 * @params PushLock 00896 * Pointer to the pushlock which is to be initialized. 00897 * 00898 * @return None. 00899 * 00900 * @remarks None. 00901 * 00902 *--*/ 00903 FORCEINLINE 00904 VOID 00905 _ExInitializePushLock(OUT PEX_PUSH_LOCK PushLock) 00906 { 00907 /* Set the value to 0 */ 00908 PushLock->Ptr = 0; 00909 } 00910 #define ExInitializePushLock _ExInitializePushLock 00911 00912 /*++ 00913 * @name ExAcquirePushLockExclusive 00914 * INTERNAL MACRO 00915 * 00916 * The ExAcquirePushLockExclusive macro exclusively acquires a PushLock. 00917 * 00918 * @params PushLock 00919 * Pointer to the pushlock which is to be acquired. 00920 * 00921 * @return None. 00922 * 00923 * @remarks The function attempts the quickest route to acquire the lock, which is 00924 * to simply set the lock bit. 00925 * However, if the pushlock is already shared, the slower path is taken. 00926 * 00927 * Callers of ExAcquirePushLockShared must be running at IRQL <= APC_LEVEL. 00928 * This macro should usually be paired up with KeAcquireCriticalRegion. 00929 * 00930 *--*/ 00931 FORCEINLINE 00932 VOID 00933 ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock) 00934 { 00935 /* Try acquiring the lock */ 00936 if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V)) 00937 { 00938 /* Someone changed it, use the slow path */ 00939 ExfAcquirePushLockExclusive(PushLock); 00940 } 00941 00942 /* Sanity check */ 00943 ASSERT(PushLock->Locked); 00944 } 00945 00946 /*++ 00947 * @name ExTryToAcquirePushLockExclusive 00948 * INTERNAL MACRO 00949 * 00950 * The ExAcquirePushLockExclusive macro exclusively acquires a PushLock. 00951 * 00952 * @params PushLock 00953 * Pointer to the pushlock which is to be acquired. 00954 * 00955 * @return None. 00956 * 00957 * @remarks The function attempts the quickest route to acquire the lock, which is 00958 * to simply set the lock bit. 00959 * However, if the pushlock is already shared, the slower path is taken. 00960 * 00961 * Callers of ExAcquirePushLockShared must be running at IRQL <= APC_LEVEL. 00962 * This macro should usually be paired up with KeAcquireCriticalRegion. 00963 * 00964 *--*/ 00965 FORCEINLINE 00966 BOOLEAN 00967 ExTryToAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock) 00968 { 00969 /* Try acquiring the lock */ 00970 if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V)) 00971 { 00972 /* Can't acquire */ 00973 return FALSE; 00974 } 00975 00976 /* Got acquired */ 00977 ASSERT (PushLock->Locked); 00978 return TRUE; 00979 } 00980 00981 /*++ 00982 * @name ExAcquirePushLockShared 00983 * INTERNAL MACRO 00984 * 00985 * The ExAcquirePushLockShared macro acquires a shared PushLock. 00986 * 00987 * @params PushLock 00988 * Pointer to the pushlock which is to be acquired. 00989 * 00990 * @return None. 00991 * 00992 * @remarks The function attempts the quickest route to acquire the lock, which is 00993 * to simply set the lock bit and set the share count to one. 00994 * However, if the pushlock is already shared, the slower path is taken. 00995 * 00996 * Callers of ExAcquirePushLockShared must be running at IRQL <= APC_LEVEL. 00997 * This macro should usually be paired up with KeAcquireCriticalRegion. 00998 * 00999 *--*/ 01000 FORCEINLINE 01001 VOID 01002 ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock) 01003 { 01004 EX_PUSH_LOCK NewValue; 01005 01006 /* Try acquiring the lock */ 01007 NewValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC; 01008 if (ExpChangePushlock(PushLock, NewValue.Ptr, 0)) 01009 { 01010 /* Someone changed it, use the slow path */ 01011 ExfAcquirePushLockShared(PushLock); 01012 } 01013 01014 /* Sanity checks */ 01015 ASSERT(PushLock->Locked); 01016 ASSERT(PushLock->Waiting || PushLock->Shared > 0); 01017 } 01018 01019 /*++ 01020 * @name ExConvertPushLockSharedToExclusive 01021 * INTERNAL MACRO 01022 * 01023 * The ExConvertPushLockSharedToExclusive macro converts an exclusive 01024 * pushlock to a shared pushlock. 01025 * 01026 * @params PushLock 01027 * Pointer to the pushlock which is to be converted. 01028 * 01029 * @return FALSE if conversion failed, TRUE otherwise. 01030 * 01031 * @remarks The function attempts the quickest route to convert the lock, which is 01032 * to simply set the lock bit and remove any other bits. 01033 * 01034 *--*/ 01035 FORCEINLINE 01036 BOOLEAN 01037 ExConvertPushLockSharedToExclusive(IN PEX_PUSH_LOCK PushLock) 01038 { 01039 EX_PUSH_LOCK OldValue; 01040 01041 /* Set the expected old value */ 01042 OldValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC; 01043 01044 /* Try converting the lock */ 01045 if (ExpChangePushlock(PushLock, EX_PUSH_LOCK_LOCK, OldValue.Value) != 01046 OldValue.Ptr) 01047 { 01048 /* Conversion failed */ 01049 return FALSE; 01050 } 01051 01052 /* Sanity check */ 01053 ASSERT(PushLock->Locked); 01054 return TRUE; 01055 } 01056 01057 /*++ 01058 * @name ExWaitOnPushLock 01059 * INTERNAL MACRO 01060 * 01061 * The ExWaitOnPushLock macro acquires and instantly releases a pushlock. 01062 * 01063 * @params PushLock 01064 * Pointer to a pushlock. 01065 * 01066 * @return None. 01067 * 01068 * @remarks The function attempts to get any exclusive waiters out of their slow 01069 * path by forcing an instant acquire/release operation. 01070 * 01071 * Callers of ExWaitOnPushLock must be running at IRQL <= APC_LEVEL. 01072 * 01073 *--*/ 01074 FORCEINLINE 01075 VOID 01076 ExWaitOnPushLock(PEX_PUSH_LOCK PushLock) 01077 { 01078 /* Check if we're locked */ 01079 if (PushLock->Locked) 01080 { 01081 /* Acquire the lock */ 01082 ExfAcquirePushLockExclusive(PushLock); 01083 ASSERT(PushLock->Locked); 01084 01085 /* Release it */ 01086 ExfReleasePushLockExclusive(PushLock); 01087 } 01088 } 01089 01090 /*++ 01091 * @name ExReleasePushLockShared 01092 * INTERNAL MACRO 01093 * 01094 * The ExReleasePushLockShared macro releases a previously acquired PushLock. 01095 * 01096 * @params PushLock 01097 * Pointer to a previously acquired pushlock. 01098 * 01099 * @return None. 01100 * 01101 * @remarks The function attempts the quickest route to release the lock, which is 01102 * to simply decrease the share count and remove the lock bit. 01103 * However, if the pushlock is being waited on then the long path is taken. 01104 * 01105 * Callers of ExReleasePushLockShared must be running at IRQL <= APC_LEVEL. 01106 * This macro should usually be paired up with KeLeaveCriticalRegion. 01107 * 01108 *--*/ 01109 FORCEINLINE 01110 VOID 01111 ExReleasePushLockShared(PEX_PUSH_LOCK PushLock) 01112 { 01113 EX_PUSH_LOCK OldValue; 01114 01115 /* Sanity checks */ 01116 ASSERT(PushLock->Locked); 01117 ASSERT(PushLock->Waiting || PushLock->Shared > 0); 01118 01119 /* Try to clear the pushlock */ 01120 OldValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC; 01121 if (ExpChangePushlock(PushLock, 0, OldValue.Ptr) != OldValue.Ptr) 01122 { 01123 /* There are still other people waiting on it */ 01124 ExfReleasePushLockShared(PushLock); 01125 } 01126 } 01127 01128 /*++ 01129 * @name ExReleasePushLockExclusive 01130 * INTERNAL MACRO 01131 * 01132 * The ExReleasePushLockExclusive macro releases a previously 01133 * exclusively acquired PushLock. 01134 * 01135 * @params PushLock 01136 * Pointer to a previously acquired pushlock. 01137 * 01138 * @return None. 01139 * 01140 * @remarks The function attempts the quickest route to release the lock, which is 01141 * to simply clear the locked bit. 01142 * However, if the pushlock is being waited on, the slow path is taken 01143 * in an attempt to wake up the lock. 01144 * 01145 * Callers of ExReleasePushLockExclusive must be running at IRQL <= APC_LEVEL. 01146 * This macro should usually be paired up with KeLeaveCriticalRegion. 01147 * 01148 *--*/ 01149 FORCEINLINE 01150 VOID 01151 ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock) 01152 { 01153 EX_PUSH_LOCK OldValue; 01154 01155 /* Sanity checks */ 01156 ASSERT(PushLock->Locked); 01157 ASSERT(PushLock->Waiting || PushLock->Shared == 0); 01158 01159 /* Unlock the pushlock */ 01160 OldValue.Value = InterlockedExchangeAddSizeT((PSIZE_T)PushLock, 01161 -(SSIZE_T)EX_PUSH_LOCK_LOCK); 01162 01163 /* Sanity checks */ 01164 ASSERT(OldValue.Locked); 01165 ASSERT(OldValue.Waiting || OldValue.Shared == 0); 01166 01167 /* Check if anyone is waiting on it and it's not already waking*/ 01168 if ((OldValue.Waiting) && !(OldValue.Waking)) 01169 { 01170 /* Wake it up */ 01171 ExfTryToWakePushLock(PushLock); 01172 } 01173 } 01174 01175 /*++ 01176 * @name ExReleasePushLock 01177 * INTERNAL MACRO 01178 * 01179 * The ExReleasePushLock macro releases a previously acquired PushLock. 01180 * 01181 * @params PushLock 01182 * Pointer to a previously acquired pushlock. 01183 * 01184 * @return None. 01185 * 01186 * @remarks The function attempts the quickest route to release the lock, which is 01187 * to simply clear all the fields and decrease the share count if required. 01188 * However, if the pushlock is being waited on then the long path is taken. 01189 * 01190 * Callers of ExReleasePushLock must be running at IRQL <= APC_LEVEL. 01191 * This macro should usually be paired up with KeLeaveCriticalRegion. 01192 * 01193 *--*/ 01194 FORCEINLINE 01195 VOID 01196 ExReleasePushLock(PEX_PUSH_LOCK PushLock) 01197 { 01198 EX_PUSH_LOCK OldValue = *PushLock; 01199 EX_PUSH_LOCK NewValue; 01200 01201 /* Sanity checks */ 01202 ASSERT(OldValue.Locked); 01203 01204 /* Check if the pushlock is shared */ 01205 if (OldValue.Shared > 1) 01206 { 01207 /* Decrease the share count */ 01208 NewValue.Value = OldValue.Value - EX_PUSH_LOCK_SHARE_INC; 01209 } 01210 else 01211 { 01212 /* Clear the pushlock entirely */ 01213 NewValue.Value = 0; 01214 } 01215 01216 /* Check if nobody is waiting on us and try clearing the lock here */ 01217 if ((OldValue.Waiting) || 01218 (ExpChangePushlock(PushLock, NewValue.Ptr, OldValue.Ptr) != 01219 OldValue.Ptr)) 01220 { 01221 /* We have waiters, use the long path */ 01222 ExfReleasePushLock(PushLock); 01223 } 01224 } 01225 01226 /* FAST MUTEX INLINES *********************************************************/ 01227 01228 FORCEINLINE 01229 VOID 01230 _ExAcquireFastMutexUnsafe(IN PFAST_MUTEX FastMutex) 01231 { 01232 PKTHREAD Thread = KeGetCurrentThread(); 01233 01234 /* Sanity check */ 01235 ASSERT((KeGetCurrentIrql() == APC_LEVEL) || 01236 (Thread->CombinedApcDisable != 0) || 01237 (Thread->Teb == NULL) || 01238 (Thread->Teb >= (PTEB)MM_SYSTEM_RANGE_START)); 01239 ASSERT(FastMutex->Owner != Thread); 01240 01241 /* Decrease the count */ 01242 if (InterlockedDecrement(&FastMutex->Count)) 01243 { 01244 /* Someone is still holding it, use slow path */ 01245 KiAcquireFastMutex(FastMutex); 01246 } 01247 01248 /* Set the owner */ 01249 FastMutex->Owner = Thread; 01250 } 01251 01252 FORCEINLINE 01253 VOID 01254 _ExReleaseFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex) 01255 { 01256 ASSERT((KeGetCurrentIrql() == APC_LEVEL) || 01257 (KeGetCurrentThread()->CombinedApcDisable != 0) || 01258 (KeGetCurrentThread()->Teb == NULL) || 01259 (KeGetCurrentThread()->Teb >= (PTEB)MM_SYSTEM_RANGE_START)); 01260 ASSERT(FastMutex->Owner == KeGetCurrentThread()); 01261 01262 /* Erase the owner */ 01263 FastMutex->Owner = NULL; 01264 01265 /* Increase the count */ 01266 if (InterlockedIncrement(&FastMutex->Count) <= 0) 01267 { 01268 /* Someone was waiting for it, signal the waiter */ 01269 KeSetEventBoostPriority(&FastMutex->Event, NULL); 01270 } 01271 } 01272 01273 FORCEINLINE 01274 VOID 01275 _ExAcquireFastMutex(IN PFAST_MUTEX FastMutex) 01276 { 01277 KIRQL OldIrql; 01278 ASSERT(KeGetCurrentIrql() <= APC_LEVEL); 01279 01280 /* Raise IRQL to APC */ 01281 KeRaiseIrql(APC_LEVEL, &OldIrql); 01282 01283 /* Decrease the count */ 01284 if (InterlockedDecrement(&FastMutex->Count)) 01285 { 01286 /* Someone is still holding it, use slow path */ 01287 KiAcquireFastMutex(FastMutex); 01288 } 01289 01290 /* Set the owner and IRQL */ 01291 FastMutex->Owner = KeGetCurrentThread(); 01292 FastMutex->OldIrql = OldIrql; 01293 } 01294 01295 FORCEINLINE 01296 VOID 01297 _ExReleaseFastMutex(IN OUT PFAST_MUTEX FastMutex) 01298 { 01299 KIRQL OldIrql; 01300 ASSERT(KeGetCurrentIrql() == APC_LEVEL); 01301 01302 /* Erase the owner */ 01303 FastMutex->Owner = NULL; 01304 OldIrql = (KIRQL)FastMutex->OldIrql; 01305 01306 /* Increase the count */ 01307 if (InterlockedIncrement(&FastMutex->Count) <= 0) 01308 { 01309 /* Someone was waiting for it, signal the waiter */ 01310 KeSetEventBoostPriority(&FastMutex->Event, NULL); 01311 } 01312 01313 /* Lower IRQL back */ 01314 KeLowerIrql(OldIrql); 01315 } 01316 01317 FORCEINLINE 01318 BOOLEAN 01319 _ExTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex) 01320 { 01321 KIRQL OldIrql; 01322 ASSERT(KeGetCurrentIrql() <= APC_LEVEL); 01323 01324 /* Raise to APC_LEVEL */ 01325 KeRaiseIrql(APC_LEVEL, &OldIrql); 01326 01327 /* Check if we can quickly acquire it */ 01328 if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1) 01329 { 01330 /* We have, set us as owners */ 01331 FastMutex->Owner = KeGetCurrentThread(); 01332 FastMutex->OldIrql = OldIrql; 01333 return TRUE; 01334 } 01335 else 01336 { 01337 /* Acquire attempt failed */ 01338 KeLowerIrql(OldIrql); 01339 YieldProcessor(); 01340 return FALSE; 01341 } 01342 } 01343 01344 FORCEINLINE 01345 VOID 01346 _ExEnterCriticalRegionAndAcquireFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex) 01347 { 01348 /* Enter the Critical Region */ 01349 KeEnterCriticalRegion(); 01350 01351 /* Acquire the mutex unsafely */ 01352 _ExAcquireFastMutexUnsafe(FastMutex); 01353 } 01354 01355 FORCEINLINE 01356 VOID 01357 _ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(IN OUT PFAST_MUTEX FastMutex) 01358 { 01359 /* Release the mutex unsafely */ 01360 _ExReleaseFastMutexUnsafe(FastMutex); 01361 01362 /* Leave the critical region */ 01363 KeLeaveCriticalRegion(); 01364 } 01365 01366 /* OTHER FUNCTIONS **********************************************************/ 01367 01368 BOOLEAN 01369 NTAPI 01370 ExTryToAcquireResourceExclusiveLite( 01371 IN PERESOURCE Resource 01372 ); 01373 01374 NTSTATUS 01375 ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation); 01376 01377 BOOLEAN 01378 NTAPI 01379 ExAcquireTimeRefreshLock(BOOLEAN Wait); 01380 01381 VOID 01382 NTAPI 01383 ExReleaseTimeRefreshLock(VOID); 01384 01385 VOID 01386 NTAPI 01387 ExUpdateSystemTimeFromCmos(IN BOOLEAN UpdateInterruptTime, 01388 IN ULONG MaxSepInSeconds); 01389 01390 NTSTATUS 01391 NTAPI 01392 ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId); 01393 01394 VOID 01395 NTAPI 01396 ExTimerRundown(VOID); 01397 01398 VOID 01399 NTAPI 01400 HeadlessInit( 01401 IN PLOADER_PARAMETER_BLOCK LoaderBlock 01402 ); 01403 01404 VOID 01405 NTAPI 01406 XIPInit( 01407 IN PLOADER_PARAMETER_BLOCK LoaderBlock 01408 ); 01409 01410 #define InterlockedDecrementUL(Addend) \ 01411 (ULONG)InterlockedDecrement((PLONG)(Addend)) 01412 01413 #define InterlockedIncrementUL(Addend) \ 01414 (ULONG)InterlockedIncrement((PLONG)(Addend)) 01415 01416 #define InterlockedExchangeUL(Target, Value) \ 01417 (ULONG)InterlockedExchange((PLONG)(Target), (LONG)(Value)) 01418 01419 #define InterlockedExchangeAddUL(Addend, Value) \ 01420 (ULONG)InterlockedExchangeAdd((PLONG)(Addend), (LONG)(Value)) 01421 01422 #define InterlockedCompareExchangeUL(Destination, Exchange, Comperand) \ 01423 (ULONG)InterlockedCompareExchange((PLONG)(Destination), (LONG)(Exchange), (LONG)(Comperand)) 01424 01425 #define ExfInterlockedCompareExchange64UL(Destination, Exchange, Comperand) \ 01426 (ULONGLONG)ExfInterlockedCompareExchange64((PLONGLONG)(Destination), (PLONGLONG)(Exchange), (PLONGLONG)(Comperand)) Generated on Wed May 23 2012 04:35:06 for ReactOS by
1.7.6.1
|