https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bad0dd599179eb7212749a0aaae1275fd20b570f

commit bad0dd599179eb7212749a0aaae1275fd20b570f
Author:     Whindmar Saksit <whinds...@proton.me>
AuthorDate: Thu Sep 12 19:28:15 2024 +0200
Commit:     GitHub <nore...@github.com>
CommitDate: Thu Sep 12 19:28:15 2024 +0200

    [SHELL32] Store target FS attributes in .lnk header (#7302)
---
 dll/win32/shell32/CShellLink.cpp | 44 ++++++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 18 deletions(-)

diff --git a/dll/win32/shell32/CShellLink.cpp b/dll/win32/shell32/CShellLink.cpp
index ca1f6b1a3ef..d438fa204ff 100644
--- a/dll/win32/shell32/CShellLink.cpp
+++ b/dll/win32/shell32/CShellLink.cpp
@@ -882,6 +882,21 @@ HRESULT STDMETHODCALLTYPE CShellLink::Save(IStream *stm, 
BOOL fClearDirty)
     m_Header.dwSize = sizeof(m_Header);
     m_Header.clsid = CLSID_ShellLink;
 
+    /* Store target attributes */
+    WIN32_FIND_DATAW wfd = {};
+    WCHAR FsTarget[MAX_PATH];
+    if (GetPath(FsTarget, _countof(FsTarget), NULL, 0) == S_OK && 
PathFileExistsW(FsTarget))
+    {
+        HANDLE hFind = FindFirstFileW(FsTarget, &wfd);
+        if (hFind != INVALID_HANDLE_VALUE)
+            FindClose(hFind);
+    }
+    m_Header.dwFileAttributes = wfd.dwFileAttributes;
+    m_Header.ftCreationTime = wfd.ftCreationTime;
+    m_Header.ftLastAccessTime = wfd.ftLastAccessTime;
+    m_Header.ftLastWriteTime = wfd.ftLastWriteTime;
+    m_Header.nFileSizeLow = wfd.nFileSizeLow;
+
     /*
      * Reset the flags: keep only the flags related to data blocks as they were
      * already set in accordance by the different mutator member functions.
@@ -1077,7 +1092,7 @@ HRESULT STDMETHODCALLTYPE CShellLink::GetPath(LPSTR 
pszFile, INT cchMaxPath, WIN
           this, pszFile, cchMaxPath, pfd, fFlags, debugstr_w(m_sPath));
 
     /* Allocate a temporary UNICODE buffer */
-    pszFileW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, cchMaxPath * 
sizeof(WCHAR));
+    pszFileW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, max(cchMaxPath, 
MAX_PATH) * sizeof(WCHAR));
     if (!pszFileW)
         return E_OUTOFMEMORY;
 
@@ -2690,31 +2705,24 @@ INT_PTR CALLBACK ExtendedShortcutProc(HWND hwndDlg, 
UINT uMsg,
     return FALSE;
 }
 
-/**************************************************************************
-* SH_GetTargetTypeByPath
-*
-* Function to get target type by passing full path to it
-*/
-void SH_GetTargetTypeByPath(LPCWSTR lpcwFullPath, LPWSTR szBuf, UINT cchBuf)
+static void GetTypeDescriptionByPath(PCWSTR pszFullPath, DWORD fAttributes, 
PWSTR szBuf, UINT cchBuf)
 {
-    LPCWSTR pwszExt;
-    BOOL fFolderTarget = PathIsDirectoryW(lpcwFullPath);
-    DWORD fAttribs = fFolderTarget ? FILE_ATTRIBUTE_DIRECTORY : 0;
+    if (fAttributes == INVALID_FILE_ATTRIBUTES && 
!PathFileExistsAndAttributesW(pszFullPath, &fAttributes))
+        fAttributes = 0;
 
-    /* Get file information */
     SHFILEINFOW fi;
-    if (!SHGetFileInfoW(lpcwFullPath, fAttribs, &fi, sizeof(fi), 
SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES))
+    if (!SHGetFileInfoW(pszFullPath, fAttributes, &fi, sizeof(fi), 
SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES))
     {
-        ERR("SHGetFileInfoW failed for %ls (%lu)\n", lpcwFullPath, 
GetLastError());
-        fi.szTypeName[0] = L'\0';
-        fi.hIcon = NULL;
+        ERR("SHGetFileInfoW failed for %ls (%lu)\n", pszFullPath, 
GetLastError());
+        fi.szTypeName[0] = UNICODE_NULL;
     }
 
-    pwszExt = fFolderTarget ? L"" : PathFindExtensionW(lpcwFullPath);
+    BOOL fFolder = (fAttributes & FILE_ATTRIBUTE_DIRECTORY);
+    LPCWSTR pwszExt = fFolder ? L"" : PathFindExtensionW(pszFullPath);
     if (pwszExt[0])
     {
         if (!fi.szTypeName[0])
-            StringCchPrintfW(szBuf, cchBuf,L"%s ", pwszExt + 1);
+            StringCchPrintfW(szBuf, cchBuf, L"%s", pwszExt + 1);
         else
             StringCchPrintfW(szBuf, cchBuf, L"%s (%s)", fi.szTypeName, 
pwszExt);
     }
@@ -2764,7 +2772,7 @@ BOOL CShellLink::OnInitDialog(HWND hwndDlg, HWND 
hwndFocus, LPARAM lParam)
     if (m_sPath)
     {
         WCHAR buf[MAX_PATH];
-        SH_GetTargetTypeByPath(m_sPath, buf, _countof(buf));
+        GetTypeDescriptionByPath(m_sPath, m_Header.dwFileAttributes, buf, 
_countof(buf));
         SetDlgItemTextW(hwndDlg, IDC_SHORTCUT_TYPE_EDIT, buf);
     }
 

Reply via email to