Module: wine Branch: master Commit: f0e2ea988e666533dd9f5ba1a6e68b2853dd0038 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f0e2ea988e666533dd9f5ba1a6...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sun Feb 15 14:30:00 2015 +0300
wshom.ocx: Properly handle optional argument in Run().
---
dlls/wshom.ocx/shell.c | 43 +++++++++++++++++++++++------------------- dlls/wshom.ocx/tests/wshom.c | 32 ++++++++++++++++++++++++++++++- dlls/wshom.ocx/tests/wshom.idl | 2 +- dlls/wshom.ocx/wshom.idl | 2 +- 4 files changed, 57 insertions(+), 22 deletions(-)
diff --git a/dlls/wshom.ocx/shell.c b/dlls/wshom.ocx/shell.c index 09c7504..14eab75 100644 --- a/dlls/wshom.ocx/shell.c +++ b/dlls/wshom.ocx/shell.c @@ -912,14 +912,22 @@ static HRESULT WINAPI WshShell3_get_Environment(IWshShell3 *iface, VARIANT *type return WshEnvironment_Create(env); }
-static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, VARIANT *WaitOnReturn, int *exit_code) +static inline BOOL is_optional_argument(const VARIANT *arg) +{ + return V_VT(arg) == VT_ERROR && V_ERROR(arg) == DISP_E_PARAMNOTFOUND; +} + +static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, VARIANT *wait, DWORD *exit_code) { SHELLEXECUTEINFOW info; int waitforprocess; - VARIANT s, w; + VARIANT s; HRESULT hr;
- TRACE("(%s %s %s %p)\n", debugstr_w(cmd), debugstr_variant(style), debugstr_variant(WaitOnReturn), exit_code); + TRACE("(%s %s %s %p)\n", debugstr_w(cmd), debugstr_variant(style), debugstr_variant(wait), exit_code); + + if (!style || !wait || !exit_code) + return E_POINTER;
VariantInit(&s); hr = VariantChangeType(&s, style, 0, VT_I4); @@ -929,19 +937,21 @@ static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, return hr; }
- VariantInit(&w); - hr = VariantChangeType(&w, WaitOnReturn, 0, VT_I4); - if (FAILED(hr)) - { - ERR("failed to convert wait argument, 0x%08x\n", hr); - return hr; + if (is_optional_argument(wait)) + waitforprocess = 0; + else { + VARIANT w; + + VariantInit(&w); + hr = VariantChangeType(&w, wait, 0, VT_I4); + if (FAILED(hr)) + return hr; + + waitforprocess = V_I4(&w); }
memset(&info, 0, sizeof(info)); info.cbSize = sizeof(info); - - waitforprocess = V_I4(&w); - info.fMask = waitforprocess ? SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS : SEE_MASK_DEFAULT; info.lpFile = cmd; info.nShow = V_I4(&s); @@ -955,16 +965,11 @@ static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, { if (waitforprocess) { - if (exit_code) - { - DWORD code; - GetExitCodeProcess(info.hProcess, &code); - *exit_code = code; - } + GetExitCodeProcess(info.hProcess, exit_code); CloseHandle(info.hProcess); } else - if (exit_code) *exit_code = 0; + *exit_code = 0;
return S_OK; } diff --git a/dlls/wshom.ocx/tests/wshom.c b/dlls/wshom.ocx/tests/wshom.c index 4c3581e..b2e9859 100644 --- a/dlls/wshom.ocx/tests/wshom.c +++ b/dlls/wshom.ocx/tests/wshom.c @@ -33,6 +33,7 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
static void test_wshshell(void) { + static const WCHAR notepadW[] = {'n','o','t','e','p','a','d','.','e','x','e',0}; static const WCHAR desktopW[] = {'D','e','s','k','t','o','p',0}; static const WCHAR lnk1W[] = {'f','i','l','e','.','l','n','k',0}; static const WCHAR pathW[] = {'%','P','A','T','H','%',0}; @@ -51,8 +52,9 @@ static void test_wshshell(void) TYPEATTR *tattr; DISPPARAMS dp; EXCEPINFO ei; - VARIANT arg, res; + VARIANT arg, res, arg2; BSTR str, ret; + DWORD retval; UINT err;
hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, @@ -171,6 +173,34 @@ static void test_wshshell(void)
IWshEnvironment_Release(env);
+ V_VT(&arg) = VT_I2; + V_I2(&arg) = 0; + V_VT(&arg2) = VT_ERROR; + V_ERROR(&arg2) = DISP_E_PARAMNOTFOUND; + + str = SysAllocString(notepadW); + hr = IWshShell3_Run(sh3, str, &arg, &arg2, NULL); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + + retval = 10; + hr = IWshShell3_Run(sh3, str, NULL, &arg2, &retval); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + ok(retval == 10, "got %u\n", retval); + + retval = 10; + hr = IWshShell3_Run(sh3, str, &arg, NULL, &retval); + ok(hr == E_POINTER, "got 0x%08x\n", hr); + ok(retval == 10, "got %u\n", retval); + + retval = 10; + V_VT(&arg2) = VT_ERROR; + V_ERROR(&arg2) = 0; + hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval); + ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr); + ok(retval == 10, "got %u\n", retval); + + SysFreeString(str); + IWshCollection_Release(coll); IDispatch_Release(disp); IWshShell3_Release(sh3); diff --git a/dlls/wshom.ocx/tests/wshom.idl b/dlls/wshom.ocx/tests/wshom.idl index 6255dc6..6647b2b 100644 --- a/dlls/wshom.ocx/tests/wshom.idl +++ b/dlls/wshom.ocx/tests/wshom.idl @@ -526,7 +526,7 @@ library IWshRuntimeLibrary [in] BSTR Command, [in, optional] VARIANT* WindowStyle, [in, optional] VARIANT* WaitOnReturn, - [out, retval] int* out_ExitCode); + [out, retval] DWORD* out_ExitCode);
[id(0x03e9)] HRESULT Popup( diff --git a/dlls/wshom.ocx/wshom.idl b/dlls/wshom.ocx/wshom.idl index 02224a3..aade499 100644 --- a/dlls/wshom.ocx/wshom.idl +++ b/dlls/wshom.ocx/wshom.idl @@ -528,7 +528,7 @@ library IWshRuntimeLibrary [in] BSTR Command, [in, optional] VARIANT* WindowStyle, [in, optional] VARIANT* WaitOnReturn, - [out, retval] int* out_ExitCode); + [out, retval] DWORD* out_ExitCode);
[id(0x03e9)] HRESULT Popup(