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)
12 /* INCLUDES ****************************************************************/
20 typedef INT (WINAPI
*MessageBoxW_Proc
) (HWND
, LPCWSTR
, LPCWSTR
, UINT
);
22 /* GLOBALS *******************************************************************/
24 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle
;
26 LPSTARTUPINFOA lpLocalStartupInfo
= NULL
;
29 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle
);
31 /* FUNCTIONS ****************************************************************/
37 GetProcessAffinityMask (HANDLE hProcess
,
38 LPDWORD lpProcessAffinityMask
,
39 LPDWORD lpSystemAffinityMask
)
41 PROCESS_BASIC_INFORMATION ProcessInfo
;
42 SYSTEM_BASIC_INFORMATION SystemInfo
;
45 Status
= NtQuerySystemInformation(SystemBasicInformation
,
49 if (!NT_SUCCESS(Status
))
51 SetLastErrorByStatus (Status
);
55 Status
= NtQueryInformationProcess (hProcess
,
56 ProcessBasicInformation
,
58 sizeof(PROCESS_BASIC_INFORMATION
),
60 if (!NT_SUCCESS(Status
))
62 SetLastErrorByStatus (Status
);
66 *lpProcessAffinityMask
= (DWORD
)ProcessInfo
.AffinityMask
;
67 *lpSystemAffinityMask
= (DWORD
)SystemInfo
.ActiveProcessorsAffinityMask
;
77 SetProcessAffinityMask (HANDLE hProcess
,
78 DWORD dwProcessAffinityMask
)
82 Status
= NtSetInformationProcess (hProcess
,
84 (PVOID
)&dwProcessAffinityMask
,
86 if (!NT_SUCCESS(Status
))
88 SetLastErrorByStatus (Status
);
100 GetProcessShutdownParameters (LPDWORD lpdwLevel
,
103 CSR_API_MESSAGE CsrRequest
;
107 Request
= GET_SHUTDOWN_PARAMETERS
;
108 Status
= CsrClientCallServer(&CsrRequest
,
110 MAKE_CSR_API(Request
, CSR_NATIVE
),
111 sizeof(CSR_API_MESSAGE
));
112 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.Status
))
114 SetLastErrorByStatus (Status
);
118 *lpdwLevel
= CsrRequest
.Data
.GetShutdownParametersRequest
.Level
;
119 *lpdwFlags
= CsrRequest
.Data
.GetShutdownParametersRequest
.Flags
;
129 SetProcessShutdownParameters (DWORD dwLevel
,
132 CSR_API_MESSAGE CsrRequest
;
136 CsrRequest
.Data
.SetShutdownParametersRequest
.Level
= dwLevel
;
137 CsrRequest
.Data
.SetShutdownParametersRequest
.Flags
= dwFlags
;
139 Request
= SET_SHUTDOWN_PARAMETERS
;
140 Status
= CsrClientCallServer(&CsrRequest
,
142 MAKE_CSR_API(Request
, CSR_NATIVE
),
143 sizeof(CSR_API_MESSAGE
));
144 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.Status
))
146 SetLastErrorByStatus (Status
);
158 GetProcessWorkingSetSize (HANDLE hProcess
,
159 PSIZE_T lpMinimumWorkingSetSize
,
160 PSIZE_T lpMaximumWorkingSetSize
)
162 QUOTA_LIMITS QuotaLimits
;
165 Status
= NtQueryInformationProcess(hProcess
,
168 sizeof(QUOTA_LIMITS
),
170 if (!NT_SUCCESS(Status
))
172 SetLastErrorByStatus(Status
);
176 *lpMinimumWorkingSetSize
= QuotaLimits
.MinimumWorkingSetSize
;
177 *lpMaximumWorkingSetSize
= QuotaLimits
.MaximumWorkingSetSize
;
187 SetProcessWorkingSetSize(HANDLE hProcess
,
188 SIZE_T dwMinimumWorkingSetSize
,
189 SIZE_T dwMaximumWorkingSetSize
)
191 QUOTA_LIMITS QuotaLimits
;
194 QuotaLimits
.MinimumWorkingSetSize
= dwMinimumWorkingSetSize
;
195 QuotaLimits
.MaximumWorkingSetSize
= dwMaximumWorkingSetSize
;
197 Status
= NtSetInformationProcess(hProcess
,
200 sizeof(QUOTA_LIMITS
));
201 if (!NT_SUCCESS(Status
))
203 SetLastErrorByStatus(Status
);
215 GetProcessTimes(HANDLE hProcess
,
216 LPFILETIME lpCreationTime
,
217 LPFILETIME lpExitTime
,
218 LPFILETIME lpKernelTime
,
219 LPFILETIME lpUserTime
)
221 KERNEL_USER_TIMES Kut
;
224 Status
= NtQueryInformationProcess(hProcess
,
229 if (!NT_SUCCESS(Status
))
231 SetLastErrorByStatus(Status
);
235 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
236 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
238 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
239 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
241 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
242 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
244 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
245 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
255 GetCurrentProcess(VOID
)
257 return((HANDLE
)NtCurrentProcess());
265 GetCurrentThread(VOID
)
267 return((HANDLE
)NtCurrentThread());
275 GetCurrentProcessId(VOID
)
277 return((DWORD
)GetTeb()->ClientId
.UniqueProcess
);
285 GetExitCodeProcess(HANDLE hProcess
,
288 PROCESS_BASIC_INFORMATION ProcessBasic
;
291 Status
= NtQueryInformationProcess(hProcess
,
292 ProcessBasicInformation
,
294 sizeof(PROCESS_BASIC_INFORMATION
),
296 if (!NT_SUCCESS(Status
))
298 SetLastErrorByStatus(Status
);
302 *lpExitCode
= (DWORD
)ProcessBasic
.ExitStatus
;
313 GetProcessId(HANDLE Process
)
315 PROCESS_BASIC_INFORMATION ProcessBasic
;
318 Status
= NtQueryInformationProcess(Process
,
319 ProcessBasicInformation
,
321 sizeof(PROCESS_BASIC_INFORMATION
),
323 if (!NT_SUCCESS(Status
))
325 SetLastErrorByStatus(Status
);
329 return (DWORD
)ProcessBasic
.UniqueProcessId
;
337 OpenProcess(DWORD dwDesiredAccess
,
342 HANDLE ProcessHandle
;
343 OBJECT_ATTRIBUTES ObjectAttributes
;
346 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
347 ClientId
.UniqueThread
= 0;
349 InitializeObjectAttributes(&ObjectAttributes
,
351 (bInheritHandle
? OBJ_INHERIT
: 0),
355 errCode
= NtOpenProcess(&ProcessHandle
,
359 if (!NT_SUCCESS(errCode
))
361 SetLastErrorByStatus (errCode
);
364 return ProcessHandle
;
372 WinExec(LPCSTR lpCmdLine
,
375 STARTUPINFOA StartupInfo
;
376 PROCESS_INFORMATION ProcessInformation
;
379 RtlZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
380 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
381 StartupInfo
.wShowWindow
= (WORD
)uCmdShow
;
382 StartupInfo
.dwFlags
= 0;
384 if (! CreateProcessA(NULL
,
393 &ProcessInformation
))
395 dosErr
= GetLastError();
396 return dosErr
< 32 ? dosErr
: ERROR_BAD_FORMAT
;
398 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
400 lpfnGlobalRegisterWaitForInputIdle (
401 ProcessInformation
.hProcess
,
405 NtClose(ProcessInformation
.hProcess
);
406 NtClose(ProcessInformation
.hThread
);
408 return 33; /* Something bigger than 31 means success. */
416 RegisterWaitForInputIdle (
417 WaitForInputIdleType lpfnRegisterWaitForInputIdle
420 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
428 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
430 PRTL_USER_PROCESS_PARAMETERS Params
;
432 if (lpStartupInfo
== NULL
)
434 SetLastError(ERROR_INVALID_PARAMETER
);
438 Params
= NtCurrentPeb()->ProcessParameters
;
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
;
455 lpStartupInfo
->hStdInput
= Params
->StandardInput
;
456 lpStartupInfo
->hStdOutput
= Params
->StandardOutput
;
457 lpStartupInfo
->hStdError
= Params
->StandardError
;
465 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
467 PRTL_USER_PROCESS_PARAMETERS Params
;
468 ANSI_STRING AnsiString
;
470 if (lpStartupInfo
== NULL
)
472 SetLastError(ERROR_INVALID_PARAMETER
);
476 Params
= NtCurrentPeb ()->ProcessParameters
;
478 RtlAcquirePebLock ();
480 /* FIXME - not thread-safe */
481 if (lpLocalStartupInfo
== NULL
)
483 /* create new local startup info (ansi) */
484 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
486 sizeof(STARTUPINFOA
));
487 if (lpLocalStartupInfo
== NULL
)
489 RtlReleasePebLock ();
490 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
494 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
496 /* copy window title string */
497 RtlUnicodeStringToAnsiString (&AnsiString
,
498 &Params
->WindowTitle
,
500 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
502 /* copy desktop info string */
503 RtlUnicodeStringToAnsiString (&AnsiString
,
504 &Params
->DesktopInfo
,
506 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
508 /* copy shell info string */
509 RtlUnicodeStringToAnsiString (&AnsiString
,
512 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
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
;
526 lpLocalStartupInfo
->hStdInput
= Params
->StandardInput
;
527 lpLocalStartupInfo
->hStdOutput
= Params
->StandardOutput
;
528 lpLocalStartupInfo
->hStdError
= Params
->StandardError
;
531 RtlReleasePebLock ();
533 /* copy local startup info data to external startup info */
534 memcpy (lpStartupInfo
,
536 sizeof(STARTUPINFOA
));
544 FlushInstructionCache (HANDLE hProcess
,
545 LPCVOID lpBaseAddress
,
550 Status
= NtFlushInstructionCache(hProcess
,
551 (PVOID
)lpBaseAddress
,
553 if (!NT_SUCCESS(Status
))
555 SetLastErrorByStatus(Status
);
566 ExitProcess(UINT uExitCode
)
568 CSR_API_MESSAGE CsrRequest
;
572 /* kill sibling threads ... we want to be alone at this point */
573 NtTerminateProcess (NULL
, 0);
575 /* unload all dll's */
576 LdrShutdownProcess ();
578 /* notify csrss of process termination */
579 Request
= TERMINATE_PROCESS
;
580 Status
= CsrClientCallServer(&CsrRequest
,
582 MAKE_CSR_API(Request
, CSR_NATIVE
),
583 sizeof(CSR_API_MESSAGE
));
584 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.Status
))
586 DPRINT("Failed to tell csrss about terminating process\n");
590 NtTerminateProcess (NtCurrentProcess (),
593 /* should never get here */
603 TerminateProcess (HANDLE hProcess
,
608 if (hProcess
== NULL
)
613 Status
= NtTerminateProcess (hProcess
, uExitCode
);
614 if (NT_SUCCESS(Status
))
618 SetLastErrorByStatus (Status
);
627 FatalAppExitA(UINT uAction
,
628 LPCSTR lpMessageText
)
630 UNICODE_STRING MessageTextU
;
631 ANSI_STRING MessageText
;
633 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
635 RtlAnsiStringToUnicodeString (&MessageTextU
,
639 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
641 RtlFreeUnicodeString (&MessageTextU
);
649 FatalAppExitW(UINT uAction
,
650 LPCWSTR lpMessageText
)
652 static const WCHAR szUser32
[] = L
"user32.dll\0";
654 HMODULE hModule
= GetModuleHandleW(szUser32
);
655 MessageBoxW_Proc pMessageBoxW
= NULL
;
657 DPRINT1("AppExit\n");
660 pMessageBoxW
= (MessageBoxW_Proc
) GetProcAddress(hModule
, "MessageBoxW");
663 pMessageBoxW(0, lpMessageText
, NULL
, MB_SYSTEMMODAL
| MB_OK
);
665 DPRINT1("%s\n", lpMessageText
);
675 FatalExit (int ExitCode
)
677 ExitProcess(ExitCode
);
685 GetPriorityClass (HANDLE hProcess
)
688 PROCESS_PRIORITY_CLASS PriorityClass
;
690 Status
= NtQueryInformationProcess(hProcess
,
691 ProcessPriorityClass
,
693 sizeof(PROCESS_PRIORITY_CLASS
),
695 if(NT_SUCCESS(Status
))
697 switch(PriorityClass
.PriorityClass
)
699 case PROCESS_PRIORITY_CLASS_IDLE
:
700 return IDLE_PRIORITY_CLASS
;
702 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL
:
703 return BELOW_NORMAL_PRIORITY_CLASS
;
705 case PROCESS_PRIORITY_CLASS_NORMAL
:
706 return NORMAL_PRIORITY_CLASS
;
708 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
:
709 return ABOVE_NORMAL_PRIORITY_CLASS
;
711 case PROCESS_PRIORITY_CLASS_HIGH
:
712 return HIGH_PRIORITY_CLASS
;
714 case PROCESS_PRIORITY_CLASS_REALTIME
:
715 return REALTIME_PRIORITY_CLASS
;
718 return NORMAL_PRIORITY_CLASS
;
722 SetLastErrorByStatus(Status
);
731 SetPriorityClass (HANDLE hProcess
,
732 DWORD dwPriorityClass
)
735 PROCESS_PRIORITY_CLASS PriorityClass
;
737 switch(dwPriorityClass
)
739 case IDLE_PRIORITY_CLASS
:
740 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_IDLE
;
743 case BELOW_NORMAL_PRIORITY_CLASS
:
744 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_BELOW_NORMAL
;
747 case NORMAL_PRIORITY_CLASS
:
748 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_NORMAL
;
751 case ABOVE_NORMAL_PRIORITY_CLASS
:
752 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
;
755 case HIGH_PRIORITY_CLASS
:
756 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_HIGH
;
759 case REALTIME_PRIORITY_CLASS
:
760 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_REALTIME
;
764 SetLastError(ERROR_INVALID_PARAMETER
);
768 PriorityClass
.Foreground
= FALSE
;
770 Status
= NtSetInformationProcess(hProcess
,
771 ProcessPriorityClass
,
773 sizeof(PROCESS_PRIORITY_CLASS
));
775 if(!NT_SUCCESS(Status
))
777 SetLastErrorByStatus(Status
);
789 GetProcessVersion(DWORD ProcessId
)
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
= NULL
;
805 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
807 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
808 NtHeader
= RtlImageNtHeader(BaseAddress
);
810 Version
= (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
811 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
813 else /* other process */
815 ProcessHandle
= OpenProcess(PROCESS_VM_READ
| PROCESS_QUERY_INFORMATION
,
819 if (!ProcessHandle
) return 0;
821 Status
= NtQueryInformationProcess(ProcessHandle
,
822 ProcessBasicInformation
,
824 sizeof(ProcessBasicInfo
),
826 if (!NT_SUCCESS(Status
)) goto Error
;
828 Status
= NtReadVirtualMemory(ProcessHandle
,
829 ProcessBasicInfo
.PebBaseAddress
,
833 if (!NT_SUCCESS(Status
) || Count
!= sizeof(Peb
)) goto Error
;
835 memset(&DosHeader
, 0, sizeof(DosHeader
));
836 Status
= NtReadVirtualMemory(ProcessHandle
,
837 Peb
.ImageBaseAddress
,
842 if (!NT_SUCCESS(Status
) || Count
!= sizeof(DosHeader
)) goto Error
;
843 if (DosHeader
.e_magic
!= IMAGE_DOS_SIGNATURE
) goto Error
;
845 memset(&NtHeaders
, 0, sizeof(NtHeaders
));
846 Status
= NtReadVirtualMemory(ProcessHandle
,
847 (char *)Peb
.ImageBaseAddress
+ DosHeader
.e_lfanew
,
852 if (!NT_SUCCESS(Status
) || Count
!= sizeof(NtHeaders
)) goto Error
;
853 if (NtHeaders
.Signature
!= IMAGE_NT_SIGNATURE
) goto Error
;
855 Version
= MAKELONG(NtHeaders
.OptionalHeader
.MinorSubsystemVersion
,
856 NtHeaders
.OptionalHeader
.MajorSubsystemVersion
);
859 if (!NT_SUCCESS(Status
))
861 SetLastErrorByStatus(Status
);
867 if (ProcessHandle
) CloseHandle(ProcessHandle
);
880 GetProcessIoCounters(
882 PIO_COUNTERS lpIoCounters
)
886 Status
= NtQueryInformationProcess(hProcess
,
891 if (!NT_SUCCESS(Status
))
893 SetLastErrorByStatus(Status
);
906 GetProcessPriorityBoost(HANDLE hProcess
,
907 PBOOL pDisablePriorityBoost
)
912 Status
= NtQueryInformationProcess(hProcess
,
913 ProcessPriorityBoost
,
917 if (NT_SUCCESS(Status
))
919 *pDisablePriorityBoost
= PriorityBoost
;
923 SetLastErrorByStatus(Status
);
933 SetProcessPriorityBoost(HANDLE hProcess
,
934 BOOL bDisablePriorityBoost
)
937 ULONG PriorityBoost
= (bDisablePriorityBoost
? TRUE
: FALSE
); /* prevent setting values other than 1 and 0 */
939 Status
= NtSetInformationProcess(hProcess
,
940 ProcessPriorityBoost
,
943 if (!NT_SUCCESS(Status
))
945 SetLastErrorByStatus(Status
);
958 GetProcessHandleCount(HANDLE hProcess
,
959 PDWORD pdwHandleCount
)
964 Status
= NtQueryInformationProcess(hProcess
,
969 if(NT_SUCCESS(Status
))
971 *pdwHandleCount
= phc
;
975 SetLastErrorByStatus(Status
);
993 Status
= NtQueryInformationProcess(hProcess
,
994 ProcessWow64Information
,
999 if (!NT_SUCCESS(Status
))
1001 SetLastError(RtlNtStatusToDosError(Status
));
1005 *Wow64Process
= (pbi
!= 0);
1015 QueryFullProcessImageNameW(HANDLE hProcess
,
1020 BYTE Buffer
[sizeof(UNICODE_STRING
) + MAX_PATH
* sizeof(WCHAR
)];
1021 UNICODE_STRING
*DynamicBuffer
= NULL
;
1022 UNICODE_STRING
*Result
= NULL
;
1026 Status
= NtQueryInformationProcess(hProcess
,
1027 ProcessImageFileName
,
1029 sizeof(Buffer
) - sizeof(WCHAR
),
1031 if (Status
== STATUS_INFO_LENGTH_MISMATCH
)
1033 DynamicBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Needed
+ sizeof(WCHAR
));
1036 SetLastErrorByStatus(STATUS_NO_MEMORY
);
1040 Status
= NtQueryInformationProcess(hProcess
,
1041 ProcessImageFileName
,
1042 (LPBYTE
)DynamicBuffer
,
1045 Result
= DynamicBuffer
;
1047 else Result
= (PUNICODE_STRING
)Buffer
;
1049 if (!NT_SUCCESS(Status
)) goto Cleanup
;
1051 if (Result
->Length
/ sizeof(WCHAR
) + 1 > *pdwSize
)
1053 Status
= STATUS_BUFFER_TOO_SMALL
;
1057 *pdwSize
= Result
->Length
/ sizeof(WCHAR
);
1058 memcpy(lpExeName
, Result
->Buffer
, Result
->Length
);
1059 lpExeName
[*pdwSize
] = 0;
1062 RtlFreeHeap(RtlGetProcessHeap(), 0, DynamicBuffer
);
1064 if (!NT_SUCCESS(Status
))
1066 SetLastErrorByStatus(Status
);
1077 QueryFullProcessImageNameA(HANDLE hProcess
,
1082 DWORD pdwSizeW
= *pdwSize
;
1086 lpExeNameW
= RtlAllocateHeap(RtlGetProcessHeap(),
1088 *pdwSize
* sizeof(WCHAR
));
1091 SetLastErrorByStatus(STATUS_NO_MEMORY
);
1095 Result
= QueryFullProcessImageNameW(hProcess
, dwFlags
, lpExeNameW
, &pdwSizeW
);
1098 Result
= (0 != WideCharToMultiByte(CP_ACP
, 0,
1105 *pdwSize
= strlen(lpExeName
);
1107 RtlFreeHeap(RtlGetProcessHeap(), 0, lpExeNameW
);