Nikolay Sivov : wshom.ocx: Properly handle optional argument in Run().
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Feb 16 10:01:20 CST 2015
Module: wine
Branch: master
Commit: f0e2ea988e666533dd9f5ba1a6e68b2853dd0038
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f0e2ea988e666533dd9f5ba1a6e68b2853dd0038
Author: Nikolay Sivov <nsivov at 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(
More information about the wine-cvs
mailing list