reshuffling of dlls
[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 "../include/debug.h"
18
19
20 /* GLOBALS *******************************************************************/
21
22 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
23
24 LPSTARTUPINFOA lpLocalStartupInfo = NULL;
25
26 VOID STDCALL
27 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
28
29 /* FUNCTIONS ****************************************************************/
30
31 /*
32 * @implemented
33 */
34 BOOL STDCALL
35 GetProcessAffinityMask (HANDLE hProcess,
36 LPDWORD lpProcessAffinityMask,
37 LPDWORD lpSystemAffinityMask)
38 {
39 PROCESS_BASIC_INFORMATION ProcessInfo;
40 SYSTEM_BASIC_INFORMATION SystemInfo;
41 NTSTATUS Status;
42
43 Status = NtQuerySystemInformation(SystemBasicInformation,
44 &SystemInfo,
45 sizeof(SystemInfo),
46 NULL);
47 if (!NT_SUCCESS(Status))
48 {
49 SetLastErrorByStatus (Status);
50 return FALSE;
51 }
52
53 Status = NtQueryInformationProcess (hProcess,
54 ProcessBasicInformation,
55 (PVOID)&ProcessInfo,
56 sizeof(PROCESS_BASIC_INFORMATION),
57 NULL);
58 if (!NT_SUCCESS(Status))
59 {
60 SetLastErrorByStatus (Status);
61 return FALSE;
62 }
63
64 *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask;
65 *lpSystemAffinityMask = (DWORD)SystemInfo.ActiveProcessorsAffinityMask;
66
67 return TRUE;
68 }
69
70
71 /*
72 * @implemented
73 */
74 BOOL STDCALL
75 SetProcessAffinityMask (HANDLE hProcess,
76 DWORD dwProcessAffinityMask)
77 {
78 NTSTATUS Status;
79
80 Status = NtSetInformationProcess (hProcess,
81 ProcessAffinityMask,
82 (PVOID)&dwProcessAffinityMask,
83 sizeof(DWORD));
84 if (!NT_SUCCESS(Status))
85 {
86 SetLastErrorByStatus (Status);
87 return FALSE;
88 }
89
90 return TRUE;
91 }
92
93
94 /*
95 * @implemented
96 */
97 BOOL STDCALL
98 GetProcessShutdownParameters (LPDWORD lpdwLevel,
99 LPDWORD lpdwFlags)
100 {
101 CSR_API_MESSAGE CsrRequest;
102 ULONG Request;
103 NTSTATUS Status;
104
105 Request = GET_SHUTDOWN_PARAMETERS;
106 Status = CsrClientCallServer(&CsrRequest,
107 NULL,
108 MAKE_CSR_API(Request, CSR_NATIVE),
109 sizeof(CSR_API_MESSAGE));
110 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
111 {
112 SetLastErrorByStatus (Status);
113 return(FALSE);
114 }
115
116 *lpdwLevel = CsrRequest.Data.GetShutdownParametersRequest.Level;
117 *lpdwFlags = CsrRequest.Data.GetShutdownParametersRequest.Flags;
118
119 return(TRUE);
120 }
121
122
123 /*
124 * @implemented
125 */
126 BOOL STDCALL
127 SetProcessShutdownParameters (DWORD dwLevel,
128 DWORD dwFlags)
129 {
130 CSR_API_MESSAGE CsrRequest;
131 ULONG Request;
132 NTSTATUS Status;
133
134 CsrRequest.Data.SetShutdownParametersRequest.Level = dwLevel;
135 CsrRequest.Data.SetShutdownParametersRequest.Flags = dwFlags;
136
137 Request = SET_SHUTDOWN_PARAMETERS;
138 Status = CsrClientCallServer(&CsrRequest,
139 NULL,
140 MAKE_CSR_API(Request, CSR_NATIVE),
141 sizeof(CSR_API_MESSAGE));
142 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
143 {
144 SetLastErrorByStatus (Status);
145 return(FALSE);
146 }
147
148 return(TRUE);
149 }
150
151
152 /*
153 * @implemented
154 */
155 BOOL STDCALL
156 GetProcessWorkingSetSize (HANDLE hProcess,
157 PSIZE_T lpMinimumWorkingSetSize,
158 PSIZE_T lpMaximumWorkingSetSize)
159 {
160 QUOTA_LIMITS QuotaLimits;
161 NTSTATUS Status;
162
163 Status = NtQueryInformationProcess(hProcess,
164 ProcessQuotaLimits,
165 &QuotaLimits,
166 sizeof(QUOTA_LIMITS),
167 NULL);
168 if (!NT_SUCCESS(Status))
169 {
170 SetLastErrorByStatus(Status);
171 return(FALSE);
172 }
173
174 *lpMinimumWorkingSetSize = QuotaLimits.MinimumWorkingSetSize;
175 *lpMaximumWorkingSetSize = QuotaLimits.MaximumWorkingSetSize;
176
177 return(TRUE);
178 }
179
180
181 /*
182 * @implemented
183 */
184 BOOL STDCALL
185 SetProcessWorkingSetSize(HANDLE hProcess,
186 SIZE_T dwMinimumWorkingSetSize,
187 SIZE_T dwMaximumWorkingSetSize)
188 {
189 QUOTA_LIMITS QuotaLimits;
190 NTSTATUS Status;
191
192 QuotaLimits.MinimumWorkingSetSize = dwMinimumWorkingSetSize;
193 QuotaLimits.MaximumWorkingSetSize = dwMaximumWorkingSetSize;
194
195 Status = NtSetInformationProcess(hProcess,
196 ProcessQuotaLimits,
197 &QuotaLimits,
198 sizeof(QUOTA_LIMITS));
199 if (!NT_SUCCESS(Status))
200 {
201 SetLastErrorByStatus(Status);
202 return(FALSE);
203 }
204
205 return(TRUE);
206 }
207
208
209 /*
210 * @implemented
211 */
212 BOOL STDCALL
213 GetProcessTimes(HANDLE hProcess,
214 LPFILETIME lpCreationTime,
215 LPFILETIME lpExitTime,
216 LPFILETIME lpKernelTime,
217 LPFILETIME lpUserTime)
218 {
219 KERNEL_USER_TIMES Kut;
220 NTSTATUS Status;
221
222 Status = NtQueryInformationProcess(hProcess,
223 ProcessTimes,
224 &Kut,
225 sizeof(Kut),
226 NULL);
227 if (!NT_SUCCESS(Status))
228 {
229 SetLastErrorByStatus(Status);
230 return(FALSE);
231 }
232
233 lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
234 lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
235
236 lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
237 lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
238
239 lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
240 lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
241
242 lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
243 lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
244
245 return(TRUE);
246 }
247
248
249 /*
250 * @implemented
251 */
252 HANDLE STDCALL
253 GetCurrentProcess(VOID)
254 {
255 return((HANDLE)NtCurrentProcess());
256 }
257
258
259 /*
260 * @implemented
261 */
262 HANDLE STDCALL
263 GetCurrentThread(VOID)
264 {
265 return((HANDLE)NtCurrentThread());
266 }
267
268
269 /*
270 * @implemented
271 */
272 DWORD STDCALL
273 GetCurrentProcessId(VOID)
274 {
275 return((DWORD)GetTeb()->Cid.UniqueProcess);
276 }
277
278
279 /*
280 * @implemented
281 */
282 BOOL STDCALL
283 GetExitCodeProcess(HANDLE hProcess,
284 LPDWORD lpExitCode)
285 {
286 PROCESS_BASIC_INFORMATION ProcessBasic;
287 NTSTATUS Status;
288
289 Status = NtQueryInformationProcess(hProcess,
290 ProcessBasicInformation,
291 &ProcessBasic,
292 sizeof(PROCESS_BASIC_INFORMATION),
293 NULL);
294 if (!NT_SUCCESS(Status))
295 {
296 SetLastErrorByStatus(Status);
297 return(FALSE);
298 }
299
300 *lpExitCode = (DWORD)ProcessBasic.ExitStatus;
301
302 return(TRUE);
303 }
304
305
306 /*
307 * @implemented
308 */
309 DWORD
310 STDCALL
311 GetProcessId(HANDLE Process)
312 {
313 PROCESS_BASIC_INFORMATION ProcessBasic;
314 NTSTATUS Status;
315
316 Status = NtQueryInformationProcess(Process,
317 ProcessBasicInformation,
318 &ProcessBasic,
319 sizeof(PROCESS_BASIC_INFORMATION),
320 NULL);
321 if (!NT_SUCCESS(Status))
322 {
323 SetLastErrorByStatus(Status);
324 return 0;
325 }
326
327 return (DWORD)ProcessBasic.UniqueProcessId;
328 }
329
330
331 /*
332 * @implemented
333 */
334 HANDLE STDCALL
335 OpenProcess(DWORD dwDesiredAccess,
336 BOOL bInheritHandle,
337 DWORD dwProcessId)
338 {
339 NTSTATUS errCode;
340 HANDLE ProcessHandle;
341 OBJECT_ATTRIBUTES ObjectAttributes;
342 CLIENT_ID ClientId;
343
344 ClientId.UniqueProcess = (HANDLE)dwProcessId;
345 ClientId.UniqueThread = 0;
346
347 InitializeObjectAttributes(&ObjectAttributes,
348 NULL,
349 (bInheritHandle ? OBJ_INHERIT : 0),
350 NULL,
351 NULL);
352
353 errCode = NtOpenProcess(&ProcessHandle,
354 dwDesiredAccess,
355 &ObjectAttributes,
356 &ClientId);
357 if (!NT_SUCCESS(errCode))
358 {
359 SetLastErrorByStatus (errCode);
360 return NULL;
361 }
362 return ProcessHandle;
363 }
364
365
366 /*
367 * @implemented
368 */
369 UINT STDCALL
370 WinExec(LPCSTR lpCmdLine,
371 UINT uCmdShow)
372 {
373 STARTUPINFOA StartupInfo;
374 PROCESS_INFORMATION ProcessInformation;
375 DWORD dosErr;
376
377 RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
378 StartupInfo.cb = sizeof(STARTUPINFOA);
379 StartupInfo.wShowWindow = uCmdShow;
380 StartupInfo.dwFlags = 0;
381
382 if (! CreateProcessA(NULL,
383 (PVOID)lpCmdLine,
384 NULL,
385 NULL,
386 FALSE,
387 0,
388 NULL,
389 NULL,
390 &StartupInfo,
391 &ProcessInformation))
392 {
393 dosErr = GetLastError();
394 return dosErr < 32 ? dosErr : ERROR_BAD_FORMAT;
395 }
396 if (NULL != lpfnGlobalRegisterWaitForInputIdle)
397 {
398 lpfnGlobalRegisterWaitForInputIdle (
399 ProcessInformation.hProcess,
400 10000
401 );
402 }
403 NtClose(ProcessInformation.hProcess);
404 NtClose(ProcessInformation.hThread);
405
406 return 33; /* Something bigger than 31 means success. */
407 }
408
409
410 /*
411 * @implemented
412 */
413 VOID STDCALL
414 RegisterWaitForInputIdle (
415 WaitForInputIdleType lpfnRegisterWaitForInputIdle
416 )
417 {
418 lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
419 return;
420 }
421
422
423 /*
424 * @unimplemented
425 */
426 DWORD STDCALL
427 WaitForInputIdle (
428 HANDLE hProcess,
429 DWORD dwMilliseconds
430 )
431 {
432 return 0;
433 }
434
435
436 /*
437 * @implemented
438 */
439 VOID STDCALL
440 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
441 {
442 PRTL_USER_PROCESS_PARAMETERS Params;
443
444 if (lpStartupInfo == NULL)
445 {
446 SetLastError(ERROR_INVALID_PARAMETER);
447 return;
448 }
449
450 Params = NtCurrentPeb()->ProcessParameters;
451
452 lpStartupInfo->cb = sizeof(STARTUPINFOW);
453 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
454 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
455 lpStartupInfo->dwX = Params->StartingX;
456 lpStartupInfo->dwY = Params->StartingY;
457 lpStartupInfo->dwXSize = Params->CountX;
458 lpStartupInfo->dwYSize = Params->CountY;
459 lpStartupInfo->dwXCountChars = Params->CountCharsX;
460 lpStartupInfo->dwYCountChars = Params->CountCharsY;
461 lpStartupInfo->dwFillAttribute = Params->FillAttribute;
462 lpStartupInfo->dwFlags = Params->WindowFlags;
463 lpStartupInfo->wShowWindow = Params->ShowWindowFlags;
464 lpStartupInfo->cbReserved2 = Params->RuntimeData.Length;
465 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
466
467 lpStartupInfo->hStdInput = Params->StandardInput;
468 lpStartupInfo->hStdOutput = Params->StandardOutput;
469 lpStartupInfo->hStdError = Params->StandardError;
470 }
471
472
473 /*
474 * @implemented
475 */
476 VOID STDCALL
477 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
478 {
479 PRTL_USER_PROCESS_PARAMETERS Params;
480 ANSI_STRING AnsiString;
481
482 if (lpStartupInfo == NULL)
483 {
484 SetLastError(ERROR_INVALID_PARAMETER);
485 return;
486 }
487
488 Params = NtCurrentPeb ()->ProcessParameters;
489
490 RtlAcquirePebLock ();
491
492 /* FIXME - not thread-safe */
493 if (lpLocalStartupInfo == NULL)
494 {
495 /* create new local startup info (ansi) */
496 lpLocalStartupInfo = RtlAllocateHeap (RtlGetProcessHeap (),
497 0,
498 sizeof(STARTUPINFOA));
499 if (lpLocalStartupInfo == NULL)
500 {
501 RtlReleasePebLock ();
502 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
503 return;
504 }
505
506 lpLocalStartupInfo->cb = sizeof(STARTUPINFOA);
507
508 /* copy window title string */
509 RtlUnicodeStringToAnsiString (&AnsiString,
510 &Params->WindowTitle,
511 TRUE);
512 lpLocalStartupInfo->lpTitle = AnsiString.Buffer;
513
514 /* copy desktop info string */
515 RtlUnicodeStringToAnsiString (&AnsiString,
516 &Params->DesktopInfo,
517 TRUE);
518 lpLocalStartupInfo->lpDesktop = AnsiString.Buffer;
519
520 /* copy shell info string */
521 RtlUnicodeStringToAnsiString (&AnsiString,
522 &Params->ShellInfo,
523 TRUE);
524 lpLocalStartupInfo->lpReserved = AnsiString.Buffer;
525
526 lpLocalStartupInfo->dwX = Params->StartingX;
527 lpLocalStartupInfo->dwY = Params->StartingY;
528 lpLocalStartupInfo->dwXSize = Params->CountX;
529 lpLocalStartupInfo->dwYSize = Params->CountY;
530 lpLocalStartupInfo->dwXCountChars = Params->CountCharsX;
531 lpLocalStartupInfo->dwYCountChars = Params->CountCharsY;
532 lpLocalStartupInfo->dwFillAttribute = Params->FillAttribute;
533 lpLocalStartupInfo->dwFlags = Params->WindowFlags;
534 lpLocalStartupInfo->wShowWindow = Params->ShowWindowFlags;
535 lpLocalStartupInfo->cbReserved2 = Params->RuntimeData.Length;
536 lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
537
538 lpLocalStartupInfo->hStdInput = Params->StandardInput;
539 lpLocalStartupInfo->hStdOutput = Params->StandardOutput;
540 lpLocalStartupInfo->hStdError = Params->StandardError;
541 }
542
543 RtlReleasePebLock ();
544
545 /* copy local startup info data to external startup info */
546 memcpy (lpStartupInfo,
547 lpLocalStartupInfo,
548 sizeof(STARTUPINFOA));
549 }
550
551
552 /*
553 * @implemented
554 */
555 BOOL STDCALL
556 FlushInstructionCache (HANDLE hProcess,
557 LPCVOID lpBaseAddress,
558 DWORD dwSize)
559 {
560 NTSTATUS Status;
561
562 Status = NtFlushInstructionCache(hProcess,
563 (PVOID)lpBaseAddress,
564 dwSize);
565 if (!NT_SUCCESS(Status))
566 {
567 SetLastErrorByStatus(Status);
568 return FALSE;
569 }
570 return TRUE;
571 }
572
573
574 /*
575 * @implemented
576 */
577 VOID STDCALL
578 ExitProcess(UINT uExitCode)
579 {
580 CSR_API_MESSAGE CsrRequest;
581 ULONG Request;
582 NTSTATUS Status;
583
584 /* unload all dll's */
585 LdrShutdownProcess ();
586
587 /* notify csrss of process termination */
588 Request = TERMINATE_PROCESS;
589 Status = CsrClientCallServer(&CsrRequest,
590 NULL,
591 MAKE_CSR_API(Request, CSR_NATIVE),
592 sizeof(CSR_API_MESSAGE));
593 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
594 {
595 DPRINT("Failed to tell csrss about terminating process\n");
596 }
597
598
599 NtTerminateProcess (NtCurrentProcess (),
600 uExitCode);
601
602 /* should never get here */
603 ASSERT(0);
604 while(1);
605 }
606
607
608 /*
609 * @implemented
610 */
611 BOOL STDCALL
612 TerminateProcess (HANDLE hProcess,
613 UINT uExitCode)
614 {
615 NTSTATUS Status;
616
617 Status = NtTerminateProcess (hProcess, uExitCode);
618 if (NT_SUCCESS(Status))
619 {
620 return TRUE;
621 }
622 SetLastErrorByStatus (Status);
623 return FALSE;
624 }
625
626
627 /*
628 * @unimplemented
629 */
630 VOID STDCALL
631 FatalAppExitA (UINT uAction,
632 LPCSTR lpMessageText)
633 {
634 UNICODE_STRING MessageTextU;
635 ANSI_STRING MessageText;
636
637 RtlInitAnsiString (&MessageText, (LPSTR) lpMessageText);
638
639 RtlAnsiStringToUnicodeString (&MessageTextU,
640 &MessageText,
641 TRUE);
642
643 FatalAppExitW (uAction, MessageTextU.Buffer);
644
645 RtlFreeUnicodeString (&MessageTextU);
646 }
647
648
649 /*
650 * @unimplemented
651 */
652 VOID STDCALL
653 FatalAppExitW(UINT uAction,
654 LPCWSTR lpMessageText)
655 {
656 return;
657 }
658
659
660 /*
661 * @implemented
662 */
663 VOID STDCALL
664 FatalExit (int ExitCode)
665 {
666 ExitProcess(ExitCode);
667 }
668
669
670 /*
671 * @implemented
672 */
673 DWORD STDCALL
674 GetPriorityClass (HANDLE hProcess)
675 {
676 NTSTATUS Status;
677 PROCESS_PRIORITY_CLASS PriorityClass;
678
679 Status = NtQueryInformationProcess(hProcess,
680 ProcessPriorityClass,
681 &PriorityClass,
682 sizeof(PROCESS_PRIORITY_CLASS),
683 NULL);
684 if(NT_SUCCESS(Status))
685 {
686 switch(PriorityClass.PriorityClass)
687 {
688 case PROCESS_PRIORITY_CLASS_IDLE:
689 return IDLE_PRIORITY_CLASS;
690
691 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
692 return BELOW_NORMAL_PRIORITY_CLASS;
693
694 case PROCESS_PRIORITY_CLASS_NORMAL:
695 return NORMAL_PRIORITY_CLASS;
696
697 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL:
698 return ABOVE_NORMAL_PRIORITY_CLASS;
699
700 case PROCESS_PRIORITY_CLASS_HIGH:
701 return HIGH_PRIORITY_CLASS;
702
703 case PROCESS_PRIORITY_CLASS_REALTIME:
704 return REALTIME_PRIORITY_CLASS;
705
706 default:
707 return NORMAL_PRIORITY_CLASS;
708 }
709 }
710
711 SetLastErrorByStatus(Status);
712 return FALSE;
713 }
714
715
716 /*
717 * @implemented
718 */
719 BOOL STDCALL
720 SetPriorityClass (HANDLE hProcess,
721 DWORD dwPriorityClass)
722 {
723 NTSTATUS Status;
724 PROCESS_PRIORITY_CLASS PriorityClass;
725
726 switch(dwPriorityClass)
727 {
728 case IDLE_PRIORITY_CLASS:
729 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
730 break;
731
732 case BELOW_NORMAL_PRIORITY_CLASS:
733 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
734 break;
735
736 case NORMAL_PRIORITY_CLASS:
737 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
738 break;
739
740 case ABOVE_NORMAL_PRIORITY_CLASS:
741 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
742 break;
743
744 case HIGH_PRIORITY_CLASS:
745 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
746 break;
747
748 case REALTIME_PRIORITY_CLASS:
749 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
750 break;
751
752 default:
753 SetLastError(ERROR_INVALID_PARAMETER);
754 return FALSE;
755 }
756
757 PriorityClass.Foreground = FALSE;
758
759 Status = NtSetInformationProcess(hProcess,
760 ProcessPriorityClass,
761 &PriorityClass,
762 sizeof(PROCESS_PRIORITY_CLASS));
763
764 if(!NT_SUCCESS(Status))
765 {
766 SetLastErrorByStatus(Status);
767 return FALSE;
768 }
769
770 return TRUE;
771 }
772
773
774 /*
775 * @implemented
776 */
777 DWORD STDCALL
778 GetProcessVersion (DWORD ProcessId)
779 {
780 DWORD Version = 0;
781 PIMAGE_NT_HEADERS NtHeader = NULL;
782 PVOID BaseAddress = NULL;
783
784 /* Caller's */
785 if (0 == ProcessId || GetCurrentProcessId() == ProcessId)
786 {
787 BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
788 NtHeader = RtlImageNtHeader (BaseAddress);
789 if (NULL != NtHeader)
790 {
791 Version =
792 (NtHeader->OptionalHeader.MajorOperatingSystemVersion << 16) |
793 (NtHeader->OptionalHeader.MinorOperatingSystemVersion);
794 }
795 }
796 else /* other process */
797 {
798 /* FIXME: open the other process */
799 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
800 }
801 return (Version);
802 }
803
804
805 /*
806 * @implemented
807 */
808 BOOL
809 STDCALL
810 GetProcessIoCounters(
811 HANDLE hProcess,
812 PIO_COUNTERS lpIoCounters)
813 {
814 NTSTATUS Status;
815
816 Status = NtQueryInformationProcess(hProcess,
817 ProcessIoCounters,
818 lpIoCounters,
819 sizeof(IO_COUNTERS),
820 NULL);
821 if (!NT_SUCCESS(Status))
822 {
823 SetLastErrorByStatus(Status);
824 return(FALSE);
825 }
826
827 return TRUE;
828 }
829
830
831 /*
832 * @implemented
833 */
834 BOOL
835 STDCALL
836 GetProcessPriorityBoost(HANDLE hProcess,
837 PBOOL pDisablePriorityBoost)
838 {
839 NTSTATUS Status;
840 ULONG PriorityBoost;
841
842 Status = NtQueryInformationProcess(hProcess,
843 ProcessPriorityBoost,
844 &PriorityBoost,
845 sizeof(ULONG),
846 NULL);
847 if (NT_SUCCESS(Status))
848 {
849 *pDisablePriorityBoost = PriorityBoost;
850 return TRUE;
851 }
852
853 SetLastErrorByStatus(Status);
854 return FALSE;
855 }
856
857
858 /*
859 * @implemented
860 */
861 BOOL
862 STDCALL
863 SetProcessPriorityBoost(HANDLE hProcess,
864 BOOL bDisablePriorityBoost)
865 {
866 NTSTATUS Status;
867 ULONG PriorityBoost = (bDisablePriorityBoost ? TRUE : FALSE); /* prevent setting values other than 1 and 0 */
868
869 Status = NtSetInformationProcess(hProcess,
870 ProcessPriorityBoost,
871 &PriorityBoost,
872 sizeof(ULONG));
873 if (!NT_SUCCESS(Status))
874 {
875 SetLastErrorByStatus(Status);
876 return FALSE;
877 }
878
879 return TRUE;
880 }
881
882
883 /*
884 * @implemented
885 */
886 BOOL
887 STDCALL
888 GetProcessHandleCount(HANDLE hProcess,
889 PDWORD pdwHandleCount)
890 {
891 ULONG phc;
892 NTSTATUS Status;
893
894 Status = NtQueryInformationProcess(hProcess,
895 ProcessHandleCount,
896 &phc,
897 sizeof(ULONG),
898 NULL);
899 if(NT_SUCCESS(Status))
900 {
901 *pdwHandleCount = phc;
902 return TRUE;
903 }
904
905 SetLastErrorByStatus(Status);
906 return FALSE;
907 }
908
909 /* EOF */