970df075fbaf23dfc3776c2a0a6f5278e897baa4
[reactos.git] / reactos / ntoskrnl / ps / process.c
1 /* $Id: process.c,v 1.43 2000/06/03 21:36:32 ekohl Exp $
2 *
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)
8 * REVISION HISTORY:
9 * 21/07/98: Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/mm.h>
17 #include <internal/ke.h>
18 #include <internal/ps.h>
19 #include <string.h>
20 #include <internal/string.h>
21 #include <internal/id.h>
22 #include <internal/teb.h>
23 #include <internal/ldr.h>
24 #include <internal/port.h>
25 #include <napi/dbg.h>
26 #include <internal/dbg.h>
27
28 #define NDEBUG
29 #include <internal/debug.h>
30
31 /* GLOBALS ******************************************************************/
32
33 PEPROCESS EXPORTED PsInitialSystemProcess = NULL;
34 HANDLE SystemProcessHandle = NULL;
35
36 POBJECT_TYPE EXPORTED PsProcessType = NULL;
37
38 static LIST_ENTRY PsProcessListHead;
39 static KSPIN_LOCK PsProcessListLock;
40 static ULONG PiNextProcessUniqueId = 0;
41
42 /* FUNCTIONS *****************************************************************/
43
44 NTSTATUS STDCALL NtOpenProcessToken(IN HANDLE ProcessHandle,
45 IN ACCESS_MASK DesiredAccess,
46 OUT PHANDLE TokenHandle)
47 {
48 PACCESS_TOKEN Token;
49 NTSTATUS Status;
50
51 Status = PsOpenTokenOfProcess(ProcessHandle,
52 &Token);
53 if (!NT_SUCCESS(Status))
54 {
55 return(Status);
56 }
57 Status = ObCreateHandle(PsGetCurrentProcess(),
58 Token,
59 DesiredAccess,
60 FALSE,
61 ProcessHandle);
62 ObDereferenceObject(Token);
63 return(Status);
64 }
65
66 PACCESS_TOKEN STDCALL PsReferencePrimaryToken(PEPROCESS Process)
67 {
68 ObReferenceObjectByPointer(Process->Token,
69 GENERIC_ALL,
70 SeTokenType,
71 UserMode);
72 return(Process->Token);
73 }
74
75 NTSTATUS PsOpenTokenOfProcess(HANDLE ProcessHandle,
76 PACCESS_TOKEN* Token)
77 {
78 PEPROCESS Process;
79 NTSTATUS Status;
80
81 Status = ObReferenceObjectByHandle(ProcessHandle,
82 PROCESS_QUERY_INFORMATION,
83 PsProcessType,
84 UserMode,
85 (PVOID*)&Process,
86 NULL);
87 if (!NT_SUCCESS(Status))
88 {
89 return(Status);
90 }
91 *Token = PsReferencePrimaryToken(Process);
92 ObDereferenceObject(Process);
93 return(STATUS_SUCCESS);
94 }
95
96 VOID PiKillMostProcesses(VOID)
97 {
98 KIRQL oldIrql;
99 PLIST_ENTRY current_entry;
100 PEPROCESS current;
101
102 KeAcquireSpinLock(&PsProcessListLock, &oldIrql);
103
104 current_entry = PsProcessListHead.Flink;
105 while (current_entry != &PsProcessListHead)
106 {
107 current = CONTAINING_RECORD(current_entry, EPROCESS,
108 Pcb.ProcessListEntry);
109 current_entry = current_entry->Flink;
110
111 if (current->UniqueProcessId != PsInitialSystemProcess->UniqueProcessId &&
112 current->UniqueProcessId != (ULONG)PsGetCurrentProcessId())
113 {
114 PiTerminateProcess(current, STATUS_SUCCESS);
115 }
116 }
117
118 KeReleaseSpinLock(&PsProcessListLock, oldIrql);
119 }
120
121 VOID PsInitProcessManagment(VOID)
122 {
123 ANSI_STRING AnsiString;
124 PKPROCESS KProcess;
125 KIRQL oldIrql;
126
127 /*
128 * Register the process object type
129 */
130
131 PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
132
133 PsProcessType->TotalObjects = 0;
134 PsProcessType->TotalHandles = 0;
135 PsProcessType->MaxObjects = ULONG_MAX;
136 PsProcessType->MaxHandles = ULONG_MAX;
137 PsProcessType->PagedPoolCharge = 0;
138 PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);
139 PsProcessType->Dump = NULL;
140 PsProcessType->Open = NULL;
141 PsProcessType->Close = NULL;
142 PsProcessType->Delete = PiDeleteProcess;
143 PsProcessType->Parse = NULL;
144 PsProcessType->Security = NULL;
145 PsProcessType->QueryName = NULL;
146 PsProcessType->OkayToClose = NULL;
147 PsProcessType->Create = NULL;
148
149 RtlInitAnsiString(&AnsiString,"Process");
150 RtlAnsiStringToUnicodeString(&PsProcessType->TypeName,&AnsiString,TRUE);
151
152 InitializeListHead(&PsProcessListHead);
153 KeInitializeSpinLock(&PsProcessListLock);
154
155 /*
156 * Initialize the system process
157 */
158 PsInitialSystemProcess = ObCreateObject(NULL,
159 PROCESS_ALL_ACCESS,
160 NULL,
161 PsProcessType);
162 PsInitialSystemProcess->Pcb.BasePriority = PROCESS_PRIO_NORMAL;
163 KeInitializeDispatcherHeader(&PsInitialSystemProcess->Pcb.DispatcherHeader,
164 InternalProcessType,
165 sizeof(EPROCESS),
166 FALSE);
167 KProcess = &PsInitialSystemProcess->Pcb;
168
169 MmInitializeAddressSpace(PsInitialSystemProcess,
170 &PsInitialSystemProcess->Pcb.AddressSpace);
171 ObCreateHandleTable(NULL,FALSE,PsInitialSystemProcess);
172 KProcess->PageTableDirectory = get_page_directory();
173 PsInitialSystemProcess->UniqueProcessId =
174 InterlockedIncrement(&PiNextProcessUniqueId);
175
176 KeAcquireSpinLock(&PsProcessListLock, &oldIrql);
177 InsertHeadList(&PsProcessListHead, &KProcess->ProcessListEntry);
178 InitializeListHead( &KProcess->ThreadListHead );
179 KeReleaseSpinLock(&PsProcessListLock, oldIrql);
180
181 strcpy(PsInitialSystemProcess->ImageFileName, "SYSTEM");
182
183 ObCreateHandle(PsInitialSystemProcess,
184 PsInitialSystemProcess,
185 PROCESS_ALL_ACCESS,
186 FALSE,
187 &SystemProcessHandle);
188 }
189
190 VOID PiDeleteProcess(PVOID ObjectBody)
191 {
192 KIRQL oldIrql;
193
194 DPRINT1("PiDeleteProcess(ObjectBody %x)\n",ObjectBody);
195
196 KeAcquireSpinLock(&PsProcessListLock, &oldIrql);
197 RemoveEntryList(&((PEPROCESS)ObjectBody)->Pcb.ProcessListEntry);
198 KeReleaseSpinLock(&PsProcessListLock, oldIrql);
199 (VOID)MmReleaseMmInfo((PEPROCESS)ObjectBody);
200 ObDeleteHandleTable((PEPROCESS)ObjectBody);
201 }
202
203
204 static NTSTATUS PsCreatePeb(HANDLE ProcessHandle,
205 PVOID ImageBase,
206 PVOID* RPeb)
207 {
208 NTSTATUS Status;
209 PVOID PebBase;
210 ULONG PebSize;
211 PEB Peb;
212 ULONG BytesWritten;
213
214 memset(&Peb, 0, sizeof(Peb));
215 Peb.ImageBaseAddress = ImageBase;
216
217 PebBase = (PVOID)PEB_BASE;
218 PebSize = 0x1000;
219 Status = NtAllocateVirtualMemory(ProcessHandle,
220 &PebBase,
221 0,
222 &PebSize,
223 MEM_COMMIT,
224 PAGE_READWRITE);
225 if (!NT_SUCCESS(Status))
226 {
227 return(Status);
228 }
229
230 ZwWriteVirtualMemory(ProcessHandle,
231 (PVOID)PEB_BASE,
232 &Peb,
233 sizeof(Peb),
234 &BytesWritten);
235
236 DPRINT("PsCreatePeb: Peb created at %x\n", PebBase);
237
238 *RPeb = PebBase;
239
240 return(STATUS_SUCCESS);
241 }
242
243
244 PKPROCESS KeGetCurrentProcess(VOID)
245 /*
246 * FUNCTION: Returns a pointer to the current process
247 */
248 {
249 return(&(PsGetCurrentProcess()->Pcb));
250 }
251
252 HANDLE STDCALL PsGetCurrentProcessId(VOID)
253 {
254 return((HANDLE)PsGetCurrentProcess()->UniqueProcessId);
255 }
256
257 struct _EPROCESS* PsGetCurrentProcess(VOID)
258 /*
259 * FUNCTION: Returns a pointer to the current process
260 */
261 {
262 if (PsGetCurrentThread() == NULL ||
263 PsGetCurrentThread()->ThreadsProcess == NULL)
264 {
265 return(PsInitialSystemProcess);
266 }
267 else
268 {
269 return(PsGetCurrentThread()->ThreadsProcess);
270 }
271 }
272
273 NTSTATUS STDCALL NtCreateProcess (OUT PHANDLE ProcessHandle,
274 IN ACCESS_MASK DesiredAccess,
275 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
276 IN HANDLE ParentProcessHandle,
277 IN BOOLEAN InheritObjectTable,
278 IN HANDLE SectionHandle OPTIONAL,
279 IN HANDLE DebugPortHandle OPTIONAL,
280 IN HANDLE ExceptionPortHandle OPTIONAL)
281 /*
282 * FUNCTION: Creates a process.
283 * ARGUMENTS:
284 * ProcessHandle (OUT) = Caller supplied storage for the resulting
285 * handle
286 * DesiredAccess = Specifies the allowed or desired access to the
287 * process can be a combination of
288 * STANDARD_RIGHTS_REQUIRED| ..
289 * ObjectAttribute = Initialized attributes for the object, contains
290 * the rootdirectory and the filename
291 * ParentProcess = Handle to the parent process.
292 * InheritObjectTable = Specifies to inherit the objects of the parent
293 * process if true.
294 * SectionHandle = Handle to a section object to back the image file
295 * DebugPort = Handle to a DebugPort if NULL the system default debug
296 * port will be used.
297 * ExceptionPort = Handle to a exception port.
298 * REMARKS:
299 * This function maps to the win32 CreateProcess.
300 * RETURNS: Status
301 */
302 {
303 PEPROCESS Process;
304 PEPROCESS ParentProcess;
305 PKPROCESS KProcess;
306 NTSTATUS Status;
307 KIRQL oldIrql;
308 PVOID LdrStartupAddr;
309 PVOID ImageBase;
310 PVOID Peb;
311 PEPORT DebugPort;
312 PEPORT ExceptionPort;
313
314 DPRINT("NtCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);
315
316 Status = ObReferenceObjectByHandle(ParentProcessHandle,
317 PROCESS_CREATE_PROCESS,
318 PsProcessType,
319 UserMode,
320 (PVOID*)&ParentProcess,
321 NULL);
322
323 if (Status != STATUS_SUCCESS)
324 {
325 DPRINT("NtCreateProcess() = %x\n",Status);
326 return(Status);
327 }
328
329 Process = ObCreateObject(ProcessHandle,
330 DesiredAccess,
331 ObjectAttributes,
332 PsProcessType);
333 KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader,
334 InternalProcessType,
335 sizeof(EPROCESS),
336 FALSE);
337 KProcess = &Process->Pcb;
338
339 KProcess->BasePriority = PROCESS_PRIO_NORMAL;
340 MmInitializeAddressSpace(Process,
341 &KProcess->AddressSpace);
342 Process->UniqueProcessId = InterlockedIncrement(&PiNextProcessUniqueId);
343 Process->InheritedFromUniqueProcessId = ParentProcess->UniqueProcessId;
344 ObCreateHandleTable(ParentProcess,
345 InheritObjectTable,
346 Process);
347 MmCopyMmInfo(ParentProcess, Process);
348
349 KeAcquireSpinLock(&PsProcessListLock, &oldIrql);
350 InsertHeadList(&PsProcessListHead, &KProcess->ProcessListEntry);
351 InitializeListHead( &KProcess->ThreadListHead );
352 KeReleaseSpinLock(&PsProcessListLock, oldIrql);
353
354 Process->Pcb.ProcessState = PROCESS_STATE_ACTIVE;
355
356 /*
357 * Add the debug port
358 */
359 if (DebugPortHandle != NULL)
360 {
361 Status = ObReferenceObjectByHandle(DebugPortHandle,
362 PORT_ALL_ACCESS,
363 ExPortType,
364 UserMode,
365 (PVOID*)&DebugPort,
366 NULL);
367 if (!NT_SUCCESS(Status))
368 {
369 ObDereferenceObject(Process);
370 ObDereferenceObject(ParentProcess);
371 ZwClose(*ProcessHandle);
372 *ProcessHandle = NULL;
373 return(Status);
374 }
375 Process->DebugPort = DebugPort;
376 }
377
378 /*
379 * Add the exception port
380 */
381 if (ExceptionPortHandle != NULL)
382 {
383 Status = ObReferenceObjectByHandle(ExceptionPortHandle,
384 PORT_ALL_ACCESS,
385 ExPortType,
386 UserMode,
387 (PVOID*)&ExceptionPort,
388 NULL);
389 if (!NT_SUCCESS(Status))
390 {
391 ObDereferenceObject(Process);
392 ObDereferenceObject(ParentProcess);
393 ZwClose(*ProcessHandle);
394 *ProcessHandle = NULL;
395 return(Status);
396 }
397 Process->ExceptionPort = ExceptionPort;
398 }
399
400 /*
401 * Now we have created the process proper
402 */
403
404 /*
405 * Map ntdll
406 */
407 Status = LdrpMapSystemDll(*ProcessHandle,
408 &LdrStartupAddr);
409 if (!NT_SUCCESS(Status))
410 {
411 DbgPrint("LdrpMapSystemDll failed (Status %x)\n", Status);
412 ObDereferenceObject(Process);
413 ObDereferenceObject(ParentProcess);
414 return(Status);
415 }
416
417 /*
418 * Map the process image
419 */
420 if (SectionHandle != NULL)
421 {
422 DPRINT("Mapping process image\n");
423 Status = LdrpMapImage(*ProcessHandle,
424 SectionHandle,
425 &ImageBase);
426 if (!NT_SUCCESS(Status))
427 {
428 DbgPrint("LdrpMapImage failed (Status %x)\n", Status);
429 ObDereferenceObject(Process);
430 ObDereferenceObject(ParentProcess);
431 return(Status);
432 }
433 }
434 else
435 {
436 ImageBase = NULL;
437 }
438
439 /*
440 *
441 */
442 DPRINT("Creating PEB\n");
443 Status = PsCreatePeb(*ProcessHandle,
444 ImageBase,
445 &Peb);
446 if (!NT_SUCCESS(Status))
447 {
448 DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
449 ObDereferenceObject(Process);
450 ObDereferenceObject(ParentProcess);
451 ZwClose(*ProcessHandle);
452 *ProcessHandle = NULL;
453 return(Status);
454 }
455 Process->Peb = Peb;
456
457 /*
458 * Maybe send a message to the creator process's debugger
459 */
460 if (ParentProcess->DebugPort != NULL)
461 {
462 LPC_DBG_MESSAGE Message;
463 HANDLE FileHandle;
464
465 ObCreateHandle(NULL, // Debugger Process
466 NULL, // SectionHandle
467 FILE_ALL_ACCESS,
468 FALSE,
469 &FileHandle);
470
471 Message.Header.MessageSize = sizeof(LPC_DBG_MESSAGE);
472 Message.Header.DataSize = sizeof(LPC_DBG_MESSAGE) -
473 sizeof(LPC_MESSAGE_HEADER);
474 Message.Type = DBG_EVENT_CREATE_PROCESS;
475 Message.Data.CreateProcess.FileHandle = FileHandle;
476 Message.Data.CreateProcess.Base = ImageBase;
477 Message.Data.CreateProcess.EntryPoint = NULL; //
478
479 Status = LpcSendDebugMessagePort(ParentProcess->DebugPort,
480 &Message);
481 }
482
483 ObDereferenceObject(Process);
484 ObDereferenceObject(ParentProcess);
485 return(STATUS_SUCCESS);
486 }
487
488
489 NTSTATUS STDCALL NtOpenProcess (OUT PHANDLE ProcessHandle,
490 IN ACCESS_MASK DesiredAccess,
491 IN POBJECT_ATTRIBUTES ObjectAttributes,
492 IN PCLIENT_ID ClientId)
493 {
494 DPRINT("NtOpenProcess(ProcessHandle %x, DesiredAccess %x, "
495 "ObjectAttributes %x, ClientId %x { UniP %d, UniT %d })\n",
496 ProcessHandle, DesiredAccess, ObjectAttributes, ClientId,
497 ClientId->UniqueProcess, ClientId->UniqueThread);
498
499
500 /*
501 * Not sure of the exact semantics
502 */
503 if (ObjectAttributes != NULL && ObjectAttributes->ObjectName != NULL &&
504 ObjectAttributes->ObjectName->Buffer != NULL)
505 {
506 NTSTATUS Status;
507 PEPROCESS Process;
508
509 Status = ObReferenceObjectByName(ObjectAttributes->ObjectName,
510 ObjectAttributes->Attributes,
511 NULL,
512 DesiredAccess,
513 PsProcessType,
514 UserMode,
515 NULL,
516 (PVOID*)&Process);
517 if (Status != STATUS_SUCCESS)
518 {
519 return(Status);
520 }
521
522 Status = ObCreateHandle(PsGetCurrentProcess(),
523 Process,
524 DesiredAccess,
525 FALSE,
526 ProcessHandle);
527 ObDereferenceObject(Process);
528
529 return(Status);
530 }
531 else
532 {
533 KIRQL oldIrql;
534 PLIST_ENTRY current_entry;
535 PEPROCESS current;
536 NTSTATUS Status;
537
538 KeAcquireSpinLock(&PsProcessListLock, &oldIrql);
539 current_entry = PsProcessListHead.Flink;
540 while (current_entry != &PsProcessListHead)
541 {
542 current = CONTAINING_RECORD(current_entry, EPROCESS,
543 Pcb.ProcessListEntry);
544 if (current->UniqueProcessId == (ULONG)ClientId->UniqueProcess)
545 {
546 ObReferenceObjectByPointer(current,
547 DesiredAccess,
548 PsProcessType,
549 UserMode);
550 KeReleaseSpinLock(&PsProcessListLock, oldIrql);
551 Status = ObCreateHandle(PsGetCurrentProcess(),
552 current,
553 DesiredAccess,
554 FALSE,
555 ProcessHandle);
556 ObDereferenceObject(current);
557 DPRINT("*ProcessHandle %x\n", ProcessHandle);
558 DPRINT("NtOpenProcess() = %x\n", Status);
559 return(Status);
560 }
561 current_entry = current_entry->Flink;
562 }
563 KeReleaseSpinLock(&PsProcessListLock, oldIrql);
564 DPRINT("NtOpenProcess() = STATUS_UNSUCCESSFUL\n");
565 return(STATUS_UNSUCCESSFUL);
566 }
567 return(STATUS_UNSUCCESSFUL);
568 }
569
570
571 NTSTATUS STDCALL NtQueryInformationProcess (IN HANDLE ProcessHandle,
572 IN CINT ProcessInformationClass,
573 OUT PVOID ProcessInformation,
574 IN ULONG ProcessInformationLength,
575 OUT PULONG ReturnLength)
576 {
577 PEPROCESS Process;
578 NTSTATUS Status;
579 PPROCESS_BASIC_INFORMATION ProcessBasicInformationP;
580
581 Status = ObReferenceObjectByHandle(ProcessHandle,
582 PROCESS_SET_INFORMATION,
583 PsProcessType,
584 UserMode,
585 (PVOID*)&Process,
586 NULL);
587 if (Status != STATUS_SUCCESS)
588 {
589 return(Status);
590 }
591
592 switch (ProcessInformationClass)
593 {
594 case ProcessBasicInformation:
595 ProcessBasicInformationP = (PPROCESS_BASIC_INFORMATION)
596 ProcessInformation;
597 ProcessBasicInformationP->ExitStatus = Process->ExitStatus;
598 ProcessBasicInformationP->PebBaseAddress = Process->Peb;
599 ProcessBasicInformationP->AffinityMask = Process->Pcb.Affinity;
600 ProcessBasicInformationP->UniqueProcessId =
601 Process->UniqueProcessId;
602 ProcessBasicInformationP->InheritedFromUniqueProcessId =
603 Process->InheritedFromUniqueProcessId;
604 Status = STATUS_SUCCESS;
605 break;
606
607 case ProcessQuotaLimits:
608 case ProcessIoCounters:
609 case ProcessVmCounters:
610 case ProcessTimes:
611 case ProcessBasePriority:
612 case ProcessRaisePriority:
613 case ProcessDebugPort:
614 case ProcessExceptionPort:
615 case ProcessAccessToken:
616 case ProcessLdtInformation:
617 case ProcessLdtSize:
618 Status = STATUS_NOT_IMPLEMENTED;
619 break;
620
621 case ProcessDefaultHardErrorMode:
622 *((PULONG)ProcessInformation) = Process->DefaultHardErrorProcessing;
623 break;
624
625 case ProcessIoPortHandlers:
626 case ProcessWorkingSetWatch:
627 case ProcessUserModeIOPL:
628 case ProcessEnableAlignmentFaultFixup:
629 case ProcessPriorityClass:
630 case ProcessWx86Information:
631 case ProcessHandleCount:
632 case ProcessAffinityMask:
633 default:
634 Status = STATUS_NOT_IMPLEMENTED;
635 }
636 ObDereferenceObject(Process);
637 return(Status);
638 }
639
640 NTSTATUS PspAssignPrimaryToken(PEPROCESS Process,
641 HANDLE TokenHandle)
642 {
643 PACCESS_TOKEN Token;
644 PACCESS_TOKEN OldToken;
645 NTSTATUS Status;
646
647 Status = ObReferenceObjectByHandle(TokenHandle,
648 0,
649 SeTokenType,
650 UserMode,
651 (PVOID*)&Token,
652 NULL);
653 if (!NT_SUCCESS(Status))
654 {
655 return(Status);
656 }
657 Status = SeExchangePrimaryToken(Process, Token, &OldToken);
658 if (!NT_SUCCESS(Status))
659 {
660 ObDereferenceObject(OldToken);
661 }
662 ObDereferenceObject(Token);
663 return(Status);
664 }
665
666 NTSTATUS STDCALL NtSetInformationProcess(IN HANDLE ProcessHandle,
667 IN CINT ProcessInformationClass,
668 IN PVOID ProcessInformation,
669 IN ULONG ProcessInformationLength)
670 {
671 PEPROCESS Process;
672 NTSTATUS Status;
673 PPROCESS_BASIC_INFORMATION ProcessBasicInformationP;
674 PHANDLE ProcessAccessTokenP;
675
676 Status = ObReferenceObjectByHandle(ProcessHandle,
677 PROCESS_SET_INFORMATION,
678 PsProcessType,
679 UserMode,
680 (PVOID*)&Process,
681 NULL);
682 if (!NT_SUCCESS(Status))
683 {
684 return(Status);
685 }
686
687 switch (ProcessInformationClass)
688 {
689 case ProcessBasicInformation:
690 ProcessBasicInformationP = (PPROCESS_BASIC_INFORMATION)
691 ProcessInformation;
692 memset(ProcessBasicInformationP, 0, sizeof(PROCESS_BASIC_INFORMATION));
693 Process->Pcb.Affinity = ProcessBasicInformationP->AffinityMask;
694 Status = STATUS_SUCCESS;
695 break;
696
697 case ProcessQuotaLimits:
698 case ProcessIoCounters:
699 case ProcessVmCounters:
700 case ProcessTimes:
701 case ProcessBasePriority:
702 case ProcessRaisePriority:
703 case ProcessDebugPort:
704 case ProcessExceptionPort:
705 case ProcessAccessToken:
706 ProcessAccessTokenP = (PHANDLE)ProcessInformation;
707 Status = PspAssignPrimaryToken(Process, *ProcessAccessTokenP);
708 break;
709
710 case ProcessImageFileName:
711 memcpy(Process->ImageFileName, ProcessInformation, 8);
712 // DPRINT1("Process->ImageFileName %.8s\n", Process->ImageFileName);
713 Status = STATUS_SUCCESS;
714 break;
715
716 case ProcessLdtInformation:
717 case ProcessLdtSize:
718 case ProcessDefaultHardErrorMode:
719 case ProcessIoPortHandlers:
720 case ProcessWorkingSetWatch:
721 case ProcessUserModeIOPL:
722 case ProcessEnableAlignmentFaultFixup:
723 case ProcessPriorityClass:
724 case ProcessWx86Information:
725 case ProcessHandleCount:
726 case ProcessAffinityMask:
727 default:
728 Status = STATUS_NOT_IMPLEMENTED;
729 }
730 ObDereferenceObject(Process);
731 return(Status);
732 }
733
734
735 #if 0
736 /**********************************************************************
737 * NAME INTERNAL
738 * PiSnapshotProcessTable
739 *
740 * DESCRIPTION
741 * Compute the size of a process+thread snapshot as
742 * expected by NtQuerySystemInformation.
743 *
744 * RETURN VALUE
745 * 0 on error; otherwise the size, in bytes of the buffer
746 * required to write a full snapshot.
747 *
748 * NOTE
749 * We assume (sizeof (PVOID) == sizeof (ULONG)) holds.
750 */
751 NTSTATUS
752 STDCALL
753 PiSnapshotProcessTable (
754 IN PVOID SnapshotBuffer,
755 IN ULONG Size,
756 IN PULONG pRequiredSize
757 )
758 {
759 KIRQL OldIrql;
760 PLIST_ENTRY CurrentEntry;
761 PEPROCESS Current;
762
763 ULONG RequiredSize = 0L;
764 BOOLEAN SizeOnly = FALSE;
765
766 ULONG SpiSizeLast = 0L;
767 ULONG SpiSizeCurrent = 0L;
768
769 PSYSTEM_PROCESS_INFORMATION pInfoP = (PSYSTEM_PROCESS_INFORMATION) SnapshotBuffer;
770 PSYSTEM_THREAD_INFO pInfoT = NULL;
771
772
773 /*
774 * Lock the process list.
775 */
776 KeAcquireSpinLock (
777 & PsProcessListLock,
778 & OldIrql
779 );
780 /*
781 * Scan the process list. Since the
782 * list is circular, the guard is false
783 * after the last process.
784 */
785 for ( CurrentEntry = PsProcessListHead.Flink;
786 (CurrentEntry != & PsProcessListHead);
787 CurrentEntry = CurrentEntry->Flink
788 )
789 {
790 /*
791 * Get a reference to the
792 * process object we are
793 * handling.
794 */
795 Current = CONTAINING_RECORD(
796 CurrentEntry,
797 EPROCESS,
798 Pcb.ProcessListEntry
799 );
800 /* FIXME: assert (NULL != Current) */
801 /*
802 * Compute how much space is
803 * occupied in the snapshot
804 * by adding this process info.
805 */
806 SpiSizeCurrent =
807 sizeof (SYSTEM_PROCESS_INFORMATION)
808 + (
809 (Current->ThreadCount - 1)
810 * sizeof (SYSTEM_THREAD_INFORMATION)
811 );
812 RequiredSize += SpiSizeCurrent;
813 /*
814 * Do not write process data in the
815 * buffer if it is too small.
816 */
817 if (TRUE == SizeOnly) continue;
818 /*
819 * Check if the buffer can contain
820 * the full snapshot.
821 */
822 if (Size < RequiredSize)
823 {
824 SizeOnly = TRUE;
825 continue;
826 }
827 /*
828 * Compute the offset of the
829 * SYSTEM_PROCESS_INFORMATION
830 * descriptor in the snapshot
831 * buffer for this process.
832 */
833 if (0L != SpiSizeLast)
834 {
835 (ULONG) pInfoP += SpiSizeLast;
836 /* Save current process SpiSize */
837 SpiSizeLast = SpiSizeCurrent;
838 }
839 /*
840 * Write process data in the buffer.
841 */
842 pInfoP->RelativeOffset = SpiSizeCurrent;
843 /* PROCESS */
844 pInfoP->ThreadCount =
845 pInfoP->ProcessId = Current->UniqueProcessId;
846 RtlInitUnicodeString (
847 & pInfoP->Name,
848 Current->ImageFileName
849 );
850 /* THREAD */
851 for ( ThreadIndex = 0;
852 (ThreadIndex < Current->ThreadCount);
853 ThreadIndex ++
854 )
855 {
856 }
857 }
858 /*
859 * Unlock the process list.
860 */
861 KeReleaseSpinLock (
862 & PsProcessListLock,
863 OldIrql
864 );
865 /*
866 * Return the proper error status code,
867 * if the buffer was too small.
868 */
869 if (TRUE == SizeOnly)
870 {
871 *pRequiredSize = RequiredSize;
872 return STATUS_INFO_LENGTH_MISMATCH;
873 }
874 /*
875 * Mark the end of the snapshot.
876 */
877 pInfoP->RelativeOffset = 0L;
878 /* OK */
879 return STATUS_SUCCESS;
880 }
881 #endif
882
883 /* EOF */