ReactOS  r75907
procobj.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ke/procobj.c
5  * PURPOSE: Kernel Process Management and System Call Tables
6  * PROGRAMMERS: Alex Ionescu
7  * Gregor Anich
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* GLOBALS *******************************************************************/
17 
22 
25 
30 
31 /* PRIVATE FUNCTIONS *********************************************************/
32 
33 VOID
34 NTAPI
37  IN PKLOCK_QUEUE_HANDLE ApcLock,
38  IN PRKAPC_STATE SavedApcState)
39 {
40 #if 0
41  PLIST_ENTRY ListHead, NextEntry;
42  PKTHREAD CurrentThread;
43 #endif
44  ASSERT(Process != Thread->ApcState.Process);
45 
46  /* Increase Stack Count */
47  ASSERT(Process->StackCount != MAXULONG_PTR);
48  Process->StackCount++;
49 
50  /* Swap the APC Environment */
51  KiMoveApcState(&Thread->ApcState, SavedApcState);
52 
53  /* Reinitialize Apc State */
54  InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
55  InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
56  Thread->ApcState.Process = Process;
57  Thread->ApcState.KernelApcInProgress = FALSE;
58  Thread->ApcState.KernelApcPending = FALSE;
59  Thread->ApcState.UserApcPending = FALSE;
60 
61  /* Update Environment Pointers if needed*/
62  if (SavedApcState == &Thread->SavedApcState)
63  {
64  Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->
65  SavedApcState;
66  Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
67  Thread->ApcStateIndex = AttachedApcEnvironment;
68  }
69 
70  /* Check if the process is paged in */
71  if (Process->State == ProcessInMemory)
72  {
73  /* Scan the ready list */
74 #if 0
75  ListHead = &Process->ReadyListHead;
76  NextEntry = ListHead->Flink;
77  while (NextEntry != ListHead)
78  {
79  /* Get the thread */
80  CurrentThread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry);
81 
82  /* Remove it */
83  RemoveEntryList(NextEntry);
84  CurrentThread->ProcessReadyQueue = FALSE;
85 
86  /* Mark it ready */
87  KiReadyThread(CurrentThread);
88 
89  /* Go to the next one */
90  NextEntry = ListHead->Flink;
91  }
92 #endif
93 
94  /* Release dispatcher lock */
96 
97  /* Release lock */
99 
100  /* Swap Processes */
101  KiSwapProcess(Process, SavedApcState->Process);
102 
103  /* Exit the dispatcher */
104  KiExitDispatcher(ApcLock->OldIrql);
105  }
106  else
107  {
108  DPRINT1("Errr. ReactOS doesn't support paging out processes yet...\n");
109  ASSERT(FALSE);
110  }
111 }
112 
113 VOID
114 NTAPI
118  IN PULONG_PTR DirectoryTableBase,
119  IN BOOLEAN Enable)
120 {
121 #ifdef CONFIG_SMP
122  ULONG i = 0;
123  UCHAR IdealNode = 0;
124  PKNODE Node;
125 #endif
126 
127  /* Initialize the Dispatcher Header */
128  Process->Header.Type = ProcessObject;
129  Process->Header.Size = sizeof(KPROCESS) / sizeof(ULONG);
130  Process->Header.SignalState = 0;
131  InitializeListHead(&(Process->Header.WaitListHead));
132 
133  /* Initialize Scheduler Data, Alignment Faults and Set the PDE */
134  Process->Affinity = Affinity;
135  Process->BasePriority = (CHAR)Priority;
136  Process->QuantumReset = 6;
137  Process->DirectoryTableBase[0] = DirectoryTableBase[0];
138  Process->DirectoryTableBase[1] = DirectoryTableBase[1];
139  Process->AutoAlignment = Enable;
140 #if defined(_M_IX86)
141  Process->IopmOffset = KiComputeIopmOffset(IO_ACCESS_MAP_NONE);
142 #endif
143 
144  /* Initialize the lists */
145  InitializeListHead(&Process->ThreadListHead);
146  InitializeListHead(&Process->ProfileListHead);
147  InitializeListHead(&Process->ReadyListHead);
148 
149  /* Initialize the current State */
150  Process->State = ProcessInMemory;
151 
152  /* Check how many Nodes there are on the system */
153 #ifdef CONFIG_SMP
154  if (KeNumberNodes > 1)
155  {
156  /* Set the new seed */
158  IdealNode = KeProcessNodeSeed;
159 
160  /* Loop every node */
161  do
162  {
163  /* Check if the affinity matches */
164  if (KeNodeBlock[IdealNode]->ProcessorMask != Affinity) break;
165 
166  /* No match, try next Ideal Node and increase node loop index */
167  IdealNode++;
168  i++;
169 
170  /* Check if the Ideal Node is beyond the total number of nodes */
171  if (IdealNode >= KeNumberNodes)
172  {
173  /* Normalize the Ideal Node */
174  IdealNode -= KeNumberNodes;
175  }
176  } while (i < KeNumberNodes);
177  }
178 
179  /* Set the ideal node and get the ideal node block */
180  Process->IdealNode = IdealNode;
181  Node = KeNodeBlock[IdealNode];
182  ASSERT(Node->ProcessorMask & Affinity);
183 
184  /* Find the matching affinity set to calculate the thread seed */
185  Affinity &= Node->ProcessorMask;
186  Process->ThreadSeed = KeFindNextRightSetAffinity(Node->Seed,
187  (ULONG)Affinity);
188  Node->Seed = Process->ThreadSeed;
189 #endif
190 }
191 
192 ULONG
193 NTAPI
196  IN BOOLEAN InWait)
197 {
198  KIRQL OldIrql;
199  ULONG OldState;
200  ASSERT_PROCESS(Process);
202 
203  /* Lock Dispatcher */
204  OldIrql = KiAcquireDispatcherLock();
205 
206  /* Get Old State */
207  OldState = Process->Header.SignalState;
208 
209  /* Signal the Process */
210  Process->Header.SignalState = TRUE;
211 
212  /* Check if was unsignaled and has waiters */
213  if (!(OldState) &&
214  !(IsListEmpty(&Process->Header.WaitListHead)))
215  {
216  /* Unwait the threads */
217  KxUnwaitThread(&Process->Header, Increment);
218  }
219 
220  /* Release Dispatcher Database */
221  KiReleaseDispatcherLock(OldIrql);
222 
223  /* Return the previous State */
224  return OldState;
225 }
226 
227 VOID
228 NTAPI
230  IN UCHAR Quantum)
231 {
232  KLOCK_QUEUE_HANDLE ProcessLock;
233  PLIST_ENTRY NextEntry, ListHead;
235  ASSERT_PROCESS(Process);
237 
238  /* Lock the process */
239  KiAcquireProcessLock(Process, &ProcessLock);
240 
241  /* Set new quantum */
242  Process->QuantumReset = Quantum;
243 
244  /* Loop all child threads */
245  ListHead = &Process->ThreadListHead;
246  NextEntry = ListHead->Flink;
247  while (ListHead != NextEntry)
248  {
249  /* Get the thread */
250  Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
251 
252  /* Set quantum */
253  Thread->QuantumReset = Quantum;
254 
255  /* Go to the next one */
256  NextEntry = NextEntry->Flink;
257  }
258 
259  /* Release lock */
260  KiReleaseProcessLock(&ProcessLock);
261 }
262 
263 KAFFINITY
264 NTAPI
267 {
268 
269  KLOCK_QUEUE_HANDLE ProcessLock;
270  PLIST_ENTRY NextEntry, ListHead;
271  KAFFINITY OldAffinity;
273  ASSERT_PROCESS(Process);
275  ASSERT((Affinity & KeActiveProcessors) != 0);
276 
277  /* Lock the process */
278  KiAcquireProcessLock(Process, &ProcessLock);
279 
280  /* Acquire the dispatcher lock */
282 
283  /* Capture old affinity and update it */
284  OldAffinity = Process->Affinity;
285  Process->Affinity = Affinity;
286 
287  /* Loop all child threads */
288  ListHead = &Process->ThreadListHead;
289  NextEntry = ListHead->Flink;
290  while (ListHead != NextEntry)
291  {
292  /* Get the thread */
293  Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
294 
295  /* Set affinity on it */
296  KiSetAffinityThread(Thread, Affinity);
297  NextEntry = NextEntry->Flink;
298  }
299 
300  /* Release Dispatcher Database */
302 
303  /* Release the process lock */
304  KiReleaseProcessLockFromDpcLevel(&ProcessLock);
305  KiExitDispatcher(ProcessLock.OldIrql);
306 
307  /* Return previous affinity */
308  return OldAffinity;
309 }
310 
311 BOOLEAN
312 NTAPI
314  IN BOOLEAN Enable)
315 {
316  /* Set or reset the bit depending on what the enable flag says */
317  if (Enable)
318  {
319  return InterlockedBitTestAndSet(&Process->ProcessFlags,
321  }
322  else
323  {
324  return InterlockedBitTestAndReset(&Process->ProcessFlags,
326  }
327 }
328 
329 BOOLEAN
330 NTAPI
332  IN BOOLEAN Disable)
333 {
334  /* Set or reset the bit depending on what the disable flag says */
335  if (Disable)
336  {
337  return InterlockedBitTestAndSet(&Process->ProcessFlags,
339  }
340  else
341  {
342  return InterlockedBitTestAndReset(&Process->ProcessFlags,
344  }
345 }
346 
347 KPRIORITY
348 NTAPI
351  IN UCHAR Quantum OPTIONAL)
352 {
353  KLOCK_QUEUE_HANDLE ProcessLock;
355  PLIST_ENTRY NextEntry, ListHead;
356  KPRIORITY NewPriority, OldPriority;
358  ASSERT_PROCESS(Process);
360 
361  /* Check if the process already has this priority */
362  if (Process->BasePriority == Priority) return Process->BasePriority;
363 
364  /* If the caller gave priority 0, normalize to 1 */
365  if (!Priority) Priority = LOW_PRIORITY + 1;
366 
367  /* Lock the process */
368  KiAcquireProcessLock(Process, &ProcessLock);
369 
370  /* Check if we are modifying the quantum too */
371  if (Quantum) Process->QuantumReset = Quantum;
372 
373  /* Save the current base priority and update it */
374  OldPriority = Process->BasePriority;
375  Process->BasePriority = (SCHAR)Priority;
376 
377  /* Calculate the priority delta */
378  Delta = Priority - OldPriority;
379 
380  /* Set the list head and list entry */
381  ListHead = &Process->ThreadListHead;
382  NextEntry = ListHead->Flink;
383 
384  /* Check if this is a real-time priority */
385  if (Priority >= LOW_REALTIME_PRIORITY)
386  {
387  /* Loop the thread list */
388  while (NextEntry != ListHead)
389  {
390  /* Get the thread */
391  Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
392 
393  /* Update the quantum if we had one */
394  if (Quantum) Thread->QuantumReset = Quantum;
395 
396  /* Acquire the thread lock */
397  KiAcquireThreadLock(Thread);
398 
399  /* Calculate the new priority */
400  NewPriority = Thread->BasePriority + Delta;
401  if (NewPriority < LOW_REALTIME_PRIORITY)
402  {
403  /* We're in real-time range, don't let it go below */
404  NewPriority = LOW_REALTIME_PRIORITY;
405  }
406  else if (NewPriority > HIGH_PRIORITY)
407  {
408  /* We're going beyond the maximum priority, normalize */
409  NewPriority = HIGH_PRIORITY;
410  }
411 
412  /*
413  * If priority saturation occured or the old priority was still in
414  * the real-time range, don't do anything.
415  */
416  if (!(Thread->Saturation) || (OldPriority < LOW_REALTIME_PRIORITY))
417  {
418  /* Check if we had priority saturation */
419  if (Thread->Saturation > 0)
420  {
421  /* Boost priority to maximum */
422  NewPriority = HIGH_PRIORITY;
423  }
424  else if (Thread->Saturation < 0)
425  {
426  /* If we had negative saturation, set minimum priority */
427  NewPriority = LOW_REALTIME_PRIORITY;
428  }
429 
430  /* Update priority and quantum */
431  Thread->BasePriority = (SCHAR)NewPriority;
432  Thread->Quantum = Thread->QuantumReset;
433 
434  /* Disable decrements and update priority */
435  Thread->PriorityDecrement = 0;
436  KiSetPriorityThread(Thread, NewPriority);
437  }
438 
439  /* Release the thread lock */
440  KiReleaseThreadLock(Thread);
441 
442  /* Go to the next thread */
443  NextEntry = NextEntry->Flink;
444  }
445  }
446  else
447  {
448  /* Loop the thread list */
449  while (NextEntry != ListHead)
450  {
451  /* Get the thread */
452  Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
453 
454  /* Update the quantum if we had one */
455  if (Quantum) Thread->QuantumReset = Quantum;
456 
457  /* Lock the thread */
458  KiAcquireThreadLock(Thread);
459 
460  /* Calculate the new priority */
461  NewPriority = Thread->BasePriority + Delta;
462  if (NewPriority >= LOW_REALTIME_PRIORITY)
463  {
464  /* We're not real-time range, don't let it enter RT range */
465  NewPriority = LOW_REALTIME_PRIORITY - 1;
466  }
467  else if (NewPriority <= LOW_PRIORITY)
468  {
469  /* We're going below the minimum priority, normalize */
470  NewPriority = 1;
471  }
472 
473  /*
474  * If priority saturation occured or the old priority was still in
475  * the real-time range, don't do anything.
476  */
477  if (!(Thread->Saturation) ||
478  (OldPriority >= LOW_REALTIME_PRIORITY))
479  {
480  /* Check if we had priority saturation */
481  if (Thread->Saturation > 0)
482  {
483  /* Boost priority to maximum */
484  NewPriority = LOW_REALTIME_PRIORITY - 1;
485  }
486  else if (Thread->Saturation < 0)
487  {
488  /* If we had negative saturation, set minimum priority */
489  NewPriority = 1;
490  }
491 
492  /* Update priority and quantum */
493  Thread->BasePriority = (SCHAR)NewPriority;
494  Thread->Quantum = Thread->QuantumReset;
495 
496  /* Disable decrements and update priority */
497  Thread->PriorityDecrement = 0;
498  KiSetPriorityThread(Thread, NewPriority);
499  }
500 
501  /* Release the thread lock */
502  KiReleaseThreadLock(Thread);
503 
504  /* Go to the next thread */
505  NextEntry = NextEntry->Flink;
506  }
507  }
508 
509  /* Release Dispatcher Database */
511 
512  /* Release the process lock */
513  KiReleaseProcessLockFromDpcLevel(&ProcessLock);
514  KiExitDispatcher(ProcessLock.OldIrql);
515 
516  /* Return previous priority */
517  return OldPriority;
518 }
519 
520 /* PUBLIC FUNCTIONS **********************************************************/
521 
522 /*
523  * @implemented
524  */
525 VOID
526 NTAPI
528 {
529  KLOCK_QUEUE_HANDLE ApcLock;
531  ASSERT_PROCESS(Process);
533 
534  /* Check if we're already in that process */
535  if (Thread->ApcState.Process == Process) return;
536 
537  /* Check if a DPC is executing or if we're already attached */
538  if ((Thread->ApcStateIndex != OriginalApcEnvironment) ||
539  (KeIsExecutingDpc()))
540  {
541  /* Invalid attempt */
542  KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
543  (ULONG_PTR)Process,
544  (ULONG_PTR)Thread->ApcState.Process,
545  Thread->ApcStateIndex,
546  KeIsExecutingDpc());
547  }
548  else
549  {
550  /* Acquire APC Lock */
551  KiAcquireApcLock(Thread, &ApcLock);
552 
553  /* Acquire the dispatcher lock */
555 
556  /* Legit attach attempt: do it! */
557  KiAttachProcess(Thread, Process, &ApcLock, &Thread->SavedApcState);
558  }
559 }
560 
561 /*
562  * @implemented
563  */
564 VOID
565 NTAPI
567 {
569  KLOCK_QUEUE_HANDLE ApcLock;
572 
573  /* Check if it's attached */
574  if (Thread->ApcStateIndex == OriginalApcEnvironment) return;
575 
576  /* Acquire APC Lock */
577  KiAcquireApcLock(Thread, &ApcLock);
578 
579  /* Check for invalid attach attempts */
580  if ((Thread->ApcState.KernelApcInProgress) ||
581  !(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) ||
582  !(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
583  {
584  /* Crash the system */
585  KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT);
586  }
587 
588  /* Get the process */
589  Process = Thread->ApcState.Process;
590 
591  /* Acquire dispatcher lock */
593 
594  /* Decrease the stack count */
595  ASSERT(Process->StackCount != 0);
596  ASSERT(Process->State == ProcessInMemory);
597  Process->StackCount--;
598 
599  /* Check if we can swap the process out */
600  if (!Process->StackCount)
601  {
602  /* FIXME: Swap the process out */
603  }
604 
605  /* Release dispatcher lock */
607 
608  /* Restore the APC State */
609  KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
610  Thread->SavedApcState.Process = NULL;
611  Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
614 
615  /* Release lock */
617 
618  /* Swap Processes */
619  KiSwapProcess(Thread->ApcState.Process, Process);
620 
621  /* Exit the dispatcher */
622  KiExitDispatcher(ApcLock.OldIrql);
623 
624  /* Check if we have pending APCs */
625  if (!(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])))
626  {
627  /* What do you know, we do! Request them to be delivered */
628  Thread->ApcState.KernelApcPending = TRUE;
630  }
631 }
632 
633 /*
634  * @implemented
635  */
636 BOOLEAN
637 NTAPI
639 {
640  /* Return the APC State */
641  return KeGetCurrentThread()->ApcStateIndex;
642 }
643 
644 /*
645  * @implemented
646  */
647 VOID
648 NTAPI
651 {
652  KLOCK_QUEUE_HANDLE ApcLock;
654  ASSERT_PROCESS(Process);
656 
657  /* Crash system if DPC is being executed! */
658  if (KeIsExecutingDpc())
659  {
660  /* Executing a DPC, crash! */
661  KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
662  (ULONG_PTR)Process,
663  (ULONG_PTR)Thread->ApcState.Process,
664  Thread->ApcStateIndex,
665  KeIsExecutingDpc());
666  }
667 
668  /* Check if we are already in the target process */
669  if (Thread->ApcState.Process == Process)
670  {
671  /* Set magic value so we don't crash later when detaching */
672  ApcState->Process = (PKPROCESS)1;
673  return;
674  }
675 
676  /* Acquire APC Lock */
677  KiAcquireApcLock(Thread, &ApcLock);
678 
679  /* Acquire dispatcher lock */
681 
682  /* Check if the Current Thread is already attached */
683  if (Thread->ApcStateIndex != OriginalApcEnvironment)
684  {
685  /* We're already attached, so save the APC State into what we got */
686  KiAttachProcess(Thread, Process, &ApcLock, ApcState);
687  }
688  else
689  {
690  /* We're not attached, so save the APC State into SavedApcState */
691  KiAttachProcess(Thread, Process, &ApcLock, &Thread->SavedApcState);
692  ApcState->Process = NULL;
693  }
694 }
695 
696 /*
697  * @implemented
698  */
699 VOID
700 NTAPI
702 {
703  KLOCK_QUEUE_HANDLE ApcLock;
707 
708  /* Check for magic value meaning we were already in the same process */
709  if (ApcState->Process == (PKPROCESS)1) return;
710 
711  /* Loop to make sure no APCs are pending */
712  for (;;)
713  {
714  /* Acquire APC Lock */
715  KiAcquireApcLock(Thread, &ApcLock);
716 
717  /* Check if a kernel APC is pending */
718  if (Thread->ApcState.KernelApcPending)
719  {
720  /* Check if kernel APC should be delivered */
721  if (!(Thread->KernelApcDisable) && (ApcLock.OldIrql <= APC_LEVEL))
722  {
723  /* Release the APC lock so that the APC can be delivered */
724  KiReleaseApcLock(&ApcLock);
725  continue;
726  }
727  }
728 
729  /* Otherwise, break out */
730  break;
731  }
732 
733  /*
734  * Check if the process isn't attacked, or has a Kernel APC in progress
735  * or has pending APC of any kind.
736  */
737  if ((Thread->ApcStateIndex == OriginalApcEnvironment) ||
738  (Thread->ApcState.KernelApcInProgress) ||
739  (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) ||
740  (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
741  {
742  /* Bugcheck the system */
743  KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT);
744  }
745 
746  /* Get the process */
747  Process = Thread->ApcState.Process;
748 
749  /* Acquire dispatcher lock */
751 
752  /* Decrease the stack count */
753  ASSERT(Process->StackCount != 0);
754  ASSERT(Process->State == ProcessInMemory);
755  Process->StackCount--;
756 
757  /* Check if we can swap the process out */
758  if (!Process->StackCount)
759  {
760  /* FIXME: Swap the process out */
761  }
762 
763  /* Release dispatcher lock */
765 
766  /* Check if there's an APC state to restore */
767  if (ApcState->Process)
768  {
769  /* Restore the APC State */
770  KiMoveApcState(ApcState, &Thread->ApcState);
771  }
772  else
773  {
774  /* The ApcState parameter is useless, so use the saved data and reset it */
775  KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
776  Thread->SavedApcState.Process = NULL;
778  Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
780  }
781 
782  /* Release lock */
784 
785  /* Swap Processes */
786  KiSwapProcess(Thread->ApcState.Process, Process);
787 
788  /* Exit the dispatcher */
789  KiExitDispatcher(ApcLock.OldIrql);
790 
791  /* Check if we have pending APCs */
792  if (!(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])))
793  {
794  /* What do you know, we do! Request them to be delivered */
795  Thread->ApcState.KernelApcPending = TRUE;
797  }
798 }
799 
800 /*
801  * @implemented
802  */
803 ULONG
804 NTAPI
807 {
808  ULONG TotalUser, TotalKernel;
809  KLOCK_QUEUE_HANDLE ProcessLock;
810  PLIST_ENTRY NextEntry, ListHead;
812 
813  ASSERT_PROCESS(Process);
814 
815  /* Initialize user and kernel times */
816  TotalUser = Process->UserTime;
817  TotalKernel = Process->KernelTime;
818 
819  /* Lock the process */
820  KiAcquireProcessLock(Process, &ProcessLock);
821 
822  /* Loop all child threads and sum up their times */
823  ListHead = &Process->ThreadListHead;
824  NextEntry = ListHead->Flink;
825  while (ListHead != NextEntry)
826  {
827  /* Get the thread */
828  Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
829 
830  /* Sum up times */
831  TotalKernel += Thread->KernelTime;
832  TotalUser += Thread->UserTime;
833 
834  /* Go to the next one */
835  NextEntry = NextEntry->Flink;
836  }
837 
838  /* Release lock */
839  KiReleaseProcessLock(&ProcessLock);
840 
841  /* Return the user time */
842  *UserTime = TotalUser;
843 
844  /* Return the kernel time */
845  return TotalKernel;
846 }
847 
848 /*
849  * @implemented
850  */
851 BOOLEAN
852 NTAPI
855  IN ULONG Limit,
856  IN PUCHAR Number,
857  IN ULONG Index)
858 {
859  PAGED_CODE();
860 
861  /* Check if descriptor table entry is free */
862  if ((Index > SSDT_MAX_ENTRIES - 1) ||
863  (KeServiceDescriptorTable[Index].Base) ||
864  (KeServiceDescriptorTableShadow[Index].Base))
865  {
866  /* It's not, fail */
867  return FALSE;
868  }
869 
870  /* Initialize the shadow service descriptor table */
871  KeServiceDescriptorTableShadow[Index].Base = Base;
872  KeServiceDescriptorTableShadow[Index].Limit = Limit;
873  KeServiceDescriptorTableShadow[Index].Number = Number;
874  KeServiceDescriptorTableShadow[Index].Count = Count;
875  return TRUE;
876 }
877 
878 /*
879  * @implemented
880  */
881 BOOLEAN
882 NTAPI
884 {
885  PAGED_CODE();
886 
887  /* Make sure the Index is valid */
888  if (Index > (SSDT_MAX_ENTRIES - 1)) return FALSE;
889 
890  /* Is there a Normal Descriptor Table? */
891  if (!KeServiceDescriptorTable[Index].Base)
892  {
893  /* Not with the index, is there a shadow at least? */
894  if (!KeServiceDescriptorTableShadow[Index].Base) return FALSE;
895  }
896 
897  /* Now clear from the Shadow Table. */
898  KeServiceDescriptorTableShadow[Index].Base = NULL;
899  KeServiceDescriptorTableShadow[Index].Number = NULL;
900  KeServiceDescriptorTableShadow[Index].Limit = 0;
901  KeServiceDescriptorTableShadow[Index].Count = NULL;
902 
903  /* Check if we should clean from the Master one too */
904  if (Index == 1)
905  {
906  KeServiceDescriptorTable[Index].Base = NULL;
907  KeServiceDescriptorTable[Index].Number = NULL;
908  KeServiceDescriptorTable[Index].Limit = 0;
909  KeServiceDescriptorTable[Index].Count = NULL;
910  }
911 
912  /* Return success */
913  return TRUE;
914 }
915 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE VOID KiReleaseThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:244
BOOLEAN NTAPI KeSetAutoAlignmentProcess(IN PKPROCESS Process, IN BOOLEAN Enable)
Definition: procobj.c:313
KAFFINITY FASTCALL KiSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdschd.c:685
PVOID KeUserCallbackDispatcher
Definition: procobj.c:27
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:250
#define IN
Definition: typedefs.h:39
#define TRUE
Definition: types.h:120
VOID NTAPI KiAttachProcess(IN PKTHREAD Thread, IN PKPROCESS Process, IN PKLOCK_QUEUE_HANDLE ApcLock, IN PRKAPC_STATE SavedApcState)
Definition: procobj.c:35
SCHAR PriorityDecrement
Definition: ketypes.h:1210
UCHAR State
Definition: ketypes.h:1419
BOOLEAN Enable
Definition: acefiex.h:245
FORCEINLINE VOID KiReleaseProcessLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:660
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
KAPC_STATE SavedApcState
Definition: ketypes.h:1244
BOOLEAN NTAPI KeAddSystemServiceTable(IN PULONG_PTR Base, IN PULONG Count OPTIONAL, IN ULONG Limit, IN PUCHAR Number, IN ULONG Index)
Definition: procobj.c:853
unsigned char * PUCHAR
Definition: retypes.h:3
KEVENT KiSwapEvent
Definition: procobj.c:21
ULONG NTAPI KeSetProcess(IN PKPROCESS Process, IN KPRIORITY Increment, IN BOOLEAN InWait)
Definition: procobj.c:194
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
FORCEINLINE VOID KiAcquireApcLock(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:600
CHAR Saturation
Definition: ketypes.h:1221
#define MAXULONG_PTR
Definition: basetsd.h:102
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
_Must_inspect_result_ _In_ ULONG Index
Definition: fltkernel.h:1824
#define SSDT_MAX_ENTRIES
Definition: ketypes.h:100
ULONG ProcessReadyQueue
Definition: ketypes.h:951
#define LOW_REALTIME_PRIORITY
FORCEINLINE VOID KiReleaseApcLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:627
BOOLEAN NTAPI KeIsExecutingDpc(VOID)
Definition: dpc.c:946
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LONG KPRIORITY
Definition: compat.h:454
uint32_t ULONG_PTR
Definition: typedefs.h:64
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLenum GLclampf GLint i
Definition: glfuncs.h:14
UCHAR NTAPI KeFindNextRightSetAffinity(IN UCHAR Number, IN ULONG Set)
Definition: thrdobj.c:32
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
SHORT KernelApcDisable
Definition: ketypes.h:1051
#define FALSE
Definition: types.h:117
BOOLEAN NTAPI KeRemoveSystemServiceTable(IN ULONG Index)
Definition: procobj.c:883
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:649
LIST_ENTRY KiStackInSwapListHead
Definition: procobj.c:20
KAFFINITY NTAPI KeSetAffinityProcess(IN PKPROCESS Process, IN KAFFINITY Affinity)
Definition: procobj.c:265
KAPC_STATE ApcState
Definition: ketypes.h:969
UCHAR KeProcessNodeSeed
Definition: krnlinit.c:41
VOID FASTCALL KiSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdschd.c:511
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:638
ULONG NTAPI KeQueryRuntimeProcess(IN PKPROCESS Process, OUT PULONG UserTime)
Definition: procobj.c:805
#define InterlockedBitTestAndReset
Definition: interlocked.h:35
ULONG StackCount
Definition: ketypes.h:1429
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES]
Definition: procobj.c:24
#define LOW_PRIORITY
smooth NULL
Definition: ftsmooth.c:513
VOID NTAPI KeInitializeProcess(IN OUT PKPROCESS Process, IN KPRIORITY Priority, IN KAFFINITY Affinity, IN PULONG_PTR DirectoryTableBase, IN BOOLEAN Enable)
Definition: procobj.c:115
FORCEINLINE VOID KiReleaseApcLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:635
LIST_ENTRY KiProcessInSwapListHead
Definition: procobj.c:19
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
VOID FASTCALL KiExitDispatcher(KIRQL OldIrql)
VOID NTAPI KiReadyThread(IN PKTHREAD Thread)
Definition: thrdschd.c:429
_Out_ PULONG UserTime
Definition: kefuncs.h:784
#define InterlockedBitTestAndSet
Definition: interlocked.h:30
FORCEINLINE VOID KiAcquireThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:234
SCHAR BasePriority
Definition: ketypes.h:1209
#define IO_ACCESS_MAP_NONE
Definition: ketypes.h:263
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
unsigned char BOOLEAN
struct _KPROCESS KPROCESS
ULONG KernelTime
Definition: ketypes.h:1305
PVOID KeUserExceptionDispatcher
Definition: procobj.c:28
KPRIORITY NTAPI KeSetPriorityAndQuantumProcess(IN PKPROCESS Process, IN KPRIORITY Priority, IN UCHAR Quantum OPTIONAL)
Definition: procobj.c:349
VOID NTAPI KeSetQuantumProcess(IN PKPROCESS Process, IN UCHAR Quantum)
Definition: procobj.c:229
PKNODE KeNodeBlock[1]
Definition: krnlinit.c:39
signed char SCHAR
Definition: sqltypes.h:14
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define PAGED_CODE()
Definition: video.h:57
FORCEINLINE VOID KiReleaseProcessLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:652
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:566
unsigned char UCHAR
Definition: xmlstorage.h:181
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
FORCEINLINE VOID KiAcquireProcessLock(IN PKPROCESS Process, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:643
Definition: typedefs.h:118
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
UCHAR KeNumberNodes
Definition: krnlinit.c:40
VOID NTAPI KiSwapProcess(struct _KPROCESS *NewProcess, struct _KPROCESS *OldProcess)
Definition: stubs.c:139
#define KPSF_AUTO_ALIGNMENT_BIT
Definition: pstypes.h:252
UCHAR QuantumReset
Definition: ketypes.h:1300
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:152
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
struct _KPROCESS * PKPROCESS
Definition: wdm.template.h:199
ULONG_PTR KAFFINITY
Definition: compat.h:75
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:527
#define KiComputeIopmOffset(MapNumber)
Definition: ketypes.h:265
VOID NTAPI KiMoveApcState(PKAPC_STATE OldState, PKAPC_STATE NewState)
Definition: apc.c:538
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:701
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
*RESTRICTED_POINTER PRKAPC_STATE
Definition: ketypes.h:1258
static ULONG Delta
Definition: xboxvideo.c:28
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1411
unsigned int * PULONG
Definition: retypes.h:1
#define KPSF_DISABLE_BOOST_BIT
Definition: pstypes.h:253
LIST_ENTRY KiProcessOutSwapListHead
Definition: procobj.c:19
#define DPRINT1
Definition: precomp.h:8
ULONG UserTime
Definition: ketypes.h:1335
FORCEINLINE VOID KiReleaseDispatcherLockFromDpcLevel(VOID)
Definition: ke_x.h:168
BOOLEAN NTAPI KeSetDisableBoostProcess(IN PKPROCESS Process, IN BOOLEAN Disable)
Definition: procobj.c:331
PVOID KeRaiseUserExceptionDispatcher
Definition: procobj.c:29
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define OUT
Definition: typedefs.h:40
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES]
Definition: procobj.c:23
LIST_ENTRY KiProcessListHead
Definition: procobj.c:18
unsigned int ULONG
Definition: retypes.h:1
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t * PULONG_PTR
Definition: typedefs.h:64
#define HIGH_PRIORITY
UCHAR ApcStateIndex
Definition: ketypes.h:1198
KAFFINITY ProcessorMask
Definition: ketypes.h:776
PVOID KeUserApcDispatcher
Definition: procobj.c:26
UCHAR Seed
Definition: ketypes.h:778
FORCEINLINE VOID KxUnwaitThread(IN DISPATCHER_HEADER *Object, IN KPRIORITY Increment)
Definition: ke_x.h:1250
#define KeGetCurrentThread
Definition: hal.h:44
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:42
PKAPC_STATE ApcStatePointer[2]
Definition: ketypes.h:1241
#define CHAR(Char)
#define ASSERT_PROCESS(object)
Definition: ketypes.h:1436
#define APC_LEVEL
Definition: env_spec_w32.h:695
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:328
IN HDEVINFO IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
Definition: devinst.c:44
union gl_dlist_node Node
Definition: dlist.c:302
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:90
FORCEINLINE VOID KiAcquireDispatcherLockAtDpcLevel(VOID)
Definition: ke_x.h:160