From a0fe8bfff5f705076b20457964d2befe25178a09 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 1 Jun 2021 16:55:33 +0900 Subject: [PATCH 1/5] [SHELL32] Improve ShellExecCmdLine on URL --- dll/win32/shell32/shlexec.cpp | 62 +++++++---------------------------- 1 file changed, 12 insertions(+), 50 deletions(-) diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index 4e31cfff6251..eea59108525d 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -2365,53 +2365,6 @@ OpenAs_RunDLLA(HWND hwnd, HINSTANCE hinst, LPCSTR cmdline, int cmdshow) /*************************************************************************/ -static LPCWSTR -SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0) -{ - LPCWSTR pch; - size_t ich = 0; - if (*psz == L'"') - { - // 1st argument is quoted. the string in quotes is quoted 1st argument. - // [pch] --> [pszArg0+ich] - for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch) - { - if (*pch == L'"' && pch[1] == L'"') - { - // doubled double quotations found! - pszArg0[ich] = L'"'; - } - else if (*pch == L'"') - { - // single double quotation found! - ++pch; - break; - } - else - { - // otherwise - pszArg0[ich] = *pch; - } - } - } - else - { - // 1st argument is unquoted. non-space sequence is 1st argument. - // [pch] --> [pszArg0+ich] - for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch) - { - pszArg0[ich] = *pch; - } - } - pszArg0[ich] = 0; - - // skip space - while (iswspace(*pch)) - ++pch; - - return pch; -} - HRESULT WINAPI ShellExecCmdLine( HWND hwnd, LPCWSTR pwszCommand, @@ -2433,7 +2386,7 @@ HRESULT WINAPI ShellExecCmdLine( 1, (ULONG_PTR*)pwszCommand); __SHCloneStrW(&lpCommand, pwszCommand); - StrTrimW(lpCommand, L" \t"); + PathRemoveBlanksW(lpCommand); if (dwSeclFlags & SECL_NO_UI) dwFlags |= SEE_MASK_FLAG_NO_UI; @@ -2452,14 +2405,23 @@ HRESULT WINAPI ShellExecCmdLine( } } - if (PathIsURLW(lpCommand) || UrlIsW(lpCommand, URLIS_APPLIABLE)) + dwSize = _countof(szFile); + if (UrlIsW(lpCommand, URLIS_URL)) { StringCchCopyW(szFile, _countof(szFile), lpCommand); pchParams = NULL; } + else if (UrlApplySchemeW(lpCommand, szFile, &dwSize, URL_APPLY_GUESSSCHEME) == S_OK) + { + pchParams = NULL; + } else { - pchParams = SplitParams(lpCommand, szFile, _countof(szFile)); + pchParams = PathGetArgsW(lpCommand); + PathRemoveArgsW(lpCommand); + PathUnquoteSpacesW(lpCommand); + StringCchCopyW(szFile, _countof(szFile), lpCommand); + if (szFile[0] != UNICODE_NULL && szFile[1] == L':' && szFile[2] == UNICODE_NULL) { From a4e02cfd5dbb3a8e98d3768098cf6f9cb78f0897 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Wed, 2 Jun 2021 06:47:50 +0900 Subject: [PATCH 2/5] change also ShellExecCmdLine testcase --- .../apitests/shell32/ShellExecCmdLine.cpp | 61 ++++--------------- 1 file changed, 12 insertions(+), 49 deletions(-) diff --git a/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp b/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp index 1ec15fa02c20..f9f57e375003 100644 --- a/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp +++ b/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp @@ -37,52 +37,6 @@ static __inline void __SHCloneStrW(WCHAR **target, const WCHAR *source) } // NOTE: You have to sync the following code to dll/win32/shell32/shlexec.cpp. -static LPCWSTR -SplitParams(LPCWSTR psz, LPWSTR pszArg0, size_t cchArg0) -{ - LPCWSTR pch; - size_t ich = 0; - if (*psz == L'"') - { - // 1st argument is quoted. the string in quotes is quoted 1st argument. - // [pch] --> [pszArg0+ich] - for (pch = psz + 1; *pch && ich + 1 < cchArg0; ++ich, ++pch) - { - if (*pch == L'"' && pch[1] == L'"') - { - // doubled double quotations found! - pszArg0[ich] = L'"'; - } - else if (*pch == L'"') - { - // single double quotation found! - ++pch; - break; - } - else - { - // otherwise - pszArg0[ich] = *pch; - } - } - } - else - { - // 1st argument is unquoted. non-space sequence is 1st argument. - // [pch] --> [pszArg0+ich] - for (pch = psz; *pch && !iswspace(*pch) && ich + 1 < cchArg0; ++ich, ++pch) - { - pszArg0[ich] = *pch; - } - } - pszArg0[ich] = 0; - - // skip space - while (iswspace(*pch)) - ++pch; - - return pch; -} HRESULT WINAPI ShellExecCmdLine( HWND hwnd, @@ -105,7 +59,7 @@ HRESULT WINAPI ShellExecCmdLine( 1, (ULONG_PTR*)pwszCommand); __SHCloneStrW(&lpCommand, pwszCommand); - StrTrimW(lpCommand, L" \t"); + PathRemoveBlanksW(lpCommand); if (dwSeclFlags & SECL_NO_UI) dwFlags |= SEE_MASK_FLAG_NO_UI; @@ -124,14 +78,23 @@ HRESULT WINAPI ShellExecCmdLine( } } - if (UrlIsFileUrlW(lpCommand)) + dwSize = _countof(szFile); + if (UrlIsW(lpCommand, URLIS_URL)) { StringCchCopyW(szFile, _countof(szFile), lpCommand); pchParams = NULL; } + else if (UrlApplySchemeW(lpCommand, szFile, &dwSize, URL_APPLY_GUESSSCHEME) == S_OK) + { + pchParams = NULL; + } else { - pchParams = SplitParams(lpCommand, szFile, _countof(szFile)); + pchParams = PathGetArgsW(lpCommand); + PathRemoveArgsW(lpCommand); + PathUnquoteSpacesW(lpCommand); + StringCchCopyW(szFile, _countof(szFile), lpCommand); + if (szFile[0] != UNICODE_NULL && szFile[1] == L':' && szFile[2] == UNICODE_NULL) { From dd9a9f28dcbc82b754837c8d747e7c072f76a71b Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Wed, 2 Jun 2021 15:42:16 +0900 Subject: [PATCH 3/5] big fix --- dll/win32/shell32/shlexec.cpp | 90 +++---------------- .../apitests/shell32/ShellExecCmdLine.cpp | 80 +---------------- sdk/include/reactos/shlwapi_undoc.h | 2 + 3 files changed, 20 insertions(+), 152 deletions(-) diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index eea59108525d..8226114aef87 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -780,6 +780,16 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, lpFile = xlpFile; /* The file was found in one of the directories in the system-wide search path */ } +#ifdef __REACTOS__ + else + { + lstrcpynW(xlpFile, lpFile, _countof(xlpFile)); + if (PathFindOnPathExW(xlpFile, NULL, 0xFF)) + lpFile = xlpFile; + else + xlpFile[0] = 0; + } +#endif attribs = GetFileAttributesW(lpFile); if (attribs != INVALID_FILE_ATTRIBUTES && (attribs & FILE_ATTRIBUTE_DIRECTORY)) @@ -2374,9 +2384,9 @@ HRESULT WINAPI ShellExecCmdLine( DWORD dwSeclFlags) { SHELLEXECUTEINFOW info; - DWORD dwSize, dwError, dwType, dwFlags = SEE_MASK_DOENVSUBST | SEE_MASK_NOASYNC; + DWORD dwSize, dwError, dwFlags = SEE_MASK_DOENVSUBST | SEE_MASK_NOASYNC; LPCWSTR pszVerb = NULL; - WCHAR szFile[MAX_PATH], szFile2[MAX_PATH]; + WCHAR szFile[MAX_PATH]; HRESULT hr; LPCWSTR pchParams; LPWSTR lpCommand = NULL; @@ -2422,82 +2432,10 @@ HRESULT WINAPI ShellExecCmdLine( PathUnquoteSpacesW(lpCommand); StringCchCopyW(szFile, _countof(szFile), lpCommand); - if (szFile[0] != UNICODE_NULL && szFile[1] == L':' && - szFile[2] == UNICODE_NULL) + if (PathIsRootW(szFile)) { PathAddBackslashW(szFile); } - - WCHAR szCurDir[MAX_PATH]; - GetCurrentDirectoryW(_countof(szCurDir), szCurDir); - if (pwszStartDir) - { - SetCurrentDirectoryW(pwszStartDir); - } - - if (PathIsRelativeW(szFile) && - GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) && - PathFileExistsW(szFile2)) - { - StringCchCopyW(szFile, _countof(szFile), szFile2); - } - else if (SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL) || - SearchPathW(NULL, szFile, wszExe, _countof(szFile2), szFile2, NULL) || - SearchPathW(NULL, szFile, wszCom, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, szFile, NULL, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, szFile, wszExe, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, szFile, wszCom, _countof(szFile2), szFile2, NULL)) - { - StringCchCopyW(szFile, _countof(szFile), szFile2); - } - else if (SearchPathW(NULL, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || - SearchPathW(NULL, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || - SearchPathW(NULL, lpCommand, wszCom, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, lpCommand, wszCom, _countof(szFile2), szFile2, NULL)) - { - StringCchCopyW(szFile, _countof(szFile), szFile2); - pchParams = NULL; - } - - if (pwszStartDir) - { - SetCurrentDirectoryW(szCurDir); - } - - if (!(dwSeclFlags & SECL_ALLOW_NONEXE)) - { - if (!GetBinaryTypeW(szFile, &dwType)) - { - SHFree(lpCommand); - - if (!(dwSeclFlags & SECL_NO_UI)) - { - WCHAR szText[128 + MAX_PATH], szFormat[128]; - LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); - StringCchPrintfW(szText, _countof(szText), szFormat, szFile); - MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); - } - return CO_E_APPNOTFOUND; - } - } - else - { - if (GetFileAttributesW(szFile) == INVALID_FILE_ATTRIBUTES) - { - SHFree(lpCommand); - - if (!(dwSeclFlags & SECL_NO_UI)) - { - WCHAR szText[128 + MAX_PATH], szFormat[128]; - LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); - StringCchPrintfW(szText, _countof(szText), szFormat, szFile); - MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); - } - return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - } - } } ZeroMemory(&info, sizeof(info)); @@ -2507,7 +2445,7 @@ HRESULT WINAPI ShellExecCmdLine( info.lpVerb = pszVerb; info.lpFile = szFile; info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL; - info.lpDirectory = pwszStartDir; + info.lpDirectory = (pwszStartDir && *pwszStartDir) ? pwszStartDir : NULL; info.nShow = nShow; if (ShellExecuteExW(&info)) { diff --git a/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp b/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp index f9f57e375003..460cc4ed421e 100644 --- a/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp +++ b/modules/rostests/apitests/shell32/ShellExecCmdLine.cpp @@ -47,9 +47,9 @@ HRESULT WINAPI ShellExecCmdLine( DWORD dwSeclFlags) { SHELLEXECUTEINFOW info; - DWORD dwSize, dwError, dwType, dwFlags = SEE_MASK_DOENVSUBST | SEE_MASK_NOASYNC; + DWORD dwSize, dwError, dwFlags = SEE_MASK_DOENVSUBST | SEE_MASK_NOASYNC; LPCWSTR pszVerb = NULL; - WCHAR szFile[MAX_PATH], szFile2[MAX_PATH]; + WCHAR szFile[MAX_PATH]; HRESULT hr; LPCWSTR pchParams; LPWSTR lpCommand = NULL; @@ -95,82 +95,10 @@ HRESULT WINAPI ShellExecCmdLine( PathUnquoteSpacesW(lpCommand); StringCchCopyW(szFile, _countof(szFile), lpCommand); - if (szFile[0] != UNICODE_NULL && szFile[1] == L':' && - szFile[2] == UNICODE_NULL) + if (PathIsRootW(szFile)) { PathAddBackslashW(szFile); } - - WCHAR szCurDir[MAX_PATH]; - GetCurrentDirectoryW(_countof(szCurDir), szCurDir); - if (pwszStartDir) - { - SetCurrentDirectoryW(pwszStartDir); - } - - if (PathIsRelativeW(szFile) && - GetFullPathNameW(szFile, _countof(szFile2), szFile2, NULL) && - PathFileExistsW(szFile2)) - { - StringCchCopyW(szFile, _countof(szFile), szFile2); - } - else if (SearchPathW(NULL, szFile, NULL, _countof(szFile2), szFile2, NULL) || - SearchPathW(NULL, szFile, wszExe, _countof(szFile2), szFile2, NULL) || - SearchPathW(NULL, szFile, wszCom, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, szFile, NULL, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, szFile, wszExe, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, szFile, wszCom, _countof(szFile2), szFile2, NULL)) - { - StringCchCopyW(szFile, _countof(szFile), szFile2); - } - else if (SearchPathW(NULL, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || - SearchPathW(NULL, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || - SearchPathW(NULL, lpCommand, wszCom, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, lpCommand, NULL, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, lpCommand, wszExe, _countof(szFile2), szFile2, NULL) || - SearchPathW(pwszStartDir, lpCommand, wszCom, _countof(szFile2), szFile2, NULL)) - { - StringCchCopyW(szFile, _countof(szFile), szFile2); - pchParams = NULL; - } - - if (pwszStartDir) - { - SetCurrentDirectoryW(szCurDir); - } - - if (!(dwSeclFlags & SECL_ALLOW_NONEXE)) - { - if (!GetBinaryTypeW(szFile, &dwType)) - { - SHFree(lpCommand); - - if (!(dwSeclFlags & SECL_NO_UI)) - { - WCHAR szText[128 + MAX_PATH], szFormat[128]; - LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); - StringCchPrintfW(szText, _countof(szText), szFormat, szFile); - MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); - } - return CO_E_APPNOTFOUND; - } - } - else - { - if (GetFileAttributesW(szFile) == INVALID_FILE_ATTRIBUTES) - { - SHFree(lpCommand); - - if (!(dwSeclFlags & SECL_NO_UI)) - { - WCHAR szText[128 + MAX_PATH], szFormat[128]; - LoadStringW(shell32_hInstance, IDS_FILE_NOT_FOUND, szFormat, _countof(szFormat)); - StringCchPrintfW(szText, _countof(szText), szFormat, szFile); - MessageBoxW(hwnd, szText, NULL, MB_ICONERROR); - } - return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - } - } } ZeroMemory(&info, sizeof(info)); @@ -180,7 +108,7 @@ HRESULT WINAPI ShellExecCmdLine( info.lpVerb = pszVerb; info.lpFile = szFile; info.lpParameters = (pchParams && *pchParams) ? pchParams : NULL; - info.lpDirectory = pwszStartDir; + info.lpDirectory = (pwszStartDir && *pwszStartDir) ? pwszStartDir : NULL; info.nShow = nShow; if (ShellExecuteExW(&info)) { diff --git a/sdk/include/reactos/shlwapi_undoc.h b/sdk/include/reactos/shlwapi_undoc.h index c1f92559e55c..c67a51e1aede 100644 --- a/sdk/include/reactos/shlwapi_undoc.h +++ b/sdk/include/reactos/shlwapi_undoc.h @@ -150,6 +150,8 @@ ShellMessageBoxWrapW( _In_ UINT fuStyle, ...); +BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich); + #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */ From 210445fa37218537ef2c1293366edb2f897abe8d Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Wed, 2 Jun 2021 15:51:01 +0900 Subject: [PATCH 4/5] update copyright year --- dll/win32/shell32/shlexec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index 8226114aef87..d54255ea15a9 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -3,7 +3,7 @@ * * Copyright 1998 Marcus Meissner * Copyright 2002 Eric Pouech - * Copyright 2018-2019 Katayama Hirofumi MZ + * Copyright 2018-2021 Katayama Hirofumi MZ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public From f77cbc6563243969d90b187ebe303f81b31e4d29 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Wed, 2 Jun 2021 15:57:23 +0900 Subject: [PATCH 5/5] add NOTE --- dll/win32/shell32/shlexec.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index d54255ea15a9..c522b12b1d34 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -2375,6 +2375,8 @@ OpenAs_RunDLLA(HWND hwnd, HINSTANCE hinst, LPCSTR cmdline, int cmdshow) /*************************************************************************/ +// NOTE: You have to sync the following code to modules/rostests/apitests/shell32/ShellExecCmdLine.cpp + HRESULT WINAPI ShellExecCmdLine( HWND hwnd, LPCWSTR pwszCommand,