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