9c8a49ac060bfb2f491371128440402818ff314b
[reactos.git] / reactos / ntoskrnl / include / internal / ke.h
1 #ifndef __NTOSKRNL_INCLUDE_INTERNAL_KE_H
2 #define __NTOSKRNL_INCLUDE_INTERNAL_KE_H
3
4 /* INCLUDES *****************************************************************/
5
6 #include "arch/ke.h"
7
8 /* INTERNAL KERNEL TYPES ****************************************************/
9
10 typedef struct _WOW64_PROCESS
11 {
12 PVOID Wow64;
13 } WOW64_PROCESS, *PWOW64_PROCESS;
14
15 typedef struct _KPROFILE_SOURCE_OBJECT
16 {
17 KPROFILE_SOURCE Source;
18 LIST_ENTRY ListEntry;
19 } KPROFILE_SOURCE_OBJECT, *PKPROFILE_SOURCE_OBJECT;
20
21 /* Cached modules from the loader block */
22 typedef enum _CACHED_MODULE_TYPE
23 {
24 AnsiCodepage,
25 OemCodepage,
26 UnicodeCasemap,
27 SystemRegistry,
28 HardwareRegistry,
29 MaximumCachedModuleType,
30 } CACHED_MODULE_TYPE, *PCACHED_MODULE_TYPE;
31 extern PLOADER_MODULE CachedModules[MaximumCachedModuleType];
32
33 struct _KIRQ_TRAPFRAME;
34 struct _KPCR;
35 struct _KPRCB;
36 struct _KEXCEPTION_FRAME;
37
38 extern PVOID KeUserApcDispatcher;
39 extern PVOID KeUserCallbackDispatcher;
40 extern PVOID KeUserExceptionDispatcher;
41 extern PVOID KeRaiseUserExceptionDispatcher;
42 extern LARGE_INTEGER SystemBootTime;
43 extern ULONG_PTR KERNEL_BASE;
44
45 /* MACROS *************************************************************************/
46
47 /*
48 * On UP machines, we don't actually have a spinlock, we merely raise
49 * IRQL to DPC level.
50 */
51 #ifndef CONFIG_SMP
52 #define KeInitializeDispatcher()
53 #define KeAcquireDispatcherDatabaseLock() KeRaiseIrqlToDpcLevel();
54 #define KeReleaseDispatcherDatabaseLock(OldIrql) KiExitDispatcher(OldIrql);
55 #define KeAcquireDispatcherDatabaseLockAtDpcLevel()
56 #define KeReleaseDispatcherDatabaseLockFromDpcLevel()
57 #else
58 #define KeInitializeDispatcher() KeInitializeSpinLock(&DispatcherDatabaseLock);
59 #define KeAcquireDispatcherDatabaseLock() KfAcquireSpinLock(&DispatcherDatabaseLock);
60 #define KeAcquireDispatcherDatabaseLockAtDpcLevel() \
61 KeAcquireSpinLockAtDpcLevel (&DispatcherDatabaseLock);
62 #define KeReleaseDispatcherDatabaseLockFromDpcLevel() \
63 KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock);
64 #define KeReleaseDispatcherDatabaseLock(OldIrql) \
65 KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock); \
66 KiExitDispatcher(OldIrql);
67 #endif
68
69 /* The following macro initializes a dispatcher object's header */
70 #define KeInitializeDispatcherHeader(Header, t, s, State) \
71 { \
72 (Header)->Type = t; \
73 (Header)->Absolute = 0; \
74 (Header)->Inserted = 0; \
75 (Header)->Size = s; \
76 (Header)->SignalState = State; \
77 InitializeListHead(&((Header)->WaitListHead)); \
78 }
79
80 /* The following macro satisfies the wait of any dispatcher object */
81 #define KiSatisfyObjectWait(Object, Thread) \
82 { \
83 /* Special case for Mutants */ \
84 if ((Object)->Header.Type == MutantObject) \
85 { \
86 /* Decrease the Signal State */ \
87 (Object)->Header.SignalState--; \
88 \
89 /* Check if it's now non-signaled */ \
90 if (!(Object)->Header.SignalState) \
91 { \
92 /* Set the Owner Thread */ \
93 (Object)->OwnerThread = Thread; \
94 \
95 /* Disable APCs if needed */ \
96 Thread->KernelApcDisable -= (Object)->ApcDisable; \
97 \
98 /* Check if it's abandoned */ \
99 if ((Object)->Abandoned) \
100 { \
101 /* Unabandon it */ \
102 (Object)->Abandoned = FALSE; \
103 \
104 /* Return Status */ \
105 Thread->WaitStatus = STATUS_ABANDONED; \
106 } \
107 \
108 /* Insert it into the Mutant List */ \
109 InsertHeadList(&Thread->MutantListHead, \
110 &(Object)->MutantListEntry); \
111 } \
112 } \
113 else if (((Object)->Header.Type & TIMER_OR_EVENT_TYPE) == \
114 EventSynchronizationObject) \
115 { \
116 /* Synchronization Timers and Events just get un-signaled */ \
117 (Object)->Header.SignalState = 0; \
118 } \
119 else if ((Object)->Header.Type == SemaphoreObject) \
120 { \
121 /* These ones can have multiple states, so we only decrease it */ \
122 (Object)->Header.SignalState--; \
123 } \
124 }
125
126 /* The following macro satisfies the wait of a mutant dispatcher object */
127 #define KiSatisfyMutantWait(Object, Thread) \
128 { \
129 /* Decrease the Signal State */ \
130 (Object)->Header.SignalState--; \
131 \
132 /* Check if it's now non-signaled */ \
133 if (!(Object)->Header.SignalState) \
134 { \
135 /* Set the Owner Thread */ \
136 (Object)->OwnerThread = Thread; \
137 \
138 /* Disable APCs if needed */ \
139 Thread->KernelApcDisable -= (Object)->ApcDisable; \
140 \
141 /* Check if it's abandoned */ \
142 if ((Object)->Abandoned) \
143 { \
144 /* Unabandon it */ \
145 (Object)->Abandoned = FALSE; \
146 \
147 /* Return Status */ \
148 Thread->WaitStatus = STATUS_ABANDONED; \
149 } \
150 \
151 /* Insert it into the Mutant List */ \
152 InsertHeadList(&Thread->MutantListHead, \
153 &(Object)->MutantListEntry); \
154 } \
155 }
156
157 /* The following macro satisfies the wait of any nonmutant dispatcher object */
158 #define KiSatisfyNonMutantWait(Object, Thread) \
159 { \
160 if (((Object)->Header.Type & TIMER_OR_EVENT_TYPE) == \
161 EventSynchronizationObject) \
162 { \
163 /* Synchronization Timers and Events just get un-signaled */ \
164 (Object)->Header.SignalState = 0; \
165 } \
166 else if ((Object)->Header.Type == SemaphoreObject) \
167 { \
168 /* These ones can have multiple states, so we only decrease it */ \
169 (Object)->Header.SignalState--; \
170 } \
171 }
172
173 /* The following macro satisfies multiple objects in a wait state */
174 #define KiSatisifyMultipleObjectWaits(FirstBlock) \
175 { \
176 PKWAIT_BLOCK WaitBlock = FirstBlock; \
177 PKTHREAD WaitThread = WaitBlock->Thread; \
178 \
179 /* Loop through all the Wait Blocks, and wake each Object */ \
180 do \
181 { \
182 /* Make sure it hasn't timed out */ \
183 if (WaitBlock->WaitKey != STATUS_TIMEOUT) \
184 { \
185 /* Wake the Object */ \
186 KiSatisfyObjectWait((PKMUTANT)WaitBlock->Object, WaitThread); \
187 } \
188 \
189 /* Move to the next block */ \
190 WaitBlock = WaitBlock->NextWaitBlock; \
191 } while (WaitBlock != FirstBlock); \
192 }
193
194 extern KSPIN_LOCK DispatcherDatabaseLock;
195
196 #define KeEnterCriticalRegion() \
197 { \
198 PKTHREAD _Thread = KeGetCurrentThread(); \
199 if (_Thread) _Thread->KernelApcDisable--; \
200 }
201
202 #define KeLeaveCriticalRegion() \
203 { \
204 PKTHREAD _Thread = KeGetCurrentThread(); \
205 if((_Thread) && (++_Thread->KernelApcDisable == 0)) \
206 { \
207 if (!IsListEmpty(&_Thread->ApcState.ApcListHead[KernelMode]) && \
208 (_Thread->SpecialApcDisable == 0)) \
209 { \
210 KiCheckForKernelApcDelivery(); \
211 } \
212 } \
213 }
214
215 #define KEBUGCHECKWITHTF(a,b,c,d,e,f) \
216 DbgPrint("KeBugCheckWithTf at %s:%i\n",__FILE__,__LINE__), \
217 KeBugCheckWithTf(a,b,c,d,e,f)
218
219 /* INTERNAL KERNEL FUNCTIONS ************************************************/
220
221 /* threadsch.c ********************************************************************/
222
223 /* Thread Scheduler Functions */
224
225 /* Readies a Thread for Execution. */
226 VOID
227 STDCALL
228 KiDispatchThreadNoLock(ULONG NewThreadStatus);
229
230 /* Readies a Thread for Execution. */
231 VOID
232 STDCALL
233 KiDispatchThread(ULONG NewThreadStatus);
234
235 /* Puts a Thread into a block state. */
236 VOID
237 STDCALL
238 KiBlockThread(
239 PNTSTATUS Status,
240 UCHAR Alertable,
241 ULONG WaitMode,
242 UCHAR WaitReason
243 );
244
245 /* Removes a thread out of a block state. */
246 VOID
247 STDCALL
248 KiUnblockThread(
249 PKTHREAD Thread,
250 PNTSTATUS WaitStatus,
251 KPRIORITY Increment
252 );
253
254 NTSTATUS
255 STDCALL
256 KeSuspendThread(PKTHREAD Thread);
257
258 NTSTATUS
259 FASTCALL
260 KiSwapContext(PKTHREAD NewThread);
261
262 VOID
263 STDCALL
264 KiAdjustQuantumThread(IN PKTHREAD Thread);
265
266 VOID
267 FASTCALL
268 KiExitDispatcher(KIRQL OldIrql);
269
270 /* gmutex.c ********************************************************************/
271
272 VOID
273 FASTCALL
274 KiAcquireGuardedMutexContented(PKGUARDED_MUTEX GuardedMutex);
275
276 /* gate.c **********************************************************************/
277
278 VOID
279 FASTCALL
280 KeInitializeGate(PKGATE Gate);
281
282 VOID
283 FASTCALL
284 KeSignalGateBoostPriority(PKGATE Gate);
285
286 VOID
287 FASTCALL
288 KeWaitForGate(
289 PKGATE Gate,
290 KWAIT_REASON WaitReason,
291 KPROCESSOR_MODE WaitMode
292 );
293
294 /* ipi.c ********************************************************************/
295
296 BOOLEAN
297 STDCALL
298 KiIpiServiceRoutine(
299 IN PKTRAP_FRAME TrapFrame,
300 IN struct _KEXCEPTION_FRAME* ExceptionFrame
301 );
302
303 VOID
304 NTAPI
305 KiIpiSendRequest(
306 KAFFINITY TargetSet,
307 ULONG IpiRequest
308 );
309
310 VOID
311 NTAPI
312 KeIpiGenericCall(
313 VOID (STDCALL *WorkerRoutine)(PVOID),
314 PVOID Argument
315 );
316
317 /* next file ***************************************************************/
318
319 VOID
320 STDCALL
321 DbgBreakPointNoBugCheck(VOID);
322
323 VOID
324 STDCALL
325 KeInitializeProfile(
326 struct _KPROFILE* Profile,
327 struct _KPROCESS* Process,
328 PVOID ImageBase,
329 ULONG ImageSize,
330 ULONG BucketSize,
331 KPROFILE_SOURCE ProfileSource,
332 KAFFINITY Affinity
333 );
334
335 VOID
336 STDCALL
337 KeStartProfile(
338 struct _KPROFILE* Profile,
339 PVOID Buffer
340 );
341
342 BOOLEAN
343 STDCALL
344 KeStopProfile(struct _KPROFILE* Profile);
345
346 ULONG
347 STDCALL
348 KeQueryIntervalProfile(KPROFILE_SOURCE ProfileSource);
349
350 VOID
351 STDCALL
352 KeSetIntervalProfile(
353 KPROFILE_SOURCE ProfileSource,
354 ULONG Interval
355 );
356
357 VOID
358 STDCALL
359 KeProfileInterrupt(
360 PKTRAP_FRAME TrapFrame
361 );
362
363 VOID
364 STDCALL
365 KeProfileInterruptWithSource(
366 IN PKTRAP_FRAME TrapFrame,
367 IN KPROFILE_SOURCE Source
368 );
369
370 BOOLEAN
371 STDCALL
372 KiRosPrintAddress(PVOID Address);
373
374 VOID
375 STDCALL
376 KeUpdateSystemTime(
377 PKTRAP_FRAME TrapFrame,
378 KIRQL Irql
379 );
380
381 VOID
382 STDCALL
383 KeUpdateRunTime(
384 PKTRAP_FRAME TrapFrame,
385 KIRQL Irql
386 );
387
388 VOID
389 STDCALL
390 KiExpireTimers(
391 PKDPC Dpc,
392 PVOID DeferredContext,
393 PVOID SystemArgument1,
394 PVOID SystemArgument2
395 );
396
397 VOID
398 STDCALL
399 KeInitializeThread(
400 struct _KPROCESS* Process,
401 PKTHREAD Thread,
402 PKSYSTEM_ROUTINE SystemRoutine,
403 PKSTART_ROUTINE StartRoutine,
404 PVOID StartContext,
405 PCONTEXT Context,
406 PVOID Teb,
407 PVOID KernelStack
408 );
409
410 VOID
411 STDCALL
412 KeRundownThread(VOID);
413
414 NTSTATUS
415 NTAPI
416 KeReleaseThread(PKTHREAD Thread);
417
418 LONG
419 STDCALL
420 KeQueryBasePriorityThread(IN PKTHREAD Thread);
421
422 VOID
423 STDCALL
424 KiSetPriorityThread(
425 PKTHREAD Thread,
426 KPRIORITY Priority,
427 PBOOLEAN Released
428 );
429
430 BOOLEAN
431 NTAPI
432 KiDispatcherObjectWake(
433 DISPATCHER_HEADER* hdr,
434 KPRIORITY increment
435 );
436
437 VOID
438 STDCALL
439 KeExpireTimers(
440 PKDPC Apc,
441 PVOID Arg1,
442 PVOID Arg2,
443 PVOID Arg3
444 );
445
446 VOID
447 NTAPI
448 KeDumpStackFrames(PULONG Frame);
449
450 BOOLEAN
451 NTAPI
452 KiTestAlert(VOID);
453
454 VOID
455 FASTCALL
456 KiAbortWaitThread(
457 PKTHREAD Thread,
458 NTSTATUS WaitStatus,
459 KPRIORITY Increment
460 );
461
462 VOID
463 STDCALL
464 KeInitializeProcess(
465 struct _KPROCESS *Process,
466 KPRIORITY Priority,
467 KAFFINITY Affinity,
468 LARGE_INTEGER DirectoryTableBase
469 );
470
471 ULONG
472 STDCALL
473 KeForceResumeThread(IN PKTHREAD Thread);
474
475 BOOLEAN
476 STDCALL
477 KeDisableThreadApcQueueing(IN PKTHREAD Thread);
478
479 BOOLEAN
480 STDCALL
481 KiInsertTimer(
482 PKTIMER Timer,
483 LARGE_INTEGER DueTime
484 );
485
486 BOOLEAN
487 __inline
488 FASTCALL
489 KiIsObjectSignaled(
490 PDISPATCHER_HEADER Object,
491 PKTHREAD Thread
492 );
493
494 VOID
495 FASTCALL
496 KiWaitTest(
497 PVOID Object,
498 KPRIORITY Increment
499 );
500
501 PULONG
502 NTAPI
503 KeGetStackTopThread(struct _ETHREAD* Thread);
504
505 BOOLEAN
506 STDCALL
507 KeContextToTrapFrame(
508 PCONTEXT Context,
509 PKEXCEPTION_FRAME ExeptionFrame,
510 PKTRAP_FRAME TrapFrame,
511 KPROCESSOR_MODE PreviousMode
512 );
513
514 VOID
515 STDCALL
516 KiDeliverApc(
517 KPROCESSOR_MODE PreviousMode,
518 PVOID Reserved,
519 PKTRAP_FRAME TrapFrame
520 );
521
522 VOID
523 STDCALL
524 KiCheckForKernelApcDelivery(VOID);
525
526 LONG
527 STDCALL
528 KiInsertQueue(
529 IN PKQUEUE Queue,
530 IN PLIST_ENTRY Entry,
531 BOOLEAN Head
532 );
533
534 ULONG
535 STDCALL
536 KeSetProcess(
537 struct _KPROCESS* Process,
538 KPRIORITY Increment
539 );
540
541 VOID
542 STDCALL
543 KeInitializeEventPair(PKEVENT_PAIR EventPair);
544
545 VOID
546 STDCALL
547 KiInitializeUserApc(
548 IN PKEXCEPTION_FRAME Reserved,
549 IN PKTRAP_FRAME TrapFrame,
550 IN PKNORMAL_ROUTINE NormalRoutine,
551 IN PVOID NormalContext,
552 IN PVOID SystemArgument1,
553 IN PVOID SystemArgument2
554 );
555
556 PLIST_ENTRY
557 STDCALL
558 KeFlushQueueApc(
559 IN PKTHREAD Thread,
560 IN KPROCESSOR_MODE PreviousMode
561 );
562
563 VOID
564 STDCALL
565 KiAttachProcess(
566 struct _KTHREAD *Thread,
567 struct _KPROCESS *Process,
568 KIRQL ApcLock,
569 struct _KAPC_STATE *SavedApcState
570 );
571
572 VOID
573 STDCALL
574 KiSwapProcess(
575 struct _KPROCESS *NewProcess,
576 struct _KPROCESS *OldProcess
577 );
578
579 BOOLEAN
580 STDCALL
581 KeTestAlertThread(IN KPROCESSOR_MODE AlertMode);
582
583 BOOLEAN
584 STDCALL
585 KeRemoveQueueApc(PKAPC Apc);
586
587 VOID
588 FASTCALL
589 KiWakeQueue(IN PKQUEUE Queue);
590
591 PLIST_ENTRY
592 STDCALL
593 KeRundownQueue(IN PKQUEUE Queue);
594
595 /* INITIALIZATION FUNCTIONS *************************************************/
596
597 VOID
598 NTAPI
599 KeInitExceptions(VOID);
600
601 VOID
602 NTAPI
603 KeInitInterrupts(VOID);
604
605 VOID
606 NTAPI
607 KeInitTimer(VOID);
608
609 VOID
610 NTAPI
611 KeInitDpc(struct _KPRCB* Prcb);
612
613 VOID
614 NTAPI
615 KeInitDispatcher(VOID);
616
617 VOID
618 NTAPI
619 KiInitializeSystemClock(VOID);
620
621 VOID
622 NTAPI
623 KiInitializeBugCheck(VOID);
624
625 VOID
626 NTAPI
627 Phase1Initialization(PVOID Context);
628
629 VOID
630 NTAPI
631 KeInit1(
632 PCHAR CommandLine,
633 PULONG LastKernelAddress
634 );
635
636 VOID
637 NTAPI
638 KeInit2(VOID);
639
640 BOOLEAN
641 NTAPI
642 KiDeliverUserApc(PKTRAP_FRAME TrapFrame);
643
644 VOID
645 STDCALL
646 KiMoveApcState(
647 PKAPC_STATE OldState,
648 PKAPC_STATE NewState
649 );
650
651 VOID
652 NTAPI
653 KiAddProfileEvent(
654 KPROFILE_SOURCE Source,
655 ULONG Pc
656 );
657
658 VOID
659 NTAPI
660 KiDispatchException(
661 PEXCEPTION_RECORD ExceptionRecord,
662 PKEXCEPTION_FRAME ExceptionFrame,
663 PKTRAP_FRAME Tf,
664 KPROCESSOR_MODE PreviousMode,
665 BOOLEAN SearchFrames
666 );
667
668 VOID
669 NTAPI
670 KeTrapFrameToContext(
671 IN PKTRAP_FRAME TrapFrame,
672 IN PKEXCEPTION_FRAME ExceptionFrame,
673 IN OUT PCONTEXT Context
674 );
675
676 VOID
677 NTAPI
678 KeApplicationProcessorInit(VOID);
679
680 VOID
681 NTAPI
682 KePrepareForApplicationProcessorInit(ULONG id);
683
684 ULONG
685 NTAPI
686 KiUserTrapHandler(
687 PKTRAP_FRAME Tf,
688 ULONG ExceptionNr,
689 PVOID Cr2
690 );
691
692 VOID
693 STDCALL
694 KePushAndStackSwitchAndSysRet(
695 ULONG Push,
696 PVOID NewStack
697 );
698
699 VOID
700 STDCALL
701 KeStackSwitchAndRet(PVOID NewStack);
702
703 VOID
704 STDCALL
705 KeBugCheckWithTf(
706 ULONG BugCheckCode,
707 ULONG BugCheckParameter1,
708 ULONG BugCheckParameter2,
709 ULONG BugCheckParameter3,
710 ULONG BugCheckParameter4,
711 PKTRAP_FRAME Tf
712 );
713
714 VOID
715 STDCALL
716 KiDumpTrapFrame(
717 PKTRAP_FRAME Tf,
718 ULONG ExceptionNr,
719 ULONG cr2
720 );
721
722 VOID
723 STDCALL
724 KeFlushCurrentTb(VOID);
725
726 VOID
727 STDCALL
728 KeRosDumpStackFrames(
729 PULONG Frame,
730 ULONG FrameCount
731 );
732
733 ULONG
734 STDCALL
735 KeRosGetStackFrames(
736 PULONG Frames,
737 ULONG FrameCount
738 );
739
740 VOID
741 NTAPI
742 KiSetSystemTime(PLARGE_INTEGER NewSystemTime);
743
744 NTSTATUS
745 STDCALL
746 Ke386CallBios(
747 UCHAR Int,
748 PKV86M_REGISTERS Regs
749 );
750
751 ULONG
752 NTAPI
753 KeV86Exception(
754 ULONG ExceptionNr,
755 PKTRAP_FRAME Tf,
756 ULONG address
757 );
758
759 #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */