Paul Gofman : shell32: Handle file extensions in SHELL_FindExecutableByVerb().
Alexandre Julliard
julliard at winehq.org
Tue Jul 19 15:55:02 CDT 2022
Module: wine
Branch: master
Commit: 6888e92ebc77655ea1af4fe49c83f17d60fda871
URL: https://gitlab.winehq.org/wine/wine/-/commit/6888e92ebc77655ea1af4fe49c83f17d60fda871
Author: Paul Gofman <pgofman at codeweavers.com>
Date: Thu Jun 30 14:17:46 2022 -0500
shell32: Handle file extensions in SHELL_FindExecutableByVerb().
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
dlls/shell32/shlexec.c | 12 +++++++++
dlls/shell32/tests/shlexec.c | 61 ++++++++++++++++++++++++++++++++++++--------
2 files changed, 63 insertions(+), 10 deletions(-)
diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c
index fbf39e99fc6..da2b5fdc2b0 100644
--- a/dlls/shell32/shlexec.c
+++ b/dlls/shell32/shlexec.c
@@ -473,6 +473,18 @@ static UINT SHELL_FindExecutableByVerb(LPCWSTR lpVerb, LPWSTR key, LPWSTR classn
HKEY hkeyClass;
WCHAR verb[MAX_PATH];
+ if (*classname == '.')
+ {
+ /* Extension, default key value holds class name. Extension may also have
+ * empty class name and shell\verb\command subkey. */
+ WCHAR class[MAX_PATH];
+ LONG len;
+
+ len = sizeof(class);
+ if (!RegQueryValueW(HKEY_CLASSES_ROOT, classname, class, &len) && *class)
+ wcscpy(classname, class);
+ }
+
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, classname, 0, 0x02000000, &hkeyClass))
return SE_ERR_NOASSOC;
if (!HCR_GetDefaultVerbW(hkeyClass, lpVerb, verb, ARRAY_SIZE(verb)))
diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c
index 50de1eeb750..4af4d735b68 100644
--- a/dlls/shell32/tests/shlexec.c
+++ b/dlls/shell32/tests/shlexec.c
@@ -708,23 +708,31 @@ static BOOL create_test_class(const char* class, BOOL protocol)
return TRUE;
}
-static BOOL create_test_association(const char* extension)
+static BOOL create_test_association_key(const char* extension, const char *class)
{
HKEY hkey;
- char class[MAX_PATH];
LONG rc;
- sprintf(class, "shlexec%s", extension);
- rc=RegCreateKeyExA(HKEY_CLASSES_ROOT, extension, 0, NULL, 0, KEY_SET_VALUE,
- NULL, &hkey, NULL);
+ rc = RegCreateKeyExA(HKEY_CLASSES_ROOT, extension, 0, NULL, 0, KEY_SET_VALUE,
+ NULL, &hkey, NULL);
ok(rc == ERROR_SUCCESS || rc == ERROR_ACCESS_DENIED,
"could not create association %s (rc=%ld)\n", class, rc);
if (rc != ERROR_SUCCESS)
return FALSE;
- rc=RegSetValueExA(hkey, NULL, 0, REG_SZ, (LPBYTE) class, strlen(class)+1);
- ok(rc==ERROR_SUCCESS, "RegSetValueEx '%s' failed, expected ERROR_SUCCESS, got %ld\n", class, rc);
+ rc = RegSetValueExA(hkey, NULL, 0, REG_SZ, (LPBYTE) class, strlen(class)+1);
+ ok(rc == ERROR_SUCCESS, "RegSetValueEx '%s' failed, expected ERROR_SUCCESS, got %ld\n", class, rc);
CloseHandle(hkey);
+ return TRUE;
+}
+
+static BOOL create_test_association(const char* extension)
+{
+ char class[MAX_PATH];
+
+ sprintf(class, "shlexec%s", extension);
+ if (!create_test_association_key(extension, class))
+ return FALSE;
return create_test_class(class, FALSE);
}
@@ -2216,6 +2224,39 @@ static void test_exes(void)
okChildInt("argcA", 4);
okChildString("argvA3", "Exec");
+ rc=shell_execute_ex(SEE_MASK_NOZONECHECKS | SEE_MASK_CLASSNAME | SEE_MASK_FLAG_NO_UI, NULL, argv0, params,
+ NULL, ".exe");
+ okShell(rc > 32, "returned %Iu\n", rc);
+ okChildInt("argcA", 4);
+ okChildString("argvA3", "Exec");
+
+ if (create_test_association_key(".qqqq", "exefile"))
+ {
+ rc = shell_execute_ex(SEE_MASK_NOZONECHECKS | SEE_MASK_CLASSNAME | SEE_MASK_FLAG_NO_UI, NULL, argv0, params,
+ NULL, ".qqqq");
+ okShell(rc > 32, "returned %Iu\n", rc);
+ okChildInt("argcA", 4);
+ okChildString("argvA3", "Exec");
+ delete_test_association(".qqqq");
+ }
+ else
+ {
+ skip("Could not create associtation.\n");
+ }
+
+ if (create_test_association_key("qqqq", "exefile"))
+ {
+ rc = shell_execute_ex(SEE_MASK_NOZONECHECKS | SEE_MASK_CLASSNAME | SEE_MASK_FLAG_NO_UI, NULL, argv0, params,
+ NULL, "qqqq");
+ okShell(rc < 32, "returned %Iu\n", rc);
+ todo_wine okShell(rc == SE_ERR_NOASSOC, "returned %Iu\n", rc);
+ delete_test_association("qqqq");
+ }
+ else
+ {
+ skip("Could not create associtation.\n");
+ }
+
if (! skip_noassoc_tests)
{
sprintf(filename, "%s\\test file.noassoc", tmpdir);
@@ -2252,10 +2293,10 @@ static void test_exes(void)
/* FIXME SEE_MASK_FLAG_NO_UI is only needed due to Wine's bug */
rc = shell_execute_ex(SEE_MASK_CLASSNAME | SEE_MASK_FLAG_NO_UI,
NULL, argv0, NULL, NULL, ".shlexec");
- todo_wine okShell(rc > 32, "returned %Iu\n", rc);
+ okShell(rc > 32, "returned %Iu\n", rc);
okChildInt("argcA", 5);
- todo_wine okChildString("argvA3", "Open");
- todo_wine okChildPath("argvA4", argv0);
+ okChildString("argvA3", "Open");
+ okChildPath("argvA4", argv0);
}
}
More information about the wine-cvs
mailing list