1 /* $Id: process.c,v 1.91 2002/09/07 15:13:05 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 ******************************************************************/
17 #include <internal/debug.h>
20 /* GLOBALS ******************************************************************/
22 PEPROCESS PsInitialSystemProcess
= NULL
;
23 HANDLE SystemProcessHandle
= NULL
;
25 POBJECT_TYPE PsProcessType
= NULL
;
27 LIST_ENTRY PsProcessListHead
;
28 static KSPIN_LOCK PsProcessListLock
;
29 static ULONG PiNextProcessUniqueId
= 0;
31 static GENERIC_MAPPING PiProcessMapping
= {PROCESS_READ
,
36 #define MAX_PROCESS_NOTIFY_ROUTINE_COUNT 8
38 static ULONG PiProcessNotifyRoutineCount
= 0;
39 static PCREATE_PROCESS_NOTIFY_ROUTINE
40 PiProcessNotifyRoutine
[MAX_PROCESS_NOTIFY_ROUTINE_COUNT
];
42 /* FUNCTIONS *****************************************************************/
45 PsGetNextProcess(PEPROCESS OldProcess
)
48 PEPROCESS NextProcess
;
51 if (OldProcess
== NULL
)
53 return(PsInitialSystemProcess
);
56 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
57 if (OldProcess
->ProcessListEntry
.Flink
== &PsProcessListHead
)
59 NextProcess
= CONTAINING_RECORD (PsProcessListHead
.Flink
,
65 NextProcess
= CONTAINING_RECORD(OldProcess
->ProcessListEntry
.Flink
,
69 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
70 Status
= ObReferenceObjectByPointer(NextProcess
,
74 if (!NT_SUCCESS(Status
))
76 CPRINT("PsGetNextProcess(): ObReferenceObjectByPointer failed\n");
79 ObDereferenceObject(OldProcess
);
86 _NtOpenProcessToken(IN HANDLE ProcessHandle
,
87 IN ACCESS_MASK DesiredAccess
,
88 OUT PHANDLE TokenHandle
)
90 PIACCESS_TOKEN iToken
;
93 Status
= PsOpenTokenOfProcess(ProcessHandle
,
95 if (!NT_SUCCESS(Status
))
99 Status
= ObCreateHandle(PsGetCurrentProcess(),
104 ObDereferenceObject(iToken
);
110 NtOpenProcessToken(IN HANDLE ProcessHandle
,
111 IN ACCESS_MASK DesiredAccess
,
112 OUT PHANDLE TokenHandle
)
114 return _NtOpenProcessToken(ProcessHandle
, DesiredAccess
, TokenHandle
);
118 PACCESS_TOKEN STDCALL
119 PsReferencePrimaryToken(PEPROCESS Process
)
121 ObReferenceObjectByPointer(Process
->Token
,
125 return(Process
->Token
);
130 PsOpenTokenOfProcess(HANDLE ProcessHandle
,
131 PIACCESS_TOKEN
* Token
)
136 Status
= ObReferenceObjectByHandle(ProcessHandle
,
137 PROCESS_QUERY_INFORMATION
,
142 if (!NT_SUCCESS(Status
))
146 *Token
= PsReferencePrimaryToken(Process
);
147 ObDereferenceObject(Process
);
148 return(STATUS_SUCCESS
);
153 PiKillMostProcesses(VOID
)
156 PLIST_ENTRY current_entry
;
159 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
161 current_entry
= PsProcessListHead
.Flink
;
162 while (current_entry
!= &PsProcessListHead
)
164 current
= CONTAINING_RECORD(current_entry
, EPROCESS
,
166 current_entry
= current_entry
->Flink
;
168 if (current
->UniqueProcessId
!= PsInitialSystemProcess
->UniqueProcessId
&&
169 current
->UniqueProcessId
!= (ULONG
)PsGetCurrentProcessId())
171 PiTerminateProcessThreads(current
, STATUS_SUCCESS
);
175 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
180 PsInitProcessManagment(VOID
)
187 * Register the process object type
190 PsProcessType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
192 PsProcessType
->Tag
= TAG('P', 'R', 'O', 'C');
193 PsProcessType
->TotalObjects
= 0;
194 PsProcessType
->TotalHandles
= 0;
195 PsProcessType
->MaxObjects
= ULONG_MAX
;
196 PsProcessType
->MaxHandles
= ULONG_MAX
;
197 PsProcessType
->PagedPoolCharge
= 0;
198 PsProcessType
->NonpagedPoolCharge
= sizeof(EPROCESS
);
199 PsProcessType
->Mapping
= &PiProcessMapping
;
200 PsProcessType
->Dump
= NULL
;
201 PsProcessType
->Open
= NULL
;
202 PsProcessType
->Close
= NULL
;
203 PsProcessType
->Delete
= PiDeleteProcess
;
204 PsProcessType
->Parse
= NULL
;
205 PsProcessType
->Security
= NULL
;
206 PsProcessType
->QueryName
= NULL
;
207 PsProcessType
->OkayToClose
= NULL
;
208 PsProcessType
->Create
= NULL
;
209 PsProcessType
->DuplicationNotify
= NULL
;
211 RtlInitUnicodeStringFromLiteral(&PsProcessType
->TypeName
, L
"Process");
213 InitializeListHead(&PsProcessListHead
);
214 KeInitializeSpinLock(&PsProcessListLock
);
217 * Initialize the system process
219 Status
= ObRosCreateObject(NULL
,
223 (PVOID
*)&PsInitialSystemProcess
);
224 if (!NT_SUCCESS(Status
))
229 /* System threads may run on any processor. */
230 PsInitialSystemProcess
->Pcb
.Affinity
= 0xFFFFFFFF;
231 PsInitialSystemProcess
->Pcb
.BasePriority
= PROCESS_PRIO_NORMAL
;
232 KeInitializeDispatcherHeader(&PsInitialSystemProcess
->Pcb
.DispatcherHeader
,
236 KProcess
= &PsInitialSystemProcess
->Pcb
;
238 MmInitializeAddressSpace(PsInitialSystemProcess
,
239 &PsInitialSystemProcess
->AddressSpace
);
240 ObCreateHandleTable(NULL
,FALSE
,PsInitialSystemProcess
);
241 KProcess
->DirectoryTableBase
=
242 (LARGE_INTEGER
)(LONGLONG
)(ULONG
)MmGetPageDirectory();
243 PsInitialSystemProcess
->UniqueProcessId
=
244 InterlockedIncrement(&PiNextProcessUniqueId
);
245 PsInitialSystemProcess
->Win32WindowStation
= (HANDLE
)0;
246 PsInitialSystemProcess
->Win32Desktop
= (HANDLE
)0;
248 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
249 InsertHeadList(&PsProcessListHead
,
250 &PsInitialSystemProcess
->ProcessListEntry
);
251 InitializeListHead(&PsInitialSystemProcess
->ThreadListHead
);
252 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
254 strcpy(PsInitialSystemProcess
->ImageFileName
, "SYSTEM");
256 Status
= SepCreateSystemProcessToken(PsInitialSystemProcess
);
257 if (!NT_SUCCESS(Status
))
259 assertmsg(FALSE
, ("SepCreateSystemProcessToken() failed with status 0x%.08x\n", Status
));
263 ObCreateHandle(PsInitialSystemProcess
,
264 PsInitialSystemProcess
,
267 &SystemProcessHandle
);
271 PiDeleteProcess(PVOID ObjectBody
)
277 DPRINT("PiDeleteProcess(ObjectBody %x)\n",ObjectBody
);
279 Process
= (PEPROCESS
)ObjectBody
;
280 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
281 for (i
= 0; i
< PiProcessNotifyRoutineCount
; i
++)
283 PiProcessNotifyRoutine
[i
](Process
->InheritedFromUniqueProcessId
,
284 (HANDLE
)Process
->UniqueProcessId
,
287 RemoveEntryList(&Process
->ProcessListEntry
);
288 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
291 KDB_DELETEPROCESS_HOOK(Process
->Peb
);
293 ObDereferenceObject(Process
->Token
);
295 (VOID
)MmReleaseMmInfo(Process
);
296 ObDeleteHandleTable(Process
);
301 PsCreatePeb(HANDLE ProcessHandle
,
311 memset(&Peb
, 0, sizeof(Peb
));
312 Peb
.ImageBaseAddress
= ImageBase
;
314 PebBase
= (PVOID
)PEB_BASE
;
316 Status
= NtAllocateVirtualMemory(ProcessHandle
,
320 MEM_RESERVE
| MEM_COMMIT
,
322 if (!NT_SUCCESS(Status
))
327 NtWriteVirtualMemory(ProcessHandle
,
333 DPRINT("PsCreatePeb: Peb created at %x\n", PebBase
);
337 return(STATUS_SUCCESS
);
342 KeGetCurrentProcess(VOID
)
344 * FUNCTION: Returns a pointer to the current process
347 return(&(PsGetCurrentProcess()->Pcb
));
351 PsGetCurrentProcessId(VOID
)
353 return((HANDLE
)PsGetCurrentProcess()->UniqueProcessId
);
356 #undef PsGetCurrentProcess
359 * FUNCTION: Returns a pointer to the current process
362 PsGetCurrentProcess(VOID
)
364 if (PsGetCurrentThread() == NULL
||
365 PsGetCurrentThread()->ThreadsProcess
== NULL
)
367 return(PsInitialSystemProcess
);
371 return(PsGetCurrentThread()->ThreadsProcess
);
376 IoGetCurrentProcess(VOID
)
378 return(PsGetCurrentProcess());
382 PsCreateSystemProcess(PHANDLE ProcessHandle
,
383 ACCESS_MASK DesiredAccess
,
384 POBJECT_ATTRIBUTES ObjectAttributes
)
386 return NtCreateProcess(ProcessHandle
,
397 NtCreateProcess(OUT PHANDLE ProcessHandle
,
398 IN ACCESS_MASK DesiredAccess
,
399 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
400 IN HANDLE ParentProcessHandle
,
401 IN BOOLEAN InheritObjectTable
,
402 IN HANDLE SectionHandle OPTIONAL
,
403 IN HANDLE DebugPortHandle OPTIONAL
,
404 IN HANDLE ExceptionPortHandle OPTIONAL
)
406 * FUNCTION: Creates a process.
408 * ProcessHandle (OUT) = Caller supplied storage for the resulting
410 * DesiredAccess = Specifies the allowed or desired access to the
411 * process can be a combination of
412 * STANDARD_RIGHTS_REQUIRED| ..
413 * ObjectAttribute = Initialized attributes for the object, contains
414 * the rootdirectory and the filename
415 * ParentProcess = Handle to the parent process.
416 * InheritObjectTable = Specifies to inherit the objects of the parent
418 * SectionHandle = Handle to a section object to back the image file
419 * DebugPort = Handle to a DebugPort if NULL the system default debug
421 * ExceptionPort = Handle to a exception port.
423 * This function maps to the win32 CreateProcess.
428 PEPROCESS ParentProcess
;
432 PVOID LdrStartupAddr
;
436 PEPORT ExceptionPort
;
438 PMEMORY_AREA MemoryArea
;
441 DPRINT("NtCreateProcess(ObjectAttributes %x)\n",ObjectAttributes
);
443 Status
= ObReferenceObjectByHandle(ParentProcessHandle
,
444 PROCESS_CREATE_PROCESS
,
447 (PVOID
*)&ParentProcess
,
449 if (!NT_SUCCESS(Status
))
451 DPRINT("NtCreateProcess() = %x\n",Status
);
455 Status
= ObRosCreateObject(ProcessHandle
,
460 if (!NT_SUCCESS(Status
))
462 ObDereferenceObject(ParentProcess
);
463 DPRINT("ObRosCreateObject() = %x\n",Status
);
467 KeInitializeDispatcherHeader(&Process
->Pcb
.DispatcherHeader
,
471 KProcess
= &Process
->Pcb
;
472 /* Inherit parent process's affinity. */
473 KProcess
->Affinity
= ParentProcess
->Pcb
.Affinity
;
474 KProcess
->BasePriority
= PROCESS_PRIO_NORMAL
;
475 MmInitializeAddressSpace(Process
,
476 &Process
->AddressSpace
);
477 Process
->UniqueProcessId
= InterlockedIncrement(&PiNextProcessUniqueId
);
478 Process
->InheritedFromUniqueProcessId
=
479 (HANDLE
)ParentProcess
->UniqueProcessId
;
480 ObCreateHandleTable(ParentProcess
,
483 MmCopyMmInfo(ParentProcess
, Process
);
484 if (ParentProcess
->Win32WindowStation
!= (HANDLE
)0)
486 /* Always duplicate the process window station. */
487 Process
->Win32WindowStation
= 0;
488 Status
= ObDuplicateObject(ParentProcess
,
490 ParentProcess
->Win32WindowStation
,
491 &Process
->Win32WindowStation
,
494 DUPLICATE_SAME_ACCESS
);
495 if (!NT_SUCCESS(Status
))
502 Process
->Win32WindowStation
= (HANDLE
)0;
504 if (ParentProcess
->Win32Desktop
!= (HANDLE
)0)
506 /* Always duplicate the process window station. */
507 Process
->Win32Desktop
= 0;
508 Status
= ObDuplicateObject(ParentProcess
,
510 ParentProcess
->Win32Desktop
,
511 &Process
->Win32Desktop
,
514 DUPLICATE_SAME_ACCESS
);
515 if (!NT_SUCCESS(Status
))
522 Process
->Win32Desktop
= (HANDLE
)0;
525 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
526 for (i
= 0; i
< PiProcessNotifyRoutineCount
; i
++)
528 PiProcessNotifyRoutine
[i
](Process
->InheritedFromUniqueProcessId
,
529 (HANDLE
)Process
->UniqueProcessId
,
532 InsertHeadList(&PsProcessListHead
, &Process
->ProcessListEntry
);
533 InitializeListHead(&Process
->ThreadListHead
);
534 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
536 Process
->Pcb
.State
= PROCESS_STATE_ACTIVE
;
541 if (DebugPortHandle
!= NULL
)
543 Status
= ObReferenceObjectByHandle(DebugPortHandle
,
549 if (!NT_SUCCESS(Status
))
551 ObDereferenceObject(Process
);
552 ObDereferenceObject(ParentProcess
);
553 ZwClose(*ProcessHandle
);
554 *ProcessHandle
= NULL
;
557 Process
->DebugPort
= DebugPort
;
561 * Add the exception port
563 if (ExceptionPortHandle
!= NULL
)
565 Status
= ObReferenceObjectByHandle(ExceptionPortHandle
,
569 (PVOID
*)&ExceptionPort
,
571 if (!NT_SUCCESS(Status
))
573 ObDereferenceObject(Process
);
574 ObDereferenceObject(ParentProcess
);
575 ZwClose(*ProcessHandle
);
576 *ProcessHandle
= NULL
;
579 Process
->ExceptionPort
= ExceptionPort
;
583 * Now we have created the process proper
587 * Create the shared data page
589 MmLockAddressSpace(&Process
->AddressSpace
);
590 BaseAddress
= (PVOID
)USER_SHARED_DATA
;
591 Status
= MmCreateMemoryArea(Process
,
592 &Process
->AddressSpace
,
593 MEMORY_AREA_SHARED_DATA
,
599 MmUnlockAddressSpace(&Process
->AddressSpace
);
600 if (!NT_SUCCESS(Status
))
602 DPRINT1("Failed to create shared data page\n");
609 Status
= LdrpMapSystemDll(*ProcessHandle
,
611 if (!NT_SUCCESS(Status
))
613 DbgPrint("LdrpMapSystemDll failed (Status %x)\n", Status
);
614 ObDereferenceObject(Process
);
615 ObDereferenceObject(ParentProcess
);
620 * Map the process image
622 if (SectionHandle
!= NULL
)
624 DPRINT("Mapping process image\n");
625 Status
= LdrpMapImage(*ProcessHandle
,
628 if (!NT_SUCCESS(Status
))
630 DbgPrint("LdrpMapImage failed (Status %x)\n", Status
);
631 ObDereferenceObject(Process
);
632 ObDereferenceObject(ParentProcess
);
642 * Duplicate the token
644 Status
= SepInitializeNewProcess(Process
, ParentProcess
);
645 if (!NT_SUCCESS(Status
))
647 DbgPrint("SepInitializeNewProcess failed (Status %x)\n", Status
);
648 ObDereferenceObject(Process
);
649 ObDereferenceObject(ParentProcess
);
656 DPRINT("Creating PEB\n");
657 Status
= PsCreatePeb(*ProcessHandle
,
660 if (!NT_SUCCESS(Status
))
662 DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status
);
663 ObDereferenceObject(Process
);
664 ObDereferenceObject(ParentProcess
);
665 ZwClose(*ProcessHandle
);
666 *ProcessHandle
= NULL
;
672 * Maybe send a message to the creator process's debugger
675 if (ParentProcess
->DebugPort
!= NULL
)
677 LPC_DBG_MESSAGE Message
;
680 ObCreateHandle(NULL
, // Debugger Process
681 NULL
, // SectionHandle
686 Message
.Header
.MessageSize
= sizeof(LPC_DBG_MESSAGE
);
687 Message
.Header
.DataSize
= sizeof(LPC_DBG_MESSAGE
) -
688 sizeof(LPC_MESSAGE_HEADER
);
689 Message
.Type
= DBG_EVENT_CREATE_PROCESS
;
690 Message
.Data
.CreateProcess
.FileHandle
= FileHandle
;
691 Message
.Data
.CreateProcess
.Base
= ImageBase
;
692 Message
.Data
.CreateProcess
.EntryPoint
= NULL
; //
694 Status
= LpcSendDebugMessagePort(ParentProcess
->DebugPort
,
699 ObDereferenceObject(Process
);
700 ObDereferenceObject(ParentProcess
);
701 return(STATUS_SUCCESS
);
706 NtOpenProcess(OUT PHANDLE ProcessHandle
,
707 IN ACCESS_MASK DesiredAccess
,
708 IN POBJECT_ATTRIBUTES ObjectAttributes
,
709 IN PCLIENT_ID ClientId
)
711 DPRINT("NtOpenProcess(ProcessHandle %x, DesiredAccess %x, "
712 "ObjectAttributes %x, ClientId %x { UniP %d, UniT %d })\n",
713 ProcessHandle
, DesiredAccess
, ObjectAttributes
, ClientId
,
714 ClientId
->UniqueProcess
, ClientId
->UniqueThread
);
718 * Not sure of the exact semantics
720 if (ObjectAttributes
!= NULL
&& ObjectAttributes
->ObjectName
!= NULL
&&
721 ObjectAttributes
->ObjectName
->Buffer
!= NULL
)
726 Status
= ObReferenceObjectByName(ObjectAttributes
->ObjectName
,
727 ObjectAttributes
->Attributes
,
734 if (Status
!= STATUS_SUCCESS
)
739 Status
= ObCreateHandle(PsGetCurrentProcess(),
744 ObDereferenceObject(Process
);
751 PLIST_ENTRY current_entry
;
755 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
756 current_entry
= PsProcessListHead
.Flink
;
757 while (current_entry
!= &PsProcessListHead
)
759 current
= CONTAINING_RECORD(current_entry
, EPROCESS
,
761 if (current
->UniqueProcessId
== (ULONG
)ClientId
->UniqueProcess
)
763 ObReferenceObjectByPointer(current
,
767 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
768 Status
= ObCreateHandle(PsGetCurrentProcess(),
773 ObDereferenceObject(current
);
774 DPRINT("*ProcessHandle %x\n", ProcessHandle
);
775 DPRINT("NtOpenProcess() = %x\n", Status
);
778 current_entry
= current_entry
->Flink
;
780 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
781 DPRINT("NtOpenProcess() = STATUS_UNSUCCESSFUL\n");
782 return(STATUS_UNSUCCESSFUL
);
784 return(STATUS_UNSUCCESSFUL
);
789 NtQueryInformationProcess(IN HANDLE ProcessHandle
,
790 IN PROCESSINFOCLASS ProcessInformationClass
,
791 OUT PVOID ProcessInformation
,
792 IN ULONG ProcessInformationLength
,
793 OUT PULONG ReturnLength OPTIONAL
)
797 PPROCESS_BASIC_INFORMATION ProcessBasicInformationP
;
799 Status
= ObReferenceObjectByHandle(ProcessHandle
,
800 PROCESS_SET_INFORMATION
,
805 if (Status
!= STATUS_SUCCESS
)
810 switch (ProcessInformationClass
)
812 case ProcessBasicInformation
:
813 ProcessBasicInformationP
= (PPROCESS_BASIC_INFORMATION
)
815 ProcessBasicInformationP
->ExitStatus
= Process
->ExitStatus
;
816 ProcessBasicInformationP
->PebBaseAddress
= Process
->Peb
;
817 ProcessBasicInformationP
->AffinityMask
= Process
->Pcb
.Affinity
;
818 ProcessBasicInformationP
->UniqueProcessId
=
819 Process
->UniqueProcessId
;
820 ProcessBasicInformationP
->InheritedFromUniqueProcessId
=
821 (ULONG
)Process
->InheritedFromUniqueProcessId
;
822 Status
= STATUS_SUCCESS
;
825 case ProcessQuotaLimits
:
826 case ProcessIoCounters
:
827 case ProcessVmCounters
:
829 case ProcessDebugPort
:
830 case ProcessLdtInformation
:
831 Status
= STATUS_NOT_IMPLEMENTED
;
834 case ProcessDefaultHardErrorMode
:
835 *((PULONG
)ProcessInformation
) = Process
->DefaultHardErrorProcessing
;
838 case ProcessWorkingSetWatch
:
839 Status
= STATUS_NOT_IMPLEMENTED
;
842 case ProcessWx86Information
:
843 case ProcessHandleCount
:
844 case ProcessPriorityBoost
:
845 case ProcessDeviceMap
:
846 case ProcessSessionInformation
:
847 case ProcessWow64Information
:
848 Status
= STATUS_NOT_IMPLEMENTED
;
851 case ProcessBasePriority
:
852 case ProcessRaisePriority
:
853 case ProcessExceptionPort
:
854 case ProcessAccessToken
:
856 case ProcessIoPortHandlers
:
857 case ProcessUserModeIOPL
:
858 case ProcessEnableAlignmentFaultFixup
:
859 case ProcessPriorityClass
:
860 case ProcessAffinityMask
:
861 case ProcessForegroundInformation
:
863 Status
= STATUS_INVALID_INFO_CLASS
;
865 ObDereferenceObject(Process
);
870 PspAssignPrimaryToken(PEPROCESS Process
,
873 PIACCESS_TOKEN iToken
;
874 PIACCESS_TOKEN OldToken
;
877 Status
= ObReferenceObjectByHandle(TokenHandle
,
883 if (!NT_SUCCESS(Status
))
887 Status
= SeExchangePrimaryToken(Process
, iToken
, &OldToken
);
888 if (NT_SUCCESS(Status
))
890 ObDereferenceObject(OldToken
);
892 ObDereferenceObject(iToken
);
897 NtSetInformationProcess(IN HANDLE ProcessHandle
,
898 IN PROCESSINFOCLASS ProcessInformationClass
,
899 IN PVOID ProcessInformation
,
900 IN ULONG ProcessInformationLength
)
904 PHANDLE ProcessAccessTokenP
;
906 Status
= ObReferenceObjectByHandle(ProcessHandle
,
907 PROCESS_SET_INFORMATION
,
912 if (!NT_SUCCESS(Status
))
917 switch (ProcessInformationClass
)
919 case ProcessQuotaLimits
:
920 case ProcessBasePriority
:
921 case ProcessRaisePriority
:
922 case ProcessDebugPort
:
923 case ProcessExceptionPort
:
924 Status
= STATUS_NOT_IMPLEMENTED
;
927 case ProcessAccessToken
:
928 ProcessAccessTokenP
= (PHANDLE
)ProcessInformation
;
929 Status
= PspAssignPrimaryToken(Process
, *ProcessAccessTokenP
);
932 case ProcessImageFileName
:
933 memcpy(Process
->ImageFileName
, ProcessInformation
, 8);
934 Status
= STATUS_SUCCESS
;
937 case ProcessLdtInformation
:
939 case ProcessDefaultHardErrorMode
:
940 case ProcessIoPortHandlers
:
941 case ProcessWorkingSetWatch
:
942 case ProcessUserModeIOPL
:
943 case ProcessEnableAlignmentFaultFixup
:
944 case ProcessPriorityClass
:
945 case ProcessAffinityMask
:
946 Status
= STATUS_NOT_IMPLEMENTED
;
949 case ProcessBasicInformation
:
950 case ProcessIoCounters
:
951 case ProcessVmCounters
:
953 case ProcessPooledUsageAndLimits
:
954 case ProcessWx86Information
:
955 case ProcessHandleCount
:
956 case ProcessWow64Information
:
958 Status
= STATUS_INVALID_INFO_CLASS
;
961 Process
->Win32Desktop
= *(PHANDLE
)ProcessInformation
;
962 Status
= STATUS_SUCCESS
;
965 ObDereferenceObject(Process
);
970 /**********************************************************************
972 * PiQuerySystemProcessInformation
975 * Compute the size of a process+thread snapshot as
976 * expected by NtQuerySystemInformation.
979 * 0 on error; otherwise the size, in bytes of the buffer
980 * required to write a full snapshot.
983 * We assume (sizeof (PVOID) == sizeof (ULONG)) holds.
986 PiQuerySystemProcessInformation(PVOID Buffer
,
990 return STATUS_NOT_IMPLEMENTED
;
994 PLIST_ENTRY CurrentEntryP
;
996 PLIST_ENTRY CurrentEntryT
;
999 ULONG RequiredSize
= 0L;
1000 BOOLEAN SizeOnly
= FALSE
;
1004 PSYSTEM_PROCESS_INFORMATION pInfoP
= (PSYSTEM_PROCESS_INFORMATION
) SnapshotBuffer
;
1005 PSYSTEM_PROCESS_INFORMATION pInfoPLast
= NULL
;
1006 PSYSTEM_THREAD_INFO pInfoT
= NULL
;
1009 /* Lock the process list. */
1010 KeAcquireSpinLock(&PsProcessListLock
,
1014 * Scan the process list. Since the
1015 * list is circular, the guard is false
1016 * after the last process.
1018 for ( CurrentEntryP
= PsProcessListHead
.Flink
;
1019 (CurrentEntryP
!= & PsProcessListHead
);
1020 CurrentEntryP
= CurrentEntryP
->Flink
1024 * Compute how much space is
1025 * occupied in the snapshot
1026 * by adding this process info.
1027 * (at least one thread).
1029 SpiSizeCurrent
= sizeof (SYSTEM_PROCESS_INFORMATION
);
1030 RequiredSize
+= SpiSizeCurrent
;
1032 * Do not write process data in the
1033 * buffer if it is too small.
1035 if (TRUE
== SizeOnly
) continue;
1037 * Check if the buffer can contain
1038 * the full snapshot.
1040 if (Size
< RequiredSize
)
1046 * Get a reference to the
1047 * process descriptor we are
1050 CurrentP
= CONTAINING_RECORD(
1056 * Write process data in the buffer.
1058 RtlZeroMemory (pInfoP
, sizeof (SYSTEM_PROCESS_INFORMATION
));
1060 pInfoP
->ThreadCount
= 0L;
1061 pInfoP
->ProcessId
= CurrentP
->UniqueProcessId
;
1062 RtlInitUnicodeString (
1064 CurrentP
->ImageFileName
1067 for ( pInfoT
= & CurrentP
->ThreadSysInfo
[0],
1068 CurrentEntryT
= CurrentP
->ThreadListHead
.Flink
;
1070 (CurrentEntryT
!= & CurrentP
->ThreadListHead
);
1072 pInfoT
= & CurrentP
->ThreadSysInfo
[pInfoP
->ThreadCount
],
1073 CurrentEntryT
= CurrentEntryT
->Flink
1077 * Recalculate the size of the
1078 * information block.
1080 if (0 < pInfoP
->ThreadCount
)
1082 RequiredSize
+= sizeof (SYSTEM_THREAD_INFORMATION
);
1085 * Do not write thread data in the
1086 * buffer if it is too small.
1088 if (TRUE
== SizeOnly
) continue;
1090 * Check if the buffer can contain
1091 * the full snapshot.
1093 if (Size
< RequiredSize
)
1099 * Get a reference to the
1100 * thread descriptor we are
1103 CurrentT
= CONTAINING_RECORD(
1109 * Write thread data.
1113 sizeof (SYSTEM_THREAD_INFORMATION
)
1115 pInfoT
->KernelTime
= CurrentT
-> ; /* TIME */
1116 pInfoT
->UserTime
= CurrentT
-> ; /* TIME */
1117 pInfoT
->CreateTime
= CurrentT
-> ; /* TIME */
1118 pInfoT
->TickCount
= CurrentT
-> ; /* ULONG */
1119 pInfoT
->StartEIP
= CurrentT
-> ; /* ULONG */
1120 pInfoT
->ClientId
= CurrentT
-> ; /* CLIENT_ID */
1121 pInfoT
->ClientId
= CurrentT
-> ; /* CLIENT_ID */
1122 pInfoT
->DynamicPriority
= CurrentT
-> ; /* ULONG */
1123 pInfoT
->BasePriority
= CurrentT
-> ; /* ULONG */
1124 pInfoT
->nSwitches
= CurrentT
-> ; /* ULONG */
1125 pInfoT
->State
= CurrentT
-> ; /* DWORD */
1126 pInfoT
->WaitReason
= CurrentT
-> ; /* KWAIT_REASON */
1128 * Count the number of threads
1131 ++ pInfoP
->ThreadCount
;
1134 * Save the size of information
1135 * stored in the buffer for the
1138 pInfoP
->RelativeOffset
= SpiSize
;
1140 * Save a reference to the last
1141 * valid information block.
1143 pInfoPLast
= pInfoP
;
1145 * Compute the offset of the
1146 * SYSTEM_PROCESS_INFORMATION
1147 * descriptor in the snapshot
1148 * buffer for the next process.
1150 (ULONG
) pInfoP
+= SpiSize
;
1153 * Unlock the process list.
1156 & PsProcessListLock
,
1160 * Return the proper error status code,
1161 * if the buffer was too small.
1163 if (TRUE
== SizeOnly
)
1165 if (NULL
!= RequiredSize
)
1167 *pRequiredSize
= RequiredSize
;
1169 return STATUS_INFO_LENGTH_MISMATCH
;
1172 * Mark the end of the snapshot.
1174 pInfoP
->RelativeOffset
= 0L;
1176 return STATUS_SUCCESS
;
1181 PsGetProcessExitTime(VOID
)
1183 return PsGetCurrentProcess()->ExitTime
.QuadPart
;
1187 PsIsThreadTerminating(IN PETHREAD Thread
)
1189 return(Thread
->DeadThread
);
1194 PsLookupProcessByProcessId(IN PVOID ProcessId
,
1195 OUT PEPROCESS
*Process
)
1198 PLIST_ENTRY current_entry
;
1201 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
1203 current_entry
= PsProcessListHead
.Flink
;
1204 while (current_entry
!= &PsProcessListHead
)
1206 current
= CONTAINING_RECORD(current_entry
,
1209 if (current
->UniqueProcessId
== (ULONG
)ProcessId
)
1212 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
1213 return(STATUS_SUCCESS
);
1215 current_entry
= current_entry
->Flink
;
1218 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
1220 return(STATUS_INVALID_PARAMETER
);
1225 PsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine
,
1228 if (PiProcessNotifyRoutineCount
>= MAX_PROCESS_NOTIFY_ROUTINE_COUNT
)
1229 return(STATUS_INSUFFICIENT_RESOURCES
);
1231 PiProcessNotifyRoutine
[PiProcessNotifyRoutineCount
] = NotifyRoutine
;
1232 PiProcessNotifyRoutineCount
++;
1234 return(STATUS_SUCCESS
);