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

commit f379a29606aa03c74f521de5b9028eb623ed4055
Author:     Mark Jansen <[email protected]>
AuthorDate: Mon Apr 27 20:43:16 2020 +0200
Commit:     Mark Jansen <[email protected]>
CommitDate: Sun May 17 17:09:04 2020 +0200

    [SHELL32] Properly enumerate virtual shell folders (on files) as fake 
folders
    CORE-16908
---
 dll/win32/shell32/folders/CFSFolder.cpp | 100 +++++++++++++++++++++++++++++++-
 sdk/include/reactos/shlwapi_undoc.h     |   1 +
 2 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/dll/win32/shell32/folders/CFSFolder.cpp 
b/dll/win32/shell32/folders/CFSFolder.cpp
index 266a7478367..a97ad5d4980 100644
--- a/dll/win32/shell32/folders/CFSFolder.cpp
+++ b/dll/win32/shell32/folders/CFSFolder.cpp
@@ -371,6 +371,52 @@ private:
 
         BOOL bDirectory = (FindData.dwFileAttributes & 
FILE_ATTRIBUTE_DIRECTORY) != 0;
 
+        HRESULT hr;
+        if (bDirectory)
+        {
+            // Skip the current and parent directory nodes
+            if (!strcmpW(FindData.cFileName, L".") || 
!strcmpW(FindData.cFileName, L".."))
+                return S_OK;
+
+            // Does this directory need special handling?
+            if ((FindData.dwFileAttributes & (FILE_ATTRIBUTE_SYSTEM | 
FILE_ATTRIBUTE_READONLY)) != 0)
+            {
+                WCHAR Tmp[MAX_PATH];
+                CLSID clsidFolder;
+
+                PathCombineW(Tmp, sParentDir, FindData.cFileName);
+
+                hr = SHELL32_GetCLSIDForDirectory(Tmp, L"CLSID", &clsidFolder);
+                if (SUCCEEDED(hr))
+                {
+                    ERR("SHOULD DO SOMETHING WITH CLSID?\n");
+                }
+            }
+        }
+        else
+        {
+            CLSID clsidFile;
+            LPWSTR pExtension = PathFindExtensionW(FindData.cFileName);
+            if (pExtension)
+            {
+                // FIXME: Cache this?
+                hr = GetCLSIDForFileTypeFromExtension(pExtension, L"CLSID", 
&clsidFile);
+                if (hr == S_OK)
+                {
+                    HKEY hkey;
+                    hr = SHRegGetCLSIDKeyW(clsidFile, L"ShellFolder", FALSE, 
FALSE, &hkey);
+                    if (SUCCEEDED(hr))
+                    {
+                        ::RegCloseKey(hkey);
+
+                        // This should be presented as directory!
+                        bDirectory = TRUE;
+                        TRACE("Treating '%S' as directory!\n", 
FindData.cFileName);
+                    }
+                }
+            }
+        }
+
         LPITEMIDLIST pidl = NULL;
         if (bDirectory)
         {
@@ -573,10 +619,60 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, 
LPCITEMIDLIST pidl, LPDW
     dwShellAttributes = SFGAO_CANCOPY | SFGAO_CANMOVE | SFGAO_CANLINK | 
SFGAO_CANRENAME | SFGAO_CANDELETE |
                         SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | 
SFGAO_FILESYSTEM;
 
-    if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-        dwShellAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | 
SFGAO_FILESYSANCESTOR | SFGAO_STORAGEANCESTOR | SFGAO_STORAGE);
+    BOOL bDirectory = (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+
+    if (!bDirectory)
+    {
+        // 
https://git.reactos.org/?p=reactos.git;a=blob;f=dll/shellext/zipfldr/res/zipfldr.rgs;hb=032b5aacd233cd7b83ab6282aad638c161fdc400#l9
+        WCHAR szFileName[MAX_PATH];
+        LPWSTR pExtension;
+
+        if (_ILSimpleGetTextW(pidl, szFileName, _countof(szFileName)) && 
(pExtension = PathFindExtensionW(szFileName)))
+        {
+            CLSID clsidFile;
+            // FIXME: Cache this?
+            HRESULT hr = GetCLSIDForFileTypeFromExtension(pExtension, 
L"CLSID", &clsidFile);
+            if (hr == S_OK)
+            {
+                HKEY hkey;
+                hr = SHRegGetCLSIDKeyW(clsidFile, L"ShellFolder", FALSE, 
FALSE, &hkey);
+                if (SUCCEEDED(hr))
+                {
+                    DWORD dwAttributes = 0;
+                    DWORD dwSize = sizeof(dwAttributes);
+                    LSTATUS Status;
+
+                    Status = SHRegGetValueW(hkey, NULL, L"Attributes", 
RRF_RT_REG_DWORD, NULL, &dwAttributes, &dwSize);
+                    if (Status == STATUS_SUCCESS)
+                    {
+                        ERR("Augmenting '%S' with dwAttributes=0x%x\n", 
szFileName, dwAttributes);
+                        dwShellAttributes |= dwAttributes;
+                    }
+                    ::RegCloseKey(hkey);
+
+                    // This should be presented as directory!
+                    bDirectory = TRUE;
+                    ERR("Treating '%S' as directory!\n", szFileName);
+                }
+            }
+        }
+    }
+
+    // This is a directory
+    if (bDirectory)
+    {
+        dwShellAttributes |= (SFGAO_FOLDER | /*SFGAO_HASSUBFOLDER |*/ 
SFGAO_STORAGE);
+
+        // Is this a real directory?
+        if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        {
+            dwShellAttributes |= (SFGAO_FILESYSANCESTOR | 
SFGAO_STORAGEANCESTOR);
+        }
+    }
     else
+    {
         dwShellAttributes |= SFGAO_STREAM;
+    }
 
     if (dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
         dwShellAttributes |=  SFGAO_HIDDEN;
diff --git a/sdk/include/reactos/shlwapi_undoc.h 
b/sdk/include/reactos/shlwapi_undoc.h
index a90537fbd30..08af85972d7 100644
--- a/sdk/include/reactos/shlwapi_undoc.h
+++ b/sdk/include/reactos/shlwapi_undoc.h
@@ -53,6 +53,7 @@ HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup,ULONG cCmds, 
OLECMD *prgCmds);
 BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild);
 HRESULT WINAPI SHForwardContextMenuMsg(IUnknown* pUnk, UINT uMsg, WPARAM 
wParam, LPARAM lParam, LRESULT* pResult, BOOL useIContextMenu2);
 
+HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID guid, LPCWSTR lpszValue, BOOL 
bUseHKCU, BOOL bCreate, PHKEY phKey);
 
 BOOL WINAPI SHAddDataBlock(LPDBLIST* lppList, const DATABLOCK_HEADER 
*lpNewItem);
 BOOL WINAPI SHRemoveDataBlock(LPDBLIST* lppList, DWORD dwSignature);

Reply via email to