https://git.reactos.org/?p=reactos.git;a=commitdiff;h=47f6745bcdfb833b0311e…
commit 47f6745bcdfb833b0311e052f04e6cd5634660eb
Author: Jesús Sanz del Rey <jesussanz2003(a)gmail.com>
AuthorDate: Tue Jan 11 00:40:25 2022 +0100
Commit: GitHub <noreply(a)github.com>
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 (hpoussin(a)reactos.org)
+ * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin(a)reactos.org)
*/
#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 (hpoussin(a)reactos.org)
+ * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin(a)reactos.org)
*/
#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,
};