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