kernel32: Add basic OpenProcess test, make it pass under Wine
Dmitry Timoshkov
dmitry at codeweavers.com
Mon Nov 6 08:24:02 CST 2006
Hello,
Changelog:
kernel32: Add basic OpenProcess test, make it pass under Wine.
diff -up a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
--- a/dlls/kernel32/tests/process.c 2006-10-11 12:34:26.000000000 +0900
+++ b/dlls/kernel32/tests/process.c 2006-11-06 22:10:54.000000000 +0800
@@ -2,6 +2,7 @@
* Unit test suite for CreateProcess function.
*
* Copyright 2002 Eric Pouech
+ * Copyright 2006 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1265,6 +1266,79 @@ static void test_ExitCode(void)
assert(DeleteFileA(resfile) != 0);
}
+static void test_OpenProcess(void)
+{
+ HANDLE hproc;
+ void *addr1;
+ MEMORY_BASIC_INFORMATION info;
+ SIZE_T dummy, read_bytes;
+
+ /* without PROCESS_VM_OPERATION */
+ hproc = OpenProcess(PROCESS_ALL_ACCESS & ~PROCESS_VM_OPERATION, FALSE, GetCurrentProcessId());
+ ok(hproc != NULL, "OpenProcess error %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ addr1 = VirtualAllocEx(hproc, 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS);
+ ok(!addr1, "VirtualAllocEx should fail\n");
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %d\n", GetLastError());
+
+ read_bytes = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ok(ReadProcessMemory(hproc, test_OpenProcess, &dummy, sizeof(dummy), &read_bytes),
+ "ReadProcessMemory error %d\n", GetLastError());
+ ok(read_bytes == sizeof(dummy), "wrong read bytes %ld\n", read_bytes);
+
+ CloseHandle(hproc);
+
+ hproc = OpenProcess(PROCESS_VM_OPERATION, FALSE, GetCurrentProcessId());
+ ok(hproc != NULL, "OpenProcess error %d\n", GetLastError());
+
+ addr1 = VirtualAllocEx(hproc, 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS);
+ ok(addr1 != NULL, "VirtualAllocEx error %d\n", GetLastError());
+
+ /* without PROCESS_QUERY_INFORMATION */
+ SetLastError(0xdeadbeef);
+ ok(!VirtualQueryEx(hproc, addr1, &info, sizeof(info)),
+ "VirtualQueryEx without PROCESS_QUERY_INFORMATION rights should fail\n");
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %d\n", GetLastError());
+
+ /* without PROCESS_VM_READ */
+ read_bytes = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ok(!ReadProcessMemory(hproc, addr1, &dummy, sizeof(dummy), &read_bytes),
+ "ReadProcessMemory without PROCESS_VM_READ rights should fail\n");
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %d\n", GetLastError());
+ ok(read_bytes == 0, "wrong read bytes %ld\n", read_bytes);
+
+ CloseHandle(hproc);
+
+ hproc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
+
+ memset(&info, 0xaa, sizeof(info));
+ ok(VirtualQueryEx(hproc, addr1, &info, sizeof(info)) == sizeof(info),
+ "VirtualQueryEx error %d\n", GetLastError());
+
+ ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
+ ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
+ ok(info.AllocationProtect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.AllocationProtect);
+ ok(info.RegionSize == 0x10000, "%lx != 0x10000\n", info.RegionSize);
+ ok(info.State == MEM_RESERVE, "%x != MEM_RESERVE\n", info.State);
+ /* NT reports Protect == 0 for a not committed memory block */
+ ok(info.Protect == 0 /* NT */ ||
+ info.Protect == PAGE_NOACCESS, /* Win9x */
+ "%x != PAGE_NOACCESS\n", info.Protect);
+ ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
+
+ SetLastError(0xdeadbeef);
+ ok(!VirtualFreeEx(hproc, addr1, 0, MEM_RELEASE),
+ "VirtualFreeEx without PROCESS_VM_OPERATION rights should fail\n");
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %d\n", GetLastError());
+
+ CloseHandle(hproc);
+
+ ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
+}
+
START_TEST(process)
{
int b = init();
@@ -1284,6 +1358,7 @@ START_TEST(process)
test_DebuggingFlag();
test_Console();
test_ExitCode();
+ test_OpenProcess();
/* things that can be tested:
* lookup: check the way program to be executed is searched
* handles: check the handle inheritance stuff (+sec options)
diff -up a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
--- a/dlls/ntdll/ntdll_misc.h 2006-11-06 18:35:24.000000000 +0800
+++ b/dlls/ntdll/ntdll_misc.h 2006-11-06 22:07:21.000000000 +0800
@@ -114,7 +114,7 @@ extern NTSTATUS VIRTUAL_HandleFault(LPCV
extern BOOL VIRTUAL_HasMapping( LPCVOID addr );
extern void VIRTUAL_UseLargeAddressSpace(void);
-extern BOOL is_current_process( HANDLE handle );
+extern BOOL is_current_process( HANDLE handle, UINT access );
/* code pages */
extern int ntdll_umbstowcs(DWORD flags, const char* src, int srclen, WCHAR* dst, int dstlen);
diff -up a/dlls/ntdll/process.c b/dlls/ntdll/process.c
--- a/dlls/ntdll/process.c 2006-10-19 12:41:25.000000000 +0900
+++ b/dlls/ntdll/process.c 2006-11-06 21:52:23.000000000 +0800
@@ -141,6 +141,7 @@ NTSTATUS WINAPI NtQueryInformationProces
SERVER_START_REQ(get_process_info)
{
req->handle = ProcessHandle;
+ req->access = PROCESS_QUERY_INFORMATION;
if ((ret = wine_server_call( req )) == STATUS_SUCCESS)
{
pbi.ExitStatus = reply->exit_code;
@@ -234,6 +235,7 @@ NTSTATUS WINAPI NtQueryInformationProces
SERVER_START_REQ(get_process_info)
{
req->handle = ProcessHandle;
+ req->access = PROCESS_QUERY_INFORMATION;
if ((ret = wine_server_call( req )) == STATUS_SUCCESS)
{
NTDLL_from_server_abstime(&pti.CreateTime, &reply->start_time);
diff -up a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
--- a/dlls/ntdll/thread.c 2006-10-04 16:28:20.000000000 +0900
+++ b/dlls/ntdll/thread.c 2006-11-06 22:06:47.000000000 +0800
@@ -406,7 +406,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HAN
NTSTATUS status;
SIZE_T size, page_size = getpagesize();
- if( ! is_current_process( process ) )
+ if( !is_current_process( process, PROCESS_CREATE_THREAD ) )
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
diff -up a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
--- a/dlls/ntdll/virtual.c 2006-11-06 18:35:25.000000000 +0800
+++ b/dlls/ntdll/virtual.c 2006-11-06 22:15:48.000000000 +0800
@@ -1193,7 +1193,7 @@ static NTSTATUS map_image( HANDLE hmappi
*
* Check whether a process handle is for the current process.
*/
-BOOL is_current_process( HANDLE handle )
+BOOL is_current_process( HANDLE handle, UINT access )
{
BOOL ret = FALSE;
@@ -1201,6 +1201,7 @@ BOOL is_current_process( HANDLE handle )
SERVER_START_REQ( get_process_info )
{
req->handle = handle;
+ req->access = access;
if (!wine_server_call( req ))
ret = ((DWORD)reply->pid == GetCurrentProcessId());
}
@@ -1315,7 +1316,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory(
if (!size) return STATUS_INVALID_PARAMETER;
- if (!is_current_process( process ))
+ if (!is_current_process( process, PROCESS_VM_OPERATION ))
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
@@ -1419,7 +1420,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HAN
TRACE("%p %p %08lx %x\n", process, addr, size, type );
- if (!is_current_process( process ))
+ if (!is_current_process( process, PROCESS_VM_OPERATION ))
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
@@ -1497,7 +1498,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory(
TRACE("%p %p %08lx %08x\n", process, addr, size, new_prot );
- if (!is_current_process( process ))
+ if (!is_current_process( process, PROCESS_VM_OPERATION ))
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
@@ -1581,7 +1582,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
if (ADDRESS_SPACE_LIMIT && addr >= ADDRESS_SPACE_LIMIT)
return STATUS_WORKING_SET_LIMIT_RANGE;
- if (!is_current_process( process ))
+ if (!is_current_process( process, PROCESS_QUERY_INFORMATION ))
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
@@ -1666,7 +1667,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HA
*/
NTSTATUS WINAPI NtLockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size, ULONG unknown )
{
- if (!is_current_process( process ))
+ if (!is_current_process( process, PROCESS_VM_OPERATION ))
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
@@ -1681,7 +1682,7 @@ NTSTATUS WINAPI NtLockVirtualMemory( HAN
*/
NTSTATUS WINAPI NtUnlockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size, ULONG unknown )
{
- if (!is_current_process( process ))
+ if (!is_current_process( process, PROCESS_VM_OPERATION ))
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
@@ -1784,7 +1785,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
TRACE("handle=%p process=%p addr=%p off=%x%08x size=%lx access=%x\n",
handle, process, *addr_ptr, offset.u.HighPart, offset.u.LowPart, size, protect );
- if (!is_current_process( process ))
+ if (!is_current_process( process, PROCESS_VM_OPERATION ))
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
@@ -1933,7 +1934,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HA
NTSTATUS status = STATUS_INVALID_PARAMETER;
void *base = ROUND_ADDR( addr, page_mask );
- if (!is_current_process( process ))
+ if (!is_current_process( process, PROCESS_VM_OPERATION ))
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
@@ -1960,7 +1961,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HA
NTSTATUS status = STATUS_SUCCESS;
void *addr = ROUND_ADDR( *addr_ptr, page_mask );
- if (!is_current_process( process ))
+ if (!is_current_process( process, PROCESS_VM_OPERATION ))
{
ERR("Unsupported on other process\n");
return STATUS_ACCESS_DENIED;
diff -up a/include/winnt.h b/include/winnt.h
--- a/include/winnt.h 2006-11-03 21:34:19.000000000 +0800
+++ b/include/winnt.h 2006-11-06 19:24:53.000000000 +0800
@@ -3826,6 +3826,7 @@ typedef enum tagSID_NAME_USE {
#define PROCESS_SET_QUOTA 0x0100
#define PROCESS_SET_INFORMATION 0x0200
#define PROCESS_QUERY_INFORMATION 0x0400
+#define PROCESS_SUSPEND_RESUME 0x0800
#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xfff)
#define THREAD_TERMINATE 0x0001
diff -up a/server/process.c b/server/process.c
--- a/server/process.c 2006-10-11 12:34:29.000000000 +0900
+++ b/server/process.c 2006-11-06 21:50:01.000000000 +0800
@@ -986,7 +986,7 @@ DECL_HANDLER(get_process_info)
{
struct process *process;
- if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
+ if ((process = get_process_from_handle( req->handle, req->access )))
{
reply->pid = get_process_id( process );
reply->ppid = process->parent ? get_process_id( process->parent ) : 0;
diff -up a/server/protocol.def b/server/protocol.def
--- a/server/protocol.def 2006-11-06 18:35:52.000000000 +0800
+++ b/server/protocol.def 2006-11-06 21:57:22.000000000 +0800
@@ -335,6 +335,7 @@ struct token_groups
/* Retrieve information about a process */
@REQ(get_process_info)
obj_handle_t handle; /* process handle */
+ unsigned int access; /* wanted access rights */
@REPLY
process_id_t pid; /* server process id */
process_id_t ppid; /* server process id of parent */
More information about the wine-patches
mailing list