Commit bfd2d1d7 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Implement NtWow64Read/WriteVirtualMemory64().

parent cbf7a101
...@@ -430,6 +430,8 @@ ...@@ -430,6 +430,8 @@
@ stdcall -syscall NtWaitForSingleObject(long long ptr) @ stdcall -syscall NtWaitForSingleObject(long long ptr)
@ stub NtWaitHighEventPair @ stub NtWaitHighEventPair
@ stub NtWaitLowEventPair @ stub NtWaitLowEventPair
@ stdcall -syscall -arch=win32 NtWow64ReadVirtualMemory64(long int64 ptr int64 ptr)
@ stdcall -syscall -arch=win32 NtWow64WriteVirtualMemory64(long int64 ptr int64 ptr)
@ stdcall -syscall NtWriteFile(long long ptr ptr ptr ptr long ptr ptr) @ stdcall -syscall NtWriteFile(long long ptr ptr ptr ptr long ptr ptr)
@ stdcall -syscall NtWriteFileGather(long long ptr ptr ptr ptr long ptr ptr) @ stdcall -syscall NtWriteFileGather(long long ptr ptr ptr ptr long ptr ptr)
@ stub NtWriteRequestData @ stub NtWriteRequestData
...@@ -1444,6 +1446,8 @@ ...@@ -1444,6 +1446,8 @@
@ stdcall -private -syscall ZwWaitForSingleObject(long long ptr) NtWaitForSingleObject @ stdcall -private -syscall ZwWaitForSingleObject(long long ptr) NtWaitForSingleObject
@ stub ZwWaitHighEventPair @ stub ZwWaitHighEventPair
@ stub ZwWaitLowEventPair @ stub ZwWaitLowEventPair
@ stdcall -syscall -arch=win32 ZwWow64ReadVirtualMemory64(long int64 ptr int64 ptr) NtWow64ReadVirtualMemory64
@ stdcall -syscall -arch=win32 ZwWow64WriteVirtualMemory64(long int64 ptr int64 ptr) NtWow64WriteVirtualMemory64
@ stdcall -private -syscall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr) NtWriteFile @ stdcall -private -syscall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr) NtWriteFile
@ stdcall -private -syscall ZwWriteFileGather(long long ptr ptr ptr ptr long ptr ptr) NtWriteFileGather @ stdcall -private -syscall ZwWriteFileGather(long long ptr ptr ptr ptr long ptr ptr) NtWriteFileGather
@ stub ZwWriteRequestData @ stub ZwWriteRequestData
......
...@@ -27,6 +27,9 @@ static NTSTATUS (WINAPI *pRtlWow64GetProcessMachines)(HANDLE,WORD*,WORD*); ...@@ -27,6 +27,9 @@ static NTSTATUS (WINAPI *pRtlWow64GetProcessMachines)(HANDLE,WORD*,WORD*);
static NTSTATUS (WINAPI *pRtlWow64IsWowGuestMachineSupported)(USHORT,BOOLEAN*); static NTSTATUS (WINAPI *pRtlWow64IsWowGuestMachineSupported)(USHORT,BOOLEAN*);
#ifdef _WIN64 #ifdef _WIN64
static NTSTATUS (WINAPI *pRtlWow64GetCpuAreaInfo)(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*); static NTSTATUS (WINAPI *pRtlWow64GetCpuAreaInfo)(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
#else
static NTSTATUS (WINAPI *pNtWow64ReadVirtualMemory64)(HANDLE,ULONG64,void*,ULONG64,ULONG64*);
static NTSTATUS (WINAPI *pNtWow64WriteVirtualMemory64)(HANDLE,ULONG64,const void *,ULONG64,ULONG64*);
#endif #endif
static BOOL is_wow64; static BOOL is_wow64;
...@@ -44,6 +47,9 @@ static void init(void) ...@@ -44,6 +47,9 @@ static void init(void)
GET_PROC( RtlWow64IsWowGuestMachineSupported ); GET_PROC( RtlWow64IsWowGuestMachineSupported );
#ifdef _WIN64 #ifdef _WIN64
GET_PROC( RtlWow64GetCpuAreaInfo ); GET_PROC( RtlWow64GetCpuAreaInfo );
#else
GET_PROC( NtWow64ReadVirtualMemory64 );
GET_PROC( NtWow64WriteVirtualMemory64 );
#endif #endif
#undef GET_PROC #undef GET_PROC
} }
...@@ -453,6 +459,40 @@ static void test_cpu_area(void) ...@@ -453,6 +459,40 @@ static void test_cpu_area(void)
else win_skip( "RtlWow64GetCpuAreaInfo not supported\n" ); else win_skip( "RtlWow64GetCpuAreaInfo not supported\n" );
} }
#else /* _WIN64 */
static void test_nt_wow64(void)
{
const char str[] = "hello wow64";
char buffer[100];
NTSTATUS status;
ULONG64 res;
HANDLE process = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() );
ok( process != 0, "failed to open current process %u\n", GetLastError() );
if (pNtWow64ReadVirtualMemory64)
{
status = pNtWow64ReadVirtualMemory64( process, (ULONG_PTR)str, buffer, sizeof(str), &res );
ok( !status, "NtWow64ReadVirtualMemory64 failed %x\n", status );
ok( res == sizeof(str), "wrong size %s\n", wine_dbgstr_longlong(res) );
ok( !strcmp( buffer, str ), "wrong data %s\n", debugstr_a(buffer) );
status = pNtWow64WriteVirtualMemory64( process, (ULONG_PTR)buffer, " bye ", 5, &res );
ok( !status, "NtWow64WriteVirtualMemory64 failed %x\n", status );
ok( res == 5, "wrong size %s\n", wine_dbgstr_longlong(res) );
ok( !strcmp( buffer, " bye wow64" ), "wrong data %s\n", debugstr_a(buffer) );
/* current process pseudo-handle is broken on some Windows versions */
status = pNtWow64ReadVirtualMemory64( GetCurrentProcess(), (ULONG_PTR)str, buffer, sizeof(str), &res );
ok( !status || broken( status == STATUS_INVALID_HANDLE ),
"NtWow64ReadVirtualMemory64 failed %x\n", status );
status = pNtWow64WriteVirtualMemory64( GetCurrentProcess(), (ULONG_PTR)buffer, " bye ", 5, &res );
ok( !status || broken( status == STATUS_INVALID_HANDLE ),
"NtWow64WriteVirtualMemory64 failed %x\n", status );
}
else win_skip( "NtWow64ReadVirtualMemory64 not supported\n" );
NtClose( process );
}
#endif /* _WIN64 */ #endif /* _WIN64 */
...@@ -463,5 +503,7 @@ START_TEST(wow64) ...@@ -463,5 +503,7 @@ START_TEST(wow64)
test_peb_teb(); test_peb_teb();
#ifdef _WIN64 #ifdef _WIN64
test_cpu_area(); test_cpu_area();
#else
test_nt_wow64();
#endif #endif
} }
...@@ -4833,3 +4833,70 @@ NTSTATUS WINAPI NtCreatePagingFile( UNICODE_STRING *name, LARGE_INTEGER *min_siz ...@@ -4833,3 +4833,70 @@ NTSTATUS WINAPI NtCreatePagingFile( UNICODE_STRING *name, LARGE_INTEGER *min_siz
FIXME( "(%s %p %p %p) stub\n", debugstr_us(name), min_size, max_size, actual_size ); FIXME( "(%s %p %p %p) stub\n", debugstr_us(name), min_size, max_size, actual_size );
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
#ifndef _WIN64
/***********************************************************************
* NtWow64ReadVirtualMemory64 (NTDLL.@)
* ZwWow64ReadVirtualMemory64 (NTDLL.@)
*/
NTSTATUS WINAPI NtWow64ReadVirtualMemory64( HANDLE process, ULONG64 addr, void *buffer,
ULONG64 size, ULONG64 *bytes_read )
{
NTSTATUS status;
if (size > MAXLONG) size = MAXLONG;
if (virtual_check_buffer_for_write( buffer, size ))
{
SERVER_START_REQ( read_process_memory )
{
req->handle = wine_server_obj_handle( process );
req->addr = addr;
wine_server_set_reply( req, buffer, size );
if ((status = wine_server_call( req ))) size = 0;
}
SERVER_END_REQ;
}
else
{
status = STATUS_ACCESS_VIOLATION;
size = 0;
}
if (bytes_read) *bytes_read = size;
return status;
}
/***********************************************************************
* NtWow64WriteVirtualMemory64 (NTDLL.@)
* ZwWow64WriteVirtualMemory64 (NTDLL.@)
*/
NTSTATUS WINAPI NtWow64WriteVirtualMemory64( HANDLE process, ULONG64 addr, const void *buffer,
ULONG64 size, ULONG64 *bytes_written )
{
NTSTATUS status;
if (size > MAXLONG) size = MAXLONG;
if (virtual_check_buffer_for_read( buffer, size ))
{
SERVER_START_REQ( write_process_memory )
{
req->handle = wine_server_obj_handle( process );
req->addr = addr;
wine_server_add_data( req, buffer, size );
if ((status = wine_server_call( req ))) size = 0;
}
SERVER_END_REQ;
}
else
{
status = STATUS_PARTIAL_COPY;
size = 0;
}
if (bytes_written) *bytes_written = size;
return status;
}
#endif /* _WIN64 */
...@@ -4396,19 +4396,19 @@ NTSYSAPI NTSTATUS WINAPI RtlpUnWaitCriticalSection(RTL_CRITICAL_SECTION *); ...@@ -4396,19 +4396,19 @@ NTSYSAPI NTSTATUS WINAPI RtlpUnWaitCriticalSection(RTL_CRITICAL_SECTION *);
NTSYSAPI NTSTATUS WINAPI vDbgPrintEx(ULONG,ULONG,LPCSTR,__ms_va_list); NTSYSAPI NTSTATUS WINAPI vDbgPrintEx(ULONG,ULONG,LPCSTR,__ms_va_list);
NTSYSAPI NTSTATUS WINAPI vDbgPrintExWithPrefix(LPCSTR,ULONG,ULONG,LPCSTR,__ms_va_list); NTSYSAPI NTSTATUS WINAPI vDbgPrintExWithPrefix(LPCSTR,ULONG,ULONG,LPCSTR,__ms_va_list);
#ifdef _WIN64
NTSYSAPI NTSTATUS WINAPI RtlWow64GetCpuAreaInfo(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE,WOW64_CONTEXT*);
NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*);
#endif
#ifndef __WINE_USE_MSVCRT #ifndef __WINE_USE_MSVCRT
NTSYSAPI int __cdecl _strnicmp(LPCSTR,LPCSTR,size_t); NTSYSAPI int __cdecl _strnicmp(LPCSTR,LPCSTR,size_t);
#endif #endif
/* 32-bit only functions */ /* 32-bit or 64-bit only functions */
#ifndef _WIN64 #ifdef _WIN64
NTSYSAPI NTSTATUS WINAPI RtlWow64GetCpuAreaInfo(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE,WOW64_CONTEXT*);
NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*);
#else
NTSYSAPI NTSTATUS WINAPI NtWow64ReadVirtualMemory64(HANDLE,ULONG64,void*,ULONG64,ULONG64*);
NTSYSAPI NTSTATUS WINAPI NtWow64WriteVirtualMemory64(HANDLE,ULONG64,const void*,ULONG64,ULONG64*);
NTSYSAPI LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG); NTSYSAPI LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG);
NTSYSAPI ULONGLONG WINAPI RtlConvertUlongToLargeInteger(ULONG); NTSYSAPI ULONGLONG WINAPI RtlConvertUlongToLargeInteger(ULONG);
NTSYSAPI LONGLONG WINAPI RtlEnlargedIntegerMultiply(INT,INT); NTSYSAPI LONGLONG WINAPI RtlEnlargedIntegerMultiply(INT,INT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment