- Implement ProtocolResetComplete
[reactos.git] / 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 /* 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 = (WORD)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 * @implemented
424 */
425 VOID STDCALL
426 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
427 {
428 PRTL_USER_PROCESS_PARAMETERS Params;
429
430 if (lpStartupInfo == NULL)
431 {
432 SetLastError(ERROR_INVALID_PARAMETER);
433 return;
434 }
435
436 Params = NtCurrentPeb()->ProcessParameters;
437
438 lpStartupInfo->cb = sizeof(STARTUPINFOW);
439 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
440 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
441 lpStartupInfo->dwX = Params->StartingX;
442 lpStartupInfo->dwY = Params->StartingY;
443 lpStartupInfo->dwXSize = Params->CountX;
444 lpStartupInfo->dwYSize = Params->CountY;
445 lpStartupInfo->dwXCountChars = Params->CountCharsX;
446 lpStartupInfo->dwYCountChars = Params->CountCharsY;
447 lpStartupInfo->dwFillAttribute = Params->FillAttribute;
448 lpStartupInfo->dwFlags = Params->WindowFlags;
449 lpStartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
450 lpStartupInfo->cbReserved2 = Params->RuntimeData.Length;
451 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
452
453 lpStartupInfo->hStdInput = Params->StandardInput;
454 lpStartupInfo->hStdOutput = Params->StandardOutput;
455 lpStartupInfo->hStdError = Params->StandardError;
456 }
457
458
459 /*
460 * @implemented
461 */
462 VOID STDCALL
463 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
464 {
465 PRTL_USER_PROCESS_PARAMETERS Params;
466 ANSI_STRING AnsiString;
467
468 if (lpStartupInfo == NULL)
469 {
470 SetLastError(ERROR_INVALID_PARAMETER);
471 return;
472 }
473
474 Params = NtCurrentPeb ()->ProcessParameters;
475
476 RtlAcquirePebLock ();
477
478 /* FIXME - not thread-safe */
479 if (lpLocalStartupInfo == NULL)
480 {
481 /* create new local startup info (ansi) */
482 lpLocalStartupInfo = RtlAllocateHeap (RtlGetProcessHeap (),
483 0,
484 sizeof(STARTUPINFOA));
485 if (lpLocalStartupInfo == NULL)
486 {
487 RtlReleasePebLock ();
488 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
489 return;
490 }
491
492 lpLocalStartupInfo->cb = sizeof(STARTUPINFOA);
493
494 /* copy window title string */
495 RtlUnicodeStringToAnsiString (&AnsiString,
496 &Params->WindowTitle,
497 TRUE);
498 lpLocalStartupInfo->lpTitle = AnsiString.Buffer;
499
500 /* copy desktop info string */
501 RtlUnicodeStringToAnsiString (&AnsiString,
502 &Params->DesktopInfo,
503 TRUE);
504 lpLocalStartupInfo->lpDesktop = AnsiString.Buffer;
505
506 /* copy shell info string */
507 RtlUnicodeStringToAnsiString (&AnsiString,
508 &Params->ShellInfo,
509 TRUE);
510 lpLocalStartupInfo->lpReserved = AnsiString.Buffer;
511
512 lpLocalStartupInfo->dwX = Params->StartingX;
513 lpLocalStartupInfo->dwY = Params->StartingY;
514 lpLocalStartupInfo->dwXSize = Params->CountX;
515 lpLocalStartupInfo->dwYSize = Params->CountY;
516 lpLocalStartupInfo->dwXCountChars = Params->CountCharsX;
517 lpLocalStartupInfo->dwYCountChars = Params->CountCharsY;
518 lpLocalStartupInfo->dwFillAttribute = Params->FillAttribute;
519 lpLocalStartupInfo->dwFlags = Params->WindowFlags;
520 lpLocalStartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
521 lpLocalStartupInfo->cbReserved2 = Params->RuntimeData.Length;
522 lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
523
524 lpLocalStartupInfo->hStdInput = Params->StandardInput;
525 lpLocalStartupInfo->hStdOutput = Params->StandardOutput;
526 lpLocalStartupInfo->hStdError = Params->StandardError;
527 }
528
529 RtlReleasePebLock ();
530
531 /* copy local startup info data to external startup info */
532 memcpy (lpStartupInfo,
533 lpLocalStartupInfo,
534 sizeof(STARTUPINFOA));
535 }
536
537
538 /*
539 * @implemented
540 */
541 BOOL STDCALL
542 FlushInstructionCache (HANDLE hProcess,
543 LPCVOID lpBaseAddress,
544 DWORD dwSize)
545 {
546 NTSTATUS Status;
547
548 Status = NtFlushInstructionCache(hProcess,
549 (PVOID)lpBaseAddress,
550 dwSize);
551 if (!NT_SUCCESS(Status))
552 {
553 SetLastErrorByStatus(Status);
554 return FALSE;
555 }
556 return TRUE;
557 }
558
559
560 /*
561 * @implemented
562 */
563 VOID STDCALL
564 ExitProcess(UINT uExitCode)
565 {
566 CSR_API_MESSAGE CsrRequest;
567 ULONG Request;
568 NTSTATUS Status;
569
570 /* kill sibling threads ... we want to be alone at this point */
571 NtTerminateProcess (NULL, 0);
572
573 /* unload all dll's */
574 LdrShutdownProcess ();
575
576 /* notify csrss of process termination */
577 Request = TERMINATE_PROCESS;
578 Status = CsrClientCallServer(&CsrRequest,
579 NULL,
580 MAKE_CSR_API(Request, CSR_NATIVE),
581 sizeof(CSR_API_MESSAGE));
582 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
583 {
584 DPRINT("Failed to tell csrss about terminating process\n");
585 }
586
587
588 NtTerminateProcess (NtCurrentProcess (),
589 uExitCode);
590
591 /* should never get here */
592 ASSERT(0);
593 while(1);
594 }
595
596
597 /*
598 * @implemented
599 */
600 BOOL STDCALL
601 TerminateProcess (HANDLE hProcess,
602 UINT uExitCode)
603 {
604 NTSTATUS Status;
605
606 Status = NtTerminateProcess (hProcess, uExitCode);
607 if (NT_SUCCESS(Status))
608 {
609 return TRUE;
610 }
611 SetLastErrorByStatus (Status);
612 return FALSE;
613 }
614
615
616 /*
617 * @unimplemented
618 */
619 VOID STDCALL
620 FatalAppExitA (UINT uAction,
621 LPCSTR lpMessageText)
622 {
623 UNICODE_STRING MessageTextU;
624 ANSI_STRING MessageText;
625
626 RtlInitAnsiString (&MessageText, (LPSTR) lpMessageText);
627
628 RtlAnsiStringToUnicodeString (&MessageTextU,
629 &MessageText,
630 TRUE);
631
632 FatalAppExitW (uAction, MessageTextU.Buffer);
633
634 RtlFreeUnicodeString (&MessageTextU);
635 }
636
637
638 /*
639 * @unimplemented
640 */
641 VOID STDCALL
642 FatalAppExitW(UINT uAction,
643 LPCWSTR lpMessageText)
644 {
645 return;
646 }
647
648
649 /*
650 * @implemented
651 */
652 VOID STDCALL
653 FatalExit (int ExitCode)
654 {
655 ExitProcess(ExitCode);
656 }
657
658
659 /*
660 * @implemented
661 */
662 DWORD STDCALL
663 GetPriorityClass (HANDLE hProcess)
664 {
665 NTSTATUS Status;
666 PROCESS_PRIORITY_CLASS PriorityClass;
667
668 Status = NtQueryInformationProcess(hProcess,
669 ProcessPriorityClass,
670 &PriorityClass,
671 sizeof(PROCESS_PRIORITY_CLASS),
672 NULL);
673 if(NT_SUCCESS(Status))
674 {
675 switch(PriorityClass.PriorityClass)
676 {
677 case PROCESS_PRIORITY_CLASS_IDLE:
678 return IDLE_PRIORITY_CLASS;
679
680 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL:
681 return BELOW_NORMAL_PRIORITY_CLASS;
682
683 case PROCESS_PRIORITY_CLASS_NORMAL:
684 return NORMAL_PRIORITY_CLASS;
685
686 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL:
687 return ABOVE_NORMAL_PRIORITY_CLASS;
688
689 case PROCESS_PRIORITY_CLASS_HIGH:
690 return HIGH_PRIORITY_CLASS;
691
692 case PROCESS_PRIORITY_CLASS_REALTIME:
693 return REALTIME_PRIORITY_CLASS;
694
695 default:
696 return NORMAL_PRIORITY_CLASS;
697 }
698 }
699
700 SetLastErrorByStatus(Status);
701 return FALSE;
702 }
703
704
705 /*
706 * @implemented
707 */
708 BOOL STDCALL
709 SetPriorityClass (HANDLE hProcess,
710 DWORD dwPriorityClass)
711 {
712 NTSTATUS Status;
713 PROCESS_PRIORITY_CLASS PriorityClass;
714
715 switch(dwPriorityClass)
716 {
717 case IDLE_PRIORITY_CLASS:
718 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
719 break;
720
721 case BELOW_NORMAL_PRIORITY_CLASS:
722 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
723 break;
724
725 case NORMAL_PRIORITY_CLASS:
726 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
727 break;
728
729 case ABOVE_NORMAL_PRIORITY_CLASS:
730 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
731 break;
732
733 case HIGH_PRIORITY_CLASS:
734 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
735 break;
736
737 case REALTIME_PRIORITY_CLASS:
738 PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
739 break;
740
741 default:
742 SetLastError(ERROR_INVALID_PARAMETER);
743 return FALSE;
744 }
745
746 PriorityClass.Foreground = FALSE;
747
748 Status = NtSetInformationProcess(hProcess,
749 ProcessPriorityClass,
750 &PriorityClass,
751 sizeof(PROCESS_PRIORITY_CLASS));
752
753 if(!NT_SUCCESS(Status))
754 {
755 SetLastErrorByStatus(Status);
756 return FALSE;
757 }
758
759 return TRUE;
760 }
761
762
763 /*
764 * @implemented
765 */
766 DWORD STDCALL
767 GetProcessVersion (DWORD ProcessId)
768 {
769 DWORD Version = 0;
770 PIMAGE_NT_HEADERS NtHeader = NULL;
771 PVOID BaseAddress = NULL;
772
773 /* Caller's */
774 if (0 == ProcessId || GetCurrentProcessId() == ProcessId)
775 {
776 BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
777 NtHeader = RtlImageNtHeader (BaseAddress);
778 if (NULL != NtHeader)
779 {
780 Version =
781 (NtHeader->OptionalHeader.MajorOperatingSystemVersion << 16) |
782 (NtHeader->OptionalHeader.MinorOperatingSystemVersion);
783 }
784 }
785 else /* other process */
786 {
787 /* FIXME: open the other process */
788 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
789 }
790 return (Version);
791 }
792
793
794 /*
795 * @implemented
796 */
797 BOOL
798 STDCALL
799 GetProcessIoCounters(
800 HANDLE hProcess,
801 PIO_COUNTERS lpIoCounters)
802 {
803 NTSTATUS Status;
804
805 Status = NtQueryInformationProcess(hProcess,
806 ProcessIoCounters,
807 lpIoCounters,
808 sizeof(IO_COUNTERS),
809 NULL);
810 if (!NT_SUCCESS(Status))
811 {
812 SetLastErrorByStatus(Status);
813 return(FALSE);
814 }
815
816 return TRUE;
817 }
818
819
820 /*
821 * @implemented
822 */
823 BOOL
824 STDCALL
825 GetProcessPriorityBoost(HANDLE hProcess,
826 PBOOL pDisablePriorityBoost)
827 {
828 NTSTATUS Status;
829 ULONG PriorityBoost;
830
831 Status = NtQueryInformationProcess(hProcess,
832 ProcessPriorityBoost,
833 &PriorityBoost,
834 sizeof(ULONG),
835 NULL);
836 if (NT_SUCCESS(Status))
837 {
838 *pDisablePriorityBoost = PriorityBoost;
839 return TRUE;
840 }
841
842 SetLastErrorByStatus(Status);
843 return FALSE;
844 }
845
846
847 /*
848 * @implemented
849 */
850 BOOL
851 STDCALL
852 SetProcessPriorityBoost(HANDLE hProcess,
853 BOOL bDisablePriorityBoost)
854 {
855 NTSTATUS Status;
856 ULONG PriorityBoost = (bDisablePriorityBoost ? TRUE : FALSE); /* prevent setting values other than 1 and 0 */
857
858 Status = NtSetInformationProcess(hProcess,
859 ProcessPriorityBoost,
860 &PriorityBoost,
861 sizeof(ULONG));
862 if (!NT_SUCCESS(Status))
863 {
864 SetLastErrorByStatus(Status);
865 return FALSE;
866 }
867
868 return TRUE;
869 }
870
871
872 /*
873 * @implemented
874 */
875 BOOL
876 STDCALL
877 GetProcessHandleCount(HANDLE hProcess,
878 PDWORD pdwHandleCount)
879 {
880 ULONG phc;
881 NTSTATUS Status;
882
883 Status = NtQueryInformationProcess(hProcess,
884 ProcessHandleCount,
885 &phc,
886 sizeof(ULONG),
887 NULL);
888 if(NT_SUCCESS(Status))
889 {
890 *pdwHandleCount = phc;
891 return TRUE;
892 }
893
894 SetLastErrorByStatus(Status);
895 return FALSE;
896 }
897
898 /* EOF */