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

commit 47f6745bcdfb833b0311e052f04e6cd5634660eb
Author:     Jesús Sanz del Rey <[email protected]>
AuthorDate: Tue Jan 11 00:40:25 2022 +0100
Commit:     GitHub <[email protected]>
CommitDate: Tue Jan 11 00:40:25 2022 +0100

    [SHELL32] Fix folders on recycle bin and adjust the column size (#4234)
    
    CORE-11000
    
    - Now, folders can be sent to recycle bin (fixed a bug inside the 
implementation).
    - Adjust column size of the RecycleBin virtual folder in details mode.
---
 dll/win32/shell32/folders/CRecycleBin.cpp          | 39 ++++++++++++---------
 dll/win32/shell32/shellrecyclebin/recyclebin.c     | 28 ++++++++++++++-
 dll/win32/shell32/shellrecyclebin/recyclebin.h     | 10 ++++++
 dll/win32/shell32/shellrecyclebin/recyclebin_v5.c  |  2 +-
 .../shellrecyclebin/recyclebin_v5_enumerator.c     | 40 +++++++++++++++++++++-
 5 files changed, 99 insertions(+), 20 deletions(-)

diff --git a/dll/win32/shell32/folders/CRecycleBin.cpp 
b/dll/win32/shell32/folders/CRecycleBin.cpp
index cba7c52e42e..48d285c9ac7 100644
--- a/dll/win32/shell32/folders/CRecycleBin.cpp
+++ b/dll/win32/shell32/folders/CRecycleBin.cpp
@@ -39,14 +39,14 @@ typedef struct
 
 static const columninfo RecycleBinColumns[] =
 {
-    {IDS_SHV_COLUMN_NAME,        &FMTID_Storage,   PID_STG_NAME,       
SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT,  LVCFMT_LEFT,  30},
-    {IDS_SHV_COLUMN_DELFROM, &FMTID_Displaced, PID_DISPLACED_FROM, 
SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT,  LVCFMT_LEFT,  30},
-    {IDS_SHV_COLUMN_DELDATE, &FMTID_Displaced, PID_DISPLACED_DATE, 
SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT,  20},
-    {IDS_SHV_COLUMN_SIZE,        &FMTID_Storage,   PID_STG_SIZE,       
SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT,  LVCFMT_RIGHT, 20},
-    {IDS_SHV_COLUMN_TYPE,        &FMTID_Storage,   PID_STG_STORAGETYPE, 
SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT,  LVCFMT_LEFT,  20},
-    {IDS_SHV_COLUMN_MODIFIED,        &FMTID_Storage,   PID_STG_WRITETIME,  
SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT,  20},
-    /*    {"creation time",  &FMTID_Storage,   PID_STG_CREATETIME, 
SHCOLSTATE_TYPE_DATE,                        LVCFMT_LEFT,  20}, */
-    /*    {"attribs",        &FMTID_Storage,   PID_STG_ATTRIBUTES, 
SHCOLSTATE_TYPE_STR,                         LVCFMT_LEFT,  20},       */
+    {IDS_SHV_COLUMN_NAME,     &FMTID_Storage,   PID_STG_NAME,        
SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT,  LVCFMT_LEFT,  25},
+    {IDS_SHV_COLUMN_DELFROM,  &FMTID_Displaced, PID_DISPLACED_FROM,  
SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT,  LVCFMT_LEFT,  35},
+    {IDS_SHV_COLUMN_DELDATE,  &FMTID_Displaced, PID_DISPLACED_DATE,  
SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT,  15},
+    {IDS_SHV_COLUMN_SIZE,     &FMTID_Storage,   PID_STG_SIZE,        
SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT,  LVCFMT_RIGHT, 10},
+    {IDS_SHV_COLUMN_TYPE,     &FMTID_Storage,   PID_STG_STORAGETYPE, 
SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT,  LVCFMT_LEFT,  15},
+    {IDS_SHV_COLUMN_MODIFIED, &FMTID_Storage,   PID_STG_WRITETIME,   
SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT,  15},
+    /* {"creation time",  &FMTID_Storage,   PID_STG_CREATETIME, 
SHCOLSTATE_TYPE_DATE, LVCFMT_LEFT,  20}, */
+    /* {"attribs",        &FMTID_Storage,   PID_STG_ATTRIBUTES, 
SHCOLSTATE_TYPE_STR,  LVCFMT_LEFT,  20}, */
 };
 
 #define COLUMN_NAME    0
@@ -745,21 +745,26 @@ HRESULT WINAPI CRecycleBin::GetDetailsOf(PCUITEMID_CHILD 
pidl, UINT iColumn, LPS
             FormatDateTime(buffer, MAX_PATH, &pFileDetails->LastModification);
             break;
         case COLUMN_TYPE:
-            // FIXME: We should in fact use a UNICODE version of _ILGetFileType
-            szTypeName[0] = L'\0';
-            wcscpy(buffer, PathFindExtensionW(pFileDetails->szName));
-            if (!( HCR_MapTypeToValueW(buffer, buffer, _countof(buffer), TRUE) 
&&
-                    HCR_MapTypeToValueW(buffer, szTypeName, 
_countof(szTypeName), FALSE )))
             {
+                SEARCH_CONTEXT Context;
+                Context.pFileDetails = pFileDetails;
+                Context.bFound = FALSE;
+                EnumerateRecycleBinW(NULL, CBSearchRecycleBin, 
(PVOID)&Context);
+
+                if (Context.bFound)
+                {
+                    GetDeletedFileTypeNameW(Context.hDeletedFile, buffer, 
_countof(buffer), NULL);
+
+                    CloseRecycleBinHandle(Context.hDeletedFile);
+                }
                 /* load localized file string */
-                szTypeName[0] = '\0';
-                if(LoadStringW(shell32_hInstance, IDS_ANY_FILE, szTypeName, 
_countof(szTypeName)))
+                else if (LoadStringW(shell32_hInstance, IDS_ANY_FILE, 
szTypeName, _countof(szTypeName)))
                 {
-                    szTypeName[63] = '\0';
                     StringCchPrintfW(buffer, _countof(buffer), szTypeName, 
PathFindExtensionW(pFileDetails->szName));
                 }
+
+                return SHSetStrRet(&pDetails->str, buffer);
             }
-            return SHSetStrRet(&pDetails->str, szTypeName);
         default:
             return E_FAIL;
     }
diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin.c 
b/dll/win32/shell32/shellrecyclebin/recyclebin.c
index 50d06a9608c..a6392496012 100644
--- a/dll/win32/shell32/shellrecyclebin/recyclebin.c
+++ b/dll/win32/shell32/shellrecyclebin/recyclebin.c
@@ -3,7 +3,7 @@
  * LICENSE:     GPL v2 - See COPYING in the top level directory
  * FILE:        lib/recyclebin/recyclebin.c
  * PURPOSE:     Public interface
- * PROGRAMMERS: Copyright 2006-2007 Herv� Poussineau ([email protected])
+ * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau ([email protected])
  */
 
 #include "recyclebin_private.h"
@@ -252,6 +252,32 @@ cleanup:
     return FALSE;
 }
 
+BOOL WINAPI
+GetDeletedFileTypeNameW(
+    IN HANDLE hDeletedFile,
+    OUT LPWSTR pTypeName,
+    IN DWORD BufferSize,
+    OUT LPDWORD RequiredSize OPTIONAL)
+{
+    IRecycleBinFile *prbf = (IRecycleBinFile *)hDeletedFile;
+    SIZE_T FinalSize;
+
+    HRESULT hr = IRecycleBinFile_GetTypeName(prbf, BufferSize, pTypeName, 
&FinalSize);
+
+    if (SUCCEEDED(hr))
+    {
+        if (RequiredSize)
+            *RequiredSize = (DWORD)FinalSize;
+
+        return TRUE;
+    }
+    if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
+        SetLastError(HRESULT_CODE(hr));
+    else
+        SetLastError(ERROR_GEN_FAILURE);
+    return FALSE;
+}
+
 BOOL WINAPI
 GetDeletedFileDetailsA(
     IN HANDLE hDeletedFile,
diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin.h 
b/dll/win32/shell32/shellrecyclebin/recyclebin.h
index 2fa2d00139b..50c020c839f 100644
--- a/dll/win32/shell32/shellrecyclebin/recyclebin.h
+++ b/dll/win32/shell32/shellrecyclebin/recyclebin.h
@@ -131,6 +131,13 @@ EnumerateRecycleBinW(
 #define EnumerateRecycleBin EnumerateRecycleBinA
 #endif
 
+BOOL WINAPI
+GetDeletedFileTypeNameW(
+    IN HANDLE hDeletedFile,
+    OUT LPWSTR pTypeName,
+    IN DWORD BufferSize,
+    OUT LPDWORD RequiredSize OPTIONAL);
+
 /* Gets details about a deleted file
  * hDeletedFile: handle of the deleted file to get details about
  * BufferSize: size of the 'FileDetails' buffer, in bytes
@@ -196,6 +203,7 @@ DECLARE_INTERFACE_(IRecycleBinFile, IUnknown)
     STDMETHOD(GetPhysicalFileSize)(THIS_ ULARGE_INTEGER *pPhysicalFileSize) 
PURE;
     STDMETHOD(GetAttributes)(THIS_ DWORD *pAttributes) PURE;
     STDMETHOD(GetFileName)(THIS_ SIZE_T BufferSize, LPWSTR Buffer, SIZE_T 
*RequiredSize) PURE;
+    STDMETHOD(GetTypeName)(THIS_ SIZE_T BufferSize, LPWSTR Buffer, SIZE_T 
*RequiredSize) PURE;
     STDMETHOD(Delete)(THIS) PURE;
     STDMETHOD(Restore)(THIS) PURE;
 
@@ -264,6 +272,8 @@ EXTERN_C const IID IID_IRecycleBin;
     (This)->lpVtbl->GetAttributes(This, pAttributes)
 #define IRecycleBinFile_GetFileName(This, BufferSize, Buffer, RequiredSize) \
     (This)->lpVtbl->GetFileName(This, BufferSize, Buffer, RequiredSize)
+#define IRecycleBinFile_GetTypeName(This, BufferSize, Buffer, RequiredSize) \
+    (This)->lpVtbl->GetTypeName(This, BufferSize, Buffer, RequiredSize)
 #define IRecycleBinFile_Delete(This) \
     (This)->lpVtbl->Delete(This)
 #define IRecycleBinFile_Restore(This) \
diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin_v5.c 
b/dll/win32/shell32/shellrecyclebin/recyclebin_v5.c
index 5bbd9548997..3344b2c035c 100644
--- a/dll/win32/shell32/shellrecyclebin/recyclebin_v5.c
+++ b/dll/win32/shell32/shellrecyclebin/recyclebin_v5.c
@@ -234,7 +234,7 @@ RecycleBin5_RecycleBin5_DeleteFile(
         return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
     }
 
-    hFile = CreateFileW(szFullName, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+    hFile = CreateFileW(szFullName, 0, 0, NULL, OPEN_EXISTING, (dwAttributes & 
FILE_ATTRIBUTE_DIRECTORY) ? FILE_FLAG_BACKUP_SEMANTICS : 0, NULL);
     if (hFile == INVALID_HANDLE_VALUE)
     {
         hr = HRESULT_FROM_WIN32(GetLastError());
diff --git a/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.c 
b/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.c
index 7e5814af174..bbe4fa1e834 100644
--- a/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.c
+++ b/dll/win32/shell32/shellrecyclebin/recyclebin_v5_enumerator.c
@@ -3,7 +3,7 @@
  * LICENSE:     GPL v2 - See COPYING in the top level directory
  * FILE:        lib/recyclebin/recyclebin_v5_enumerator.c
  * PURPOSE:     Enumerates contents of a MS Windows 2000/XP/2003 recyclebin
- * PROGRAMMERS: Copyright 2006-2007 Herv� Poussineau ([email protected])
+ * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau ([email protected])
  */
 
 #include "recyclebin_private.h"
@@ -210,6 +210,43 @@ RecycleBin5File_RecycleBinFile_GetFileName(
     return S_OK;
 }
 
+static HRESULT STDMETHODCALLTYPE
+RecycleBin5File_RecycleBinFile_GetTypeName(
+    IN IRecycleBinFile *This,
+    IN SIZE_T BufferSize,
+    IN OUT LPWSTR Buffer,
+    OUT SIZE_T *RequiredSize)
+{
+    HRESULT hr;
+
+    struct RecycleBin5File *s = CONTAINING_RECORD(This, struct 
RecycleBin5File, recycleBinFileImpl);
+    DWORD dwRequired;
+    DWORD dwAttributes;
+    SHFILEINFOW shFileInfo;
+
+    TRACE("(%p, %u, %p, %p)\n", This, BufferSize, Buffer, RequiredSize);
+
+    hr = RecycleBin5File_RecycleBinFile_GetAttributes(This, &dwAttributes);
+    if (!SUCCEEDED(hr))
+        return hr;
+
+    hr = SHGetFileInfoW(s->FullName, dwAttributes, &shFileInfo, 
sizeof(shFileInfo), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES);
+    if (!SUCCEEDED(hr))
+        return hr;
+
+    dwRequired = (DWORD)(wcslen(shFileInfo.szTypeName) + 1) * sizeof(WCHAR);
+    if (RequiredSize)
+        *RequiredSize = dwRequired;
+
+    if (BufferSize == 0 && !Buffer)
+        return S_OK;
+
+    if (BufferSize < dwRequired)
+        return E_OUTOFMEMORY;
+    CopyMemory(Buffer, shFileInfo.szTypeName, dwRequired);
+    return S_OK;
+}
+
 static HRESULT STDMETHODCALLTYPE
 RecycleBin5File_RecycleBinFile_Delete(
     IN IRecycleBinFile *This)
@@ -239,6 +276,7 @@ CONST_VTBL struct IRecycleBinFileVtbl RecycleBin5FileVtbl =
     RecycleBin5File_RecycleBinFile_GetPhysicalFileSize,
     RecycleBin5File_RecycleBinFile_GetAttributes,
     RecycleBin5File_RecycleBinFile_GetFileName,
+    RecycleBin5File_RecycleBinFile_GetTypeName,
     RecycleBin5File_RecycleBinFile_Delete,
     RecycleBin5File_RecycleBinFile_Restore,
 };

Reply via email to