Sync to trunk head (r42241)
[reactos.git] / reactos / dll / win32 / kernel32 / process / proc.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/proc/proc.c
6 * PURPOSE: Process functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
8 * UPDATE HISTORY:
9 * Created 01/11/98
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <k32.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19
20 typedef INT (WINAPI *MessageBoxW_Proc) (HWND, LPCWSTR, LPCWSTR, UINT);
21
22 /* GLOBALS *******************************************************************/
23
24 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
25
26 LPSTARTUPINFOA lpLocalStartupInfo = NULL;
27
28 VOID WINAPI
29 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
30
31 /* FUNCTIONS ****************************************************************/
32
33 /*
34 * @implemented
35 */
36 BOOL WINAPI
37 GetProcessAffinityMask (HANDLE hProcess,
38 PDWORD_PTR lpProcessAffinityMask,
39 PDWORD_PTR lpSystemAffinityMask)
40 {
41 PROCESS_BASIC_INFORMATION ProcessInfo;
42 SYSTEM_BASIC_INFORMATION SystemInfo;
43 NTSTATUS Status;
44
45 Status = NtQuerySystemInformation(SystemBasicInformation,
46 &SystemInfo,
47 sizeof(SystemInfo),
48 NULL);
49 if (!NT_SUCCESS(Status))
50 {
51 SetLastErrorByStatus (Status);
52 return FALSE;
53 }
54
55 Status = NtQueryInformationProcess (hProcess,
56 ProcessBasicInformation,
57 (PVOID)&ProcessInfo,
58 sizeof(PROCESS_BASIC_INFORMATION),
59 NULL);
60 if (!NT_SUCCESS(Status))
61 {
62 SetLastErrorByStatus (Status);
63 return FALSE;
64 }
65
66 *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask;
67 *lpSystemAffinityMask = (DWORD)SystemInfo.ActiveProcessorsAffinityMask;
68
69 return TRUE;
70 }
71
72
73 /*
74 * @implemented
75 */
76 BOOL WINAPI
77 SetProcessAffinityMask (HANDLE hProcess,
78 DWORD_PTR dwProcessAffinityMask)
79 {
80 NTSTATUS Status;
81
82 Status = NtSetInformationProcess (hProcess,
83 ProcessAffinityMask,
84 (PVOID)&dwProcessAffinityMask,
85 sizeof(DWORD));
86 if (!NT_SUCCESS(Status))
87 {
88 SetLastErrorByStatus (Status);
89 return FALSE;
90 }
91
92 return TRUE;
93 }
94
95
96 /*
97 * @implemented
98 */
99 BOOL WINAPI
100 GetProcessShutdownParameters (LPDWORD lpdwLevel,
101 LPDWORD lpdwFlags)
102 {
103 CSR_API_MESSAGE CsrRequest;
104 ULONG Request;
105 NTSTATUS Status;
106
107 Request = GET_SHUTDOWN_PARAMETERS;
108 Status = CsrClientCallServer(&CsrRequest,
109 NULL,
110 MAKE_CSR_API(Request, CSR_NATIVE),
111 sizeof(CSR_API_MESSAGE));
112 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
113 {
114 SetLastErrorByStatus (Status);
115 return(FALSE);
116 }
117
118 *lpdwLevel = CsrRequest.Data.GetShutdownParametersRequest.Level;
119 *lpdwFlags = CsrRequest.Data.GetShutdownParametersRequest.Flags;
120
121 return(TRUE);
122 }
123
124
125 /*
126 * @implemented
127 */
128 BOOL WINAPI
129 SetProcessShutdownParameters (DWORD dwLevel,
130 DWORD dwFlags)
131 {
132 CSR_API_MESSAGE CsrRequest;
133 ULONG Request;
134 NTSTATUS Status;
135
136 CsrRequest.Data.SetShutdownParametersRequest.Level = dwLevel;
137 CsrRequest.Data.SetShutdownParametersRequest.Flags = dwFlags;
138
139 Request = SET_SHUTDOWN_PARAMETERS;
140 Status = CsrClientCallServer(&CsrRequest,
141 NULL,
142 MAKE_CSR_API(Request, CSR_NATIVE),
143 sizeof(CSR_API_MESSAGE));
144 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
145 {
146 SetLastErrorByStatus (Status);
147 return(FALSE);
148 }
149
150 return(TRUE);
151 }
152
153
154 /*
155 * @implemented
156 */
157 BOOL WINAPI
158 GetProcessWorkingSetSize (HANDLE hProcess,
159 PSIZE_T lpMinimumWorkingSetSize,
160 PSIZE_T lpMaximumWorkingSetSize)
161 {
162 QUOTA_LIMITS QuotaLimits;
163 NTSTATUS Status;
164
165 Status = NtQueryInformationProcess(hProcess,
166 ProcessQuotaLimits,
167 &QuotaLimits,
168 sizeof(QUOTA_LIMITS),
169 NULL);
170 if (!NT_SUCCESS(Status))
171 {
172 SetLastErrorByStatus(Status);
173 return(FALSE);
174 }
175
176 *lpMinimumWorkingSetSize = QuotaLimits.MinimumWorkingSetSize;
177 *lpMaximumWorkingSetSize = QuotaLimits.MaximumWorkingSetSize;
178
179 return(TRUE);
180 }
181
182
183 /*
184 * @implemented
185 */
186 BOOL WINAPI
187 SetProcessWorkingSetSize(HANDLE hProcess,
188 SIZE_T dwMinimumWorkingSetSize,
189 SIZE_T dwMaximumWorkingSetSize)
190 {
191 QUOTA_LIMITS QuotaLimits;
192 NTSTATUS Status;
193
194 QuotaLimits.MinimumWorkingSetSize = dwMinimumWorkingSetSize;
195 QuotaLimits.MaximumWorkingSetSize = dwMaximumWorkingSetSize;
196
197 Status = NtSetInformationProcess(hProcess,
198 ProcessQuotaLimits,
199 &QuotaLimits,
200 sizeof(QUOTA_LIMITS));
201 if (!NT_SUCCESS(Status))
202 {
203 SetLastErrorByStatus(Status);
204 return(FALSE);
205 }
206
207 return(TRUE);
208 }
209
210
211 /*
212 * @implemented
213 */
214 BOOL WINAPI
215 GetProcessTimes(HANDLE hProcess,
216 LPFILETIME lpCreationTime,
217 LPFILETIME lpExitTime,
218 LPFILETIME lpKernelTime,
219 LPFILETIME lpUserTime)
220 {
221 KERNEL_USER_TIMES Kut;
222 NTSTATUS Status;
223
224 Status = NtQueryInformationProcess(hProcess,
225 ProcessTimes,
226 &Kut,
227 sizeof(Kut),
228 NULL);
229 if (!NT_SUCCESS(Status))
230 {
231 SetLastErrorByStatus(Status);
232 return(FALSE);
233 }
234
235 lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
236 lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
237
238 lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
239 lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
240
241 lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
242 lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
243
244 lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
245 lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
246
247 return(TRUE);
248 }
249
250
251 /*
252 * @implemented
253 */
254 HANDLE WINAPI
255 GetCurrentProcess(VOID)
256 {
257 return((HANDLE)NtCurrentProcess());
258 }
259
260
261 /*
262 * @implemented
263 */
264 HANDLE WINAPI
265 GetCurrentThread(VOID)
266 {
267 return((HANDLE)NtCurrentThread());
268 }
269
270
271 /*
272 * @implemented
273 */
274 DWORD WINAPI
275 GetCurrentProcessId(VOID)
276 {
277 return((DWORD)GetTeb()->ClientId.UniqueProcess);
278 }
279
280
281 /*
282 * @implemented
283 */
284 BOOL WINAPI
285 GetExitCodeProcess(HANDLE hProcess,
286 LPDWORD lpExitCode)
287 {
288 PROCESS_BASIC_INFORMATION ProcessBasic;
289 NTSTATUS Status;
290
291 Status = NtQueryInformationProcess(hProcess,
292 ProcessBasicInformation,
293 &ProcessBasic,
294 sizeof(PROCESS_BASIC_INFORMATION),
295 NULL);
296 if (!NT_SUCCESS(Status))
297 {
298 SetLastErrorByStatus(Status);
299 return(FALSE);
300 }
301
302 *lpExitCode = (DWORD)ProcessBasic.ExitStatus;
303
304 return(TRUE);
305 }
306
307
308 /*
309 * @implemented
310 */
311 DWORD
312 WINAPI
313 GetProcessId(HANDLE Process)
314 {
315 PROCESS_BASIC_INFORMATION ProcessBasic;
316 NTSTATUS Status;
317
318 Status = NtQueryInformationProcess(Process,
319 ProcessBasicInformation,
320 &ProcessBasic,
321 sizeof(PROCESS_BASIC_INFORMATION),
322 NULL);
323 if (!NT_SUCCESS(Status))
324 {
325 SetLastErrorByStatus(Status);
326 return 0;
327 }
328
329 return (DWORD)ProcessBasic.UniqueProcessId;
330 }
331
332
333 /*
334 * @implemented
335 */
336 HANDLE WINAPI
337 OpenProcess(DWORD dwDesiredAccess,
338 BOOL bInheritHandle,
339 DWORD dwProcessId)
340 {
341 NTSTATUS errCode;
342 HANDLE ProcessHandle;
343 OBJECT_ATTRIBUTES ObjectAttributes;
344 CLIENT_ID ClientId;
345
346 ClientId.UniqueProcess = (HANDLE)dwProcessId;
347 ClientId.UniqueThread = 0;
348
349 InitializeObjectAttributes(&ObjectAttributes,
350 NULL,
351 (bInheritHandle ? OBJ_INHERIT : 0),
352 NULL,
353 NULL);
354
355 errCode = NtOpenProcess(&ProcessHandle,
356 dwDesiredAccess,
357 &ObjectAttributes,
358 &ClientId);
359 if (!NT_SUCCESS(errCode))
360 {
361 SetLastErrorByStatus (errCode);
362 return NULL;
363 }
364 return ProcessHandle;
365 }
366
367
368 /*
369 * @implemented
370 */
371 UINT WINAPI
372 WinExec(LPCSTR lpCmdLine,
373 UINT uCmdShow)
374 {
375 STARTUPINFOA StartupInfo;
376 PROCESS_INFORMATION ProcessInformation;
377 DWORD dosErr;
378
379 RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
380 StartupInfo.cb = sizeof(STARTUPINFOA);
381 StartupInfo.wShowWindow = (WORD)uCmdShow;
382 StartupInfo.dwFlags = 0;
383
384 if (! CreateProcessA(NULL,
385 (PVOID)lpCmdLine,
386 NULL,
387 NULL,
388 FALSE,
389 0,
390 NULL,
391 NULL,
392 &StartupInfo,
393 &ProcessInformation))
394 {
395 dosErr = GetLastError();
396 return dosErr < 32 ? dosErr : ERROR_BAD_FORMAT;
397 }
398 if (NULL != lpfnGlobalRegisterWaitForInputIdle)
399 {
400 lpfnGlobalRegisterWaitForInputIdle (
401 ProcessInformation.hProcess,
402 10000
403 );
404 }
405 NtClose(ProcessInformation.hProcess);
406 NtClose(ProcessInformation.hThread);
407
408 return 33; /* Something bigger than 31 means success. */
409 }
410
411
412 /*
413 * @implemented
414 */
415 VOID WINAPI
416 RegisterWaitForInputIdle (
417 WaitForInputIdleType lpfnRegisterWaitForInputIdle
418 )
419 {
420 lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
421 return;
422 }
423
424 /*
425 * @implemented
426 */
427 VOID WINAPI
428 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
429 {
430 PRTL_USER_PROCESS_PARAMETERS Params;
431
432 if (lpStartupInfo == NULL)
433 {
434 SetLastError(ERROR_INVALID_PARAMETER);
435 return;
436 }
437
438 Params = NtCurrentPeb()->ProcessParameters;
439
440 lpStartupInfo->cb = sizeof(STARTUPINFOW);
441 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
442 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
443 lpStartupInfo->dwX = Params->StartingX;
444 lpStartupInfo->dwY = Params->StartingY;
445 lpStartupInfo->dwXSize = Params->CountX;
446 lpStartupInfo->dwYSize = Params->CountY;
447 lpStartupInfo->dwXCountChars = Params->CountCharsX;
448 lpStartupInfo->dwYCountChars = Params->CountCharsY;
449 lpStartupInfo->dwFillAttribute = Params->FillAttribute;
450 lpStartupInfo->dwFlags = Params->WindowFlags;
451 lpStartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
452 lpStartupInfo->cbReserved2 = Params->RuntimeData.Length;
453 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
454
455 lpStartupInfo->hStdInput = Params->StandardInput;
456 lpStartupInfo->hStdOutput = Params->StandardOutput;
457 lpStartupInfo->hStdError = Params->StandardError;
458 }
459
460
461 /*
462 * @implemented
463 */
464 VOID WINAPI
465 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
466 {
467 PRTL_USER_PROCESS_PARAMETERS Params;
468 ANSI_STRING AnsiString;
469
470 if (lpStartupInfo == NULL)
471 {
472 SetLastError(ERROR_INVALID_PARAMETER);
473 return;
474 }
475
476 Params = NtCurrentPeb ()->ProcessParameters;
477
478 RtlAcquirePebLock ();
479
480 /* FIXME - not thread-safe */
481 if (lpLocalStartupInfo == NULL)
482 {
483 /* create new local startup info (ansi) */
484 lpLocalStartupInfo = RtlAllocateHeap (RtlGetProcessHeap (),
485 0,
486 sizeof(STARTUPINFOA));
487 if (lpLocalStartupInfo == NULL)
488 {
489 RtlReleasePebLock ();
490 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
491 return;
492 }
493
494 lpLocalStartupInfo->cb = sizeof(STARTUPINFOA);
495
496 /* copy window title string */
497 RtlUnicodeStringToAnsiString (&AnsiString,
498 &Params->WindowTitle,
499 TRUE);
500 lpLocalStartupInfo->lpTitle = AnsiString.Buffer;
501
502 /* copy desktop info string */
503 RtlUnicodeStringToAnsiString (&AnsiString,
504 &Params->DesktopInfo,
505 TRUE);
506 lpLocalStartupInfo->lpDesktop = AnsiString.Buffer;
507
508 /* copy shell info string */
509 RtlUnicodeStringToAnsiString (&AnsiString,
510 &Params->ShellInfo,
511 TRUE);
512 lpLocalStartupInfo->lpReserved = AnsiString.Buffer;
513
514 lpLocalStartupInfo->dwX = Params->StartingX;
515 lpLocalStartupInfo->dwY = Params->StartingY;
516 lpLocalStartupInfo->dwXSize = Params->CountX;
517 lpLocalStartupInfo->dwYSize = Params->CountY;
518 lpLocalStartupInfo->dwXCountChars = Params->CountCharsX;
519 lpLocalStartupInfo->dwYCountChars = Params->CountCharsY;
520 lpLocalStartupInfo->dwFillAttribute = Params->FillAttribute;
521 lpLocalStartupInfo->dwFlags = Params->WindowFlags;
522 lpLocalStartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
523 lpLocalStartupInfo->cbReserved2 = Params->RuntimeData.Length;
524 lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
525
526 lpLocalStartupInfo->hStdInput = Params->StandardInput;
527 lpLocalStartupInfo->hStdOutput = Params->StandardOutput;
528 lpLocalStartupInfo->hStdError = Params->StandardError;
529 }
530
531 RtlReleasePebLock ();
532
533 /* copy local startup info data to external startup info */
534 memcpy (lpStartupInfo,
535 lpLocalStartupInfo,
536 sizeof(STARTUPINFOA));
537 }
538
539
540 /*
541 * @implemented
542 */
543 BOOL WINAPI
544 FlushInstructionCache (HANDLE hProcess,
545 LPCVOID lpBaseAddress,
546 DWORD dwSize)
547 {
548 NTSTATUS Status;
549
550 Status = NtFlushInstructionCache(hProcess,
551 (PVOID)lpBaseAddress,
552 dwSize);
553 if (!NT_SUCCESS(Status))
554 {
555 SetLastErrorByStatus(Status);
556 return FALSE;
557 }
558 return TRUE;
559 }
560
561
562 /*
563 * @implemented
564 */
565 VOID WINAPI
566 ExitProcess(UINT uExitCode)
567 {
568 CSR_API_MESSAGE CsrRequest;
569 ULONG Request;
570 NTSTATUS Status;
571
572 /* kill sibling threads ... we want to be alone at this point */
573 NtTerminateProcess (NULL, 0);
574
575 /* unload all dll's */
576 LdrShutdownProcess ();
577
578 /* notify csrss of process termination */
579 Request = TERMINATE_PROCESS;
580 Status = CsrClientCallServer(&CsrRequest,
581 NULL,
582 MAKE_CSR_API(Request, CSR_NATIVE),
583 sizeof(CSR_API_MESSAGE));
584 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
585 {
586 DPRINT("Failed to tell csrss about terminating process\n");
587 }
588
589
590 NtTerminateProcess (NtCurrentProcess (),
591 uExitCode);
592
593 /* should never get here */
594 ASSERT(0);
595 while(1);
596 }
597
598
599 /*
600 * @implemented
601 */
602 BOOL WINAPI
603 TerminateProcess (HANDLE hProcess,
604 UINT uExitCode)
605 {
606 NTSTATUS Status;
607
608 if (hProcess == NULL)
609 {
610 return FALSE;
611 }
612
613 Status = NtTerminateProcess (hProcess, uExitCode);
614 if (NT_SUCCESS(Status))
615 {
616 return TRUE;
617 }
618 SetLastErrorByStatus (Status);
619 return FALSE;
620 }
621
622
623 /*
624 * @unimplemented
625 */
626 VOID WINAPI
627 FatalAppExitA(UINT uAction,
628 LPCSTR lpMessageText)
629 {
630 UNICODE_STRING MessageTextU;
631 ANSI_STRING MessageText;
632
633 RtlInitAnsiString (&MessageText, (LPSTR) lpMessageText);
634
635 RtlAnsiStringToUnicodeString (&MessageTextU,
636 &MessageText,
637 TRUE);
638
639 FatalAppExitW (uAction, MessageTextU.Buffer);
640
641 RtlFreeUnicodeString (&MessageTextU);
642 }
643
644
645 /*
646 * @unimplemented
647 */
648 VOID WINAPI
649 FatalAppExitW(UINT uAction,
650 LPCWSTR lpMessageText)
651 {
652 static const WCHAR szUser32[] = L"user32.dll\0";
653
654 HMODULE hModule = GetModuleHandleW(szUser32);
655 MessageBoxW_Proc pMessageBoxW = NULL;
656
657 DPRINT1("AppExit\n");
658
659 if (hModule)
660 pMessageBoxW = (MessageBoxW_Proc) GetProcAddress(hModule, "MessageBoxW");
661
662 if (pMessageBoxW)
663 pMessageBoxW(0, lpMessageText, NULL, MB_SYSTEMMODAL | MB_OK);
664 else
665 DPRINT1("%s\n", lpMessageText);
666
667 ExitProcess(0);
668 }
669
670
671 /*
672 * @implemented
673 */
674 VOID WINAPI
675 FatalExit (int ExitCode)
676 {
677 ExitProcess(ExitCode);
678 }
679
680
681 /*
682 * @implemented
683 */
684 DWORD WINAPI
685 GetPriorityClass (HANDLE hProcess)
686 {
687 NTSTATUS Status;
688 PROCESS_PRIORITY_CLASS PriorityClass;
689
690 Status = NtQueryInformationProcess(hProcess,
691 ProcessPriorityClass,
692 &PriorityClass,
693 sizeof(PROCESS_PRIORITY_CLASS),
694 NULL);
695 if(NT_SUCCESS(Status))
696 {
697 switch(PriorityClass.PriorityClass)
698 {
699 case PROCESS_PRIORITY_CLASS_IDLE:
700 return IDLE_PRIORITY_CLASS;
701
702 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
703 return BELOW_NORMAL_PRIORITY_CLASS;
704
705 case PROCESS_PRIORITY_CLASS_NORMAL:
706 return NORMAL_PRIORITY_CLASS;
707
708 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL:
709 return ABOVE_NORMAL_PRIORITY_CLASS;
710
711 case PROCESS_PRIORITY_CLASS_HIGH:
712 return HIGH_PRIORITY_CLASS;
713
714 case PROCESS_PRIORITY_CLASS_REALTIME:
715 return REALTIME_PRIORITY_CLASS;
716
717 default:
718 return NORMAL_PRIORITY_CLASS;
719 }
720 }
721
722 SetLastErrorByStatus(Status);
723 return FALSE;
724 }
725
726
727 /*
728 * @implemented
729 */
730 BOOL WINAPI
731 SetPriorityClass (HANDLE hProcess,
732 DWORD dwPriorityClass)
733 {
734 NTSTATUS Status;
735 PROCESS_PRIORITY_CLASS PriorityClass;
736
737 switch(dwPriorityClass)
738 {
739 case IDLE_PRIORITY_CLASS:
740 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
741 break;
742
743 case BELOW_NORMAL_PRIORITY_CLASS:
744 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
745 break;
746
747 case NORMAL_PRIORITY_CLASS:
748 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
749 break;
750
751 case ABOVE_NORMAL_PRIORITY_CLASS:
752 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
753 break;
754
755 case HIGH_PRIORITY_CLASS:
756 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
757 break;
758
759 case REALTIME_PRIORITY_CLASS:
760 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
761 break;
762
763 default:
764 SetLastError(ERROR_INVALID_PARAMETER);
765 return FALSE;
766 }
767
768 PriorityClass.Foreground = FALSE;
769
770 Status = NtSetInformationProcess(hProcess,
771 ProcessPriorityClass,
772 &PriorityClass,
773 sizeof(PROCESS_PRIORITY_CLASS));
774
775 if(!NT_SUCCESS(Status))
776 {
777 SetLastErrorByStatus(Status);
778 return FALSE;
779 }
780
781 return TRUE;
782 }
783
784
785 /*
786 * @implemented
787 */
788 DWORD WINAPI
789 GetProcessVersion(DWORD ProcessId)
790 {
791 DWORD Version = 0;
792 PIMAGE_NT_HEADERS NtHeader = NULL;
793 IMAGE_NT_HEADERS NtHeaders;
794 IMAGE_DOS_HEADER DosHeader;
795 PROCESS_BASIC_INFORMATION ProcessBasicInfo;
796 PVOID BaseAddress = NULL;
797 HANDLE ProcessHandle;
798 NTSTATUS Status;
799 SIZE_T Count;
800 PEB Peb;
801
802 _SEH2_TRY
803 {
804 /* Caller's */
805 if (0 == ProcessId || GetCurrentProcessId() == ProcessId)
806 {
807 BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
808 NtHeader = RtlImageNtHeader(BaseAddress);
809
810 Version = (NtHeader->OptionalHeader.MajorOperatingSystemVersion << 16) |
811 (NtHeader->OptionalHeader.MinorOperatingSystemVersion);
812 }
813 else /* other process */
814 {
815 ProcessHandle = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
816 FALSE,
817 ProcessId);
818
819 if (!ProcessHandle) return 0;
820
821 Status = NtQueryInformationProcess(ProcessHandle,
822 ProcessBasicInformation,
823 &ProcessBasicInfo,
824 sizeof(ProcessBasicInfo),
825 NULL);
826 if (!NT_SUCCESS(Status)) goto Error;
827
828 Status = NtReadVirtualMemory(ProcessHandle,
829 ProcessBasicInfo.PebBaseAddress,
830 &Peb,
831 sizeof(Peb),
832 &Count);
833 if (!NT_SUCCESS(Status) || Count != sizeof(Peb)) goto Error;
834
835 memset(&DosHeader, 0, sizeof(DosHeader));
836 Status = NtReadVirtualMemory(ProcessHandle,
837 Peb.ImageBaseAddress,
838 &DosHeader,
839 sizeof(DosHeader),
840 &Count);
841
842 if (!NT_SUCCESS(Status) || Count != sizeof(DosHeader)) goto Error;
843 if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) goto Error;
844
845 memset(&NtHeaders, 0, sizeof(NtHeaders));
846 Status = NtReadVirtualMemory(ProcessHandle,
847 (char *)Peb.ImageBaseAddress + DosHeader.e_lfanew,
848 &NtHeaders,
849 sizeof(NtHeaders),
850 &Count);
851
852 if (!NT_SUCCESS(Status) || Count != sizeof(NtHeaders)) goto Error;
853 if (NtHeaders.Signature != IMAGE_NT_SIGNATURE) goto Error;
854
855 Version = MAKELONG(NtHeaders.OptionalHeader.MinorSubsystemVersion,
856 NtHeaders.OptionalHeader.MajorSubsystemVersion);
857
858 Error:
859 if (!NT_SUCCESS(Status))
860 {
861 SetLastErrorByStatus(Status);
862 }
863 }
864 }
865 _SEH2_FINALLY
866 {
867 if (ProcessHandle) CloseHandle(ProcessHandle);
868 }
869 _SEH2_END;
870
871 return Version;
872 }
873
874
875 /*
876 * @implemented
877 */
878 BOOL
879 WINAPI
880 GetProcessIoCounters(
881 HANDLE hProcess,
882 PIO_COUNTERS lpIoCounters)
883 {
884 NTSTATUS Status;
885
886 Status = NtQueryInformationProcess(hProcess,
887 ProcessIoCounters,
888 lpIoCounters,
889 sizeof(IO_COUNTERS),
890 NULL);
891 if (!NT_SUCCESS(Status))
892 {
893 SetLastErrorByStatus(Status);
894 return(FALSE);
895 }
896
897 return TRUE;
898 }
899
900
901 /*
902 * @implemented
903 */
904 BOOL
905 WINAPI
906 GetProcessPriorityBoost(HANDLE hProcess,
907 PBOOL pDisablePriorityBoost)
908 {
909 NTSTATUS Status;
910 ULONG PriorityBoost;
911
912 Status = NtQueryInformationProcess(hProcess,
913 ProcessPriorityBoost,
914 &PriorityBoost,
915 sizeof(ULONG),
916 NULL);
917 if (NT_SUCCESS(Status))
918 {
919 *pDisablePriorityBoost = PriorityBoost;
920 return TRUE;
921 }
922
923 SetLastErrorByStatus(Status);
924 return FALSE;
925 }
926
927
928 /*
929 * @implemented
930 */
931 BOOL
932 WINAPI
933 SetProcessPriorityBoost(HANDLE hProcess,
934 BOOL bDisablePriorityBoost)
935 {
936 NTSTATUS Status;
937 ULONG PriorityBoost = (bDisablePriorityBoost ? TRUE : FALSE); /* prevent setting values other than 1 and 0 */
938
939 Status = NtSetInformationProcess(hProcess,
940 ProcessPriorityBoost,
941 &PriorityBoost,
942 sizeof(ULONG));
943 if (!NT_SUCCESS(Status))
944 {
945 SetLastErrorByStatus(Status);
946 return FALSE;
947 }
948
949 return TRUE;
950 }
951
952
953 /*
954 * @implemented
955 */
956 BOOL
957 WINAPI
958 GetProcessHandleCount(HANDLE hProcess,
959 PDWORD pdwHandleCount)
960 {
961 ULONG phc;
962 NTSTATUS Status;
963
964 Status = NtQueryInformationProcess(hProcess,
965 ProcessHandleCount,
966 &phc,
967 sizeof(ULONG),
968 NULL);
969 if(NT_SUCCESS(Status))
970 {
971 *pdwHandleCount = phc;
972 return TRUE;
973 }
974
975 SetLastErrorByStatus(Status);
976 return FALSE;
977 }
978
979
980 /*
981 * @implemented
982 */
983 BOOL
984 WINAPI
985 IsWow64Process(
986 HANDLE hProcess,
987 PBOOL Wow64Process
988 )
989 {
990 ULONG pbi;
991 NTSTATUS Status;
992
993 Status = NtQueryInformationProcess(hProcess,
994 ProcessWow64Information,
995 &pbi,
996 sizeof(pbi),
997 NULL);
998
999 if (!NT_SUCCESS(Status))
1000 {
1001 SetLastError(RtlNtStatusToDosError(Status));
1002 return FALSE;
1003 }
1004
1005 *Wow64Process = (pbi != 0);
1006 return TRUE;
1007 }
1008
1009
1010 /*
1011 * @implemented
1012 */
1013 BOOL
1014 WINAPI
1015 QueryFullProcessImageNameW(HANDLE hProcess,
1016 DWORD dwFlags,
1017 LPWSTR lpExeName,
1018 PDWORD pdwSize)
1019 {
1020 BYTE Buffer[sizeof(UNICODE_STRING) + MAX_PATH * sizeof(WCHAR)];
1021 UNICODE_STRING *DynamicBuffer = NULL;
1022 UNICODE_STRING *Result = NULL;
1023 NTSTATUS Status;
1024 DWORD Needed;
1025
1026 Status = NtQueryInformationProcess(hProcess,
1027 ProcessImageFileName,
1028 Buffer,
1029 sizeof(Buffer) - sizeof(WCHAR),
1030 &Needed);
1031 if (Status == STATUS_INFO_LENGTH_MISMATCH)
1032 {
1033 DynamicBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Needed + sizeof(WCHAR));
1034 if (!DynamicBuffer)
1035 {
1036 SetLastErrorByStatus(STATUS_NO_MEMORY);
1037 return FALSE;
1038 }
1039
1040 Status = NtQueryInformationProcess(hProcess,
1041 ProcessImageFileName,
1042 (LPBYTE)DynamicBuffer,
1043 Needed,
1044 &Needed);
1045 Result = DynamicBuffer;
1046 }
1047 else Result = (PUNICODE_STRING)Buffer;
1048
1049 if (!NT_SUCCESS(Status)) goto Cleanup;
1050
1051 if (Result->Length / sizeof(WCHAR) + 1 > *pdwSize)
1052 {
1053 Status = STATUS_BUFFER_TOO_SMALL;
1054 goto Cleanup;
1055 }
1056
1057 *pdwSize = Result->Length / sizeof(WCHAR);
1058 memcpy(lpExeName, Result->Buffer, Result->Length);
1059 lpExeName[*pdwSize] = 0;
1060
1061 Cleanup:
1062 RtlFreeHeap(RtlGetProcessHeap(), 0, DynamicBuffer);
1063
1064 if (!NT_SUCCESS(Status))
1065 {
1066 SetLastErrorByStatus(Status);
1067 }
1068 return !Status;
1069 }
1070
1071
1072 /*
1073 * @implemented
1074 */
1075 BOOL
1076 WINAPI
1077 QueryFullProcessImageNameA(HANDLE hProcess,
1078 DWORD dwFlags,
1079 LPSTR lpExeName,
1080 PDWORD pdwSize)
1081 {
1082 DWORD pdwSizeW = *pdwSize;
1083 BOOL Result;
1084 LPWSTR lpExeNameW;
1085
1086 lpExeNameW = RtlAllocateHeap(RtlGetProcessHeap(),
1087 HEAP_ZERO_MEMORY,
1088 *pdwSize * sizeof(WCHAR));
1089 if (!lpExeNameW)
1090 {
1091 SetLastErrorByStatus(STATUS_NO_MEMORY);
1092 return FALSE;
1093 }
1094
1095 Result = QueryFullProcessImageNameW(hProcess, dwFlags, lpExeNameW, &pdwSizeW);
1096
1097 if (Result)
1098 Result = (0 != WideCharToMultiByte(CP_ACP, 0,
1099 lpExeNameW,
1100 -1,
1101 lpExeName,
1102 *pdwSize,
1103 NULL, NULL));
1104 if (Result)
1105 *pdwSize = strlen(lpExeName);
1106
1107 RtlFreeHeap(RtlGetProcessHeap(), 0, lpExeNameW);
1108 return Result;
1109 }
1110
1111 /* EOF */