From: Nikolay Sivov Subject: [PATCH 1/5] dbgeng: Implement ReadVirtual(). Message-Id: <20190423073819.8771-1-nsivov@codeweavers.com> Date: Tue, 23 Apr 2019 10:38:15 +0300 Signed-off-by: Nikolay Sivov --- dlls/dbgeng/dbgeng.c | 23 +++++++++++++++++++++-- dlls/dbgeng/tests/dbgeng.c | 27 ++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/dlls/dbgeng/dbgeng.c b/dlls/dbgeng/dbgeng.c index 1acfe0b318..d7f8191858 100644 --- a/dlls/dbgeng/dbgeng.c +++ b/dlls/dbgeng/dbgeng.c @@ -725,9 +725,28 @@ static ULONG STDMETHODCALLTYPE debugdataspaces_Release(IDebugDataSpaces *iface) static HRESULT STDMETHODCALLTYPE debugdataspaces_ReadVirtual(IDebugDataSpaces *iface, ULONG64 offset, void *buffer, ULONG buffer_size, ULONG *read_len) { - FIXME("%p, %s, %p, %u, %p stub.\n", iface, wine_dbgstr_longlong(offset), buffer, buffer_size, read_len); + struct debug_client *debug_client = impl_from_IDebugDataSpaces(iface); + static struct target_process *target; + HRESULT hr = S_OK; + SIZE_T length; - return E_NOTIMPL; + TRACE("%p, %s, %p, %u, %p.\n", iface, wine_dbgstr_longlong(offset), buffer, buffer_size, read_len); + + if (!(target = debug_client_get_target(debug_client))) + return E_UNEXPECTED; + + if (ReadProcessMemory(target->handle, (const void *)(ULONG_PTR)offset, buffer, buffer_size, &length)) + { + if (read_len) + *read_len = length; + } + else + { + hr = HRESULT_FROM_WIN32(GetLastError()); + WARN("Failed to read process memory %#x.\n", hr); + } + + return hr; } static HRESULT STDMETHODCALLTYPE debugdataspaces_WriteVirtual(IDebugDataSpaces *iface, ULONG64 offset, void *buffer, diff --git a/dlls/dbgeng/tests/dbgeng.c b/dlls/dbgeng/tests/dbgeng.c index 2a2dd3ad06..c8906c9048 100644 --- a/dlls/dbgeng/tests/dbgeng.c +++ b/dlls/dbgeng/tests/dbgeng.c @@ -322,14 +322,15 @@ todo_wine static void test_module_information(void) { static const char *event_name = "dbgeng_test_event"; - unsigned int loaded, unloaded, index; + unsigned int loaded, unloaded, index, length; DEBUG_MODULE_PARAMETERS params[2]; + IDebugDataSpaces *dataspaces; PROCESS_INFORMATION info; IDebugSymbols *symbols; IDebugControl *control; + ULONG64 bases[2], base; IDebugClient *client; - ULONG64 bases[2]; - ULONG64 base; + char buffer[64]; HANDLE event; HRESULT hr; BOOL ret; @@ -343,6 +344,9 @@ static void test_module_information(void) hr = client->lpVtbl->QueryInterface(client, &IID_IDebugSymbols, (void **)&symbols); ok(hr == S_OK, "Failed to get interface pointer, hr %#x.\n", hr); + hr = client->lpVtbl->QueryInterface(client, &IID_IDebugDataSpaces, (void **)&dataspaces); + ok(hr == S_OK, "Failed to get interface pointer, hr %#x.\n", hr); + event = CreateEventA(NULL, FALSE, FALSE, event_name); ok(event != NULL, "Failed to create event.\n"); @@ -419,6 +423,22 @@ static void test_module_information(void) hr = symbols->lpVtbl->GetModuleParameters(symbols, 1, NULL, loaded, params); ok(FAILED(hr), "Unexpected hr %#x.\n", hr); + /* Read memory. */ + base = 0; + hr = symbols->lpVtbl->GetModuleByIndex(symbols, 0, &base); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!!base, "Unexpected module base.\n"); + + hr = dataspaces->lpVtbl->ReadVirtual(dataspaces, base, buffer, sizeof(buffer), &length); + ok(hr == S_OK, "Failed to read process memory, hr %#x.\n", hr); + ok(length == sizeof(buffer), "Unexpected length %u.\n", length); + ok(buffer[0] == 'M' && buffer[1] == 'Z', "Unexpected contents.\n"); + + memset(buffer, 0, sizeof(buffer)); + hr = dataspaces->lpVtbl->ReadVirtual(dataspaces, base, buffer, sizeof(buffer), NULL); + ok(hr == S_OK, "Failed to read process memory, hr %#x.\n", hr); + ok(buffer[0] == 'M' && buffer[1] == 'Z', "Unexpected contents.\n"); + hr = client->lpVtbl->DetachProcesses(client); ok(hr == S_OK, "Failed to detach, hr %#x.\n", hr); @@ -431,6 +451,7 @@ static void test_module_information(void) client->lpVtbl->Release(client); control->lpVtbl->Release(control); symbols->lpVtbl->Release(symbols); + dataspaces->lpVtbl->Release(dataspaces); } static void target_proc(const char *event_name, const char *event_ready_name) -- 2.20.1