1 /* $Id: process.c,v 1.75 2002/01/03 17:59:09 ekohl 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 #define MAX_PROCESS_NOTIFY_ROUTINE_COUNT 8
51 static ULONG PiProcessNotifyRoutineCount
= 0;
52 static PCREATE_PROCESS_NOTIFY_ROUTINE
53 PiProcessNotifyRoutine
[MAX_PROCESS_NOTIFY_ROUTINE_COUNT
];
55 /* FUNCTIONS *****************************************************************/
59 PsGetNextProcess(PEPROCESS OldProcess
)
62 PEPROCESS NextProcess
;
65 if (OldProcess
== NULL
)
67 return(PsInitialSystemProcess
);
70 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
71 if (OldProcess
->ProcessListEntry
.Flink
== &PsProcessListHead
)
73 NextProcess
= CONTAINING_RECORD(PsProcessListHead
.Flink
,
79 NextProcess
= CONTAINING_RECORD(OldProcess
->ProcessListEntry
.Flink
,
83 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
84 Status
= ObReferenceObjectByPointer(NextProcess
,
88 if (!NT_SUCCESS(Status
))
90 DbgPrint("PsGetNextProcess(): ObReferenceObjectByPointer failed\n");
93 ObDereferenceObject(OldProcess
);
99 NtOpenProcessToken(IN HANDLE ProcessHandle
,
100 IN ACCESS_MASK DesiredAccess
,
101 OUT PHANDLE TokenHandle
)
103 return(STATUS_UNSUCCESSFUL
);
107 _NtOpenProcessToken(IN HANDLE ProcessHandle
,
108 IN ACCESS_MASK DesiredAccess
,
109 OUT PHANDLE TokenHandle
)
114 Status
= PsOpenTokenOfProcess(ProcessHandle
,
116 if (!NT_SUCCESS(Status
))
120 Status
= ObCreateHandle(PsGetCurrentProcess(),
125 ObDereferenceObject(Token
);
130 PACCESS_TOKEN STDCALL
131 PsReferencePrimaryToken(PEPROCESS Process
)
133 ObReferenceObjectByPointer(Process
->Token
,
137 return(Process
->Token
);
142 PsOpenTokenOfProcess(HANDLE ProcessHandle
,
143 PACCESS_TOKEN
* Token
)
148 Status
= ObReferenceObjectByHandle(ProcessHandle
,
149 PROCESS_QUERY_INFORMATION
,
154 if (!NT_SUCCESS(Status
))
158 *Token
= PsReferencePrimaryToken(Process
);
159 ObDereferenceObject(Process
);
160 return(STATUS_SUCCESS
);
165 PiKillMostProcesses(VOID
)
168 PLIST_ENTRY current_entry
;
171 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
173 current_entry
= PsProcessListHead
.Flink
;
174 while (current_entry
!= &PsProcessListHead
)
176 current
= CONTAINING_RECORD(current_entry
, EPROCESS
,
178 current_entry
= current_entry
->Flink
;
180 if (current
->UniqueProcessId
!= PsInitialSystemProcess
->UniqueProcessId
&&
181 current
->UniqueProcessId
!= (ULONG
)PsGetCurrentProcessId())
183 PiTerminateProcessThreads(current
, STATUS_SUCCESS
);
187 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
192 PsInitProcessManagment(VOID
)
200 * Register the process object type
203 PsProcessType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
205 PsProcessType
->Tag
= TAG('P', 'R', 'O', 'C');
206 PsProcessType
->TotalObjects
= 0;
207 PsProcessType
->TotalHandles
= 0;
208 PsProcessType
->MaxObjects
= ULONG_MAX
;
209 PsProcessType
->MaxHandles
= ULONG_MAX
;
210 PsProcessType
->PagedPoolCharge
= 0;
211 PsProcessType
->NonpagedPoolCharge
= sizeof(EPROCESS
);
212 PsProcessType
->Mapping
= &PiProcessMapping
;
213 PsProcessType
->Dump
= NULL
;
214 PsProcessType
->Open
= NULL
;
215 PsProcessType
->Close
= NULL
;
216 PsProcessType
->Delete
= PiDeleteProcess
;
217 PsProcessType
->Parse
= NULL
;
218 PsProcessType
->Security
= NULL
;
219 PsProcessType
->QueryName
= NULL
;
220 PsProcessType
->OkayToClose
= NULL
;
221 PsProcessType
->Create
= NULL
;
222 PsProcessType
->DuplicationNotify
= NULL
;
224 RtlInitUnicodeString(&PsProcessType
->TypeName
, L
"Process");
226 InitializeListHead(&PsProcessListHead
);
227 KeInitializeSpinLock(&PsProcessListLock
);
230 * Initialize the system process
232 Status
= ObCreateObject(NULL
,
236 (PVOID
*)&PsInitialSystemProcess
);
237 if (!NT_SUCCESS(Status
))
242 /* System threads may run on any processor. */
243 PsInitialSystemProcess
->Pcb
.Affinity
= 0xFFFFFFFF;
244 PsInitialSystemProcess
->Pcb
.BasePriority
= PROCESS_PRIO_NORMAL
;
245 KeInitializeDispatcherHeader(&PsInitialSystemProcess
->Pcb
.DispatcherHeader
,
249 KProcess
= &PsInitialSystemProcess
->Pcb
;
251 MmInitializeAddressSpace(PsInitialSystemProcess
,
252 &PsInitialSystemProcess
->AddressSpace
);
253 ObCreateHandleTable(NULL
,FALSE
,PsInitialSystemProcess
);
254 KProcess
->DirectoryTableBase
[0] = MmGetPageDirectory();
255 PsInitialSystemProcess
->UniqueProcessId
=
256 InterlockedIncrement(&PiNextProcessUniqueId
);
258 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
259 InsertHeadList(&PsProcessListHead
,
260 &PsInitialSystemProcess
->ProcessListEntry
);
261 InitializeListHead(&PsInitialSystemProcess
->ThreadListHead
);
262 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
264 strcpy(PsInitialSystemProcess
->ImageFileName
, "SYSTEM");
266 ObCreateHandle(PsInitialSystemProcess
,
267 PsInitialSystemProcess
,
270 &SystemProcessHandle
);
276 PiFreeSymbols(PPEB Peb
)
278 PLIST_ENTRY CurrentEntry
;
286 CurrentEntry
= Peb
->Ldr
->InLoadOrderModuleList
.Flink
;
287 while ((CurrentEntry
!= &Peb
->Ldr
->InLoadOrderModuleList
) && (CurrentEntry
!= NULL
))
289 Current
= CONTAINING_RECORD (CurrentEntry
, LDR_MODULE
, InLoadOrderModuleList
);
290 Symbol
= Current
->Symbols
.Symbols
;
291 while (Symbol
!= NULL
)
293 NextSymbol
= Symbol
->Next
;
294 RtlFreeUnicodeString (&Symbol
->Name
);
298 Current
->Symbols
.SymbolCount
= 0;
299 Current
->Symbols
.Symbols
= NULL
;
300 CurrentEntry
= CurrentEntry
->Flink
;
307 PiDeleteProcess(PVOID ObjectBody
)
313 DPRINT("PiDeleteProcess(ObjectBody %x)\n",ObjectBody
);
315 Process
= (PEPROCESS
)Process
;
316 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
317 for (i
= 0; i
< PiProcessNotifyRoutineCount
; i
++)
319 PiProcessNotifyRoutine
[i
](Process
->InheritedFromUniqueProcessId
,
320 (HANDLE
)Process
->UniqueProcessId
,
323 RemoveEntryList(&Process
->ProcessListEntry
);
324 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
327 PiFreeSymbols(Process
->Peb
);
330 (VOID
)MmReleaseMmInfo(Process
);
331 ObDeleteHandleTable(Process
);
336 PsCreatePeb(HANDLE ProcessHandle
,
346 memset(&Peb
, 0, sizeof(Peb
));
347 Peb
.ImageBaseAddress
= ImageBase
;
349 PebBase
= (PVOID
)PEB_BASE
;
351 Status
= NtAllocateVirtualMemory(ProcessHandle
,
355 MEM_RESERVE
| MEM_COMMIT
,
357 if (!NT_SUCCESS(Status
))
362 NtWriteVirtualMemory(ProcessHandle
,
368 DPRINT("PsCreatePeb: Peb created at %x\n", PebBase
);
372 return(STATUS_SUCCESS
);
377 KeGetCurrentProcess(VOID
)
379 * FUNCTION: Returns a pointer to the current process
382 return(&(PsGetCurrentProcess()->Pcb
));
386 PsGetCurrentProcessId(VOID
)
388 return((HANDLE
)PsGetCurrentProcess()->UniqueProcessId
);
392 * FUNCTION: Returns a pointer to the current process
395 PsGetCurrentProcess(VOID
)
397 if (PsGetCurrentThread() == NULL
||
398 PsGetCurrentThread()->ThreadsProcess
== NULL
)
400 return(PsInitialSystemProcess
);
404 return(PsGetCurrentThread()->ThreadsProcess
);
409 IoGetCurrentProcess(VOID
)
411 return(PsGetCurrentProcess());
415 PsCreateSystemProcess(PHANDLE ProcessHandle
,
416 ACCESS_MASK DesiredAccess
,
417 POBJECT_ATTRIBUTES ObjectAttributes
)
419 return NtCreateProcess(ProcessHandle
,
430 NtCreateProcess(OUT PHANDLE ProcessHandle
,
431 IN ACCESS_MASK DesiredAccess
,
432 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
433 IN HANDLE ParentProcessHandle
,
434 IN BOOLEAN InheritObjectTable
,
435 IN HANDLE SectionHandle OPTIONAL
,
436 IN HANDLE DebugPortHandle OPTIONAL
,
437 IN HANDLE ExceptionPortHandle OPTIONAL
)
439 * FUNCTION: Creates a process.
441 * ProcessHandle (OUT) = Caller supplied storage for the resulting
443 * DesiredAccess = Specifies the allowed or desired access to the
444 * process can be a combination of
445 * STANDARD_RIGHTS_REQUIRED| ..
446 * ObjectAttribute = Initialized attributes for the object, contains
447 * the rootdirectory and the filename
448 * ParentProcess = Handle to the parent process.
449 * InheritObjectTable = Specifies to inherit the objects of the parent
451 * SectionHandle = Handle to a section object to back the image file
452 * DebugPort = Handle to a DebugPort if NULL the system default debug
454 * ExceptionPort = Handle to a exception port.
456 * This function maps to the win32 CreateProcess.
461 PEPROCESS ParentProcess
;
465 PVOID LdrStartupAddr
;
469 PEPORT ExceptionPort
;
471 PMEMORY_AREA MemoryArea
;
474 DPRINT("NtCreateProcess(ObjectAttributes %x)\n",ObjectAttributes
);
476 Status
= ObReferenceObjectByHandle(ParentProcessHandle
,
477 PROCESS_CREATE_PROCESS
,
480 (PVOID
*)&ParentProcess
,
482 if (!NT_SUCCESS(Status
))
484 DPRINT("NtCreateProcess() = %x\n",Status
);
488 Status
= ObCreateObject(ProcessHandle
,
493 if (!NT_SUCCESS(Status
))
495 ObDereferenceObject(ParentProcess
);
496 DPRINT("ObCreateObject() = %x\n",Status
);
500 KeInitializeDispatcherHeader(&Process
->Pcb
.DispatcherHeader
,
504 KProcess
= &Process
->Pcb
;
505 /* Inherit parent process's affinity. */
506 KProcess
->Affinity
= ParentProcess
->Pcb
.Affinity
;
507 KProcess
->BasePriority
= PROCESS_PRIO_NORMAL
;
508 MmInitializeAddressSpace(Process
,
509 &Process
->AddressSpace
);
510 Process
->UniqueProcessId
= InterlockedIncrement(&PiNextProcessUniqueId
);
511 Process
->InheritedFromUniqueProcessId
=
512 (HANDLE
)ParentProcess
->UniqueProcessId
;
513 ObCreateHandleTable(ParentProcess
,
516 MmCopyMmInfo(ParentProcess
, Process
);
518 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
519 for (i
= 0; i
< PiProcessNotifyRoutineCount
; i
++)
521 PiProcessNotifyRoutine
[i
](Process
->InheritedFromUniqueProcessId
,
522 (HANDLE
)Process
->UniqueProcessId
,
525 InsertHeadList(&PsProcessListHead
, &Process
->ProcessListEntry
);
526 InitializeListHead(&Process
->ThreadListHead
);
527 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
529 Process
->Pcb
.State
= PROCESS_STATE_ACTIVE
;
534 if (DebugPortHandle
!= NULL
)
536 Status
= ObReferenceObjectByHandle(DebugPortHandle
,
542 if (!NT_SUCCESS(Status
))
544 ObDereferenceObject(Process
);
545 ObDereferenceObject(ParentProcess
);
546 ZwClose(*ProcessHandle
);
547 *ProcessHandle
= NULL
;
550 Process
->DebugPort
= DebugPort
;
554 * Add the exception port
556 if (ExceptionPortHandle
!= NULL
)
558 Status
= ObReferenceObjectByHandle(ExceptionPortHandle
,
562 (PVOID
*)&ExceptionPort
,
564 if (!NT_SUCCESS(Status
))
566 ObDereferenceObject(Process
);
567 ObDereferenceObject(ParentProcess
);
568 ZwClose(*ProcessHandle
);
569 *ProcessHandle
= NULL
;
572 Process
->ExceptionPort
= ExceptionPort
;
576 * Now we have created the process proper
580 * Create the shared data page
582 MmLockAddressSpace(&Process
->AddressSpace
);
583 BaseAddress
= (PVOID
)USER_SHARED_DATA_BASE
;
584 Status
= MmCreateMemoryArea(Process
,
585 &Process
->AddressSpace
,
586 MEMORY_AREA_SHARED_DATA
,
592 MmUnlockAddressSpace(&Process
->AddressSpace
);
593 if (!NT_SUCCESS(Status
))
595 DPRINT1("Failed to create shared data page\n");
602 Status
= LdrpMapSystemDll(*ProcessHandle
,
604 if (!NT_SUCCESS(Status
))
606 DbgPrint("LdrpMapSystemDll failed (Status %x)\n", Status
);
607 ObDereferenceObject(Process
);
608 ObDereferenceObject(ParentProcess
);
613 * Map the process image
615 if (SectionHandle
!= NULL
)
617 DPRINT("Mapping process image\n");
618 Status
= LdrpMapImage(*ProcessHandle
,
621 if (!NT_SUCCESS(Status
))
623 DbgPrint("LdrpMapImage failed (Status %x)\n", Status
);
624 ObDereferenceObject(Process
);
625 ObDereferenceObject(ParentProcess
);
637 DPRINT("Creating PEB\n");
638 Status
= PsCreatePeb(*ProcessHandle
,
641 if (!NT_SUCCESS(Status
))
643 DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status
);
644 ObDereferenceObject(Process
);
645 ObDereferenceObject(ParentProcess
);
646 ZwClose(*ProcessHandle
);
647 *ProcessHandle
= NULL
;
653 * Maybe send a message to the creator process's debugger
656 if (ParentProcess
->DebugPort
!= NULL
)
658 LPC_DBG_MESSAGE Message
;
661 ObCreateHandle(NULL
, // Debugger Process
662 NULL
, // SectionHandle
667 Message
.Header
.MessageSize
= sizeof(LPC_DBG_MESSAGE
);
668 Message
.Header
.DataSize
= sizeof(LPC_DBG_MESSAGE
) -
669 sizeof(LPC_MESSAGE_HEADER
);
670 Message
.Type
= DBG_EVENT_CREATE_PROCESS
;
671 Message
.Data
.CreateProcess
.FileHandle
= FileHandle
;
672 Message
.Data
.CreateProcess
.Base
= ImageBase
;
673 Message
.Data
.CreateProcess
.EntryPoint
= NULL
; //
675 Status
= LpcSendDebugMessagePort(ParentProcess
->DebugPort
,
680 ObDereferenceObject(Process
);
681 ObDereferenceObject(ParentProcess
);
682 return(STATUS_SUCCESS
);
687 NtOpenProcess(OUT PHANDLE ProcessHandle
,
688 IN ACCESS_MASK DesiredAccess
,
689 IN POBJECT_ATTRIBUTES ObjectAttributes
,
690 IN PCLIENT_ID ClientId
)
692 DPRINT("NtOpenProcess(ProcessHandle %x, DesiredAccess %x, "
693 "ObjectAttributes %x, ClientId %x { UniP %d, UniT %d })\n",
694 ProcessHandle
, DesiredAccess
, ObjectAttributes
, ClientId
,
695 ClientId
->UniqueProcess
, ClientId
->UniqueThread
);
699 * Not sure of the exact semantics
701 if (ObjectAttributes
!= NULL
&& ObjectAttributes
->ObjectName
!= NULL
&&
702 ObjectAttributes
->ObjectName
->Buffer
!= NULL
)
707 Status
= ObReferenceObjectByName(ObjectAttributes
->ObjectName
,
708 ObjectAttributes
->Attributes
,
715 if (Status
!= STATUS_SUCCESS
)
720 Status
= ObCreateHandle(PsGetCurrentProcess(),
725 ObDereferenceObject(Process
);
732 PLIST_ENTRY current_entry
;
736 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
737 current_entry
= PsProcessListHead
.Flink
;
738 while (current_entry
!= &PsProcessListHead
)
740 current
= CONTAINING_RECORD(current_entry
, EPROCESS
,
742 if (current
->UniqueProcessId
== (ULONG
)ClientId
->UniqueProcess
)
744 ObReferenceObjectByPointer(current
,
748 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
749 Status
= ObCreateHandle(PsGetCurrentProcess(),
754 ObDereferenceObject(current
);
755 DPRINT("*ProcessHandle %x\n", ProcessHandle
);
756 DPRINT("NtOpenProcess() = %x\n", Status
);
759 current_entry
= current_entry
->Flink
;
761 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
762 DPRINT("NtOpenProcess() = STATUS_UNSUCCESSFUL\n");
763 return(STATUS_UNSUCCESSFUL
);
765 return(STATUS_UNSUCCESSFUL
);
770 NtQueryInformationProcess(IN HANDLE ProcessHandle
,
771 IN CINT ProcessInformationClass
,
772 OUT PVOID ProcessInformation
,
773 IN ULONG ProcessInformationLength
,
774 OUT PULONG ReturnLength
)
778 PPROCESS_BASIC_INFORMATION ProcessBasicInformationP
;
780 Status
= ObReferenceObjectByHandle(ProcessHandle
,
781 PROCESS_SET_INFORMATION
,
786 if (Status
!= STATUS_SUCCESS
)
791 switch (ProcessInformationClass
)
793 case ProcessBasicInformation
:
794 ProcessBasicInformationP
= (PPROCESS_BASIC_INFORMATION
)
796 ProcessBasicInformationP
->ExitStatus
= Process
->ExitStatus
;
797 ProcessBasicInformationP
->PebBaseAddress
= Process
->Peb
;
798 ProcessBasicInformationP
->AffinityMask
= Process
->Pcb
.Affinity
;
799 ProcessBasicInformationP
->UniqueProcessId
=
800 Process
->UniqueProcessId
;
801 ProcessBasicInformationP
->InheritedFromUniqueProcessId
=
802 (ULONG
)Process
->InheritedFromUniqueProcessId
;
803 Status
= STATUS_SUCCESS
;
806 case ProcessQuotaLimits
:
807 case ProcessIoCounters
:
808 case ProcessVmCounters
:
810 case ProcessBasePriority
:
811 case ProcessRaisePriority
:
812 case ProcessDebugPort
:
813 case ProcessExceptionPort
:
814 case ProcessAccessToken
:
815 case ProcessLdtInformation
:
817 Status
= STATUS_NOT_IMPLEMENTED
;
820 case ProcessDefaultHardErrorMode
:
821 *((PULONG
)ProcessInformation
) = Process
->DefaultHardErrorProcessing
;
824 case ProcessIoPortHandlers
:
825 case ProcessWorkingSetWatch
:
826 case ProcessUserModeIOPL
:
827 case ProcessEnableAlignmentFaultFixup
:
828 Status
= STATUS_NOT_IMPLEMENTED
;
831 case ProcessForegroundInformation
:
832 ((PPROCESS_PRIORITY_CLASS
)ProcessInformation
)->Foreground
=
833 FALSE
; /*FIXME: how to compute it? */
834 case ProcessPriorityClass
:
835 ((PPROCESS_PRIORITY_CLASS
)ProcessInformation
)->PriorityClass
=
836 Process
->PriorityClass
;
839 case ProcessWx86Information
:
840 case ProcessHandleCount
:
841 case ProcessAffinityMask
:
842 case ProcessPriorityBoost
:
843 case ProcessDeviceMap
:
844 case ProcessSessionInformation
:
845 case ProcessWow64Information
:
846 Status
= STATUS_NOT_IMPLEMENTED
;
850 Status
= STATUS_INVALID_INFO_CLASS
;
852 ObDereferenceObject(Process
);
857 PspAssignPrimaryToken(PEPROCESS Process
,
861 PACCESS_TOKEN OldToken
;
864 Status
= ObReferenceObjectByHandle(TokenHandle
,
870 if (!NT_SUCCESS(Status
))
874 Status
= SeExchangePrimaryToken(Process
, Token
, &OldToken
);
875 if (!NT_SUCCESS(Status
))
877 ObDereferenceObject(OldToken
);
879 ObDereferenceObject(Token
);
884 NtSetInformationProcess(IN HANDLE ProcessHandle
,
885 IN CINT ProcessInformationClass
,
886 IN PVOID ProcessInformation
,
887 IN ULONG ProcessInformationLength
)
891 PPROCESS_BASIC_INFORMATION ProcessBasicInformationP
;
892 PHANDLE ProcessAccessTokenP
;
894 Status
= ObReferenceObjectByHandle(ProcessHandle
,
895 PROCESS_SET_INFORMATION
,
900 if (!NT_SUCCESS(Status
))
905 switch (ProcessInformationClass
)
907 case ProcessBasicInformation
:
908 ProcessBasicInformationP
= (PPROCESS_BASIC_INFORMATION
)
910 memset(ProcessBasicInformationP
, 0, sizeof(PROCESS_BASIC_INFORMATION
));
911 Process
->Pcb
.Affinity
= ProcessBasicInformationP
->AffinityMask
;
912 Status
= STATUS_SUCCESS
;
915 case ProcessQuotaLimits
:
916 case ProcessIoCounters
:
917 case ProcessVmCounters
:
919 case ProcessBasePriority
:
920 case ProcessRaisePriority
:
921 case ProcessDebugPort
:
922 case ProcessExceptionPort
:
923 case ProcessAccessToken
:
924 ProcessAccessTokenP
= (PHANDLE
)ProcessInformation
;
925 Status
= PspAssignPrimaryToken(Process
, *ProcessAccessTokenP
);
928 case ProcessImageFileName
:
929 memcpy(Process
->ImageFileName
, ProcessInformation
, 8);
930 // DPRINT1("Process->ImageFileName %.8s\n", Process->ImageFileName);
931 Status
= STATUS_SUCCESS
;
934 case ProcessLdtInformation
:
936 case ProcessDefaultHardErrorMode
:
937 case ProcessIoPortHandlers
:
938 case ProcessWorkingSetWatch
:
939 case ProcessUserModeIOPL
:
940 case ProcessEnableAlignmentFaultFixup
:
941 case ProcessPriorityClass
:
942 case ProcessWx86Information
:
943 case ProcessHandleCount
:
944 case ProcessAffinityMask
:
946 Status
= STATUS_NOT_IMPLEMENTED
;
948 ObDereferenceObject(Process
);
953 /**********************************************************************
955 * PiQuerySystemProcessInformation
958 * Compute the size of a process+thread snapshot as
959 * expected by NtQuerySystemInformation.
962 * 0 on error; otherwise the size, in bytes of the buffer
963 * required to write a full snapshot.
966 * We assume (sizeof (PVOID) == sizeof (ULONG)) holds.
969 PiQuerySystemProcessInformation(PVOID Buffer
,
973 return STATUS_NOT_IMPLEMENTED
;
977 PLIST_ENTRY CurrentEntryP
;
979 PLIST_ENTRY CurrentEntryT
;
982 ULONG RequiredSize
= 0L;
983 BOOLEAN SizeOnly
= FALSE
;
987 PSYSTEM_PROCESS_INFORMATION pInfoP
= (PSYSTEM_PROCESS_INFORMATION
) SnapshotBuffer
;
988 PSYSTEM_PROCESS_INFORMATION pInfoPLast
= NULL
;
989 PSYSTEM_THREAD_INFO pInfoT
= NULL
;
992 /* Lock the process list. */
993 KeAcquireSpinLock(&PsProcessListLock
,
997 * Scan the process list. Since the
998 * list is circular, the guard is false
999 * after the last process.
1001 for ( CurrentEntryP
= PsProcessListHead
.Flink
;
1002 (CurrentEntryP
!= & PsProcessListHead
);
1003 CurrentEntryP
= CurrentEntryP
->Flink
1007 * Compute how much space is
1008 * occupied in the snapshot
1009 * by adding this process info.
1010 * (at least one thread).
1012 SpiSizeCurrent
= sizeof (SYSTEM_PROCESS_INFORMATION
);
1013 RequiredSize
+= SpiSizeCurrent
;
1015 * Do not write process data in the
1016 * buffer if it is too small.
1018 if (TRUE
== SizeOnly
) continue;
1020 * Check if the buffer can contain
1021 * the full snapshot.
1023 if (Size
< RequiredSize
)
1029 * Get a reference to the
1030 * process descriptor we are
1033 CurrentP
= CONTAINING_RECORD(
1039 * Write process data in the buffer.
1041 RtlZeroMemory (pInfoP
, sizeof (SYSTEM_PROCESS_INFORMATION
));
1043 pInfoP
->ThreadCount
= 0L;
1044 pInfoP
->ProcessId
= CurrentP
->UniqueProcessId
;
1045 RtlInitUnicodeString (
1047 CurrentP
->ImageFileName
1050 for ( pInfoT
= & CurrentP
->ThreadSysInfo
[0],
1051 CurrentEntryT
= CurrentP
->ThreadListHead
.Flink
;
1053 (CurrentEntryT
!= & CurrentP
->ThreadListHead
);
1055 pInfoT
= & CurrentP
->ThreadSysInfo
[pInfoP
->ThreadCount
],
1056 CurrentEntryT
= CurrentEntryT
->Flink
1060 * Recalculate the size of the
1061 * information block.
1063 if (0 < pInfoP
->ThreadCount
)
1065 RequiredSize
+= sizeof (SYSTEM_THREAD_INFORMATION
);
1068 * Do not write thread data in the
1069 * buffer if it is too small.
1071 if (TRUE
== SizeOnly
) continue;
1073 * Check if the buffer can contain
1074 * the full snapshot.
1076 if (Size
< RequiredSize
)
1082 * Get a reference to the
1083 * thread descriptor we are
1086 CurrentT
= CONTAINING_RECORD(
1092 * Write thread data.
1096 sizeof (SYSTEM_THREAD_INFORMATION
)
1098 pInfoT
->KernelTime
= CurrentT
-> ; /* TIME */
1099 pInfoT
->UserTime
= CurrentT
-> ; /* TIME */
1100 pInfoT
->CreateTime
= CurrentT
-> ; /* TIME */
1101 pInfoT
->TickCount
= CurrentT
-> ; /* ULONG */
1102 pInfoT
->StartEIP
= CurrentT
-> ; /* ULONG */
1103 pInfoT
->ClientId
= CurrentT
-> ; /* CLIENT_ID */
1104 pInfoT
->ClientId
= CurrentT
-> ; /* CLIENT_ID */
1105 pInfoT
->DynamicPriority
= CurrentT
-> ; /* ULONG */
1106 pInfoT
->BasePriority
= CurrentT
-> ; /* ULONG */
1107 pInfoT
->nSwitches
= CurrentT
-> ; /* ULONG */
1108 pInfoT
->State
= CurrentT
-> ; /* DWORD */
1109 pInfoT
->WaitReason
= CurrentT
-> ; /* KWAIT_REASON */
1111 * Count the number of threads
1114 ++ pInfoP
->ThreadCount
;
1117 * Save the size of information
1118 * stored in the buffer for the
1121 pInfoP
->RelativeOffset
= SpiSize
;
1123 * Save a reference to the last
1124 * valid information block.
1126 pInfoPLast
= pInfoP
;
1128 * Compute the offset of the
1129 * SYSTEM_PROCESS_INFORMATION
1130 * descriptor in the snapshot
1131 * buffer for the next process.
1133 (ULONG
) pInfoP
+= SpiSize
;
1136 * Unlock the process list.
1139 & PsProcessListLock
,
1143 * Return the proper error status code,
1144 * if the buffer was too small.
1146 if (TRUE
== SizeOnly
)
1148 if (NULL
!= RequiredSize
)
1150 *pRequiredSize
= RequiredSize
;
1152 return STATUS_INFO_LENGTH_MISMATCH
;
1155 * Mark the end of the snapshot.
1157 pInfoP
->RelativeOffset
= 0L;
1159 return STATUS_SUCCESS
;
1163 LARGE_INTEGER STDCALL
1164 PsGetProcessExitTime(VOID
)
1167 Li
.QuadPart
= PsGetCurrentProcess()->ExitTime
.QuadPart
;
1172 PsIsThreadTerminating(IN PETHREAD Thread
)
1174 return(Thread
->DeadThread
);
1179 PsLookupProcessByProcessId(IN PVOID ProcessId
,
1180 OUT PEPROCESS
*Process
)
1183 PLIST_ENTRY current_entry
;
1186 KeAcquireSpinLock(&PsProcessListLock
, &oldIrql
);
1188 current_entry
= PsProcessListHead
.Flink
;
1189 while (current_entry
!= &PsProcessListHead
)
1191 current
= CONTAINING_RECORD(current_entry
,
1194 if (current
->UniqueProcessId
== (ULONG
)ProcessId
)
1197 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
1198 return(STATUS_SUCCESS
);
1200 current_entry
= current_entry
->Flink
;
1203 KeReleaseSpinLock(&PsProcessListLock
, oldIrql
);
1205 return(STATUS_INVALID_PARAMETER
);
1210 PsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine
,
1213 if (PiProcessNotifyRoutineCount
>= MAX_PROCESS_NOTIFY_ROUTINE_COUNT
)
1214 return(STATUS_INSUFFICIENT_RESOURCES
);
1216 PiProcessNotifyRoutine
[PiProcessNotifyRoutineCount
] = NotifyRoutine
;
1217 PiProcessNotifyRoutineCount
++;
1219 return(STATUS_SUCCESS
);