Commit 289e469e authored by Mikołaj Zalewski's avatar Mikołaj Zalewski Committed by Alexandre Julliard

shell32: Add a Trash virtual folder.

parent f0d6cba3
......@@ -27,6 +27,7 @@ C_SRCS = \
folders.c \
iconcache.c \
pidl.c \
recyclebin.c \
regsvr.c \
shell32_main.c \
shelllink.c \
......
......@@ -660,6 +660,16 @@ static struct regsvr_coclass const coclass_list[] = {
SFGAO_FILESYSANCESTOR|SFGAO_FOLDER|SFGAO_HASSUBFOLDER,
SFGAO_FILESYSTEM
},
{ &CLSID_RecycleBin,
"Trash",
IDS_RECYCLEBIN_FOLDER_NAME,
NULL,
"shell32.dll",
"Apartment",
SHELLFOLDER_ATTRIBUTES,
SFGAO_FOLDER|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET,
0
},
{ NULL } /* list terminator */
};
......@@ -677,6 +687,7 @@ static struct regsvr_interface const interface_list[] = {
static const WCHAR wszDesktop[] = { 'D','e','s','k','t','o','p',0 };
static const WCHAR wszSlash[] = { '/', 0 };
static const WCHAR wszMyDocuments[] = { 'M','y',' ','D','o','c','u','m','e','n','t','s', 0 };
static const WCHAR wszRecycleBin[] = { 'T','r','a','s','h', 0 };
static struct regsvr_namespace const namespace_extensions_list[] = {
{
......@@ -689,6 +700,11 @@ static struct regsvr_namespace const namespace_extensions_list[] = {
wszDesktop,
wszMyDocuments
},
{
&CLSID_RecycleBin,
wszDesktop,
wszRecycleBin
},
{ NULL }
};
......
......@@ -145,10 +145,13 @@ STRINGTABLE DISCARDABLE
IDS_SHV_COLUMN9 "Comments"
IDS_SHV_COLUMN10 "Owner"
IDS_SHV_COLUMN11 "Group"
IDS_SHV_COLUMN_DELFROM "Original location"
IDS_SHV_COLUMN_DELDATE "Date deleted"
/* special folders */
IDS_DESKTOP "Desktop"
IDS_MYCOMPUTER "My Computer"
IDS_RECYCLEBIN_FOLDER_NAME "Trash"
/* context menus */
IDS_VIEW_LARGE "Lar&ge Icons"
......
......@@ -97,6 +97,7 @@ HRESULT WINAPI UnixFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID
HRESULT WINAPI UnixDosFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
HRESULT WINAPI FolderShortcut_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
HRESULT WINAPI MyDocuments_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
HRESULT WINAPI RecycleBin_Constructor(IUnknown * pUnkOuter, REFIID riif, LPVOID *ppv);
HRESULT WINAPI ShellFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
extern HRESULT CPanel_GetIconLocationW(LPITEMIDLIST, LPWSTR, UINT, int*);
HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
......
......@@ -74,6 +74,7 @@ static const struct {
{&CLSID_UnixDosFolder, &UnixDosFolder_Constructor},
{&CLSID_FolderShortcut, &FolderShortcut_Constructor},
{&CLSID_MyDocuments, &MyDocuments_Constructor},
{&CLSID_RecycleBin, &RecycleBin_Constructor},
{NULL,NULL}
};
......
......@@ -33,6 +33,8 @@
#define IDS_SHV_COLUMN9 15
#define IDS_SHV_COLUMN10 16
#define IDS_SHV_COLUMN11 17
#define IDS_SHV_COLUMN_DELFROM 18
#define IDS_SHV_COLUMN_DELDATE 19
#define IDS_DESKTOP 20
#define IDS_MYCOMPUTER 21
......@@ -91,6 +93,9 @@
#define IDS_TRASHMULTIPLE_TEXT 139
#define IDS_CANTTRASH_TEXT 140
/* Note: this string is referenced from the registry*/
#define IDS_RECYCLEBIN_FOLDER_NAME 8964
/* browse for folder dialog box */
#define IDD_STATUS 0x3743
#define IDD_TITLE 0x3742
......
......@@ -306,3 +306,80 @@ BOOL TRASH_TrashFile(LPCWSTR wszPath)
HeapFree(GetProcessHeap(), 0, unix_path);
return result;
}
/*
* The item ID of a trashed element is built as follows:
* NUL byte - in most PIDLs the first byte is the type so we keep it constant
* WIN32_FIND_DATAW structure - with data about original file attributes
* bucket name - currently only an empty string meaning the home bucket is supported
* trash file name - a NUL-terminated string
*/
struct tagTRASH_ELEMENT
{
TRASH_BUCKET *bucket;
LPSTR filename;
};
static HRESULT TRASH_CreateSimplePIDL(const TRASH_ELEMENT *element, const WIN32_FIND_DATAW *data, LPITEMIDLIST *pidlOut)
{
LPITEMIDLIST pidl = SHAlloc(2+1+sizeof(WIN32_FIND_DATAW)+1+lstrlenA(element->filename)+1+2);
*pidlOut = NULL;
if (pidl == NULL)
return E_OUTOFMEMORY;
pidl->mkid.cb = (USHORT)(2+1+sizeof(WIN32_FIND_DATAW)+1+lstrlenA(element->filename)+1);
pidl->mkid.abID[0] = 0;
memcpy(pidl->mkid.abID+1, data, sizeof(WIN32_FIND_DATAW));
pidl->mkid.abID[1+sizeof(WIN32_FIND_DATAW)] = 0;
lstrcpyA((LPSTR)(pidl->mkid.abID+1+sizeof(WIN32_FIND_DATAW)+1), element->filename);
*(USHORT *)(pidl->mkid.abID+1+sizeof(WIN32_FIND_DATAW)+1+lstrlenA(element->filename)+1) = 0;
*pidlOut = pidl;
return S_OK;
}
/***********************************************************************
* TRASH_UnpackItemID [Internal]
*
* DESCRITION:
* Extract the information stored in an Item ID. The TRASH_ELEMENT
* identifies the element in the Trash. The WIN32_FIND_DATA contains the
* information about the original file. The data->ftLastAccessTime contains
* the deletion time
*
* PARAMETER(S):
* [I] id : the ID of the item
* [O] element : the trash element this item id contains. Can be NULL if not needed
* [O] data : the WIN32_FIND_DATA of the original file. Can be NULL is not needed
*/
HRESULT TRASH_UnpackItemID(LPCSHITEMID id, TRASH_ELEMENT *element, WIN32_FIND_DATAW *data)
{
if (id->cb < 2+1+sizeof(WIN32_FIND_DATAW)+2)
return E_INVALIDARG;
if (id->abID[0] != 0 || id->abID[1+sizeof(WIN32_FIND_DATAW)] != 0)
return E_INVALIDARG;
if (memchr(id->abID+1+sizeof(WIN32_FIND_DATAW)+1, 0, id->cb-(2+1+sizeof(WIN32_FIND_DATAW)+1)) == NULL)
return E_INVALIDARG;
if (data != NULL)
*data = *(WIN32_FIND_DATAW *)(id->abID+1);
if (element != NULL)
{
element->bucket = home_trash;
element->filename = StrDupA((LPCSTR)(id->abID+1+sizeof(WIN32_FIND_DATAW)+1));
if (element->filename == NULL)
return E_OUTOFMEMORY;
}
return S_OK;
}
void TRASH_DisposeElement(TRASH_ELEMENT *element)
{
if (element)
SHFree(element->filename);
}
HRESULT TRASH_EnumItems(LPITEMIDLIST **pidls, int *count)
{
*count = 0;
*pidls = SHAlloc(0);
return S_OK;
}
......@@ -33,7 +33,13 @@ int XDG_MakeDirs(const char *path);
BOOL XDG_WriteDesktopStringEntry(int fd, const char *keyName, DWORD dwFlags, const char *value);
/* implemented in trash.c */
typedef struct tagTRASH_ELEMENT TRASH_ELEMENT;
BOOL TRASH_CanTrashFile(LPCWSTR wszPath);
BOOL TRASH_TrashFile(LPCWSTR wszPath);
HRESULT TRASH_UnpackItemID(LPCSHITEMID id, TRASH_ELEMENT *element, WIN32_FIND_DATAW *data);
HRESULT TRASH_EnumItems(LPITEMIDLIST **pidls, int *count);
void TRASH_DisposeElement(TRASH_ELEMENT *element);
#endif /* ndef __XDG_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment