ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ex.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.