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