https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e4216bd015965ab45b7a4…
commit e4216bd015965ab45b7a4cb1e35a7eeb3f43c666
Author: Whindmar Saksit <whindsaks(a)proton.me>
AuthorDate: Sun Feb 9 20:07:17 2025 +0100
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Feb 9 20:07:17 2025 +0100
[SHELL32] Expand .lnk working directory string before checking if it's valid
(#7710)
Handles the case where SEE_MASK_DOENVSUBST will expand it later inside ShellExeute.
CORE-19987
---
dll/win32/shell32/CShellLink.cpp | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/dll/win32/shell32/CShellLink.cpp b/dll/win32/shell32/CShellLink.cpp
index 6ad2dec1e9a..b60987d40a3 100644
--- a/dll/win32/shell32/CShellLink.cpp
+++ b/dll/win32/shell32/CShellLink.cpp
@@ -216,6 +216,22 @@ static LPWSTR __inline strdupW(LPCWSTR src)
return dest;
}
+static BOOL PathEnvSubstIsDirectory(LPCWSTR pszPath)
+{
+ // Note: Don't call SHExpandEnvironmentStringsW here, we need the required
length
+ WCHAR szStack[MAX_PATH];
+ DWORD cch = ExpandEnvironmentStringsW(pszPath, szStack, _countof(szStack));
+ if (cch <= _countof(szStack))
+ return cch && PathIsDirectory(szStack);
+
+ PWSTR szHeap = (PWSTR)SHAlloc(cch);
+ if (!szHeap)
+ return FALSE;
+ BOOL bResult = ExpandEnvironmentStringsW(pszPath, szHeap, cch) &&
PathIsDirectory(szHeap);
+ SHFree(szHeap);
+ return bResult;
+}
+
// TODO: Use it for constructor & destructor too
VOID CShellLink::Reset()
{
@@ -2667,7 +2683,7 @@ HRESULT CShellLink::DoOpen(LPCMINVOKECOMMANDINFO lpici)
sei.nShow = lpici->nShow; // Allow invoker to override .lnk show mode
// Use the invoker specified working directory if the link did not specify one
- if (StrIsNullOrEmpty(sei.lpDirectory) || !PathIsDirectoryW(sei.lpDirectory))
+ if (StrIsNullOrEmpty(sei.lpDirectory) || !PathEnvSubstIsDirectory(sei.lpDirectory))
{
LPCSTR pszDirA = lpici->lpDirectory;
if (unicode && !StrIsNullOrEmpty(iciex->lpDirectoryW))