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