1 /* $Id: process.c,v 1.73 2002/01/03 12:48:02 chorns Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/process.c
6 * PURPOSE: Process managment
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES ******************************************************************/
15 #include <ddk/ntddk.h>
16 #include <internal/ob.h>
17 #include <internal/mm.h>
18 #include <internal/ke.h>
19 #include <internal/ps.h>
20 #include <internal/id.h>
22 #include <internal/ldr.h>
23 #include <internal/port.h>
25 #include <internal/dbg.h>
26 #include <napi/shared_data.h>
27 #include <internal/pool.h>
31 #include <internal/debug.h>
33 /* GLOBALS ******************************************************************/
35 PEPROCESS EXPORTED PsInitialSystemProcess
= NULL
;
36 HANDLE SystemProcessHandle
= NULL
;
38 POBJECT_TYPE EXPORTED PsProcessType
= NULL
;
40 LIST_ENTRY PsProcessListHead
;
41 static KSPIN_LOCK PsProcessListLock
;
42 static ULONG PiNextProcessUniqueId
= 0;
44 static GENERIC_MAPPING PiProcessMapping
= {PROCESS_READ
,
49 /* FUNCTIONS *****************************************************************/
53 PsGetNextProcess(PEPROCESS OldProcess
)
56 PEPROCESS NextProcess
;
59 if (OldProcess
== NULL
)
61 return(PsInitialSystemProcess
);
64 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
65 if (OldProcess
->ProcessListEntry
.Flink
== &PsProcessListHead
)
67 NextProcess
= CONTAINING_RECORD(PsProcessListHead
.Flink
,
73 NextProcess
= CONTAINING_RECORD(OldProcess
->ProcessListEntry
.Flink
,
77 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
78 Status
= ObReferenceObjectByPointer(NextProcess
,
82 if (!NT_SUCCESS(Status
))
84 DbgPrint("PsGetNextProcess(): ObReferenceObjectByPointer failed\n");
87 ObDereferenceObject(OldProcess
);
93 NtOpenProcessToken(IN HANDLE ProcessHandle
,
94 IN ACCESS_MASK DesiredAccess
,
95 OUT PHANDLE TokenHandle
)
97 return(STATUS_UNSUCCESSFUL
);
101 _NtOpenProcessToken(IN HANDLE ProcessHandle
,
102 IN ACCESS_MASK DesiredAccess
,
103 OUT PHANDLE TokenHandle
)
108 Status
= PsOpenTokenOfProcess(ProcessHandle
,
110 if (!NT_SUCCESS(Status
))
114 Status
= ObCreateHandle(PsGetCurrentProcess(),
119 ObDereferenceObject(Token
);
124 PACCESS_TOKEN STDCALL
125 PsReferencePrimaryToken(PEPROCESS Process
)
127 ObReferenceObjectByPointer(Process
->Token
,
131 return(Process
->Token
);
136 PsOpenTokenOfProcess(HANDLE ProcessHandle
,
137 PACCESS_TOKEN
* Token
)
142 Status
= ObReferenceObjectByHandle(ProcessHandle
,
143 PROCESS_QUERY_INFORMATION
,
148 if (!NT_SUCCESS(Status
))
152 *Token
= PsReferencePrimaryToken(Process
);
153 ObDereferenceObject(Process
);
154 return(STATUS_SUCCESS
);
159 PiKillMostProcesses(VOID
)
162 PLIST_ENTRY current_entry
;
165 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
167 current_entry
= PsProcessListHead
.Flink
;
168 while (current_entry
!= &PsProcessListHead
)
170 current
= CONTAINING_RECORD(current_entry
, EPROCESS
,
172 current_entry
= current_entry
->Flink
;
174 if (current
->UniqueProcessId
!= PsInitialSystemProcess
->UniqueProcessId
&&
175 current
->UniqueProcessId
!= (ULONG
)PsGetCurrentProcessId())
177 PiTerminateProcessThreads(current
, STATUS_SUCCESS
);
181 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
186 PsInitProcessManagment(VOID
)
194 * Register the process object type
197 PsProcessType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
199 PsProcessType
->Tag
= TAG('P', 'R', 'O', 'C');
200 PsProcessType
->TotalObjects
= 0;
201 PsProcessType
->TotalHandles
= 0;
202 PsProcessType
->MaxObjects
= ULONG_MAX
;
203 PsProcessType
->MaxHandles
= ULONG_MAX
;
204 PsProcessType
->PagedPoolCharge
= 0;
205 PsProcessType
->NonpagedPoolCharge
= sizeof(EPROCESS
);
206 PsProcessType
->Mapping
= &PiProcessMapping
;
207 PsProcessType
->Dump
= NULL
;
208 PsProcessType
->Open
= NULL
;
209 PsProcessType
->Close
= NULL
;
210 PsProcessType
->Delete
= PiDeleteProcess
;
211 PsProcessType
->Parse
= NULL
;
212 PsProcessType
->Security
= NULL
;
213 PsProcessType
->QueryName
= NULL
;
214 PsProcessType
->OkayToClose
= NULL
;
215 PsProcessType
->Create
= NULL
;
216 PsProcessType
->DuplicationNotify
= NULL
;
218 RtlInitUnicodeString(&PsProcessType
->TypeName
, L
"Process");
220 InitializeListHead(&PsProcessListHead
);
221 KeInitializeSpinLock(&PsProcessListLock
);
224 * Initialize the system process
226 Status
= ObCreateObject(NULL
,
230 (PVOID
*)&PsInitialSystemProcess
);
231 if (!NT_SUCCESS(Status
))
236 /* System threads may run on any processor. */
237 PsInitialSystemProcess
->Pcb
.Affinity
= 0xFFFFFFFF;
238 PsInitialSystemProcess
->Pcb
.BasePriority
= PROCESS_PRIO_NORMAL
;
239 KeInitializeDispatcherHeader(&PsInitialSystemProcess
->Pcb
.DispatcherHeader
,
243 KProcess
= &PsInitialSystemProcess
->Pcb
;
245 MmInitializeAddressSpace(PsInitialSystemProcess
,
246 &PsInitialSystemProcess
->AddressSpace
);
247 ObCreateHandleTable(NULL
,FALSE
,PsInitialSystemProcess
);
248 KProcess
->DirectoryTableBase
[0] = MmGetPageDirectory();
249 PsInitialSystemProcess
->UniqueProcessId
=
250 InterlockedIncrement(&PiNextProcessUniqueId
);
252 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
253 InsertHeadList(&PsProcessListHead
,
254 &PsInitialSystemProcess
->ProcessListEntry
);
255 InitializeListHead(&PsInitialSystemProcess
->ThreadListHead
);
256 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
258 strcpy(PsInitialSystemProcess
->ImageFileName
, "SYSTEM");
260 ObCreateHandle(PsInitialSystemProcess
,
261 PsInitialSystemProcess
,
264 &SystemProcessHandle
);
270 PiFreeSymbols(PPEB Peb
)
272 PLIST_ENTRY CurrentEntry
;
280 CurrentEntry
= Peb
->Ldr
->InLoadOrderModuleList
.Flink
;
281 while ((CurrentEntry
!= &Peb
->Ldr
->InLoadOrderModuleList
) && (CurrentEntry
!= NULL
))
283 Current
= CONTAINING_RECORD (CurrentEntry
, LDR_MODULE
, InLoadOrderModuleList
);
284 Symbol
= Current
->Symbols
.Symbols
;
285 while (Symbol
!= NULL
)
287 NextSymbol
= Symbol
->Next
;
288 RtlFreeUnicodeString (&Symbol
->Name
);
292 Current
->Symbols
.SymbolCount
= 0;
293 Current
->Symbols
.Symbols
= NULL
;
294 CurrentEntry
= CurrentEntry
->Flink
;
301 PiDeleteProcess(PVOID ObjectBody
)
305 DPRINT("PiDeleteProcess(ObjectBody %x)\n",ObjectBody
);
307 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
308 RemoveEntryList(&((PEPROCESS
)ObjectBody
)->ProcessListEntry
);
309 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
312 PiFreeSymbols(((PEPROCESS
)ObjectBody
)->Peb
);
315 (VOID
)MmReleaseMmInfo((PEPROCESS
)ObjectBody
);
316 ObDeleteHandleTable((PEPROCESS
)ObjectBody
);
321 PsCreatePeb(HANDLE ProcessHandle
,
331 memset(&Peb
, 0, sizeof(Peb
));
332 Peb
.ImageBaseAddress
= ImageBase
;
334 PebBase
= (PVOID
)PEB_BASE
;
336 Status
= NtAllocateVirtualMemory(ProcessHandle
,
340 MEM_RESERVE
| MEM_COMMIT
,
342 if (!NT_SUCCESS(Status
))
347 NtWriteVirtualMemory(ProcessHandle
,
353 DPRINT("PsCreatePeb: Peb created at %x\n", PebBase
);
357 return(STATUS_SUCCESS
);
362 KeGetCurrentProcess(VOID
)
364 * FUNCTION: Returns a pointer to the current process
367 return(&(PsGetCurrentProcess()->Pcb
));
371 PsGetCurrentProcessId(VOID
)
373 return((HANDLE
)PsGetCurrentProcess()->UniqueProcessId
);
377 * FUNCTION: Returns a pointer to the current process
380 PsGetCurrentProcess(VOID
)
382 if (PsGetCurrentThread() == NULL
||
383 PsGetCurrentThread()->ThreadsProcess
== NULL
)
385 return(PsInitialSystemProcess
);
389 return(PsGetCurrentThread()->ThreadsProcess
);
394 IoGetCurrentProcess(VOID
)
396 return(PsGetCurrentProcess());
400 PsCreateSystemProcess(PHANDLE ProcessHandle
,
401 ACCESS_MASK DesiredAccess
,
402 POBJECT_ATTRIBUTES ObjectAttributes
)
404 return NtCreateProcess(ProcessHandle
,
415 NtCreateProcess(OUT PHANDLE ProcessHandle
,
416 IN ACCESS_MASK DesiredAccess
,
417 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
418 IN HANDLE ParentProcessHandle
,
419 IN BOOLEAN InheritObjectTable
,
420 IN HANDLE SectionHandle OPTIONAL
,
421 IN HANDLE DebugPortHandle OPTIONAL
,
422 IN HANDLE ExceptionPortHandle OPTIONAL
)
424 * FUNCTION: Creates a process.
426 * ProcessHandle (OUT) = Caller supplied storage for the resulting
428 * DesiredAccess = Specifies the allowed or desired access to the
429 * process can be a combination of
430 * STANDARD_RIGHTS_REQUIRED| ..
431 * ObjectAttribute = Initialized attributes for the object, contains
432 * the rootdirectory and the filename
433 * ParentProcess = Handle to the parent process.
434 * InheritObjectTable = Specifies to inherit the objects of the parent
436 * SectionHandle = Handle to a section object to back the image file
437 * DebugPort = Handle to a DebugPort if NULL the system default debug
439 * ExceptionPort = Handle to a exception port.
441 * This function maps to the win32 CreateProcess.
446 PEPROCESS ParentProcess
;
450 PVOID LdrStartupAddr
;
454 PEPORT ExceptionPort
;
456 PMEMORY_AREA MemoryArea
;
458 DPRINT("NtCreateProcess(ObjectAttributes %x)\n",ObjectAttributes
);
460 Status
= ObReferenceObjectByHandle(ParentProcessHandle
,
461 PROCESS_CREATE_PROCESS
,
464 (PVOID
*)&ParentProcess
,
466 if (!NT_SUCCESS(Status
))
468 DPRINT("NtCreateProcess() = %x\n",Status
);
472 Status
= ObCreateObject(ProcessHandle
,
477 if (!NT_SUCCESS(Status
))
479 ObDereferenceObject(ParentProcess
);
480 DPRINT("ObCreateObject() = %x\n",Status
);
484 KeInitializeDispatcherHeader(&Process
->Pcb
.DispatcherHeader
,
488 KProcess
= &Process
->Pcb
;
489 /* Inherit parent process's affinity. */
490 KProcess
->Affinity
= ParentProcess
->Pcb
.Affinity
;
491 KProcess
->BasePriority
= PROCESS_PRIO_NORMAL
;
492 MmInitializeAddressSpace(Process
,
493 &Process
->AddressSpace
);
494 Process
->UniqueProcessId
= InterlockedIncrement(&PiNextProcessUniqueId
);
495 Process
->InheritedFromUniqueProcessId
=
496 (HANDLE
)ParentProcess
->UniqueProcessId
;
497 ObCreateHandleTable(ParentProcess
,
500 MmCopyMmInfo(ParentProcess
, Process
);
502 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
503 InsertHeadList(&PsProcessListHead
, &Process
->ProcessListEntry
);
504 InitializeListHead(&Process
->ThreadListHead
);
505 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
507 Process
->Pcb
.State
= PROCESS_STATE_ACTIVE
;
512 if (DebugPortHandle
!= NULL
)
514 Status
= ObReferenceObjectByHandle(DebugPortHandle
,
520 if (!NT_SUCCESS(Status
))
522 ObDereferenceObject(Process
);
523 ObDereferenceObject(ParentProcess
);
524 ZwClose(*ProcessHandle
);
525 *ProcessHandle
= NULL
;
528 Process
->DebugPort
= DebugPort
;
532 * Add the exception port
534 if (ExceptionPortHandle
!= NULL
)
536 Status
= ObReferenceObjectByHandle(ExceptionPortHandle
,
540 (PVOID
*)&ExceptionPort
,
542 if (!NT_SUCCESS(Status
))
544 ObDereferenceObject(Process
);
545 ObDereferenceObject(ParentProcess
);
546 ZwClose(*ProcessHandle
);
547 *ProcessHandle
= NULL
;
550 Process
->ExceptionPort
= ExceptionPort
;
554 * Now we have created the process proper
558 * Create the shared data page
560 MmLockAddressSpace(&Process
->AddressSpace
);
561 BaseAddress
= (PVOID
)USER_SHARED_DATA_BASE
;
562 Status
= MmCreateMemoryArea(Process
,
563 &Process
->AddressSpace
,
564 MEMORY_AREA_SHARED_DATA
,
570 MmUnlockAddressSpace(&Process
->AddressSpace
);
571 if (!NT_SUCCESS(Status
))
573 DPRINT1("Failed to create shared data page\n");
580 Status
= LdrpMapSystemDll(*ProcessHandle
,
582 if (!NT_SUCCESS(Status
))
584 DbgPrint("LdrpMapSystemDll failed (Status %x)\n", Status
);
585 ObDereferenceObject(Process
);
586 ObDereferenceObject(ParentProcess
);
591 * Map the process image
593 if (SectionHandle
!= NULL
)
595 DPRINT("Mapping process image\n");
596 Status
= LdrpMapImage(*ProcessHandle
,
599 if (!NT_SUCCESS(Status
))
601 DbgPrint("LdrpMapImage failed (Status %x)\n", Status
);
602 ObDereferenceObject(Process
);
603 ObDereferenceObject(ParentProcess
);
615 DPRINT("Creating PEB\n");
616 Status
= PsCreatePeb(*ProcessHandle
,
619 if (!NT_SUCCESS(Status
))
621 DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status
);
622 ObDereferenceObject(Process
);
623 ObDereferenceObject(ParentProcess
);
624 ZwClose(*ProcessHandle
);
625 *ProcessHandle
= NULL
;
631 * Maybe send a message to the creator process's debugger
634 if (ParentProcess
->DebugPort
!= NULL
)
636 LPC_DBG_MESSAGE Message
;
639 ObCreateHandle(NULL
, // Debugger Process
640 NULL
, // SectionHandle
645 Message
.Header
.MessageSize
= sizeof(LPC_DBG_MESSAGE
);
646 Message
.Header
.DataSize
= sizeof(LPC_DBG_MESSAGE
) -
647 sizeof(LPC_MESSAGE_HEADER
);
648 Message
.Type
= DBG_EVENT_CREATE_PROCESS
;
649 Message
.Data
.CreateProcess
.FileHandle
= FileHandle
;
650 Message
.Data
.CreateProcess
.Base
= ImageBase
;
651 Message
.Data
.CreateProcess
.EntryPoint
= NULL
; //
653 Status
= LpcSendDebugMessagePort(ParentProcess
->DebugPort
,
658 ObDereferenceObject(Process
);
659 ObDereferenceObject(ParentProcess
);
660 return(STATUS_SUCCESS
);
665 NtOpenProcess(OUT PHANDLE ProcessHandle
,
666 IN ACCESS_MASK DesiredAccess
,
667 IN POBJECT_ATTRIBUTES ObjectAttributes
,
668 IN PCLIENT_ID ClientId
)
670 DPRINT("NtOpenProcess(ProcessHandle %x, DesiredAccess %x, "
671 "ObjectAttributes %x, ClientId %x { UniP %d, UniT %d })\n",
672 ProcessHandle
, DesiredAccess
, ObjectAttributes
, ClientId
,
673 ClientId
->UniqueProcess
, ClientId
->UniqueThread
);
677 * Not sure of the exact semantics
679 if (ObjectAttributes
!= NULL
&& ObjectAttributes
->ObjectName
!= NULL
&&
680 ObjectAttributes
->ObjectName
->Buffer
!= NULL
)
685 Status
= ObReferenceObjectByName(ObjectAttributes
->ObjectName
,
686 ObjectAttributes
->Attributes
,
693 if (Status
!= STATUS_SUCCESS
)
698 Status
= ObCreateHandle(PsGetCurrentProcess(),
703 ObDereferenceObject(Process
);
710 PLIST_ENTRY current_entry
;
714 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
715 current_entry
= PsProcessListHead
.Flink
;
716 while (current_entry
!= &PsProcessListHead
)
718 current
= CONTAINING_RECORD(current_entry
, EPROCESS
,
720 if (current
->UniqueProcessId
== (ULONG
)ClientId
->UniqueProcess
)
722 ObReferenceObjectByPointer(current
,
726 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
727 Status
= ObCreateHandle(PsGetCurrentProcess(),
732 ObDereferenceObject(current
);
733 DPRINT("*ProcessHandle %x\n", ProcessHandle
);
734 DPRINT("NtOpenProcess() = %x\n", Status
);
737 current_entry
= current_entry
->Flink
;
739 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
740 DPRINT("NtOpenProcess() = STATUS_UNSUCCESSFUL\n");
741 return(STATUS_UNSUCCESSFUL
);
743 return(STATUS_UNSUCCESSFUL
);
748 NtQueryInformationProcess(IN HANDLE ProcessHandle
,
749 IN CINT ProcessInformationClass
,
750 OUT PVOID ProcessInformation
,
751 IN ULONG ProcessInformationLength
,
752 OUT PULONG ReturnLength
)
756 PPROCESS_BASIC_INFORMATION ProcessBasicInformationP
;
758 Status
= ObReferenceObjectByHandle(ProcessHandle
,
759 PROCESS_SET_INFORMATION
,
764 if (Status
!= STATUS_SUCCESS
)
769 switch (ProcessInformationClass
)
771 case ProcessBasicInformation
:
772 ProcessBasicInformationP
= (PPROCESS_BASIC_INFORMATION
)
774 ProcessBasicInformationP
->ExitStatus
= Process
->ExitStatus
;
775 ProcessBasicInformationP
->PebBaseAddress
= Process
->Peb
;
776 ProcessBasicInformationP
->AffinityMask
= Process
->Pcb
.Affinity
;
777 ProcessBasicInformationP
->UniqueProcessId
=
778 Process
->UniqueProcessId
;
779 ProcessBasicInformationP
->InheritedFromUniqueProcessId
=
780 (ULONG
)Process
->InheritedFromUniqueProcessId
;
781 Status
= STATUS_SUCCESS
;
784 case ProcessQuotaLimits
:
785 case ProcessIoCounters
:
786 case ProcessVmCounters
:
788 case ProcessBasePriority
:
789 case ProcessRaisePriority
:
790 case ProcessDebugPort
:
791 case ProcessExceptionPort
:
792 case ProcessAccessToken
:
793 case ProcessLdtInformation
:
795 Status
= STATUS_NOT_IMPLEMENTED
;
798 case ProcessDefaultHardErrorMode
:
799 *((PULONG
)ProcessInformation
) = Process
->DefaultHardErrorProcessing
;
802 case ProcessIoPortHandlers
:
803 case ProcessWorkingSetWatch
:
804 case ProcessUserModeIOPL
:
805 case ProcessEnableAlignmentFaultFixup
:
806 Status
= STATUS_NOT_IMPLEMENTED
;
809 case ProcessForegroundInformation
:
810 ((PPROCESS_PRIORITY_CLASS
)ProcessInformation
)->Foreground
=
811 FALSE
; /*FIXME: how to compute it? */
812 case ProcessPriorityClass
:
813 ((PPROCESS_PRIORITY_CLASS
)ProcessInformation
)->PriorityClass
=
814 Process
->PriorityClass
;
817 case ProcessWx86Information
:
818 case ProcessHandleCount
:
819 case ProcessAffinityMask
:
820 case ProcessPriorityBoost
:
821 case ProcessDeviceMap
:
822 case ProcessSessionInformation
:
823 case ProcessWow64Information
:
824 Status
= STATUS_NOT_IMPLEMENTED
;
828 Status
= STATUS_INVALID_INFO_CLASS
;
830 ObDereferenceObject(Process
);
835 PspAssignPrimaryToken(PEPROCESS Process
,
839 PACCESS_TOKEN OldToken
;
842 Status
= ObReferenceObjectByHandle(TokenHandle
,
848 if (!NT_SUCCESS(Status
))
852 Status
= SeExchangePrimaryToken(Process
, Token
, &OldToken
);
853 if (!NT_SUCCESS(Status
))
855 ObDereferenceObject(OldToken
);
857 ObDereferenceObject(Token
);
862 NtSetInformationProcess(IN HANDLE ProcessHandle
,
863 IN CINT ProcessInformationClass
,
864 IN PVOID ProcessInformation
,
865 IN ULONG ProcessInformationLength
)
869 PPROCESS_BASIC_INFORMATION ProcessBasicInformationP
;
870 PHANDLE ProcessAccessTokenP
;
872 Status
= ObReferenceObjectByHandle(ProcessHandle
,
873 PROCESS_SET_INFORMATION
,
878 if (!NT_SUCCESS(Status
))
883 switch (ProcessInformationClass
)
885 case ProcessBasicInformation
:
886 ProcessBasicInformationP
= (PPROCESS_BASIC_INFORMATION
)
888 memset(ProcessBasicInformationP
, 0, sizeof(PROCESS_BASIC_INFORMATION
));
889 Process
->Pcb
.Affinity
= ProcessBasicInformationP
->AffinityMask
;
890 Status
= STATUS_SUCCESS
;
893 case ProcessQuotaLimits
:
894 case ProcessIoCounters
:
895 case ProcessVmCounters
:
897 case ProcessBasePriority
:
898 case ProcessRaisePriority
:
899 case ProcessDebugPort
:
900 case ProcessExceptionPort
:
901 case ProcessAccessToken
:
902 ProcessAccessTokenP
= (PHANDLE
)ProcessInformation
;
903 Status
= PspAssignPrimaryToken(Process
, *ProcessAccessTokenP
);
906 case ProcessImageFileName
:
907 memcpy(Process
->ImageFileName
, ProcessInformation
, 8);
908 // DPRINT1("Process->ImageFileName %.8s\n", Process->ImageFileName);
909 Status
= STATUS_SUCCESS
;
912 case ProcessLdtInformation
:
914 case ProcessDefaultHardErrorMode
:
915 case ProcessIoPortHandlers
:
916 case ProcessWorkingSetWatch
:
917 case ProcessUserModeIOPL
:
918 case ProcessEnableAlignmentFaultFixup
:
919 case ProcessPriorityClass
:
920 case ProcessWx86Information
:
921 case ProcessHandleCount
:
922 case ProcessAffinityMask
:
924 Status
= STATUS_NOT_IMPLEMENTED
;
926 ObDereferenceObject(Process
);
931 /**********************************************************************
933 * PiQuerySystemProcessInformation
936 * Compute the size of a process+thread snapshot as
937 * expected by NtQuerySystemInformation.
940 * 0 on error; otherwise the size, in bytes of the buffer
941 * required to write a full snapshot.
944 * We assume (sizeof (PVOID) == sizeof (ULONG)) holds.
947 PiQuerySystemProcessInformation(PVOID Buffer
,
951 return STATUS_NOT_IMPLEMENTED
;
955 PLIST_ENTRY CurrentEntryP
;
957 PLIST_ENTRY CurrentEntryT
;
960 ULONG RequiredSize
= 0L;
961 BOOLEAN SizeOnly
= FALSE
;
965 PSYSTEM_PROCESS_INFORMATION pInfoP
= (PSYSTEM_PROCESS_INFORMATION
) SnapshotBuffer
;
966 PSYSTEM_PROCESS_INFORMATION pInfoPLast
= NULL
;
967 PSYSTEM_THREAD_INFO pInfoT
= NULL
;
970 /* Lock the process list. */
971 KeAcquireSpinLock(&PsProcessListLock
,
975 * Scan the process list. Since the
976 * list is circular, the guard is false
977 * after the last process.
979 for ( CurrentEntryP
= PsProcessListHead
.Flink
;
980 (CurrentEntryP
!= & PsProcessListHead
);
981 CurrentEntryP
= CurrentEntryP
->Flink
985 * Compute how much space is
986 * occupied in the snapshot
987 * by adding this process info.
988 * (at least one thread).
990 SpiSizeCurrent
= sizeof (SYSTEM_PROCESS_INFORMATION
);
991 RequiredSize
+= SpiSizeCurrent
;
993 * Do not write process data in the
994 * buffer if it is too small.
996 if (TRUE
== SizeOnly
) continue;
998 * Check if the buffer can contain
1001 if (Size
< RequiredSize
)
1007 * Get a reference to the
1008 * process descriptor we are
1011 CurrentP
= CONTAINING_RECORD(
1017 * Write process data in the buffer.
1019 RtlZeroMemory (pInfoP
, sizeof (SYSTEM_PROCESS_INFORMATION
));
1021 pInfoP
->ThreadCount
= 0L;
1022 pInfoP
->ProcessId
= CurrentP
->UniqueProcessId
;
1023 RtlInitUnicodeString (
1025 CurrentP
->ImageFileName
1028 for ( pInfoT
= & CurrentP
->ThreadSysInfo
[0],
1029 CurrentEntryT
= CurrentP
->ThreadListHead
.Flink
;
1031 (CurrentEntryT
!= & CurrentP
->ThreadListHead
);
1033 pInfoT
= & CurrentP
->ThreadSysInfo
[pInfoP
->ThreadCount
],
1034 CurrentEntryT
= CurrentEntryT
->Flink
1038 * Recalculate the size of the
1039 * information block.
1041 if (0 < pInfoP
->ThreadCount
)
1043 RequiredSize
+= sizeof (SYSTEM_THREAD_INFORMATION
);
1046 * Do not write thread data in the
1047 * buffer if it is too small.
1049 if (TRUE
== SizeOnly
) continue;
1051 * Check if the buffer can contain
1052 * the full snapshot.
1054 if (Size
< RequiredSize
)
1060 * Get a reference to the
1061 * thread descriptor we are
1064 CurrentT
= CONTAINING_RECORD(
1070 * Write thread data.
1074 sizeof (SYSTEM_THREAD_INFORMATION
)
1076 pInfoT
->KernelTime
= CurrentT
-> ; /* TIME */
1077 pInfoT
->UserTime
= CurrentT
-> ; /* TIME */
1078 pInfoT
->CreateTime
= CurrentT
-> ; /* TIME */
1079 pInfoT
->TickCount
= CurrentT
-> ; /* ULONG */
1080 pInfoT
->StartEIP
= CurrentT
-> ; /* ULONG */
1081 pInfoT
->ClientId
= CurrentT
-> ; /* CLIENT_ID */
1082 pInfoT
->ClientId
= CurrentT
-> ; /* CLIENT_ID */
1083 pInfoT
->DynamicPriority
= CurrentT
-> ; /* ULONG */
1084 pInfoT
->BasePriority
= CurrentT
-> ; /* ULONG */
1085 pInfoT
->nSwitches
= CurrentT
-> ; /* ULONG */
1086 pInfoT
->State
= CurrentT
-> ; /* DWORD */
1087 pInfoT
->WaitReason
= CurrentT
-> ; /* KWAIT_REASON */
1089 * Count the number of threads
1092 ++ pInfoP
->ThreadCount
;
1095 * Save the size of information
1096 * stored in the buffer for the
1099 pInfoP
->RelativeOffset
= SpiSize
;
1101 * Save a reference to the last
1102 * valid information block.
1104 pInfoPLast
= pInfoP
;
1106 * Compute the offset of the
1107 * SYSTEM_PROCESS_INFORMATION
1108 * descriptor in the snapshot
1109 * buffer for the next process.
1111 (ULONG
) pInfoP
+= SpiSize
;
1114 * Unlock the process list.
1117 & PsProcessListLock
,
1121 * Return the proper error status code,
1122 * if the buffer was too small.
1124 if (TRUE
== SizeOnly
)
1126 if (NULL
!= RequiredSize
)
1128 *pRequiredSize
= RequiredSize
;
1130 return STATUS_INFO_LENGTH_MISMATCH
;
1133 * Mark the end of the snapshot.
1135 pInfoP
->RelativeOffset
= 0L;
1137 return STATUS_SUCCESS
;
1141 LARGE_INTEGER STDCALL
1142 PsGetProcessExitTime(VOID
)
1145 Li
.QuadPart
= PsGetCurrentProcess()->ExitTime
.QuadPart
;
1150 PsIsThreadTerminating(IN PETHREAD Thread
)
1152 return(Thread
->DeadThread
);