- Implement ExpIsLoaderValid to validate the LOADER_PARAMETER_BLOCK's extension for...
[reactos.git] / reactos / ntoskrnl / include / internal / ex.h
1 #ifndef __NTOSKRNL_INCLUDE_INTERNAL_EXECUTIVE_H
2 #define __NTOSKRNL_INCLUDE_INTERNAL_EXECUTIVE_H
3
4 /* GLOBAL VARIABLES *********************************************************/
5
6 extern TIME_ZONE_INFORMATION ExpTimeZoneInfo;
7 extern LARGE_INTEGER ExpTimeZoneBias;
8 extern ULONG ExpTimeZoneId;
9 extern POBJECT_TYPE ExEventPairObjectType;
10 extern ULONG NtBuildNumber;
11 extern ULONG NtMajorVersion;
12 extern ULONG NtMinorVersion;
13
14 #define MAX_FAST_REFS 7
15
16 #define EX_OBJ_TO_HDR(eob) ((POBJECT_HEADER)((ULONG_PTR)(eob) & \
17 ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \
18 EX_HANDLE_ENTRY_AUDITONCLOSE)))
19 #define EX_HTE_TO_HDR(hte) ((POBJECT_HEADER)((ULONG_PTR)((hte)->Object) & \
20 ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \
21 EX_HANDLE_ENTRY_AUDITONCLOSE)))
22
23 /* Note: we only use a spinlock on SMP. On UP, we cli/sti intead */
24 #ifndef CONFIG_SMP
25 #define ExAcquireResourceLock(l, i) { \
26 (void)i; \
27 Ke386DisableInterrupts(); \
28 }
29 #define ExReleaseResourceLock(l, i) Ke386EnableInterrupts();
30 #else
31 #define ExAcquireResourceLock(l, i) KeAcquireSpinLock(l, i);
32 #define ExReleaseResourceLock(l, i) KeReleaseSpinLock(l, i);
33 #endif
34
35 #define ExAcquireRundownProtection _ExAcquireRundownProtection
36 #define ExReleaseRundownProtection _ExReleaseRundownProtection
37 #define ExInitializeRundownProtection _ExInitializeRundownProtection
38 #define ExWaitForRundownProtectionRelease _ExWaitForRundownProtectionRelease
39 #define ExRundownCompleted _ExRundownCompleted
40
41 /* INITIALIZATION FUNCTIONS *************************************************/
42
43 VOID
44 NTAPI
45 ExpWin32kInit(VOID);
46
47 VOID
48 NTAPI
49 ExInit2(VOID);
50
51 VOID
52 NTAPI
53 ExPhase2Init(
54 IN PVOID Context
55 );
56
57 VOID
58 NTAPI
59 ExpInitTimeZoneInfo(VOID);
60
61 VOID
62 NTAPI
63 ExpInitializeWorkerThreads(VOID);
64
65 VOID
66 NTAPI
67 ExpInitLookasideLists(VOID);
68
69 VOID
70 NTAPI
71 ExpInitializeCallbacks(VOID);
72
73 VOID
74 NTAPI
75 ExpInitUuids(VOID);
76
77 VOID
78 NTAPI
79 ExpInitializeExecutive(
80 IN ULONG Cpu,
81 IN PLOADER_PARAMETER_BLOCK LoaderBlock
82 );
83
84 VOID
85 NTAPI
86 ExpInitializeEventImplementation(VOID);
87
88 VOID
89 NTAPI
90 ExpInitializeEventImplementation(VOID);
91
92 VOID
93 NTAPI
94 ExpInitializeEventPairImplementation(VOID);
95
96 VOID
97 NTAPI
98 ExpInitializeSemaphoreImplementation(VOID);
99
100 VOID
101 NTAPI
102 ExpInitializeMutantImplementation(VOID);
103
104 VOID
105 NTAPI
106 ExpInitializeTimerImplementation(VOID);
107
108 VOID
109 NTAPI
110 ExpInitializeProfileImplementation(VOID);
111
112 VOID
113 NTAPI
114 ExpResourceInitialization(VOID);
115
116 VOID
117 NTAPI
118 ExInitPoolLookasidePointers(VOID);
119
120 /* Rundown Functions ********************************************************/
121
122 VOID
123 FASTCALL
124 ExfInitializeRundownProtection(
125 OUT PEX_RUNDOWN_REF RunRef
126 );
127
128 VOID
129 FASTCALL
130 ExfReInitializeRundownProtection(
131 OUT PEX_RUNDOWN_REF RunRef
132 );
133
134 BOOLEAN
135 FASTCALL
136 ExfAcquireRundownProtection(
137 IN OUT PEX_RUNDOWN_REF RunRef
138 );
139
140 BOOLEAN
141 FASTCALL
142 ExfAcquireRundownProtectionEx(
143 IN OUT PEX_RUNDOWN_REF RunRef,
144 IN ULONG Count
145 );
146
147 VOID
148 FASTCALL
149 ExfReleaseRundownProtection(
150 IN OUT PEX_RUNDOWN_REF RunRef
151 );
152
153 VOID
154 FASTCALL
155 ExfReleaseRundownProtectionEx(
156 IN OUT PEX_RUNDOWN_REF RunRef,
157 IN ULONG Count
158 );
159
160 VOID
161 FASTCALL
162 ExfRundownCompleted(
163 OUT PEX_RUNDOWN_REF RunRef
164 );
165
166 VOID
167 FASTCALL
168 ExfWaitForRundownProtectionRelease(
169 IN OUT PEX_RUNDOWN_REF RunRef
170 );
171
172 /* HANDLE TABLE FUNCTIONS ***************************************************/
173
174 #define EX_HANDLE_ENTRY_LOCKED (1 << ((sizeof(PVOID) * 8) - 1))
175 #define EX_HANDLE_ENTRY_PROTECTFROMCLOSE (1 << 0)
176 #define EX_HANDLE_ENTRY_INHERITABLE (1 << 1)
177 #define EX_HANDLE_ENTRY_AUDITONCLOSE (1 << 2)
178
179 #define EX_HANDLE_TABLE_CLOSING 0x1
180
181 #define EX_HANDLE_ENTRY_FLAGSMASK (EX_HANDLE_ENTRY_LOCKED | \
182 EX_HANDLE_ENTRY_PROTECTFROMCLOSE | \
183 EX_HANDLE_ENTRY_INHERITABLE | \
184 EX_HANDLE_ENTRY_AUDITONCLOSE)
185
186 typedef VOID (NTAPI PEX_SWEEP_HANDLE_CALLBACK)(
187 PHANDLE_TABLE_ENTRY HandleTableEntry,
188 HANDLE Handle,
189 PVOID Context
190 );
191
192 typedef BOOLEAN (NTAPI PEX_DUPLICATE_HANDLE_CALLBACK)(
193 PHANDLE_TABLE HandleTable,
194 PHANDLE_TABLE_ENTRY HandleTableEntry,
195 PVOID Context
196 );
197
198 typedef BOOLEAN (NTAPI PEX_CHANGE_HANDLE_CALLBACK)(
199 PHANDLE_TABLE HandleTable,
200 PHANDLE_TABLE_ENTRY HandleTableEntry,
201 PVOID Context
202 );
203
204 VOID
205 ExpInitializeHandleTables(VOID);
206
207 PHANDLE_TABLE
208 ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL);
209
210 VOID
211 ExDestroyHandleTable(
212 IN PHANDLE_TABLE HandleTable
213 );
214
215 VOID
216 ExSweepHandleTable(
217 IN PHANDLE_TABLE HandleTable,
218 IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback OPTIONAL,
219 IN PVOID Context OPTIONAL
220 );
221
222 PHANDLE_TABLE
223 ExDupHandleTable(
224 IN PEPROCESS QuotaProcess OPTIONAL,
225 IN PEX_DUPLICATE_HANDLE_CALLBACK DuplicateHandleCallback OPTIONAL,
226 IN PVOID Context OPTIONAL,
227 IN PHANDLE_TABLE SourceHandleTable
228 );
229
230 BOOLEAN
231 ExLockHandleTableEntry(
232 IN PHANDLE_TABLE HandleTable,
233 IN PHANDLE_TABLE_ENTRY Entry
234 );
235
236 VOID
237 ExUnlockHandleTableEntry(
238 IN PHANDLE_TABLE HandleTable,
239 IN PHANDLE_TABLE_ENTRY Entry
240 );
241
242 HANDLE
243 ExCreateHandle(
244 IN PHANDLE_TABLE HandleTable,
245 IN PHANDLE_TABLE_ENTRY Entry
246 );
247
248 BOOLEAN
249 ExDestroyHandle(
250 IN PHANDLE_TABLE HandleTable,
251 IN HANDLE Handle
252 );
253
254 VOID
255 ExDestroyHandleByEntry(
256 IN PHANDLE_TABLE HandleTable,
257 IN PHANDLE_TABLE_ENTRY Entry,
258 IN HANDLE Handle
259 );
260
261 PHANDLE_TABLE_ENTRY
262 ExMapHandleToPointer(
263 IN PHANDLE_TABLE HandleTable,
264 IN HANDLE Handle
265 );
266
267 BOOLEAN
268 ExChangeHandle(
269 IN PHANDLE_TABLE HandleTable,
270 IN HANDLE Handle,
271 IN PEX_CHANGE_HANDLE_CALLBACK ChangeHandleCallback,
272 IN PVOID Context
273 );
274
275 /* PSEH EXCEPTION HANDLING **************************************************/
276
277 LONG
278 NTAPI
279 ExSystemExceptionFilter(VOID);
280
281 static __inline _SEH_FILTER(_SEH_ExSystemExceptionFilter)
282 {
283 return ExSystemExceptionFilter();
284 }
285
286 /* RUNDOWN *******************************************************************/
287
288 #ifdef _WIN64
289 #define ExpChangeRundown(x, y, z) InterlockedCompareExchange64((PLONGLONG)x, y, z)
290 #define ExpSetRundown(x, y) InterlockedExchange64((PLONGLONG)x, y)
291 #else
292 #define ExpChangeRundown(x, y, z) InterlockedCompareExchange((PLONG)x, PtrToLong(y), PtrToLong(z))
293 #define ExpSetRundown(x, y) InterlockedExchange((PLONG)x, y)
294 #endif
295
296 /*++
297 * @name ExfAcquireRundownProtection
298 * INTERNAL MACRO
299 *
300 * The ExfAcquireRundownProtection routine acquires rundown protection for
301 * the specified descriptor.
302 *
303 * @param RunRef
304 * Pointer to a rundown reference descriptor.
305 *
306 * @return TRUE if access to the protected structure was granted, FALSE otherwise.
307 *
308 * @remarks This is the internal macro for system use only.In case the rundown
309 * was active, then the slow-path will be called through the exported
310 * function.
311 *
312 *--*/
313 BOOLEAN
314 FORCEINLINE
315 _ExAcquireRundownProtection(IN PEX_RUNDOWN_REF RunRef)
316 {
317 ULONG_PTR Value, NewValue, OldValue;
318
319 /* Get the current value and mask the active bit */
320 Value = RunRef->Count &~ EX_RUNDOWN_ACTIVE;
321
322 /* Add a reference */
323 NewValue = Value + EX_RUNDOWN_COUNT_INC;
324
325 /* Change the value */
326 OldValue = ExpChangeRundown(RunRef, NewValue, Value);
327 if (OldValue != Value)
328 {
329 /* Rundown was active, use long path */
330 return ExfAcquireRundownProtection(RunRef);
331 }
332
333 /* Success */
334 return TRUE;
335 }
336
337 /*++
338 * @name ExReleaseRundownProtection
339 * INTERNAL MACRO
340 *
341 * The ExReleaseRundownProtection routine releases rundown protection for
342 * the specified descriptor.
343 *
344 * @param RunRef
345 * Pointer to a rundown reference descriptor.
346 *
347 * @return TRUE if access to the protected structure was granted, FALSE otherwise.
348 *
349 * @remarks This is the internal macro for system use only.In case the rundown
350 * was active, then the slow-path will be called through the exported
351 * function.
352 *
353 *--*/
354 VOID
355 FORCEINLINE
356 _ExReleaseRundownProtection(IN PEX_RUNDOWN_REF RunRef)
357 {
358 ULONG_PTR Value, NewValue, OldValue;
359
360 /* Get the current value and mask the active bit */
361 Value = RunRef->Count &~ EX_RUNDOWN_ACTIVE;
362
363 /* Remove a reference */
364 NewValue = Value - EX_RUNDOWN_COUNT_INC;
365
366 /* Change the value */
367 OldValue = ExpChangeRundown(RunRef, NewValue, Value);
368
369 /* Check if the rundown was active */
370 if (OldValue != Value)
371 {
372 /* Rundown was active, use long path */
373 ExfReleaseRundownProtection(RunRef);
374 }
375 else
376 {
377 /* Sanity check */
378 ASSERT((Value >= EX_RUNDOWN_COUNT_INC) || (KeNumberProcessors > 1));
379 }
380 }
381
382 /*++
383 * @name ExInitializeRundownProtection
384 * INTERNAL MACRO
385 *
386 * The ExInitializeRundownProtection routine initializes a rundown
387 * protection descriptor.
388 *
389 * @param RunRef
390 * Pointer to a rundown reference descriptor.
391 *
392 * @return None.
393 *
394 * @remarks This is the internal macro for system use only.
395 *
396 *--*/
397 VOID
398 FORCEINLINE
399 _ExInitializeRundownProtection(IN PEX_RUNDOWN_REF RunRef)
400 {
401 /* Set the count to zero */
402 RunRef->Count = 0;
403 }
404
405 /*++
406 * @name ExWaitForRundownProtectionRelease
407 * INTERNAL MACRO
408 *
409 * The ExWaitForRundownProtectionRelease routine waits until the specified
410 * rundown descriptor has been released.
411 *
412 * @param RunRef
413 * Pointer to a rundown reference descriptor.
414 *
415 * @return None.
416 *
417 * @remarks This is the internal macro for system use only. If a wait is actually
418 * necessary, then the slow path is taken through the exported function.
419 *
420 *--*/
421 VOID
422 FORCEINLINE
423 _ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REF RunRef)
424 {
425 ULONG_PTR Value;
426
427 /* Set the active bit */
428 Value = ExpChangeRundown(RunRef, EX_RUNDOWN_ACTIVE, 0);
429 if ((Value) || (Value != EX_RUNDOWN_ACTIVE))
430 {
431 /* If the the rundown wasn't already active, then take the long path */
432 ExfWaitForRundownProtectionRelease(RunRef);
433 }
434 }
435
436 /*++
437 * @name ExRundownCompleted
438 * INTERNAL MACRO
439 *
440 * The ExRundownCompleted routine completes the rundown of the specified
441 * descriptor by setting the active bit.
442 *
443 * @param RunRef
444 * Pointer to a rundown reference descriptor.
445 *
446 * @return None.
447 *
448 * @remarks This is the internal macro for system use only.
449 *
450 *--*/
451 VOID
452 FORCEINLINE
453 _ExRundownCompleted(IN PEX_RUNDOWN_REF RunRef)
454 {
455 /* Sanity check */
456 ASSERT((RunRef->Count & EX_RUNDOWN_ACTIVE) != 0);
457
458 /* Mark the counter as active */
459 ExpSetRundown(&RunRef->Count, EX_RUNDOWN_ACTIVE);
460 }
461
462 /* PUSHLOCKS *****************************************************************/
463
464 /*++
465 * @name ExAcquirePushLockExclusive
466 * INTERNAL MACRO
467 *
468 * The ExAcquirePushLockExclusive macro exclusively acquires a PushLock.
469 *
470 * @params PushLock
471 * Pointer to the pushlock which is to be acquired.
472 *
473 * @return None.
474 *
475 * @remarks The function attempts the quickest route to acquire the lock, which is
476 * to simply set the lock bit.
477 * However, if the pushlock is already shared, the slower path is taken.
478 *
479 * Callers of ExAcquirePushLockShared must be running at IRQL <= APC_LEVEL.
480 * This macro should usually be paired up with KeAcquireCriticalRegion.
481 *
482 *--*/
483 VOID
484 FORCEINLINE
485 ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
486 {
487 /* Try acquiring the lock */
488 if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V))
489 {
490 /* Someone changed it, use the slow path */
491 DbgPrint("%s - Contention!\n", __FUNCTION__);
492 ExfAcquirePushLockExclusive(PushLock);
493 }
494
495 /* Sanity check */
496 ASSERT(PushLock->Locked);
497 }
498
499 /*++
500 * @name ExAcquirePushLockShared
501 * INTERNAL MACRO
502 *
503 * The ExAcquirePushLockShared macro acquires a shared PushLock.
504 *
505 * @params PushLock
506 * Pointer to the pushlock which is to be acquired.
507 *
508 * @return None.
509 *
510 * @remarks The function attempts the quickest route to acquire the lock, which is
511 * to simply set the lock bit and set the share count to one.
512 * However, if the pushlock is already shared, the slower path is taken.
513 *
514 * Callers of ExAcquirePushLockShared must be running at IRQL <= APC_LEVEL.
515 * This macro should usually be paired up with KeAcquireCriticalRegion.
516 *
517 *--*/
518 VOID
519 FORCEINLINE
520 ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
521 {
522 EX_PUSH_LOCK NewValue;
523
524 /* Try acquiring the lock */
525 NewValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC;
526 if (InterlockedCompareExchangePointer(PushLock, NewValue.Ptr, 0))
527 {
528 /* Someone changed it, use the slow path */
529 DbgPrint("%s - Contention!\n", __FUNCTION__);
530 ExfAcquirePushLockShared(PushLock);
531 }
532
533 /* Sanity checks */
534 ASSERT(PushLock->Locked);
535 ASSERT(PushLock->Waiting || PushLock->Shared > 0);
536 }
537
538 /*++
539 * @name ExWaitOnPushLock
540 * INTERNAL MACRO
541 *
542 * The ExWaitOnPushLock macro acquires and instantly releases a pushlock.
543 *
544 * @params PushLock
545 * Pointer to a pushlock.
546 *
547 * @return None.
548 *
549 * @remarks The function attempts to get any exclusive waiters out of their slow
550 * path by forcing an instant acquire/release operation.
551 *
552 * Callers of ExWaitOnPushLock must be running at IRQL <= APC_LEVEL.
553 *
554 *--*/
555 VOID
556 FORCEINLINE
557 ExWaitOnPushLock(PEX_PUSH_LOCK PushLock)
558 {
559 /* Acquire the lock */
560 ExfAcquirePushLockExclusive(PushLock);
561 ASSERT(PushLock->Locked);
562
563 /* Release it */
564 ExfReleasePushLockExclusive(PushLock);
565 }
566
567 /*++
568 * @name ExReleasePushLockShared
569 * INTERNAL MACRO
570 *
571 * The ExReleasePushLockShared macro releases a previously acquired PushLock.
572 *
573 * @params PushLock
574 * Pointer to a previously acquired pushlock.
575 *
576 * @return None.
577 *
578 * @remarks The function attempts the quickest route to release the lock, which is
579 * to simply decrease the share count and remove the lock bit.
580 * However, if the pushlock is being waited on then the long path is taken.
581 *
582 * Callers of ExReleasePushLockShared must be running at IRQL <= APC_LEVEL.
583 * This macro should usually be paired up with KeLeaveCriticalRegion.
584 *
585 *--*/
586 VOID
587 FORCEINLINE
588 ExReleasePushLockShared(PEX_PUSH_LOCK PushLock)
589 {
590 EX_PUSH_LOCK OldValue;
591
592 /* Sanity checks */
593 ASSERT(PushLock->Locked);
594 ASSERT(PushLock->Waiting || PushLock->Shared > 0);
595
596 /* Try to clear the pushlock */
597 OldValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC;
598 if (InterlockedCompareExchangePointer(PushLock, 0, OldValue.Ptr) !=
599 OldValue.Ptr)
600 {
601 /* There are still other people waiting on it */
602 DbgPrint("%s - Contention!\n", __FUNCTION__);
603 ExfReleasePushLockShared(PushLock);
604 }
605 }
606
607 /*++
608 * @name ExReleasePushLockExclusive
609 * INTERNAL MACRO
610 *
611 * The ExReleasePushLockExclusive macro releases a previously
612 * exclusively acquired PushLock.
613 *
614 * @params PushLock
615 * Pointer to a previously acquired pushlock.
616 *
617 * @return None.
618 *
619 * @remarks The function attempts the quickest route to release the lock, which is
620 * to simply clear the locked bit.
621 * However, if the pushlock is being waited on, the slow path is taken
622 * in an attempt to wake up the lock.
623 *
624 * Callers of ExReleasePushLockExclusive must be running at IRQL <= APC_LEVEL.
625 * This macro should usually be paired up with KeLeaveCriticalRegion.
626 *
627 *--*/
628 VOID
629 FORCEINLINE
630 ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
631 {
632 EX_PUSH_LOCK OldValue;
633
634 /* Sanity checks */
635 ASSERT(PushLock->Locked);
636 ASSERT(PushLock->Waiting || PushLock->Shared == 0);
637
638 /* Unlock the pushlock */
639 OldValue.Value = InterlockedExchangeAddSizeT((PLONG)PushLock, -1);
640
641 /* Sanity checks */
642 ASSERT(OldValue.Locked);
643 ASSERT(OldValue.Waiting || OldValue.Shared == 0);
644
645 /* Check if anyone is waiting on it and it's not already waking*/
646 if ((OldValue.Waiting) && !(OldValue.Waking))
647 {
648 /* Wake it up */
649 DbgPrint("%s - Contention!\n", __FUNCTION__);
650 ExfTryToWakePushLock(PushLock);
651 }
652 }
653
654 /*++
655 * @name ExReleasePushLock
656 * INTERNAL MACRO
657 *
658 * The ExReleasePushLock macro releases a previously acquired PushLock.
659 *
660 * @params PushLock
661 * Pointer to a previously acquired pushlock.
662 *
663 * @return None.
664 *
665 * @remarks The function attempts the quickest route to release the lock, which is
666 * to simply clear all the fields and decrease the share count if required.
667 * However, if the pushlock is being waited on then the long path is taken.
668 *
669 * Callers of ExReleasePushLock must be running at IRQL <= APC_LEVEL.
670 * This macro should usually be paired up with KeLeaveCriticalRegion.
671 *
672 *--*/
673 VOID
674 FORCEINLINE
675 ExReleasePushLock(PEX_PUSH_LOCK PushLock)
676 {
677 EX_PUSH_LOCK OldValue = *PushLock;
678 EX_PUSH_LOCK NewValue;
679
680 /* Sanity checks */
681 ASSERT(OldValue.Locked);
682
683 /* Check if the pushlock is shared */
684 if (OldValue.Shared > 1)
685 {
686 /* Decrease the share count */
687 NewValue.Value = OldValue.Value &~ EX_PUSH_LOCK_SHARE_INC;
688 }
689 else
690 {
691 /* Clear the pushlock entirely */
692 NewValue.Value = 0;
693 }
694
695 /* Check if nobody is waiting on us and try clearing the lock here */
696 if ((OldValue.Waiting) ||
697 (InterlockedCompareExchangePointer(PushLock, NewValue.Ptr, OldValue.Ptr) ==
698 OldValue.Ptr))
699 {
700 /* We have waiters, use the long path */
701 DbgPrint("%s - Contention!\n", __FUNCTION__);
702 ExfReleasePushLock(PushLock);
703 }
704 }
705
706 /* OTHER FUNCTIONS **********************************************************/
707
708 LONGLONG
709 FASTCALL
710 ExfpInterlockedExchange64(
711 LONGLONG volatile * Destination,
712 PLONGLONG Exchange
713 );
714
715 NTSTATUS
716 ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation);
717
718 NTSTATUS
719 NTAPI
720 ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId);
721
722 VOID
723 NTAPI
724 ExTimerRundown(VOID);
725
726 #define InterlockedDecrementUL(Addend) \
727 (ULONG)InterlockedDecrement((PLONG)(Addend))
728
729 #define InterlockedIncrementUL(Addend) \
730 (ULONG)InterlockedIncrement((PLONG)(Addend))
731
732 #define InterlockedExchangeUL(Target, Value) \
733 (ULONG)InterlockedExchange((PLONG)(Target), (LONG)(Value))
734
735 #define InterlockedExchangeAddUL(Addend, Value) \
736 (ULONG)InterlockedExchangeAdd((PLONG)(Addend), (LONG)(Value))
737
738 #define InterlockedCompareExchangeUL(Destination, Exchange, Comperand) \
739 (ULONG)InterlockedCompareExchange((PLONG)(Destination), (LONG)(Exchange), (LONG)(Comperand))
740
741 #define ExfInterlockedCompareExchange64UL(Destination, Exchange, Comperand) \
742 (ULONGLONG)ExfInterlockedCompareExchange64((PLONGLONG)(Destination), (PLONGLONG)(Exchange), (PLONGLONG)(Comperand))
743
744 #define ExfpInterlockedExchange64UL(Target, Value) \
745 (ULONGLONG)ExfpInterlockedExchange64((PLONGLONG)(Target), (PLONGLONG)(Value))
746
747 #endif /* __NTOSKRNL_INCLUDE_INTERNAL_EXECUTIVE_H */