mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 17:44:07 +00:00
ntdll: Implementation of inter-process VirtualQueryEx.
This commit is contained in:
parent
7a00142bc1
commit
3d00239586
|
@ -103,22 +103,17 @@ static void test_VirtualAllocEx(void)
|
|||
|
||||
/* test a not committed memory */
|
||||
memset(&info, 'q', sizeof(info));
|
||||
todo_wine ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info))
|
||||
== sizeof(info), "VirtualQueryEx failed\n");
|
||||
todo_wine ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress,
|
||||
addr1);
|
||||
todo_wine ok(info.AllocationBase == addr1, "%p != %p\n",
|
||||
info.AllocationBase, addr1);
|
||||
todo_wine ok(info.AllocationProtect == PAGE_NOACCESS,
|
||||
"%x != PAGE_NOACCESS\n", info.AllocationProtect);
|
||||
todo_wine ok(info.RegionSize == 0x10000, "%lx != 0x10000\n",
|
||||
info.RegionSize);
|
||||
todo_wine ok(info.State == MEM_RESERVE, "%x != MEM_RESERVE\n", info.State);
|
||||
ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info)) == sizeof(info), "VirtualQueryEx failed\n");
|
||||
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 */
|
||||
todo_wine ok(info.Protect == 0 /* NT */ ||
|
||||
ok(info.Protect == 0 /* NT */ ||
|
||||
info.Protect == PAGE_NOACCESS, /* Win9x */
|
||||
"%x != PAGE_NOACCESS\n", info.Protect);
|
||||
todo_wine ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
|
||||
ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
|
||||
|
@ -131,20 +126,16 @@ static void test_VirtualAllocEx(void)
|
|||
ok(addr1 == addr2, "VirtualAllocEx failed\n");
|
||||
|
||||
/* test a committed memory */
|
||||
todo_wine ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info))
|
||||
== sizeof(info),
|
||||
ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info)) == sizeof(info),
|
||||
"VirtualQueryEx failed\n");
|
||||
todo_wine ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress,
|
||||
addr1);
|
||||
todo_wine ok(info.AllocationBase == addr1, "%p != %p\n",
|
||||
info.AllocationBase, addr1);
|
||||
todo_wine ok(info.AllocationProtect == PAGE_NOACCESS,
|
||||
"%x != PAGE_NOACCESS\n", info.AllocationProtect);
|
||||
todo_wine ok(info.RegionSize == 0x1000, "%lx != 0x1000\n", info.RegionSize);
|
||||
todo_wine ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
|
||||
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 == 0x1000, "%lx != 0x1000\n", info.RegionSize);
|
||||
ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
|
||||
/* this time NT reports PAGE_NOACCESS as well */
|
||||
todo_wine ok(info.Protect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.Protect);
|
||||
todo_wine ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
|
||||
ok(info.Protect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.Protect);
|
||||
ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
|
||||
|
||||
/* this should fail, since not the whole range is committed yet */
|
||||
SetLastError(0xdeadbeef);
|
||||
|
|
|
@ -726,6 +726,26 @@ static BOOL call_apcs( BOOL alertable )
|
|||
&result.virtual_free.size,
|
||||
call.virtual_free.op_type );
|
||||
break;
|
||||
case APC_VIRTUAL_QUERY:
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION info;
|
||||
result.type = call.type;
|
||||
result.virtual_query.status = NtQueryVirtualMemory( NtCurrentProcess(),
|
||||
call.virtual_query.addr,
|
||||
MemoryBasicInformation, &info,
|
||||
sizeof(info), NULL );
|
||||
if (result.virtual_query.status == STATUS_SUCCESS)
|
||||
{
|
||||
result.virtual_query.base = info.BaseAddress;
|
||||
result.virtual_query.alloc_base = info.AllocationBase;
|
||||
result.virtual_query.size = info.RegionSize;
|
||||
result.virtual_query.state = info.State;
|
||||
result.virtual_query.prot = info.Protect;
|
||||
result.virtual_query.alloc_prot = info.AllocationProtect;
|
||||
result.virtual_query.alloc_type = info.Type;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
server_protocol_error( "get_apc_request: bad type %d\n", call.type );
|
||||
break;
|
||||
|
|
|
@ -1682,10 +1682,29 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
|
|||
if (ADDRESS_SPACE_LIMIT && addr >= ADDRESS_SPACE_LIMIT)
|
||||
return STATUS_WORKING_SET_LIMIT_RANGE;
|
||||
|
||||
if (!is_current_process( process ))
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
ERR("Unsupported on other process\n");
|
||||
return STATUS_ACCESS_DENIED;
|
||||
NTSTATUS status;
|
||||
apc_call_t call;
|
||||
apc_result_t result;
|
||||
|
||||
call.virtual_query.type = APC_VIRTUAL_QUERY;
|
||||
call.virtual_query.addr = addr;
|
||||
status = NTDLL_queue_process_apc( process, &call, &result );
|
||||
if (status != STATUS_SUCCESS) return status;
|
||||
|
||||
if (result.virtual_query.status == STATUS_SUCCESS)
|
||||
{
|
||||
info->BaseAddress = result.virtual_query.base;
|
||||
info->AllocationBase = result.virtual_query.alloc_base;
|
||||
info->RegionSize = result.virtual_query.size;
|
||||
info->State = result.virtual_query.state;
|
||||
info->Protect = result.virtual_query.prot;
|
||||
info->AllocationProtect = result.virtual_query.alloc_prot;
|
||||
info->Type = result.virtual_query.alloc_type;
|
||||
if (res_len) *res_len = sizeof(*info);
|
||||
}
|
||||
return result.virtual_query.status;
|
||||
}
|
||||
|
||||
base = ROUND_ADDR( addr, page_mask );
|
||||
|
|
|
@ -216,7 +216,8 @@ enum apc_type
|
|||
APC_TIMER,
|
||||
APC_ASYNC_IO,
|
||||
APC_VIRTUAL_ALLOC,
|
||||
APC_VIRTUAL_FREE
|
||||
APC_VIRTUAL_FREE,
|
||||
APC_VIRTUAL_QUERY
|
||||
};
|
||||
|
||||
typedef union
|
||||
|
@ -259,6 +260,11 @@ typedef union
|
|||
unsigned long size;
|
||||
unsigned int op_type;
|
||||
} virtual_free;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
const void *addr;
|
||||
} virtual_query;
|
||||
} apc_call_t;
|
||||
|
||||
typedef union
|
||||
|
@ -278,6 +284,18 @@ typedef union
|
|||
void *addr;
|
||||
unsigned long size;
|
||||
} virtual_free;
|
||||
struct
|
||||
{
|
||||
enum apc_type type;
|
||||
unsigned int status;
|
||||
void *base;
|
||||
void *alloc_base;
|
||||
unsigned long size;
|
||||
unsigned int state;
|
||||
unsigned int prot;
|
||||
unsigned int alloc_prot;
|
||||
unsigned int alloc_type;
|
||||
} virtual_query;
|
||||
} apc_result_t;
|
||||
|
||||
|
||||
|
@ -4499,6 +4517,6 @@ union generic_reply
|
|||
struct query_symlink_reply query_symlink_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 266
|
||||
#define SERVER_PROTOCOL_VERSION 267
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -232,7 +232,8 @@ enum apc_type
|
|||
APC_TIMER,
|
||||
APC_ASYNC_IO,
|
||||
APC_VIRTUAL_ALLOC,
|
||||
APC_VIRTUAL_FREE
|
||||
APC_VIRTUAL_FREE,
|
||||
APC_VIRTUAL_QUERY
|
||||
};
|
||||
|
||||
typedef union
|
||||
|
@ -275,6 +276,11 @@ typedef union
|
|||
unsigned long size; /* allocation size */
|
||||
unsigned int op_type; /* type of operation */
|
||||
} virtual_free;
|
||||
struct
|
||||
{
|
||||
enum apc_type type; /* APC_VIRTUAL_QUERY */
|
||||
const void *addr; /* requested address */
|
||||
} virtual_query;
|
||||
} apc_call_t;
|
||||
|
||||
typedef union
|
||||
|
@ -294,6 +300,18 @@ typedef union
|
|||
void *addr; /* resulting address */
|
||||
unsigned long size; /* resulting size */
|
||||
} virtual_free;
|
||||
struct
|
||||
{
|
||||
enum apc_type type; /* APC_VIRTUAL_QUERY */
|
||||
unsigned int status; /* status returned by call */
|
||||
void *base; /* resulting base address */
|
||||
void *alloc_base;/* resulting allocation base */
|
||||
unsigned long size; /* resulting region size */
|
||||
unsigned int state; /* resulting region state */
|
||||
unsigned int prot; /* resulting region protection */
|
||||
unsigned int alloc_prot;/* resulting allocation protection */
|
||||
unsigned int alloc_type;/* resulting region allocation type */
|
||||
} virtual_query;
|
||||
} apc_result_t;
|
||||
|
||||
/****************************************************************/
|
||||
|
|
|
@ -1140,6 +1140,7 @@ DECL_HANDLER(queue_apc)
|
|||
struct thread *thread;
|
||||
struct process *process;
|
||||
struct thread_apc *apc;
|
||||
unsigned int access;
|
||||
|
||||
if (!(apc = create_apc( NULL, &req->call ))) return;
|
||||
|
||||
|
@ -1155,7 +1156,9 @@ DECL_HANDLER(queue_apc)
|
|||
break;
|
||||
case APC_VIRTUAL_ALLOC:
|
||||
case APC_VIRTUAL_FREE:
|
||||
if ((process = get_process_from_handle( req->process, PROCESS_VM_OPERATION )))
|
||||
case APC_VIRTUAL_QUERY:
|
||||
access = (apc->call.type == APC_VIRTUAL_QUERY) ? PROCESS_QUERY_INFORMATION : PROCESS_VM_OPERATION;
|
||||
if ((process = get_process_from_handle( req->process, access )))
|
||||
{
|
||||
obj_handle_t handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 );
|
||||
if (handle)
|
||||
|
|
|
@ -130,6 +130,9 @@ static void dump_apc_call( const apc_call_t *call )
|
|||
call->virtual_free.addr, call->virtual_free.size,
|
||||
call->virtual_free.op_type );
|
||||
break;
|
||||
case APC_VIRTUAL_QUERY:
|
||||
fprintf( stderr, "APC_VIRTUAL_QUERY,addr=%p", call->virtual_query.addr );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "type=%u", call->type );
|
||||
break;
|
||||
|
@ -154,6 +157,14 @@ static void dump_apc_result( const apc_result_t *result )
|
|||
get_status_name( result->virtual_free.status ),
|
||||
result->virtual_free.addr, result->virtual_free.size );
|
||||
break;
|
||||
case APC_VIRTUAL_QUERY:
|
||||
fprintf( stderr, "APC_VIRTUAL_QUERY,status=%s,base=%p,alloc_base=%p,size=%lu,state=%x,prot=%x,alloc_prot=%x,alloc_type=%x",
|
||||
get_status_name( result->virtual_query.status ),
|
||||
result->virtual_query.base, result->virtual_query.alloc_base,
|
||||
result->virtual_query.size, result->virtual_query.state,
|
||||
result->virtual_query.prot, result->virtual_query.alloc_prot,
|
||||
result->virtual_query.alloc_type );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "type=%u", result->type );
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue