shell32: Fix ShellExecute()'s handling of file URLs.
This commit is contained in:
parent
eee9b8ee12
commit
53e4ddc399
|
@ -1504,7 +1504,7 @@ static UINT_PTR SHELL_quote_and_execute( LPCWSTR wcmd, LPCWSTR wszParameters, LP
|
|||
return retval;
|
||||
}
|
||||
|
||||
static UINT_PTR SHELL_execute_url( LPCWSTR lpFile, LPCWSTR wFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc )
|
||||
static UINT_PTR SHELL_execute_url( LPCWSTR lpFile, LPCWSTR wcmd, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc )
|
||||
{
|
||||
static const WCHAR wShell[] = {'\\','s','h','e','l','l','\\',0};
|
||||
static const WCHAR wCommand[] = {'\\','c','o','m','m','a','n','d',0};
|
||||
|
@ -1534,13 +1534,6 @@ static UINT_PTR SHELL_execute_url( LPCWSTR lpFile, LPCWSTR wFile, LPCWSTR wcmd,
|
|||
strcatW(lpstrProtocol, psei->lpVerb && *psei->lpVerb ? psei->lpVerb: wszOpen);
|
||||
strcatW(lpstrProtocol, wCommand);
|
||||
|
||||
/* Remove File Protocol from lpFile */
|
||||
/* In the case file://path/file */
|
||||
if (!strncmpiW(lpFile, wFile, iSize))
|
||||
{
|
||||
lpFile += iSize;
|
||||
while (*lpFile == ':') lpFile++;
|
||||
}
|
||||
retval = execute_from_key(lpstrProtocol, lpFile, NULL, psei->lpParameters,
|
||||
wcmd, execfunc, psei, psei_out);
|
||||
HeapFree(GetProcessHeap(), 0, lpstrProtocol);
|
||||
|
@ -1567,7 +1560,6 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
|
|||
{
|
||||
static const WCHAR wSpace[] = {' ',0};
|
||||
static const WCHAR wWww[] = {'w','w','w',0};
|
||||
static const WCHAR wFile[] = {'f','i','l','e',0};
|
||||
static const WCHAR wHttp[] = {'h','t','t','p',':','/','/',0};
|
||||
static const DWORD unsupportedFlags =
|
||||
SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
|
||||
|
@ -1724,21 +1716,39 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
|
|||
dwApplicationNameLen );
|
||||
}
|
||||
|
||||
/* expand environment strings */
|
||||
len = ExpandEnvironmentStringsW(sei_tmp.lpFile, NULL, 0);
|
||||
if (len>0)
|
||||
/* convert file URLs */
|
||||
if (UrlIsFileUrlW(sei_tmp.lpFile))
|
||||
{
|
||||
LPWSTR buf;
|
||||
buf = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
|
||||
DWORD size;
|
||||
|
||||
size = MAX_PATH;
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
|
||||
if (FAILED(PathCreateFromUrlW(sei_tmp.lpFile, buf, &size, 0)))
|
||||
return SE_ERR_OOM;
|
||||
|
||||
ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len+1);
|
||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
||||
dwApplicationNameLen = len+1;
|
||||
dwApplicationNameLen = lstrlenW(buf) + 1;
|
||||
wszApplicationName = buf;
|
||||
/* appKnownSingular unmodified */
|
||||
|
||||
sei_tmp.lpFile = wszApplicationName;
|
||||
}
|
||||
else /* or expand environment strings (not both!) */
|
||||
{
|
||||
len = ExpandEnvironmentStringsW(sei_tmp.lpFile, NULL, 0);
|
||||
if (len>0)
|
||||
{
|
||||
LPWSTR buf;
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
|
||||
|
||||
ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len + 1);
|
||||
HeapFree(GetProcessHeap(), 0, wszApplicationName);
|
||||
dwApplicationNameLen = len + 1;
|
||||
wszApplicationName = buf;
|
||||
/* appKnownSingular unmodified */
|
||||
|
||||
sei_tmp.lpFile = wszApplicationName;
|
||||
}
|
||||
}
|
||||
|
||||
if (*sei_tmp.lpDirectory)
|
||||
{
|
||||
|
@ -1889,7 +1899,7 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
|
|||
}
|
||||
else if (PathIsURLW(lpFile)) /* File not found, check for URL */
|
||||
{
|
||||
retval = SHELL_execute_url( lpFile, wFile, wcmd, &sei_tmp, sei, execfunc );
|
||||
retval = SHELL_execute_url( lpFile, wcmd, &sei_tmp, sei, execfunc );
|
||||
}
|
||||
/* Check if file specified is in the form www.??????.*** */
|
||||
else if (!strncmpiW(lpFile, wWww, 3))
|
||||
|
|
|
@ -1637,34 +1637,37 @@ typedef struct
|
|||
static fileurl_tests_t fileurl_tests[]=
|
||||
{
|
||||
/* How many slashes does it take... */
|
||||
{"file:", "%s\\test file.shlexec", URL_SUCCESS, 0x1},
|
||||
{"file:/", "%s\\test file.shlexec", URL_SUCCESS, 0x1},
|
||||
{"file://", "%s\\test file.shlexec", URL_SUCCESS, 0x1},
|
||||
{"file:///", "%s\\test file.shlexec", URL_SUCCESS, 0x1},
|
||||
{"File:///", "%s\\test file.shlexec", URL_SUCCESS, 0x1},
|
||||
{"file:////", "%s\\test file.shlexec", URL_SUCCESS, 0x1},
|
||||
{"file://///", "%s\\test file.shlexec", 0, 0x1},
|
||||
{"file:", "%s\\test file.shlexec", URL_SUCCESS, 0},
|
||||
{"file:/", "%s\\test file.shlexec", URL_SUCCESS, 0},
|
||||
{"file://", "%s\\test file.shlexec", URL_SUCCESS, 0},
|
||||
{"file:///", "%s\\test file.shlexec", URL_SUCCESS, 0},
|
||||
{"File:///", "%s\\test file.shlexec", URL_SUCCESS, 0},
|
||||
{"file:////", "%s\\test file.shlexec", URL_SUCCESS, 0},
|
||||
{"file://///", "%s\\test file.shlexec", 0, 0},
|
||||
|
||||
/* Test with Windows-style paths */
|
||||
{"file:///", "%s\\test file.shlexec", URL_SUCCESS | USE_COLON, 0x1},
|
||||
{"file:///", "%s\\test file.shlexec", URL_SUCCESS | USE_BSLASH, 0x1},
|
||||
{"file:///", "%s\\test file.shlexec", URL_SUCCESS | USE_COLON, 0},
|
||||
{"file:///", "%s\\test file.shlexec", URL_SUCCESS | USE_BSLASH, 0},
|
||||
|
||||
/* Check handling of hostnames */
|
||||
{"file://localhost/", "%s\\test file.shlexec", URL_SUCCESS, 0x1},
|
||||
{"file://localhost:80/", "%s\\test file.shlexec", 0, 0x1},
|
||||
{"file://LocalHost/", "%s\\test file.shlexec", URL_SUCCESS, 0x1},
|
||||
{"file://127.0.0.1/", "%s\\test file.shlexec", 0, 0x1},
|
||||
{"file://::1/", "%s\\test file.shlexec", 0, 0x1},
|
||||
{"file://notahost/", "%s\\test file.shlexec", 0, 0x1},
|
||||
{"file://localhost/", "%s\\test file.shlexec", URL_SUCCESS, 0},
|
||||
{"file://localhost:80/", "%s\\test file.shlexec", 0, 0},
|
||||
{"file://LocalHost/", "%s\\test file.shlexec", URL_SUCCESS, 0},
|
||||
{"file://127.0.0.1/", "%s\\test file.shlexec", 0, 0},
|
||||
{"file://::1/", "%s\\test file.shlexec", 0, 0},
|
||||
{"file://notahost/", "%s\\test file.shlexec", 0, 0},
|
||||
|
||||
/* Environment variables are not expanded in URLs */
|
||||
{"%urlprefix%", "%s\\test file.shlexec", 0, 0x1},
|
||||
{"file:///", "%s\\%%urlenvvar%% file.shlexec", 0, 0x1},
|
||||
{"file:///", "%%TMPDIR%%\\test file.shlexec", 0, 0},
|
||||
|
||||
/* Test shortcuts vs. URLs */
|
||||
{"file://///", "%s\\test_shortcut_shlexec.lnk", 0, 0x1d},
|
||||
|
||||
{NULL, NULL, 0, 0}
|
||||
};
|
||||
|
||||
static void test_fileurl(void)
|
||||
static void test_fileurls(void)
|
||||
{
|
||||
char filename[MAX_PATH], fileurl[MAX_PATH], longtmpdir[MAX_PATH];
|
||||
char command[MAX_PATH];
|
||||
|
@ -1681,7 +1684,6 @@ static void test_fileurl(void)
|
|||
|
||||
get_long_path_name(tmpdir, longtmpdir, sizeof(longtmpdir)/sizeof(*longtmpdir));
|
||||
SetEnvironmentVariable("urlprefix", "file:///");
|
||||
SetEnvironmentVariable("urlenvvar", "test");
|
||||
|
||||
test=fileurl_tests;
|
||||
while (test->basename)
|
||||
|
@ -1705,7 +1707,10 @@ static void test_fileurl(void)
|
|||
ok(rc == SE_ERR_FNF, "FindExecutable(%s) failed: bad rc=%lu\n", fileurl, rc);
|
||||
|
||||
/* Then ShellExecute() */
|
||||
rc = shell_execute(NULL, fileurl, NULL, NULL);
|
||||
if ((test->todo & 0x10) == 0)
|
||||
rc = shell_execute(NULL, fileurl, NULL, NULL);
|
||||
else todo_wait
|
||||
rc = shell_execute(NULL, fileurl, NULL, NULL);
|
||||
if (bad_shellexecute)
|
||||
{
|
||||
win_skip("shell32 is too old (likely 4.72). Skipping the file URL tests\n");
|
||||
|
@ -1750,7 +1755,6 @@ static void test_fileurl(void)
|
|||
}
|
||||
|
||||
SetEnvironmentVariable("urlprefix", NULL);
|
||||
SetEnvironmentVariable("urlenvvar", NULL);
|
||||
}
|
||||
|
||||
static void test_find_executable(void)
|
||||
|
@ -2639,7 +2643,7 @@ START_TEST(shlexec)
|
|||
test_argify();
|
||||
test_lpFile_parsed();
|
||||
test_filename();
|
||||
test_fileurl();
|
||||
test_fileurls();
|
||||
test_find_executable();
|
||||
test_lnks();
|
||||
test_exes();
|
||||
|
|
Loading…
Reference in New Issue