diff --git a/configure b/configure index 51011968044..dd000b28fe3 100755 --- a/configure +++ b/configure @@ -20021,6 +20021,7 @@ wine_fn_config_makefile dlls/d3dxof enable_d3dxof wine_fn_config_makefile dlls/d3dxof/tests enable_tests wine_fn_config_makefile dlls/davclnt enable_davclnt wine_fn_config_makefile dlls/dbgeng enable_dbgeng +wine_fn_config_makefile dlls/dbgeng/tests enable_tests wine_fn_config_makefile dlls/dbghelp enable_dbghelp wine_fn_config_makefile dlls/dbghelp/tests enable_tests wine_fn_config_makefile dlls/dciman32 enable_dciman32 diff --git a/configure.ac b/configure.ac index b0b708048ad..ad4f0e05a40 100644 --- a/configure.ac +++ b/configure.ac @@ -3180,6 +3180,7 @@ WINE_CONFIG_MAKEFILE(dlls/d3dxof) WINE_CONFIG_MAKEFILE(dlls/d3dxof/tests) WINE_CONFIG_MAKEFILE(dlls/davclnt) WINE_CONFIG_MAKEFILE(dlls/dbgeng) +WINE_CONFIG_MAKEFILE(dlls/dbgeng/tests) WINE_CONFIG_MAKEFILE(dlls/dbghelp) WINE_CONFIG_MAKEFILE(dlls/dbghelp/tests) WINE_CONFIG_MAKEFILE(dlls/dciman32) diff --git a/dlls/dbgeng/dbgeng.c b/dlls/dbgeng/dbgeng.c index 348f2b9ad59..629f8cf1c57 100644 --- a/dlls/dbgeng/dbgeng.c +++ b/dlls/dbgeng/dbgeng.c @@ -41,6 +41,7 @@ struct debug_client IDebugSymbols IDebugSymbols_iface; IDebugControl2 IDebugControl2_iface; LONG refcount; + ULONG engine_options; }; static struct debug_client *impl_from_IDebugClient(IDebugClient *iface) @@ -1572,30 +1573,52 @@ static HRESULT STDMETHODCALLTYPE debugcontrol_SetCodeLevel(IDebugControl2 *iface static HRESULT STDMETHODCALLTYPE debugcontrol_GetEngineOptions(IDebugControl2 *iface, ULONG *options) { - FIXME("%p, %p stub.\n", iface, options); + struct debug_client *debug_client = impl_from_IDebugControl2(iface); - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, options); + + *options = debug_client->engine_options; + + return S_OK; } static HRESULT STDMETHODCALLTYPE debugcontrol_AddEngineOptions(IDebugControl2 *iface, ULONG options) { - FIXME("%p, %#x stub.\n", iface, options); + struct debug_client *debug_client = impl_from_IDebugControl2(iface); - return E_NOTIMPL; + TRACE("%p, %#x.\n", iface, options); + + if (options & ~DEBUG_ENGOPT_ALL) + return E_INVALIDARG; + + debug_client->engine_options |= options; + + return S_OK; } static HRESULT STDMETHODCALLTYPE debugcontrol_RemoveEngineOptions(IDebugControl2 *iface, ULONG options) { - FIXME("%p, %#x stub.\n", iface, options); + struct debug_client *debug_client = impl_from_IDebugControl2(iface); - return E_NOTIMPL; + TRACE("%p, %#x.\n", iface, options); + + debug_client->engine_options &= ~options; + + return S_OK; } static HRESULT STDMETHODCALLTYPE debugcontrol_SetEngineOptions(IDebugControl2 *iface, ULONG options) { - FIXME("%p, %#x stub.\n", iface, options); + struct debug_client *debug_client = impl_from_IDebugControl2(iface); - return E_NOTIMPL; + TRACE("%p, %#x.\n", iface, options); + + if (options & ~DEBUG_ENGOPT_ALL) + return E_INVALIDARG; + + debug_client->engine_options = options; + + return S_OK; } static HRESULT STDMETHODCALLTYPE debugcontrol_GetSystemErrorControl(IDebugControl2 *iface, ULONG *output_level, @@ -2100,7 +2123,7 @@ HRESULT WINAPI DebugCreate(REFIID riid, void **obj) TRACE("%s, %p.\n", debugstr_guid(riid), obj); - debug_client = heap_alloc(sizeof(*debug_client)); + debug_client = heap_alloc_zero(sizeof(*debug_client)); if (!debug_client) return E_OUTOFMEMORY; diff --git a/dlls/dbgeng/tests/Makefile.in b/dlls/dbgeng/tests/Makefile.in new file mode 100644 index 00000000000..26006e9546b --- /dev/null +++ b/dlls/dbgeng/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = dbgeng.dll +IMPORTS = dbgeng + +C_SRCS = \ + dbgeng.c diff --git a/dlls/dbgeng/tests/dbgeng.c b/dlls/dbgeng/tests/dbgeng.c new file mode 100644 index 00000000000..a76b25a1289 --- /dev/null +++ b/dlls/dbgeng/tests/dbgeng.c @@ -0,0 +1,105 @@ +/* + * Copyright 2019 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" + +#include "initguid.h" +#include "dbgeng.h" + +#include "wine/test.h" + +static void test_engine_options(void) +{ + IDebugControl *control; + ULONG options; + HRESULT hr; + + hr = DebugCreate(&IID_IDebugControl, (void **)&control); + ok(hr == S_OK, "Failed to create engine object, hr %#x.\n", hr); + + options = 0xf; + hr = control->lpVtbl->GetEngineOptions(control, &options); + ok(hr == S_OK, "Failed to get engine options, hr %#x.\n", hr); + ok(options == 0, "Unexpected options %#x.\n", options); + + hr = control->lpVtbl->AddEngineOptions(control, DEBUG_ENGOPT_INITIAL_BREAK); + ok(hr == S_OK, "Failed to add engine options, hr %#x.\n", hr); + + options = 0; + hr = control->lpVtbl->GetEngineOptions(control, &options); + ok(hr == S_OK, "Failed to get engine options, hr %#x.\n", hr); + ok(options == DEBUG_ENGOPT_INITIAL_BREAK, "Unexpected options %#x.\n", options); + + hr = control->lpVtbl->AddEngineOptions(control, 0x00800000); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + options = 0; + hr = control->lpVtbl->GetEngineOptions(control, &options); + ok(hr == S_OK, "Failed to get engine options, hr %#x.\n", hr); + ok(options == DEBUG_ENGOPT_INITIAL_BREAK, "Unexpected options %#x.\n", options); + + hr = control->lpVtbl->RemoveEngineOptions(control, 0x00800000); + ok(hr == S_OK, "Failed to remove options, hr %#x.\n", hr); + + hr = control->lpVtbl->AddEngineOptions(control, DEBUG_ENGOPT_IGNORE_DBGHELP_VERSION); + ok(hr == S_OK, "Failed to add engine options, hr %#x.\n", hr); + + options = 0; + hr = control->lpVtbl->GetEngineOptions(control, &options); + ok(hr == S_OK, "Failed to get engine options, hr %#x.\n", hr); + ok(options == (DEBUG_ENGOPT_INITIAL_BREAK | DEBUG_ENGOPT_IGNORE_DBGHELP_VERSION), + "Unexpected options %#x.\n", options); + + hr = control->lpVtbl->RemoveEngineOptions(control, DEBUG_ENGOPT_INITIAL_BREAK); + ok(hr == S_OK, "Failed to remove options, hr %#x.\n", hr); + + options = 0; + hr = control->lpVtbl->GetEngineOptions(control, &options); + ok(hr == S_OK, "Failed to get engine options, hr %#x.\n", hr); + ok(options == DEBUG_ENGOPT_IGNORE_DBGHELP_VERSION, "Unexpected options %#x.\n", options); + + hr = control->lpVtbl->SetEngineOptions(control, DEBUG_ENGOPT_INITIAL_BREAK); + ok(hr == S_OK, "Failed to set options, hr %#x.\n", hr); + + options = 0; + hr = control->lpVtbl->GetEngineOptions(control, &options); + ok(hr == S_OK, "Failed to get engine options, hr %#x.\n", hr); + ok(options == DEBUG_ENGOPT_INITIAL_BREAK, "Unexpected options %#x.\n", options); + + hr = control->lpVtbl->SetEngineOptions(control, 0x00800000); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = control->lpVtbl->SetEngineOptions(control, 0x00800000 | DEBUG_ENGOPT_IGNORE_DBGHELP_VERSION); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + options = 0; + hr = control->lpVtbl->GetEngineOptions(control, &options); + ok(hr == S_OK, "Failed to get engine options, hr %#x.\n", hr); + ok(options == DEBUG_ENGOPT_INITIAL_BREAK, "Unexpected options %#x.\n", options); + + control->lpVtbl->Release(control); +} + +START_TEST(dbgeng) +{ + test_engine_options(); +} diff --git a/include/dbgeng.h b/include/dbgeng.h index 6e4529cf918..2f059710917 100644 --- a/include/dbgeng.h +++ b/include/dbgeng.h @@ -31,6 +31,31 @@ DEFINE_GUID(IID_IDebugSymbols, 0x8c31e98c, 0x983a, 0x48a5, 0x90, 0x16 DEFINE_GUID(IID_IDebugControl, 0x5182e668, 0x105e, 0x416e, 0xad, 0x92, 0x24, 0xef, 0x80, 0x04, 0x24, 0xba); DEFINE_GUID(IID_IDebugControl2, 0xd4366723, 0x44df, 0x4bed, 0x8c, 0x7e, 0x4c, 0x05, 0x42, 0x4f, 0x45, 0x88); +#define DEBUG_ENGOPT_IGNORE_DBGHELP_VERSION 0x00000001 +#define DEBUG_ENGOPT_IGNORE_EXTENSION_VERSIONS 0x00000002 +#define DEBUG_ENGOPT_ALLOW_NETWORK_PATHS 0x00000004 +#define DEBUG_ENGOPT_DISALLOW_NETWORK_PATHS 0x00000008 +#define DEBUG_ENGOPT_IGNORE_LOADER_EXCEPTIONS 0x00000010 +#define DEBUG_ENGOPT_INITIAL_BREAK 0x00000020 +#define DEBUG_ENGOPT_INITIAL_MODULE_BREAK 0x00000040 +#define DEBUG_ENGOPT_FINAL_BREAK 0x00000080 +#define DEBUG_ENGOPT_NO_EXECUTE_REPEAT 0x00000100 +#define DEBUG_ENGOPT_FAIL_INCOMPLETE_INFORMATION 0x00000200 +#define DEBUG_ENGOPT_ALLOW_READ_ONLY_BREAKPOINTS 0x00000400 +#define DEBUG_ENGOPT_SYNCHRONIZE_BREAKPOINTS 0x00000800 +#define DEBUG_ENGOPT_DISALLOW_SHELL_COMMANDS 0x00001000 +#define DEBUG_ENGOPT_KD_QUIET_MODE 0x00002000 +#define DEBUG_ENGOPT_DISABLE_MANAGED_SUPPORT 0x00004000 +#define DEBUG_ENGOPT_DISABLE_MODULE_SYMBOL_LOAD 0x00008000 +#define DEBUG_ENGOPT_DISABLE_EXECUTION_COMMANDS 0x00010000 +#define DEBUG_ENGOPT_DISALLOW_IMAGE_FILE_MAPPING 0x00020000 +#define DEBUG_ENGOPT_PREFER_DML 0x00040000 +#define DEBUG_ENGOPT_DISABLESQM 0x00080000 +#define DEBUG_ENGOPT_DISABLE_STEPLINES_OPTIONS 0x00200000 +#define DEBUG_ENGOPT_DEBUGGING_SENSITIVE_DATA 0x00400000 +#define DEBUG_ENGOPT_ALL 0x004fffff +#define DEBUG_ENGOPT_NETWORK_PATHS (DEBUG_ENGOPT_ALLOW_NETWORK_PATHS | DEBUG_ENGOPT_DISALLOW_NETWORK_PATHS) + typedef struct _DEBUG_MODULE_PARAMETERS { ULONG64 Base; @@ -645,6 +670,8 @@ DECLARE_INTERFACE_(IDebugControl2, IUnknown) }; #undef INTERFACE +HRESULT WINAPI DebugCreate(REFIID riid, void **out); + #ifdef __cplusplus } #endif