kernel32: Add support for foreign process handles in GetProcessVersion.
This commit is contained in:
parent
7b51cf49fc
commit
228c52de57
|
@ -2860,19 +2860,55 @@ BOOL WINAPI GetProcessAffinityMask( HANDLE hProcess,
|
|||
/***********************************************************************
|
||||
* GetProcessVersion (KERNEL32.@)
|
||||
*/
|
||||
DWORD WINAPI GetProcessVersion( DWORD processid )
|
||||
DWORD WINAPI GetProcessVersion( DWORD pid )
|
||||
{
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
HANDLE process;
|
||||
NTSTATUS status;
|
||||
PROCESS_BASIC_INFORMATION pbi;
|
||||
SIZE_T count;
|
||||
PEB peb;
|
||||
IMAGE_DOS_HEADER dos;
|
||||
IMAGE_NT_HEADERS nt;
|
||||
DWORD ver = 0;
|
||||
|
||||
if (processid && processid != GetCurrentProcessId())
|
||||
if (!pid || pid == GetCurrentProcessId())
|
||||
{
|
||||
FIXME("should use ReadProcessMemory\n");
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
|
||||
if ((nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress )))
|
||||
return ((nt->OptionalHeader.MajorSubsystemVersion << 16) |
|
||||
nt->OptionalHeader.MinorSubsystemVersion);
|
||||
return 0;
|
||||
}
|
||||
if ((nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress )))
|
||||
return ((nt->OptionalHeader.MajorSubsystemVersion << 16) |
|
||||
nt->OptionalHeader.MinorSubsystemVersion);
|
||||
return 0;
|
||||
|
||||
process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pid);
|
||||
if (!process) return 0;
|
||||
|
||||
status = NtQueryInformationProcess(process, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
|
||||
if (status) goto err;
|
||||
|
||||
status = NtReadVirtualMemory(process, pbi.PebBaseAddress, &peb, sizeof(peb), &count);
|
||||
if (status || count != sizeof(peb)) goto err;
|
||||
|
||||
memset(&dos, 0, sizeof(dos));
|
||||
status = NtReadVirtualMemory(process, peb.ImageBaseAddress, &dos, sizeof(dos), &count);
|
||||
if (status || count != sizeof(dos)) goto err;
|
||||
if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto err;
|
||||
|
||||
memset(&nt, 0, sizeof(nt));
|
||||
status = NtReadVirtualMemory(process, (char *)peb.ImageBaseAddress + dos.e_lfanew, &nt, sizeof(nt), &count);
|
||||
if (status || count != sizeof(nt)) goto err;
|
||||
if (nt.Signature != IMAGE_NT_SIGNATURE) goto err;
|
||||
|
||||
ver = MAKELONG(nt.OptionalHeader.MinorSubsystemVersion, nt.OptionalHeader.MajorSubsystemVersion);
|
||||
|
||||
err:
|
||||
CloseHandle(process);
|
||||
|
||||
if (status != STATUS_SUCCESS)
|
||||
SetLastError(RtlNtStatusToDosError(status));
|
||||
|
||||
return ver;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,12 +24,16 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "wincon.h"
|
||||
#include "winnls.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
static HINSTANCE hkernel32;
|
||||
static LPVOID (WINAPI *pVirtualAllocEx)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD);
|
||||
|
@ -1419,6 +1423,41 @@ static void test_OpenProcess(void)
|
|||
ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
|
||||
}
|
||||
|
||||
static void test_GetProcessVersion(void)
|
||||
{
|
||||
static char cmdline[] = "winver.exe";
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFOA si;
|
||||
DWORD ret;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetProcessVersion(0);
|
||||
ok(ret, "GetProcessVersion error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetProcessVersion(GetCurrentProcessId());
|
||||
ok(ret, "GetProcessVersion error %u\n", GetLastError());
|
||||
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(ret, "CreateProcess error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetProcessVersion(pi.dwProcessId);
|
||||
ok(ret, "GetProcessVersion error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = TerminateProcess(pi.hProcess, 0);
|
||||
ok(ret, "TerminateProcess error %u\n", GetLastError());
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
|
||||
START_TEST(process)
|
||||
{
|
||||
int b = init();
|
||||
|
@ -1439,6 +1478,7 @@ START_TEST(process)
|
|||
test_Console();
|
||||
test_ExitCode();
|
||||
test_OpenProcess();
|
||||
test_GetProcessVersion();
|
||||
/* things that can be tested:
|
||||
* lookup: check the way program to be executed is searched
|
||||
* handles: check the handle inheritance stuff (+sec options)
|
||||
|
|
Loading…
Reference in New Issue