ReactOS  0.4.13-dev-235-g7373cb3
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)
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;
202 
203  /* Lock Dispatcher */
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 */
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;
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;
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 */
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;
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 */
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 */
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 */
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 */
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 */
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 VOID
521 NTAPI
523  PPROCESS_VALUES Values)
524 {
525  PEPROCESS EProcess;
526  PLIST_ENTRY NextEntry;
527  ULONG TotalKernel, TotalUser;
528  KLOCK_QUEUE_HANDLE ProcessLock;
529 
532 
533  /* Lock the process */
534  KiAcquireProcessLock(Process, &ProcessLock);
535 
536  /* Initialize user and kernel times */
537  TotalKernel = Process->KernelTime;
538  TotalUser = Process->UserTime;
539 
540  /* Copy the IO_COUNTERS from the process */
541  EProcess = (PEPROCESS)Process;
548 
549  /* Loop all child threads and sum up their times */
550  for (NextEntry = Process->ThreadListHead.Flink;
551  NextEntry != &Process->ThreadListHead;
552  NextEntry = NextEntry->Flink)
553  {
555 
556  /* Get the thread */
557  Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
558 
559  /* Sum up times */
560  TotalKernel += Thread->KernelTime;
561  TotalUser += Thread->UserTime;
562  }
563 
564  /* Release the process lock */
565  KiReleaseProcessLock(&ProcessLock);
566 
567  /* Compute total times */
568  Values->TotalKernelTime.QuadPart = TotalKernel * (LONGLONG)KeMaximumIncrement;
569  Values->TotalUserTime.QuadPart = TotalUser * (LONGLONG)KeMaximumIncrement;
570 }
571 
572 /* PUBLIC FUNCTIONS **********************************************************/
573 
574 /*
575  * @implemented
576  */
577 VOID
578 NTAPI
580 {
581  KLOCK_QUEUE_HANDLE ApcLock;
585 
586  /* Check if we're already in that process */
587  if (Thread->ApcState.Process == Process) return;
588 
589  /* Check if a DPC is executing or if we're already attached */
590  if ((Thread->ApcStateIndex != OriginalApcEnvironment) ||
591  (KeIsExecutingDpc()))
592  {
593  /* Invalid attempt */
594  KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
596  (ULONG_PTR)Thread->ApcState.Process,
597  Thread->ApcStateIndex,
598  KeIsExecutingDpc());
599  }
600  else
601  {
602  /* Acquire APC Lock */
603  KiAcquireApcLock(Thread, &ApcLock);
604 
605  /* Acquire the dispatcher lock */
607 
608  /* Legit attach attempt: do it! */
609  KiAttachProcess(Thread, Process, &ApcLock, &Thread->SavedApcState);
610  }
611 }
612 
613 /*
614  * @implemented
615  */
616 VOID
617 NTAPI
619 {
621  KLOCK_QUEUE_HANDLE ApcLock;
624 
625  /* Check if it's attached */
626  if (Thread->ApcStateIndex == OriginalApcEnvironment) return;
627 
628  /* Acquire APC Lock */
629  KiAcquireApcLock(Thread, &ApcLock);
630 
631  /* Check for invalid attach attempts */
632  if ((Thread->ApcState.KernelApcInProgress) ||
633  !(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) ||
634  !(IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
635  {
636  /* Crash the system */
637  KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT);
638  }
639 
640  /* Get the process */
641  Process = Thread->ApcState.Process;
642 
643  /* Acquire dispatcher lock */
645 
646  /* Decrease the stack count */
647  ASSERT(Process->StackCount != 0);
648  ASSERT(Process->State == ProcessInMemory);
649  Process->StackCount--;
650 
651  /* Check if we can swap the process out */
652  if (!Process->StackCount)
653  {
654  /* FIXME: Swap the process out */
655  }
656 
657  /* Release dispatcher lock */
659 
660  /* Restore the APC State */
661  KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
662  Thread->SavedApcState.Process = NULL;
663  Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
664  Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
665  Thread->ApcStateIndex = OriginalApcEnvironment;
666 
667  /* Release lock */
669 
670  /* Swap Processes */
671  KiSwapProcess(Thread->ApcState.Process, Process);
672 
673  /* Exit the dispatcher */
674  KiExitDispatcher(ApcLock.OldIrql);
675 
676  /* Check if we have pending APCs */
677  if (!(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])))
678  {
679  /* What do you know, we do! Request them to be delivered */
680  Thread->ApcState.KernelApcPending = TRUE;
682  }
683 }
684 
685 /*
686  * @implemented
687  */
688 BOOLEAN
689 NTAPI
691 {
692  /* Return the APC State */
693  return KeGetCurrentThread()->ApcStateIndex;
694 }
695 
696 /*
697  * @implemented
698  */
699 VOID
700 NTAPI
703 {
704  KLOCK_QUEUE_HANDLE ApcLock;
708 
709  /* Crash system if DPC is being executed! */
710  if (KeIsExecutingDpc())
711  {
712  /* Executing a DPC, crash! */
713  KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
715  (ULONG_PTR)Thread->ApcState.Process,
716  Thread->ApcStateIndex,
717  KeIsExecutingDpc());
718  }
719 
720  /* Check if we are already in the target process */
721  if (Thread->ApcState.Process == Process)
722  {
723  /* Set magic value so we don't crash later when detaching */
724  ApcState->Process = (PKPROCESS)1;
725  return;
726  }
727 
728  /* Acquire APC Lock */
729  KiAcquireApcLock(Thread, &ApcLock);
730 
731  /* Acquire dispatcher lock */
733 
734  /* Check if the Current Thread is already attached */
735  if (Thread->ApcStateIndex != OriginalApcEnvironment)
736  {
737  /* We're already attached, so save the APC State into what we got */
738  KiAttachProcess(Thread, Process, &ApcLock, ApcState);
739  }
740  else
741  {
742  /* We're not attached, so save the APC State into SavedApcState */
743  KiAttachProcess(Thread, Process, &ApcLock, &Thread->SavedApcState);
744  ApcState->Process = NULL;
745  }
746 }
747 
748 /*
749  * @implemented
750  */
751 VOID
752 NTAPI
754 {
755  KLOCK_QUEUE_HANDLE ApcLock;
759 
760  /* Check for magic value meaning we were already in the same process */
761  if (ApcState->Process == (PKPROCESS)1) return;
762 
763  /* Loop to make sure no APCs are pending */
764  for (;;)
765  {
766  /* Acquire APC Lock */
767  KiAcquireApcLock(Thread, &ApcLock);
768 
769  /* Check if a kernel APC is pending */
770  if (Thread->ApcState.KernelApcPending)
771  {
772  /* Check if kernel APC should be delivered */
773  if (!(Thread->KernelApcDisable) && (ApcLock.OldIrql <= APC_LEVEL))
774  {
775  /* Release the APC lock so that the APC can be delivered */
776  KiReleaseApcLock(&ApcLock);
777  continue;
778  }
779  }
780 
781  /* Otherwise, break out */
782  break;
783  }
784 
785  /*
786  * Check if the process isn't attacked, or has a Kernel APC in progress
787  * or has pending APC of any kind.
788  */
789  if ((Thread->ApcStateIndex == OriginalApcEnvironment) ||
790  (Thread->ApcState.KernelApcInProgress) ||
791  (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) ||
792  (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
793  {
794  /* Bugcheck the system */
795  KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT);
796  }
797 
798  /* Get the process */
799  Process = Thread->ApcState.Process;
800 
801  /* Acquire dispatcher lock */
803 
804  /* Decrease the stack count */
805  ASSERT(Process->StackCount != 0);
806  ASSERT(Process->State == ProcessInMemory);
807  Process->StackCount--;
808 
809  /* Check if we can swap the process out */
810  if (!Process->StackCount)
811  {
812  /* FIXME: Swap the process out */
813  }
814 
815  /* Release dispatcher lock */
817 
818  /* Check if there's an APC state to restore */
819  if (ApcState->Process)
820  {
821  /* Restore the APC State */
822  KiMoveApcState(ApcState, &Thread->ApcState);
823  }
824  else
825  {
826  /* The ApcState parameter is useless, so use the saved data and reset it */
827  KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
828  Thread->SavedApcState.Process = NULL;
829  Thread->ApcStateIndex = OriginalApcEnvironment;
830  Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
831  Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
832  }
833 
834  /* Release lock */
836 
837  /* Swap Processes */
838  KiSwapProcess(Thread->ApcState.Process, Process);
839 
840  /* Exit the dispatcher */
841  KiExitDispatcher(ApcLock.OldIrql);
842 
843  /* Check if we have pending APCs */
844  if (!(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])))
845  {
846  /* What do you know, we do! Request them to be delivered */
847  Thread->ApcState.KernelApcPending = TRUE;
849  }
850 }
851 
852 /*
853  * @implemented
854  */
855 ULONG
856 NTAPI
859 {
860  ULONG TotalUser, TotalKernel;
861  KLOCK_QUEUE_HANDLE ProcessLock;
862  PLIST_ENTRY NextEntry, ListHead;
864 
866 
867  /* Initialize user and kernel times */
868  TotalUser = Process->UserTime;
869  TotalKernel = Process->KernelTime;
870 
871  /* Lock the process */
872  KiAcquireProcessLock(Process, &ProcessLock);
873 
874  /* Loop all child threads and sum up their times */
875  ListHead = &Process->ThreadListHead;
876  NextEntry = ListHead->Flink;
877  while (ListHead != NextEntry)
878  {
879  /* Get the thread */
880  Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
881 
882  /* Sum up times */
883  TotalKernel += Thread->KernelTime;
884  TotalUser += Thread->UserTime;
885 
886  /* Go to the next one */
887  NextEntry = NextEntry->Flink;
888  }
889 
890  /* Release lock */
891  KiReleaseProcessLock(&ProcessLock);
892 
893  /* Return the user time */
894  *UserTime = TotalUser;
895 
896  /* Return the kernel time */
897  return TotalKernel;
898 }
899 
900 /*
901  * @implemented
902  */
903 BOOLEAN
904 NTAPI
907  IN ULONG Limit,
908  IN PUCHAR Number,
909  IN ULONG Index)
910 {
911  PAGED_CODE();
912 
913  /* Check if descriptor table entry is free */
914  if ((Index > SSDT_MAX_ENTRIES - 1) ||
917  {
918  /* It's not, fail */
919  return FALSE;
920  }
921 
922  /* Initialize the shadow service descriptor table */
927  return TRUE;
928 }
929 
930 /*
931  * @implemented
932  */
933 BOOLEAN
934 NTAPI
936 {
937  PAGED_CODE();
938 
939  /* Make sure the Index is valid */
940  if (Index > (SSDT_MAX_ENTRIES - 1)) return FALSE;
941 
942  /* Is there a Normal Descriptor Table? */
944  {
945  /* Not with the index, is there a shadow at least? */
947  }
948 
949  /* Now clear from the Shadow Table. */
954 
955  /* Check if we should clean from the Master one too */
956  if (Index == 1)
957  {
962  }
963 
964  /* Return success */
965  return TRUE;
966 }
967 /* EOF */
LARGE_INTEGER WriteOperationCount
Definition: pstypes.h:1278
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE VOID KiReleaseThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:244
#define LOW_PRIORITY
ULONG KeMaximumIncrement
Definition: clock.c:20
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
ULONGLONG OtherOperationCount
Definition: pstypes.h:85
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
LARGE_INTEGER ReadOperationCount
Definition: pstypes.h:1277
VOID NTAPI KiAttachProcess(IN PKTHREAD Thread, IN PKPROCESS Process, IN PKLOCK_QUEUE_HANDLE ApcLock, IN PRKAPC_STATE SavedApcState)
Definition: procobj.c:35
#define KPSF_DISABLE_BOOST_BIT
Definition: pstypes.h:252
FORCEINLINE VOID KiReleaseProcessLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:660
BOOLEAN NTAPI KeAddSystemServiceTable(IN PULONG_PTR Base, IN PULONG Count OPTIONAL, IN ULONG Limit, IN PUCHAR Number, IN ULONG Index)
Definition: procobj.c:905
unsigned char * PUCHAR
Definition: retypes.h:3
KEVENT KiSwapEvent
Definition: procobj.c:21
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
ULONG NTAPI KeSetProcess(IN PKPROCESS Process, IN KPRIORITY Increment, IN BOOLEAN InWait)
Definition: procobj.c:194
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
struct _EPROCESS * PEPROCESS
Definition: nt_native.h:30
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
FORCEINLINE VOID KiAcquireApcLock(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:600
ULONGLONG WriteOperationCount
Definition: pstypes.h:84
#define MAXULONG_PTR
Definition: basetsd.h:103
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define LOW_REALTIME_PRIORITY
IO_COUNTERS IoInfo
Definition: ke.h:43
#define SSDT_MAX_ENTRIES
Definition: ketypes.h:100
ULONG ProcessReadyQueue
Definition: ketypes.h:1585
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
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
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
BOOLEAN NTAPI KeRemoveSystemServiceTable(IN ULONG Index)
Definition: procobj.c:935
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:701
LIST_ENTRY KiStackInSwapListHead
Definition: procobj.c:20
KAFFINITY NTAPI KeSetAffinityProcess(IN PKPROCESS Process, IN KAFFINITY Affinity)
Definition: procobj.c:265
union node Node
Definition: types.h:1255
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:690
ULONG NTAPI KeQueryRuntimeProcess(IN PKPROCESS Process, OUT PULONG UserTime)
Definition: procobj.c:857
#define InterlockedBitTestAndReset
Definition: interlocked.h:35
unsigned char BOOLEAN
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES]
Definition: procobj.c:24
smooth NULL
Definition: ftsmooth.c:416
LARGE_INTEGER OtherTransferCount
Definition: pstypes.h:1282
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
ULONGLONG WriteTransferCount
Definition: pstypes.h:87
#define HIGH_PRIORITY
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
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
VOID NTAPI KeQueryValuesProcess(IN PKPROCESS Process, PPROCESS_VALUES Values)
Definition: procobj.c:522
FORCEINLINE VOID KiAcquireThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:234
int64_t LONGLONG
Definition: typedefs.h:66
#define IO_ACCESS_MAP_NONE
Definition: ketypes.h:263
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
struct _KPROCESS KPROCESS
PVOID KeUserExceptionDispatcher
Definition: procobj.c:28
#define KPSF_AUTO_ALIGNMENT_BIT
Definition: pstypes.h:251
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
static const UCHAR Index[8]
Definition: usbohci.c:18
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
LARGE_INTEGER WriteTransferCount
Definition: pstypes.h:1281
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE VOID KiReleaseProcessLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:652
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:618
unsigned char UCHAR
Definition: xmlstorage.h:181
ULONGLONG ReadTransferCount
Definition: pstypes.h:86
_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:117
_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 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:579
#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:753
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
*RESTRICTED_POINTER PRKAPC_STATE
Definition: ketypes.h:1273
static ULONG Delta
Definition: xboxvideo.c:28
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1484
unsigned int * PULONG
Definition: retypes.h:1
LARGE_INTEGER TotalKernelTime
Definition: ke.h:41
LIST_ENTRY KiProcessOutSwapListHead
Definition: procobj.c:19
#define DPRINT1
Definition: precomp.h:8
LARGE_INTEGER OtherOperationCount
Definition: pstypes.h:1279
FORCEINLINE VOID KiReleaseDispatcherLockFromDpcLevel(VOID)
Definition: ke_x.h:168
BOOLEAN NTAPI KeSetDisableBoostProcess(IN PKPROCESS Process, IN BOOLEAN Disable)
Definition: procobj.c:331
LARGE_INTEGER ReadTransferCount
Definition: pstypes.h:1280
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:39
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
uint32_t * PULONG_PTR
Definition: typedefs.h:63
LARGE_INTEGER TotalUserTime
Definition: ke.h:42
PVOID KeUserApcDispatcher
Definition: procobj.c:26
ULONGLONG OtherTransferCount
Definition: pstypes.h:88
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
#define CHAR(Char)
#define ASSERT_PROCESS(object)
Definition: ketypes.h:2030
#define APC_LEVEL
Definition: env_spec_w32.h:695
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:328
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:107
FORCEINLINE VOID KiAcquireDispatcherLockAtDpcLevel(VOID)
Definition: ke_x.h:160
LONGLONG QuadPart
Definition: typedefs.h:112
ULONGLONG ReadOperationCount
Definition: pstypes.h:83
Definition: dlist.c:348
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68