From: Paul Gofman Subject: [PATCH 2/3] shell32: Handle file extensions in SHELL_FindExecutableByVerb(). Message-Id: Date: Thu, 30 Jun 2022 19:38:07 +0000 In-Reply-To: References: From: Paul Gofman Signed-off-by: Paul Gofman --- 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); } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/353