mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 08:50:34 +00:00
wshom: Split the command line before passing it to ShellExecuteEx.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b33b8cab0d
commit
979f9078d3
|
@ -1218,12 +1218,37 @@ static inline BOOL is_optional_argument(const VARIANT *arg)
|
||||||
return V_VT(arg) == VT_ERROR && V_ERROR(arg) == DISP_E_PARAMNOTFOUND;
|
return V_VT(arg) == VT_ERROR && V_ERROR(arg) == DISP_E_PARAMNOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WCHAR *split_command( BSTR cmd, WCHAR **params )
|
||||||
|
{
|
||||||
|
WCHAR *ret, *ptr;
|
||||||
|
BOOL in_quotes = FALSE;
|
||||||
|
|
||||||
|
if (!(ret = heap_alloc((strlenW(cmd) + 1) * sizeof(WCHAR)))) return NULL;
|
||||||
|
strcpyW( ret, cmd );
|
||||||
|
|
||||||
|
*params = NULL;
|
||||||
|
for (ptr = ret; *ptr; ptr++)
|
||||||
|
{
|
||||||
|
if (*ptr == '"') in_quotes = !in_quotes;
|
||||||
|
else if (*ptr == ' ' && !in_quotes)
|
||||||
|
{
|
||||||
|
*ptr = 0;
|
||||||
|
*params = ptr + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, VARIANT *wait, DWORD *exit_code)
|
static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, VARIANT *wait, DWORD *exit_code)
|
||||||
{
|
{
|
||||||
SHELLEXECUTEINFOW info;
|
SHELLEXECUTEINFOW info;
|
||||||
int waitforprocess;
|
int waitforprocess;
|
||||||
|
WCHAR *file, *params;
|
||||||
VARIANT s;
|
VARIANT s;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
TRACE("(%s %s %s %p)\n", debugstr_w(cmd), debugstr_variant(style), debugstr_variant(wait), exit_code);
|
TRACE("(%s %s %s %p)\n", debugstr_w(cmd), debugstr_variant(style), debugstr_variant(wait), exit_code);
|
||||||
|
|
||||||
|
@ -1251,13 +1276,18 @@ static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style,
|
||||||
waitforprocess = V_I4(&w);
|
waitforprocess = V_I4(&w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(file = split_command(cmd, ¶ms))) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
info.cbSize = sizeof(info);
|
info.cbSize = sizeof(info);
|
||||||
info.fMask = waitforprocess ? SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS : SEE_MASK_DEFAULT;
|
info.fMask = waitforprocess ? SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS : SEE_MASK_DEFAULT;
|
||||||
info.lpFile = cmd;
|
info.lpFile = file;
|
||||||
|
info.lpParameters = params;
|
||||||
info.nShow = V_I4(&s);
|
info.nShow = V_I4(&s);
|
||||||
|
|
||||||
if (!ShellExecuteExW(&info))
|
ret = ShellExecuteExW(&info);
|
||||||
|
heap_free( file );
|
||||||
|
if (!ret)
|
||||||
{
|
{
|
||||||
TRACE("ShellExecute failed, %d\n", GetLastError());
|
TRACE("ShellExecute failed, %d\n", GetLastError());
|
||||||
return HRESULT_FROM_WIN32(GetLastError());
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
|
|
@ -66,6 +66,17 @@ static void test_wshshell(void)
|
||||||
static const WCHAR path2W[] = {'P','A','T','H',0};
|
static const WCHAR path2W[] = {'P','A','T','H',0};
|
||||||
static const WCHAR dummydirW[] = {'d','e','a','d','p','a','r','r','o','t',0};
|
static const WCHAR dummydirW[] = {'d','e','a','d','p','a','r','r','o','t',0};
|
||||||
static const WCHAR emptyW[] = {'e','m','p','t','y',0};
|
static const WCHAR emptyW[] = {'e','m','p','t','y',0};
|
||||||
|
static const WCHAR cmdexeW[] = {'\\','c','m','d','.','e','x','e',0};
|
||||||
|
static const WCHAR testdirW[] = {'w','s','h','o','m',' ','t','e','s','t',' ','d','i','r',0};
|
||||||
|
static const WCHAR paramsW[] =
|
||||||
|
{' ','/','c',' ','r','d',' ','/','s',' ','/','q',' ','c',':','\\','n','o','s','u','c','h','d','i','r',0};
|
||||||
|
static const WCHAR cmdW[] =
|
||||||
|
{'c','m','d','.','e','x','e',' ','/','c',' ','r','d',' ','/','s',' ','/','q',' ','c',':','\\',
|
||||||
|
'n','o','s','u','c','h','d','i','r',0};
|
||||||
|
static const WCHAR cmd2W[] =
|
||||||
|
{'"','c','m','d','.','e','x','e',' ','"',' ','/','c',' ','r','d',' ','/','s',' ','/','q',' ','c',':','\\',
|
||||||
|
'n','o','s','u','c','h','d','i','r',0};
|
||||||
|
WCHAR path[MAX_PATH], path2[MAX_PATH], buf[MAX_PATH];
|
||||||
IWshEnvironment *env;
|
IWshEnvironment *env;
|
||||||
IWshExec *shexec;
|
IWshExec *shexec;
|
||||||
IWshShell3 *sh3;
|
IWshShell3 *sh3;
|
||||||
|
@ -82,7 +93,7 @@ static void test_wshshell(void)
|
||||||
EXCEPINFO ei;
|
EXCEPINFO ei;
|
||||||
VARIANT arg, res, arg2;
|
VARIANT arg, res, arg2;
|
||||||
BSTR str, ret;
|
BSTR str, ret;
|
||||||
DWORD retval;
|
DWORD retval, attrs;
|
||||||
UINT err;
|
UINT err;
|
||||||
|
|
||||||
hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
|
hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
|
||||||
|
@ -238,9 +249,53 @@ static void test_wshshell(void)
|
||||||
hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval);
|
hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval);
|
||||||
ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
|
ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
|
||||||
ok(retval == 10, "got %u\n", retval);
|
ok(retval == 10, "got %u\n", retval);
|
||||||
|
|
||||||
SysFreeString(str);
|
SysFreeString(str);
|
||||||
|
|
||||||
|
V_VT(&arg2) = VT_BOOL;
|
||||||
|
V_BOOL(&arg2) = VARIANT_TRUE;
|
||||||
|
|
||||||
|
retval = 0xdeadbeef;
|
||||||
|
str = SysAllocString(cmdW);
|
||||||
|
hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
todo_wine ok(retval == ERROR_FILE_NOT_FOUND, "got %u\n", retval);
|
||||||
|
SysFreeString(str);
|
||||||
|
|
||||||
|
retval = 0xdeadbeef;
|
||||||
|
str = SysAllocString(cmd2W);
|
||||||
|
hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
todo_wine ok(retval == ERROR_FILE_NOT_FOUND, "got %u\n", retval);
|
||||||
|
SysFreeString(str);
|
||||||
|
|
||||||
|
GetSystemDirectoryW(path, ARRAY_SIZE(path));
|
||||||
|
lstrcatW(path, cmdexeW);
|
||||||
|
attrs = GetFileAttributesW(path);
|
||||||
|
ok(attrs != INVALID_FILE_ATTRIBUTES, "cmd.exe not found\n");
|
||||||
|
|
||||||
|
/* copy cmd.exe to a path with spaces */
|
||||||
|
GetTempPathW(ARRAY_SIZE(path2), path2);
|
||||||
|
lstrcatW(path2, testdirW);
|
||||||
|
CreateDirectoryW(path2, NULL);
|
||||||
|
lstrcatW(path2, cmdexeW);
|
||||||
|
CopyFileW(path, path2, FALSE);
|
||||||
|
|
||||||
|
buf[0] = '"';
|
||||||
|
lstrcpyW(buf + 1, path2);
|
||||||
|
buf[lstrlenW(buf)] = '"';
|
||||||
|
lstrcpyW(buf + lstrlenW(path2) + 2, paramsW);
|
||||||
|
|
||||||
|
retval = 0xdeadbeef;
|
||||||
|
str = SysAllocString(buf);
|
||||||
|
hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
todo_wine ok(retval == ERROR_FILE_NOT_FOUND, "got %u\n", retval);
|
||||||
|
SysFreeString(str);
|
||||||
|
|
||||||
|
DeleteFileW(path2);
|
||||||
|
path2[lstrlenW(path2) - lstrlenW(cmdexeW)] = 0;
|
||||||
|
RemoveDirectoryW(path2);
|
||||||
|
|
||||||
/* current directory */
|
/* current directory */
|
||||||
if (0) /* crashes on native */
|
if (0) /* crashes on native */
|
||||||
hr = IWshShell3_get_CurrentDirectory(sh3, NULL);
|
hr = IWshShell3_get_CurrentDirectory(sh3, NULL);
|
||||||
|
|
Loading…
Reference in a new issue