shell32: Implement restoring items from the recycle bin.
This commit is contained in:
parent
4dd99dcc55
commit
80c62ca203
|
@ -186,6 +186,52 @@ static void DoErase(RecycleBinMenu *This)
|
||||||
ISFHelper_DeleteItems(helper,This->cidl,(LPCITEMIDLIST*)This->apidl);
|
ISFHelper_DeleteItems(helper,This->cidl,(LPCITEMIDLIST*)This->apidl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DoRestore(RecycleBinMenu *This)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*TODO add prompts*/
|
||||||
|
UINT i;
|
||||||
|
for(i=0;i<This->cidl;i++)
|
||||||
|
{
|
||||||
|
WIN32_FIND_DATAW data;
|
||||||
|
TRASH_UnpackItemID(&((This->apidl[i])->mkid),&data);
|
||||||
|
if(PathFileExistsW(data.cFileName))
|
||||||
|
{
|
||||||
|
PIDLIST_ABSOLUTE dest_pidl = ILCreateFromPathW(data.cFileName);
|
||||||
|
WCHAR message[100];
|
||||||
|
WCHAR caption[50];
|
||||||
|
if(_ILIsFolder(ILFindLastID(dest_pidl)))
|
||||||
|
LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_OVERWRITEFOLDER,
|
||||||
|
message,sizeof(message)/sizeof(WCHAR));
|
||||||
|
else
|
||||||
|
LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_OVERWRITEFILE,
|
||||||
|
message,sizeof(message)/sizeof(WCHAR));
|
||||||
|
LoadStringW(shell32_hInstance,IDS_RECYCLEBIN_OVERWRITE_CAPTION,
|
||||||
|
caption,sizeof(caption)/sizeof(WCHAR));
|
||||||
|
|
||||||
|
if(ShellMessageBoxW(shell32_hInstance,GetActiveWindow(),message,
|
||||||
|
caption,MB_YESNO|MB_ICONEXCLAMATION,
|
||||||
|
data.cFileName)!=IDYES)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(SUCCEEDED(TRASH_RestoreItem(This->apidl[i])))
|
||||||
|
{
|
||||||
|
IPersistFolder2 *persist;
|
||||||
|
LPITEMIDLIST root_pidl;
|
||||||
|
PIDLIST_ABSOLUTE dest_pidl = ILCreateFromPathW(data.cFileName);
|
||||||
|
BOOL is_folder = _ILIsFolder(ILFindLastID(dest_pidl));
|
||||||
|
IShellFolder2_QueryInterface(This->folder,&IID_IPersistFolder2,
|
||||||
|
(void**)&persist);
|
||||||
|
IPersistFolder2_GetCurFolder(persist,&root_pidl);
|
||||||
|
SHChangeNotify(is_folder ? SHCNE_RMDIR : SHCNE_DELETE,
|
||||||
|
SHCNF_IDLIST,ILCombine(root_pidl,This->apidl[i]),0);
|
||||||
|
SHChangeNotify(is_folder ? SHCNE_MKDIR : SHCNE_CREATE,
|
||||||
|
SHCNF_IDLIST,dest_pidl,0);
|
||||||
|
ILFree(dest_pidl);
|
||||||
|
ILFree(root_pidl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI RecycleBinMenu_InvokeCommand(IContextMenu2 *iface,
|
static HRESULT WINAPI RecycleBinMenu_InvokeCommand(IContextMenu2 *iface,
|
||||||
LPCMINVOKECOMMANDINFO pici)
|
LPCMINVOKECOMMANDINFO pici)
|
||||||
|
@ -199,6 +245,9 @@ static HRESULT WINAPI RecycleBinMenu_InvokeCommand(IContextMenu2 *iface,
|
||||||
case IDM_RECYCLEBIN_ERASE:
|
case IDM_RECYCLEBIN_ERASE:
|
||||||
DoErase(This);
|
DoErase(This);
|
||||||
break;
|
break;
|
||||||
|
case IDM_RECYCLEBIN_RESTORE:
|
||||||
|
DoRestore(This);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -544,6 +544,39 @@ failed:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT TRASH_RestoreItem(LPCITEMIDLIST pidl){
|
||||||
|
int suffix_length = strlen(trashinfo_suffix);
|
||||||
|
LPCSHITEMID id = &(pidl->mkid);
|
||||||
|
const char *bucket_name = (const char*)(id->abID+1+sizeof(WIN32_FIND_DATAW));
|
||||||
|
const char *filename = (const char*)(id->abID+1+sizeof(WIN32_FIND_DATAW)+strlen(bucket_name)+1);
|
||||||
|
char *restore_path;
|
||||||
|
WIN32_FIND_DATAW data;
|
||||||
|
char *file_path;
|
||||||
|
|
||||||
|
TRACE("(%p)",pidl);
|
||||||
|
if(strcmp(filename+strlen(filename)-suffix_length,trashinfo_suffix))
|
||||||
|
{
|
||||||
|
ERR("pidl at %p is not a valid recycle bin entry",pidl);
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
TRASH_UnpackItemID(id,&data);
|
||||||
|
restore_path = wine_get_unix_file_name(data.cFileName);
|
||||||
|
file_path = SHAlloc(max(strlen(home_trash->files_dir),strlen(home_trash->info_dir))+strlen(filename)+1);
|
||||||
|
sprintf(file_path,"%s%s",home_trash->files_dir,filename);
|
||||||
|
file_path[strlen(home_trash->files_dir)+strlen(filename)-suffix_length] = '\0';
|
||||||
|
if(!rename(file_path,restore_path))
|
||||||
|
{
|
||||||
|
sprintf(file_path,"%s%s",home_trash->info_dir,filename);
|
||||||
|
if(unlink(file_path))
|
||||||
|
WARN("failed to delete the trashinfo file %s",filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
WARN("could not erase %s from the trash (errno=%i)\n",filename,errno);
|
||||||
|
SHFree(file_path);
|
||||||
|
HeapFree(GetProcessHeap(), 0, restore_path);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT TRASH_EraseItem(LPCITEMIDLIST pidl)
|
HRESULT TRASH_EraseItem(LPCITEMIDLIST pidl)
|
||||||
{
|
{
|
||||||
int suffix_length = strlen(trashinfo_suffix);
|
int suffix_length = strlen(trashinfo_suffix);
|
||||||
|
|
|
@ -41,6 +41,7 @@ BOOL TRASH_CanTrashFile(LPCWSTR wszPath) DECLSPEC_HIDDEN;
|
||||||
BOOL TRASH_TrashFile(LPCWSTR wszPath) DECLSPEC_HIDDEN;
|
BOOL TRASH_TrashFile(LPCWSTR wszPath) DECLSPEC_HIDDEN;
|
||||||
HRESULT TRASH_UnpackItemID(LPCSHITEMID id, WIN32_FIND_DATAW *data) DECLSPEC_HIDDEN;
|
HRESULT TRASH_UnpackItemID(LPCSHITEMID id, WIN32_FIND_DATAW *data) DECLSPEC_HIDDEN;
|
||||||
HRESULT TRASH_EnumItems(LPITEMIDLIST **pidls, int *count) DECLSPEC_HIDDEN;
|
HRESULT TRASH_EnumItems(LPITEMIDLIST **pidls, int *count) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT TRASH_RestoreItem(LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;
|
||||||
HRESULT TRASH_EraseItem(LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;
|
HRESULT TRASH_EraseItem(LPCITEMIDLIST pidl) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT XDG_UserDirLookup(const char * const *xdg_dirs, const unsigned int num_dirs, char *** out_ptr) DECLSPEC_HIDDEN;
|
HRESULT XDG_UserDirLookup(const char * const *xdg_dirs, const unsigned int num_dirs, char *** out_ptr) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue