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

commit 9c6f1958d986b97eb08385a2035ed8bb794134f4
Author:     Jesús Sanz del Rey <[email protected]>
AuthorDate: Mon Jan 17 00:20:07 2022 +0100
Commit:     GitHub <[email protected]>
CommitDate: Mon Jan 17 00:20:07 2022 +0100

    [SHELL32] Implement Recycler Bin icons (#4221)
    
    CORE-3938
    
    Icon extraction from the recycle bin was not possible due to the partial 
absence of IExtractIcon interface support.
    Adding it inside the RecycleBinFile's QueryInterface private 
implementation, and then calling it from CRecycleBin, now allows retrieving and 
displaying the files' icons.
---
 dll/win32/shell32/folders/CRecycleBin.cpp          | 50 ++++++++++++++++++----
 .../shell32/shellrecyclebin/recyclebin_private.h   |  2 +
 .../shellrecyclebin/recyclebin_v5_enumerator.c     | 13 ++++++
 3 files changed, 56 insertions(+), 9 deletions(-)

diff --git a/dll/win32/shell32/folders/CRecycleBin.cpp 
b/dll/win32/shell32/folders/CRecycleBin.cpp
index 48d285c9ac7..ee6c6d60754 100644
--- a/dll/win32/shell32/folders/CRecycleBin.cpp
+++ b/dll/win32/shell32/folders/CRecycleBin.cpp
@@ -62,14 +62,53 @@ static const columninfo RecycleBinColumns[] =
  * Recycle Bin folder
  */
 
-HRESULT CRecyclerExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID riid, 
LPVOID * ppvOut)
+BOOL WINAPI CBSearchRecycleBin(IN PVOID Context, IN HANDLE hDeletedFile);
+
+static PIDLRecycleStruct * _ILGetRecycleStruct(LPCITEMIDLIST pidl);
+
+typedef struct _SEARCH_CONTEXT
+{
+    PIDLRecycleStruct *pFileDetails;
+    HANDLE hDeletedFile;
+    BOOL bFound;
+} SEARCH_CONTEXT, *PSEARCH_CONTEXT;
+
+HRESULT CRecyclerExtractIcon_CreateInstance(
+    LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
 {
+    PIDLRecycleStruct *pFileDetails = _ILGetRecycleStruct(pidl);
+    if (pFileDetails == NULL)
+        goto fallback;
+
+    // Try to obtain the file
+    SEARCH_CONTEXT Context;
+    Context.pFileDetails = pFileDetails;
+    Context.bFound = FALSE;
+
+    EnumerateRecycleBinW(NULL, CBSearchRecycleBin, &Context);
+    if (Context.bFound)
+    {
+        // This should be executed any time, if not, there are some errors in 
the implementation
+        IRecycleBinFile* pRecycleFile = (IRecycleBinFile*)Context.hDeletedFile;
+
+        // Query the interface from the private interface
+        HRESULT hr = pRecycleFile->QueryInterface(riid, ppvOut);
+
+        // Close the file handle as we don't need it anymore
+        CloseRecycleBinHandle(Context.hDeletedFile);
+
+        return hr;
+    }
+
+fallback:
+    // In case the search fails we use a default icon
+    ERR("Recycler could not retrieve the icon, this shouldn't happen\n");
+
     CComPtr<IDefaultExtractIconInit> initIcon;
     HRESULT hr = 
SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
-    /* FIXME: This is completely unimplemented */
     initIcon->SetNormalIcon(swShell32Name, 0);
 
     return initIcon->QueryInterface(riid, ppvOut);
@@ -116,13 +155,6 @@ class CRecycleBinItemContextMenu :
         END_COM_MAP()
 };
 
-typedef struct
-{
-    PIDLRecycleStruct *pFileDetails;
-    HANDLE hDeletedFile;
-    BOOL bFound;
-} SEARCH_CONTEXT, *PSEARCH_CONTEXT;
-
 BOOL WINAPI CBSearchRecycleBin(IN PVOID Context, IN HANDLE hDeletedFile)
 {
     PSEARCH_CONTEXT pContext = (PSEARCH_CONTEXT)Context;
diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin_private.h 
b/dll/win32/shell32/shellrecyclebin/recyclebin_private.h
index 9686bdfccee..6c90aa94728 100644
--- a/dll/win32/shell32/shellrecyclebin/recyclebin_private.h
+++ b/dll/win32/shell32/shellrecyclebin/recyclebin_private.h
@@ -5,6 +5,8 @@
 
 #define COBJMACROS
 
+#include <shlobj.h>
+
 #include "recyclebin.h"
 #include "recyclebin_v5.h"
 
diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.c 
b/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.c
index bbe4fa1e834..411c623b3a2 100644
--- a/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.c
+++ b/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.c
@@ -17,6 +17,11 @@ struct RecycleBin5File
     WCHAR FullName[ANY_SIZE];
 };
 
+static HRESULT STDMETHODCALLTYPE
+RecycleBin5File_RecycleBinFile_GetAttributes(
+    IN IRecycleBinFile *This,
+    OUT DWORD *pAttributes);
+
 static HRESULT STDMETHODCALLTYPE
 RecycleBin5File_RecycleBinFile_QueryInterface(
     IN IRecycleBinFile *This,
@@ -34,6 +39,14 @@ RecycleBin5File_RecycleBinFile_QueryInterface(
         *ppvObject = &s->recycleBinFileImpl;
     else if (IsEqualIID(riid, &IID_IRecycleBinFile))
         *ppvObject = &s->recycleBinFileImpl;
+    else if (IsEqualIID(riid, &IID_IExtractIconA) || IsEqualIID(riid, 
&IID_IExtractIconW))
+    {
+        DWORD dwAttributes;
+        if (RecycleBin5File_RecycleBinFile_GetAttributes(This, &dwAttributes) 
== S_OK)
+            return SHCreateFileExtractIconW(s->FullName, dwAttributes, riid, 
ppvObject);
+        else
+            return S_FALSE;
+    }
     else
     {
         *ppvObject = NULL;

Reply via email to