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 ****************************************************************/
38 GetProcessAffinityMask(HANDLE hProcess
,
39 LPDWORD lpProcessAffinityMask
,
40 LPDWORD lpSystemAffinityMask
)
42 PROCESS_BASIC_INFORMATION ProcessInfo
;
43 SYSTEM_BASIC_INFORMATION SystemInfo
;
46 Status
= NtQuerySystemInformation(SystemBasicInformation
,
50 if (!NT_SUCCESS(Status
))
52 SetLastErrorByStatus(Status
);
56 Status
= NtQueryInformationProcess(hProcess
,
57 ProcessBasicInformation
,
59 sizeof(PROCESS_BASIC_INFORMATION
),
61 if (!NT_SUCCESS(Status
))
63 SetLastErrorByStatus(Status
);
67 *lpProcessAffinityMask
= (DWORD
)ProcessInfo
.AffinityMask
;
68 *lpSystemAffinityMask
= (DWORD
)SystemInfo
.ActiveProcessorsAffinityMask
;
79 SetProcessAffinityMask(HANDLE hProcess
,
80 DWORD dwProcessAffinityMask
)
84 Status
= NtSetInformationProcess(hProcess
,
86 (PVOID
)&dwProcessAffinityMask
,
88 if (!NT_SUCCESS(Status
))
90 SetLastErrorByStatus(Status
);
103 GetProcessShutdownParameters(LPDWORD lpdwLevel
,
106 CSR_API_MESSAGE CsrRequest
;
110 Request
= GET_SHUTDOWN_PARAMETERS
;
111 Status
= CsrClientCallServer(&CsrRequest
,
113 MAKE_CSR_API(Request
, CSR_NATIVE
),
114 sizeof(CSR_API_MESSAGE
));
115 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.Status
))
117 SetLastErrorByStatus(Status
);
121 *lpdwLevel
= CsrRequest
.Data
.GetShutdownParametersRequest
.Level
;
122 *lpdwFlags
= CsrRequest
.Data
.GetShutdownParametersRequest
.Flags
;
133 SetProcessShutdownParameters(DWORD dwLevel
,
136 CSR_API_MESSAGE CsrRequest
;
140 CsrRequest
.Data
.SetShutdownParametersRequest
.Level
= dwLevel
;
141 CsrRequest
.Data
.SetShutdownParametersRequest
.Flags
= dwFlags
;
143 Request
= SET_SHUTDOWN_PARAMETERS
;
144 Status
= CsrClientCallServer(&CsrRequest
,
146 MAKE_CSR_API(Request
, CSR_NATIVE
),
147 sizeof(CSR_API_MESSAGE
));
148 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.Status
))
150 SetLastErrorByStatus(Status
);
163 GetProcessWorkingSetSize(HANDLE hProcess
,
164 PSIZE_T lpMinimumWorkingSetSize
,
165 PSIZE_T lpMaximumWorkingSetSize
)
167 QUOTA_LIMITS QuotaLimits
;
170 Status
= NtQueryInformationProcess(hProcess
,
173 sizeof(QUOTA_LIMITS
),
175 if (!NT_SUCCESS(Status
))
177 SetLastErrorByStatus(Status
);
181 *lpMinimumWorkingSetSize
= QuotaLimits
.MinimumWorkingSetSize
;
182 *lpMaximumWorkingSetSize
= QuotaLimits
.MaximumWorkingSetSize
;
193 SetProcessWorkingSetSize(HANDLE hProcess
,
194 SIZE_T dwMinimumWorkingSetSize
,
195 SIZE_T dwMaximumWorkingSetSize
)
197 QUOTA_LIMITS QuotaLimits
;
200 QuotaLimits
.MinimumWorkingSetSize
= dwMinimumWorkingSetSize
;
201 QuotaLimits
.MaximumWorkingSetSize
= dwMaximumWorkingSetSize
;
203 Status
= NtSetInformationProcess(hProcess
,
206 sizeof(QUOTA_LIMITS
));
207 if (!NT_SUCCESS(Status
))
209 SetLastErrorByStatus(Status
);
222 GetProcessTimes(HANDLE hProcess
,
223 LPFILETIME lpCreationTime
,
224 LPFILETIME lpExitTime
,
225 LPFILETIME lpKernelTime
,
226 LPFILETIME lpUserTime
)
228 KERNEL_USER_TIMES Kut
;
231 Status
= NtQueryInformationProcess(hProcess
,
236 if (!NT_SUCCESS(Status
))
238 SetLastErrorByStatus(Status
);
242 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
243 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
245 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
246 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
248 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
249 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
251 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
252 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
263 GetCurrentProcess(VOID
)
265 return (HANDLE
)NtCurrentProcess();
274 GetCurrentThread(VOID
)
276 return (HANDLE
)NtCurrentThread();
285 GetCurrentProcessId(VOID
)
287 return (DWORD
)GetTeb()->ClientId
.UniqueProcess
;
296 GetExitCodeProcess(HANDLE hProcess
,
299 PROCESS_BASIC_INFORMATION ProcessBasic
;
302 Status
= NtQueryInformationProcess(hProcess
,
303 ProcessBasicInformation
,
305 sizeof(PROCESS_BASIC_INFORMATION
),
307 if (!NT_SUCCESS(Status
))
309 SetLastErrorByStatus(Status
);
313 *lpExitCode
= (DWORD
)ProcessBasic
.ExitStatus
;
324 GetProcessId(HANDLE Process
)
326 PROCESS_BASIC_INFORMATION ProcessBasic
;
329 Status
= NtQueryInformationProcess(Process
,
330 ProcessBasicInformation
,
332 sizeof(PROCESS_BASIC_INFORMATION
),
334 if (!NT_SUCCESS(Status
))
336 SetLastErrorByStatus(Status
);
340 return (DWORD
)ProcessBasic
.UniqueProcessId
;
349 OpenProcess(DWORD dwDesiredAccess
,
354 HANDLE ProcessHandle
;
355 OBJECT_ATTRIBUTES ObjectAttributes
;
358 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
359 ClientId
.UniqueThread
= 0;
361 InitializeObjectAttributes(&ObjectAttributes
,
363 (bInheritHandle
? OBJ_INHERIT
: 0),
367 errCode
= NtOpenProcess(&ProcessHandle
,
371 if (!NT_SUCCESS(errCode
))
373 SetLastErrorByStatus(errCode
);
377 return ProcessHandle
;
386 WinExec(LPCSTR lpCmdLine
,
389 STARTUPINFOA StartupInfo
;
390 PROCESS_INFORMATION ProcessInformation
;
393 RtlZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
394 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
395 StartupInfo
.wShowWindow
= (WORD
)uCmdShow
;
396 StartupInfo
.dwFlags
= 0;
398 if (!CreateProcessA(NULL
,
407 &ProcessInformation
))
409 dosErr
= GetLastError();
410 return dosErr
< 32 ? dosErr
: ERROR_BAD_FORMAT
;
413 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
415 lpfnGlobalRegisterWaitForInputIdle(ProcessInformation
.hProcess
,
419 NtClose(ProcessInformation
.hProcess
);
420 NtClose(ProcessInformation
.hThread
);
422 return 33; /* Something bigger than 31 means success. */
431 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle
)
433 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
442 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
444 PRTL_USER_PROCESS_PARAMETERS Params
;
446 if (lpStartupInfo
== NULL
)
448 SetLastError(ERROR_INVALID_PARAMETER
);
452 Params
= NtCurrentPeb()->ProcessParameters
;
454 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
455 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
456 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
457 lpStartupInfo
->dwX
= Params
->StartingX
;
458 lpStartupInfo
->dwY
= Params
->StartingY
;
459 lpStartupInfo
->dwXSize
= Params
->CountX
;
460 lpStartupInfo
->dwYSize
= Params
->CountY
;
461 lpStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
462 lpStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
463 lpStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
464 lpStartupInfo
->dwFlags
= Params
->WindowFlags
;
465 lpStartupInfo
->wShowWindow
= (WORD
)Params
->ShowWindowFlags
;
466 lpStartupInfo
->cbReserved2
= Params
->RuntimeData
.Length
;
467 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeData
.Buffer
;
469 lpStartupInfo
->hStdInput
= Params
->StandardInput
;
470 lpStartupInfo
->hStdOutput
= Params
->StandardOutput
;
471 lpStartupInfo
->hStdError
= Params
->StandardError
;
480 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
482 PRTL_USER_PROCESS_PARAMETERS Params
;
483 ANSI_STRING AnsiString
;
485 if (lpStartupInfo
== NULL
)
487 SetLastError(ERROR_INVALID_PARAMETER
);
491 Params
= NtCurrentPeb ()->ProcessParameters
;
493 RtlAcquirePebLock ();
495 /* FIXME - not thread-safe */
496 if (lpLocalStartupInfo
== NULL
)
498 /* create new local startup info (ansi) */
499 lpLocalStartupInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
501 sizeof(STARTUPINFOA
));
502 if (lpLocalStartupInfo
== NULL
)
505 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
509 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
511 /* copy window title string */
512 RtlUnicodeStringToAnsiString(&AnsiString
,
513 &Params
->WindowTitle
,
515 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
517 /* copy desktop info string */
518 RtlUnicodeStringToAnsiString(&AnsiString
,
519 &Params
->DesktopInfo
,
521 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
523 /* copy shell info string */
524 RtlUnicodeStringToAnsiString(&AnsiString
,
527 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
529 lpLocalStartupInfo
->dwX
= Params
->StartingX
;
530 lpLocalStartupInfo
->dwY
= Params
->StartingY
;
531 lpLocalStartupInfo
->dwXSize
= Params
->CountX
;
532 lpLocalStartupInfo
->dwYSize
= Params
->CountY
;
533 lpLocalStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
534 lpLocalStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
535 lpLocalStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
536 lpLocalStartupInfo
->dwFlags
= Params
->WindowFlags
;
537 lpLocalStartupInfo
->wShowWindow
= (WORD
)Params
->ShowWindowFlags
;
538 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeData
.Length
;
539 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeData
.Buffer
;
541 lpLocalStartupInfo
->hStdInput
= Params
->StandardInput
;
542 lpLocalStartupInfo
->hStdOutput
= Params
->StandardOutput
;
543 lpLocalStartupInfo
->hStdError
= Params
->StandardError
;
548 /* copy local startup info data to external startup info */
549 memcpy(lpStartupInfo
,
551 sizeof(STARTUPINFOA
));
560 FlushInstructionCache(HANDLE hProcess
,
561 LPCVOID lpBaseAddress
,
566 Status
= NtFlushInstructionCache(hProcess
,
567 (PVOID
)lpBaseAddress
,
569 if (!NT_SUCCESS(Status
))
571 SetLastErrorByStatus(Status
);
584 ExitProcess(UINT uExitCode
)
586 CSR_API_MESSAGE CsrRequest
;
590 /* kill sibling threads ... we want to be alone at this point */
591 NtTerminateProcess(NULL
, 0);
593 /* unload all dll's */
594 LdrShutdownProcess();
596 /* notify csrss of process termination */
597 Request
= TERMINATE_PROCESS
;
598 Status
= CsrClientCallServer(&CsrRequest
,
600 MAKE_CSR_API(Request
, CSR_NATIVE
),
601 sizeof(CSR_API_MESSAGE
));
602 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.Status
))
604 DPRINT("Failed to tell csrss about terminating process\n");
607 NtTerminateProcess(NtCurrentProcess (),
610 /* should never get here */
621 TerminateProcess(HANDLE hProcess
,
626 if (hProcess
== NULL
)
631 Status
= NtTerminateProcess(hProcess
, uExitCode
);
632 if (NT_SUCCESS(Status
))
637 SetLastErrorByStatus(Status
);
647 FatalAppExitA(UINT uAction
,
648 LPCSTR lpMessageText
)
650 UNICODE_STRING MessageTextU
;
651 ANSI_STRING MessageText
;
653 RtlInitAnsiString(&MessageText
, (LPSTR
)lpMessageText
);
655 RtlAnsiStringToUnicodeString(&MessageTextU
,
659 FatalAppExitW(uAction
, MessageTextU
.Buffer
);
661 RtlFreeUnicodeString(&MessageTextU
);
670 FatalAppExitW(UINT uAction
,
671 LPCWSTR lpMessageText
)
673 static const WCHAR szUser32
[] = L
"user32.dll\0";
675 HMODULE hModule
= GetModuleHandleW(szUser32
);
676 MessageBoxW_Proc pMessageBoxW
= NULL
;
678 DPRINT1("AppExit\n");
681 pMessageBoxW
= (MessageBoxW_Proc
)GetProcAddress(hModule
, "MessageBoxW");
684 pMessageBoxW(0, lpMessageText
, NULL
, MB_SYSTEMMODAL
| MB_OK
);
686 DPRINT1("%s\n", lpMessageText
);
697 FatalExit(int ExitCode
)
699 ExitProcess(ExitCode
);
708 GetPriorityClass(HANDLE hProcess
)
711 PROCESS_PRIORITY_CLASS PriorityClass
;
713 Status
= NtQueryInformationProcess(hProcess
,
714 ProcessPriorityClass
,
716 sizeof(PROCESS_PRIORITY_CLASS
),
718 if(NT_SUCCESS(Status
))
720 switch(PriorityClass
.PriorityClass
)
722 case PROCESS_PRIORITY_CLASS_IDLE
:
723 return IDLE_PRIORITY_CLASS
;
725 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL
:
726 return BELOW_NORMAL_PRIORITY_CLASS
;
728 case PROCESS_PRIORITY_CLASS_NORMAL
:
729 return NORMAL_PRIORITY_CLASS
;
731 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
:
732 return ABOVE_NORMAL_PRIORITY_CLASS
;
734 case PROCESS_PRIORITY_CLASS_HIGH
:
735 return HIGH_PRIORITY_CLASS
;
737 case PROCESS_PRIORITY_CLASS_REALTIME
:
738 return REALTIME_PRIORITY_CLASS
;
741 return NORMAL_PRIORITY_CLASS
;
745 SetLastErrorByStatus(Status
);
755 SetPriorityClass(HANDLE hProcess
,
756 DWORD dwPriorityClass
)
759 PROCESS_PRIORITY_CLASS PriorityClass
;
761 switch (dwPriorityClass
)
763 case IDLE_PRIORITY_CLASS
:
764 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_IDLE
;
767 case BELOW_NORMAL_PRIORITY_CLASS
:
768 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_BELOW_NORMAL
;
771 case NORMAL_PRIORITY_CLASS
:
772 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_NORMAL
;
775 case ABOVE_NORMAL_PRIORITY_CLASS
:
776 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
;
779 case HIGH_PRIORITY_CLASS
:
780 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_HIGH
;
783 case REALTIME_PRIORITY_CLASS
:
784 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_REALTIME
;
788 SetLastError(ERROR_INVALID_PARAMETER
);
792 PriorityClass
.Foreground
= FALSE
;
794 Status
= NtSetInformationProcess(hProcess
,
795 ProcessPriorityClass
,
797 sizeof(PROCESS_PRIORITY_CLASS
));
798 if (!NT_SUCCESS(Status
))
800 SetLastErrorByStatus(Status
);
813 GetProcessVersion(DWORD ProcessId
)
816 PIMAGE_NT_HEADERS NtHeader
= NULL
;
817 IMAGE_NT_HEADERS NtHeaders
;
818 IMAGE_DOS_HEADER DosHeader
;
819 PROCESS_BASIC_INFORMATION ProcessBasicInfo
;
820 PVOID BaseAddress
= NULL
;
821 HANDLE ProcessHandle
= NULL
;
828 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
831 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
832 NtHeader
= RtlImageNtHeader(BaseAddress
);
834 Version
= (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
835 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
840 ProcessHandle
= OpenProcess(PROCESS_VM_READ
| PROCESS_QUERY_INFORMATION
,
844 if (!ProcessHandle
) return 0;
846 Status
= NtQueryInformationProcess(ProcessHandle
,
847 ProcessBasicInformation
,
849 sizeof(ProcessBasicInfo
),
852 if (!NT_SUCCESS(Status
)) goto Error
;
854 Status
= NtReadVirtualMemory(ProcessHandle
,
855 ProcessBasicInfo
.PebBaseAddress
,
860 if (!NT_SUCCESS(Status
) || Count
!= sizeof(Peb
)) goto Error
;
862 memset(&DosHeader
, 0, sizeof(DosHeader
));
863 Status
= NtReadVirtualMemory(ProcessHandle
,
864 Peb
.ImageBaseAddress
,
869 if (!NT_SUCCESS(Status
) || Count
!= sizeof(DosHeader
)) goto Error
;
870 if (DosHeader
.e_magic
!= IMAGE_DOS_SIGNATURE
) goto Error
;
872 memset(&NtHeaders
, 0, sizeof(NtHeaders
));
873 Status
= NtReadVirtualMemory(ProcessHandle
,
874 (char *)Peb
.ImageBaseAddress
+ DosHeader
.e_lfanew
,
879 if (!NT_SUCCESS(Status
) || Count
!= sizeof(NtHeaders
)) goto Error
;
880 if (NtHeaders
.Signature
!= IMAGE_NT_SIGNATURE
) goto Error
;
882 Version
= MAKELONG(NtHeaders
.OptionalHeader
.MinorSubsystemVersion
,
883 NtHeaders
.OptionalHeader
.MajorSubsystemVersion
);
886 if (!NT_SUCCESS(Status
))
888 SetLastErrorByStatus(Status
);
894 if (ProcessHandle
) CloseHandle(ProcessHandle
);
907 GetProcessIoCounters(HANDLE hProcess
,
908 PIO_COUNTERS lpIoCounters
)
912 Status
= NtQueryInformationProcess(hProcess
,
917 if (!NT_SUCCESS(Status
))
919 SetLastErrorByStatus(Status
);
932 GetProcessPriorityBoost(HANDLE hProcess
,
933 PBOOL pDisablePriorityBoost
)
938 Status
= NtQueryInformationProcess(hProcess
,
939 ProcessPriorityBoost
,
943 if (NT_SUCCESS(Status
))
945 *pDisablePriorityBoost
= PriorityBoost
;
949 SetLastErrorByStatus(Status
);
959 SetProcessPriorityBoost(HANDLE hProcess
,
960 BOOL bDisablePriorityBoost
)
963 ULONG PriorityBoost
= (bDisablePriorityBoost
? TRUE
: FALSE
); /* prevent setting values other than 1 and 0 */
965 Status
= NtSetInformationProcess(hProcess
,
966 ProcessPriorityBoost
,
969 if (!NT_SUCCESS(Status
))
971 SetLastErrorByStatus(Status
);
984 GetProcessHandleCount(HANDLE hProcess
,
985 PDWORD pdwHandleCount
)
990 Status
= NtQueryInformationProcess(hProcess
,
995 if(NT_SUCCESS(Status
))
997 *pdwHandleCount
= phc
;
1001 SetLastErrorByStatus(Status
);
1011 IsWow64Process(HANDLE hProcess
,
1017 Status
= NtQueryInformationProcess(hProcess
,
1018 ProcessWow64Information
,
1022 if (!NT_SUCCESS(Status
))
1024 SetLastError(RtlNtStatusToDosError(Status
));
1028 *Wow64Process
= (pbi
!= 0);
1039 QueryFullProcessImageNameW(HANDLE hProcess
,
1044 BYTE Buffer
[sizeof(UNICODE_STRING
) + MAX_PATH
* sizeof(WCHAR
)];
1045 UNICODE_STRING
*DynamicBuffer
= NULL
;
1046 UNICODE_STRING
*Result
= NULL
;
1050 Status
= NtQueryInformationProcess(hProcess
,
1051 ProcessImageFileName
,
1053 sizeof(Buffer
) - sizeof(WCHAR
),
1055 if (Status
== STATUS_INFO_LENGTH_MISMATCH
)
1057 DynamicBuffer
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Needed
+ sizeof(WCHAR
));
1060 SetLastErrorByStatus(STATUS_NO_MEMORY
);
1064 Status
= NtQueryInformationProcess(hProcess
,
1065 ProcessImageFileName
,
1066 (LPBYTE
)DynamicBuffer
,
1069 Result
= DynamicBuffer
;
1071 else Result
= (PUNICODE_STRING
)Buffer
;
1073 if (!NT_SUCCESS(Status
)) goto Cleanup
;
1075 if (Result
->Length
/ sizeof(WCHAR
) + 1 > *pdwSize
)
1077 Status
= STATUS_BUFFER_TOO_SMALL
;
1081 *pdwSize
= Result
->Length
/ sizeof(WCHAR
);
1082 memcpy(lpExeName
, Result
->Buffer
, Result
->Length
);
1083 lpExeName
[*pdwSize
] = 0;
1086 RtlFreeHeap(RtlGetProcessHeap(), 0, DynamicBuffer
);
1088 if (!NT_SUCCESS(Status
))
1090 SetLastErrorByStatus(Status
);
1102 QueryFullProcessImageNameA(HANDLE hProcess
,
1107 DWORD pdwSizeW
= *pdwSize
;
1111 lpExeNameW
= RtlAllocateHeap(RtlGetProcessHeap(),
1113 *pdwSize
* sizeof(WCHAR
));
1116 SetLastErrorByStatus(STATUS_NO_MEMORY
);
1120 Result
= QueryFullProcessImageNameW(hProcess
, dwFlags
, lpExeNameW
, &pdwSizeW
);
1123 Result
= (0 != WideCharToMultiByte(CP_ACP
, 0,
1131 *pdwSize
= strlen(lpExeName
);
1133 RtlFreeHeap(RtlGetProcessHeap(), 0, lpExeNameW
);