kernel32: Add support for foreign process handles in GetProcessVersion.

This commit is contained in:
Dmitry Timoshkov 2008-10-15 23:44:54 +09:00 committed by Alexandre Julliard
parent 7b51cf49fc
commit 228c52de57
2 changed files with 85 additions and 9 deletions

View File

@ -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;
}

View File

@ -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)