[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.
This commit is contained in:
Jesús Sanz del Rey 2022-01-11 00:40:25 +01:00 committed by GitHub
parent dae6035b3b
commit 47f6745bcd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 100 additions and 21 deletions

View file

@ -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 )))
{
/* load localized file string */
szTypeName[0] = '\0';
if(LoadStringW(shell32_hInstance, IDS_ANY_FILE, szTypeName, _countof(szTypeName)))
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 */
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;
}

View file

@ -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,

View file

@ -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) \

View file

@ -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());

View file

@ -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,
};