shell32/tests: Test ShellExecute()'s URL handling.
Francois Gouget
fgouget at codeweavers.com
Wed Oct 17 16:25:43 CDT 2012
Also adapt the helper functions so we can create the classes we need.
---
dlls/shell32/tests/shlexec.c | 158 +++++++++++++++++++++++++++++++-----------
1 file changed, 119 insertions(+), 39 deletions(-)
diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c
index 131e334..737e536 100644
--- a/dlls/shell32/tests/shlexec.c
+++ b/dlls/shell32/tests/shlexec.c
@@ -235,9 +235,34 @@ static INT_PTR shell_execute_ex(DWORD mask, LPCSTR verb, LPCSTR file,
*
***/
-static BOOL create_test_association(const char* extension)
+static void create_test_class(const char* class, BOOL protocol)
{
HKEY hkey, hkey_shell;
+ LONG rc;
+
+ rc = RegCreateKeyEx(HKEY_CLASSES_ROOT, class, 0, NULL, 0,
+ KEY_CREATE_SUB_KEY | KEY_SET_VALUE, NULL,
+ &hkey, NULL);
+ ok(rc == ERROR_SUCCESS, "RegCreateKeyEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc);
+
+ if (protocol)
+ {
+ rc = RegSetValueEx(hkey, "URL Protocol", 0, REG_SZ, (LPBYTE)"", 1);
+ ok(rc == ERROR_SUCCESS, "RegSetValueEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc);
+ }
+
+ rc = RegCreateKeyEx(hkey, "shell", 0, NULL, 0,
+ KEY_CREATE_SUB_KEY, NULL, &hkey_shell, NULL);
+ ok(rc == ERROR_SUCCESS, "RegCreateKeyEx 'shell' failed, expected ERROR_SUCCESS, got %d\n", rc);
+
+ CloseHandle(hkey);
+ CloseHandle(hkey_shell);
+
+}
+
+static BOOL create_test_association(const char* extension)
+{
+ HKEY hkey;
char class[MAX_PATH];
LONG rc;
@@ -251,17 +276,7 @@ static BOOL create_test_association(const char* extension)
ok(rc==ERROR_SUCCESS, "RegSetValueEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc);
CloseHandle(hkey);
- rc=RegCreateKeyEx(HKEY_CLASSES_ROOT, class, 0, NULL, 0,
- KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, NULL, &hkey, NULL);
- ok(rc==ERROR_SUCCESS, "RegCreateKeyEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc);
-
- rc=RegCreateKeyEx(hkey, "shell", 0, NULL, 0,
- KEY_CREATE_SUB_KEY, NULL, &hkey_shell, NULL);
- ok(rc==ERROR_SUCCESS, "RegCreateKeyEx 'shell' failed, expected ERROR_SUCCESS, got %d\n", rc);
-
- CloseHandle(hkey);
- CloseHandle(hkey_shell);
-
+ create_test_class(class, FALSE);
return TRUE;
}
@@ -332,16 +347,21 @@ cleanup:
return ret;
}
+static void delete_test_class(const char* classname)
+{
+ myRegDeleteTreeA(HKEY_CLASSES_ROOT, classname);
+}
+
static void delete_test_association(const char* extension)
{
- char class[MAX_PATH];
+ char classname[MAX_PATH];
- sprintf(class, "shlexec%s", extension);
- myRegDeleteTreeA(HKEY_CLASSES_ROOT, class);
+ sprintf(classname, "shlexec%s", extension);
+ delete_test_class(classname);
myRegDeleteTreeA(HKEY_CLASSES_ROOT, extension);
}
-static void create_test_verb_dde(const char* extension, const char* verb,
+static void create_test_verb_dde(const char* classname, const char* verb,
int rawcmd, const char* cmdtail, const char *ddeexec,
const char *application, const char *topic,
const char *ifexec)
@@ -351,7 +371,7 @@ static void create_test_verb_dde(const char* extension, const char* verb,
char* cmd;
LONG rc;
- sprintf(shell, "shlexec%s\\shell", extension);
+ sprintf(shell, "%s\\shell", classname);
rc=RegOpenKeyEx(HKEY_CLASSES_ROOT, shell, 0,
KEY_CREATE_SUB_KEY, &hkey_shell);
assert(rc==ERROR_SUCCESS);
@@ -363,17 +383,15 @@ static void create_test_verb_dde(const char* extension, const char* verb,
assert(rc==ERROR_SUCCESS);
if (rawcmd)
- {
rc=RegSetValueEx(hkey_cmd, NULL, 0, REG_SZ, (LPBYTE)cmdtail, strlen(cmdtail)+1);
- }
else
{
cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+10+strlen(child_file)+2+strlen(cmdtail)+1);
sprintf(cmd,"%s shlexec \"%s\" %s", argv0, child_file, cmdtail);
rc=RegSetValueEx(hkey_cmd, NULL, 0, REG_SZ, (LPBYTE)cmd, strlen(cmd)+1);
- assert(rc==ERROR_SUCCESS);
HeapFree(GetProcessHeap(), 0, cmd);
}
+ assert(rc==ERROR_SUCCESS);
if (ddeexec)
{
@@ -423,10 +441,10 @@ static void create_test_verb_dde(const char* extension, const char* verb,
CloseHandle(hkey_cmd);
}
-static void create_test_verb(const char* extension, const char* verb,
+static void create_test_verb(const char* classname, const char* verb,
int rawcmd, const char* cmdtail)
{
- create_test_verb_dde(extension, verb, rawcmd, cmdtail, NULL, NULL,
+ create_test_verb_dde(classname, verb, rawcmd, cmdtail, NULL, NULL,
NULL, NULL);
}
@@ -1385,13 +1403,13 @@ static void test_argify(void)
const char* cmd;
unsigned i, count;
- create_test_verb(".shlexec", "Params232S", 0, "Params232S %2 %3 \"%2\" \"%*\"");
- create_test_verb(".shlexec", "Params23456", 0, "Params23456 \"%2\" \"%3\" \"%4\" \"%5\" \"%6\"");
- create_test_verb(".shlexec", "Params23456789", 0, "Params23456789 \"%2\" \"%3\" \"%4\" \"%5\" \"%6\" \"%7\" \"%8\" \"%9\"");
- create_test_verb(".shlexec", "Params2345Etc", 0, "Params2345Etc ~2=\"%~2\" ~3=\"%~3\" ~4=\"%~4\" ~5=%~5");
- create_test_verb(".shlexec", "Params9Etc", 0, "Params9Etc ~9=\"%~9\"");
- create_test_verb(".shlexec", "Params20", 0, "Params20 \"%20\"");
- create_test_verb(".shlexec", "ParamsBad", 0, "ParamsBad \"%% %- %~ %~0 %~1 %~a %~* %a %b %c %TMPDIR%\"");
+ create_test_verb("shlexec.shlexec", "Params232S", 0, "Params232S %2 %3 \"%2\" \"%*\"");
+ create_test_verb("shlexec.shlexec", "Params23456", 0, "Params23456 \"%2\" \"%3\" \"%4\" \"%5\" \"%6\"");
+ create_test_verb("shlexec.shlexec", "Params23456789", 0, "Params23456789 \"%2\" \"%3\" \"%4\" \"%5\" \"%6\" \"%7\" \"%8\" \"%9\"");
+ create_test_verb("shlexec.shlexec", "Params2345Etc", 0, "Params2345Etc ~2=\"%~2\" ~3=\"%~3\" ~4=\"%~4\" ~5=%~5");
+ create_test_verb("shlexec.shlexec", "Params9Etc", 0, "Params9Etc ~9=\"%~9\"");
+ create_test_verb("shlexec.shlexec", "Params20", 0, "Params20 \"%20\"");
+ create_test_verb("shlexec.shlexec", "ParamsBad", 0, "ParamsBad \"%% %- %~ %~0 %~1 %~a %~* %a %b %c %TMPDIR%\"");
sprintf(fileA, "%s\\test file.shlexec", tmpdir);
@@ -1767,6 +1785,67 @@ static void test_fileurls(void)
SetEnvironmentVariable("urlprefix", NULL);
}
+static void test_urls(void)
+{
+ INT_PTR rc;
+
+ create_test_class("fakeproto", FALSE);
+ create_test_verb("fakeproto", "open", 0, "URL %1");
+
+ create_test_class("shlproto", TRUE);
+ create_test_verb("shlproto", "open", 0, "URL %1");
+
+ /* Protocols must be properly declared */
+ rc = shell_execute(NULL, "notaproto://foo", NULL, NULL);
+ todo_wine ok(rc == SE_ERR_ACCESSDENIED, "%s succeeded: rc=%lu\n", shell_call, rc);
+
+ rc = shell_execute(NULL, "fakeproto://foo/bar", NULL, NULL);
+ todo_wine ok(rc == SE_ERR_ACCESSDENIED, "%s expected SE_ERR_ACCESSDENIED got rc=%lu\n", shell_call, rc);
+
+ /* Here's a real live one */
+ rc = shell_execute(NULL, "shlproto://foo/bar", NULL, NULL);
+ ok(rc > 32, "%s failed: rc=%lu\n", shell_call, rc);
+ if (rc > 32)
+ {
+ okChildInt("argcA", 5);
+ okChildString("argvA4", "shlproto://foo/bar");
+ }
+
+ /* A .lnk ending does not turn a URL into a shortcut */
+ todo_wait rc = shell_execute(NULL, "shlproto://foo/bar.lnk", NULL, NULL);
+ ok(rc > 32, "%s failed: rc=%lu\n", shell_call, rc);
+ if (rc > 32)
+ {
+ okChildInt("argcA", 5);
+ todo_wine okChildString("argvA4", "shlproto://foo/bar.lnk");
+ }
+
+ /* Environment variables are expanded in URLs (but not in file URLs!) */
+ rc = shell_execute_ex(SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI,
+ NULL, "shlproto://%TMPDIR%/bar", NULL, NULL, NULL);
+ ok(rc > 32, "%s failed: rc=%lu\n", shell_call, rc);
+ if (rc > 32)
+ {
+ char url[MAX_PATH];
+ okChildInt("argcA", 5);
+ sprintf(url, "shlproto://%s/bar", tmpdir);
+ okChildStringBroken("argvA4", url, "shlproto://%TMPDIR%/bar");
+ }
+
+ /* But only after the path has been identified as a URL */
+ SetEnvironmentVariable("urlprefix", "shlproto:///");
+ rc = shell_execute(NULL, "%urlprefix%foo", NULL, NULL);
+ todo_wine ok(rc == SE_ERR_FNF, "%s succeeded: rc=%lu\n", shell_call, rc);
+ SetEnvironmentVariable("urlprefix", NULL);
+
+ /* Try to confuse ShellExecute() by mixing protocols */
+ rc = shell_execute(NULL, "file://shlproto://foo/bar", NULL, NULL);
+ todo_wine ok(rc == SE_ERR_PNF, "%s succeeded: rc=%lu\n", shell_call, rc);
+
+ delete_test_class("fakeproto");
+ delete_test_class("shlproto");
+}
+
static void test_find_executable(void)
{
char notepad_path[MAX_PATH];
@@ -1780,7 +1859,7 @@ static void test_find_executable(void)
skip("Unable to create association for '.sfe'\n");
return;
}
- create_test_verb(".sfe", "Open", 1, "%1");
+ create_test_verb("shlexec.sfe", "Open", 1, "%1");
/* Don't test FindExecutable(..., NULL), it always crashes */
@@ -1830,7 +1909,7 @@ static void test_find_executable(void)
skip("Unable to create association for '.shl'\n");
return;
}
- create_test_verb(".shl", "Open", 0, "Open");
+ create_test_verb("shlexec.shl", "Open", 0, "Open");
sprintf(filename, "%s\\test file.shl", tmpdir);
rc=(INT_PTR)FindExecutableA(filename, NULL, command);
@@ -2205,7 +2284,7 @@ static void test_dde(void)
skip("Unable to create association for '.sde'\n");
return;
}
- create_test_verb_dde(".sde", "Open", 0, test->command, test->ddeexec,
+ create_test_verb_dde("shlexec.sde", "Open", 0, test->command, test->ddeexec,
test->application, test->topic, test->ifexec);
if (test->application != NULL || test->topic != NULL)
@@ -2380,7 +2459,7 @@ static void test_dde_default_app(void)
return;
}
sprintf(params, test->command, tmpdir);
- create_test_verb_dde(".sde", "Open", 1, params, "[test]", NULL,
+ create_test_verb_dde("shlexec.sde", "Open", 1, params, "[test]", NULL,
"shlexec", NULL);
ddeApplication[0] = 0;
@@ -2550,12 +2629,12 @@ static void init_test(void)
skip("Unable to create association for '.shlexec'\n");
return;
}
- create_test_verb(".shlexec", "Open", 0, "Open \"%1\"");
- create_test_verb(".shlexec", "NoQuotes", 0, "NoQuotes %1");
- create_test_verb(".shlexec", "LowerL", 0, "LowerL %l");
- create_test_verb(".shlexec", "QuotedLowerL", 0, "QuotedLowerL \"%l\"");
- create_test_verb(".shlexec", "UpperL", 0, "UpperL %L");
- create_test_verb(".shlexec", "QuotedUpperL", 0, "QuotedUpperL \"%L\"");
+ create_test_verb("shlexec.shlexec", "Open", 0, "Open \"%1\"");
+ create_test_verb("shlexec.shlexec", "NoQuotes", 0, "NoQuotes %1");
+ create_test_verb("shlexec.shlexec", "LowerL", 0, "LowerL %l");
+ create_test_verb("shlexec.shlexec", "QuotedLowerL", 0, "QuotedLowerL \"%l\"");
+ create_test_verb("shlexec.shlexec", "UpperL", 0, "UpperL %L");
+ create_test_verb("shlexec.shlexec", "QuotedUpperL", 0, "QuotedUpperL \"%L\"");
}
static void cleanup_test(void)
@@ -2654,6 +2733,7 @@ START_TEST(shlexec)
test_lpFile_parsed();
test_filename();
test_fileurls();
+ test_urls();
test_find_executable();
test_lnks();
test_exes();
--
1.7.10.4
More information about the wine-patches
mailing list