shell32: Allow overwriting files in SHFileOperation(FO_COPY) (with confirmation dialogs).
This commit is contained in:
parent
c55277c7e1
commit
33ee219ce3
|
@ -165,8 +165,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_DELETEITEM_TEXT "Наистина ли искате да изтриете '%1'?"
|
||||
IDS_DELETEMULTIPLE_TEXT "Наистина ли искате да изтриете тези %1 елемента?"
|
||||
IDS_DELETESELECTED_TEXT "Наистина ли искате да изтриете избраните елементи?"
|
||||
IDS_OVERWRITEFILE_TEXT "Наистина ли искате да презапишете %1?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Потвърдете презаписа на файла"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Рестартиране"
|
||||
|
|
|
@ -163,10 +163,14 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_CREATEFOLDER_CAPTION "Chyba pøi pokusu vytvoøit nový adresáø"
|
||||
IDS_DELETEITEM_CAPTION "Potvrdit odstranìní souboru"
|
||||
IDS_DELETEFOLDER_CAPTION "Potvrdit odstranìní adresáøe"
|
||||
IDS_OVERWRITEFILE_CAPTION "Potvrdit přepsání souboru"
|
||||
IDS_DELETEITEM_TEXT "Opravdu chcete odstranit '%1'?"
|
||||
IDS_DELETEMULTIPLE_TEXT "Opravdu chcete odstranit tìchto %1 položek?"
|
||||
IDS_OVERWRITEFILE_TEXT "Přejete si přepsat soubor '%1'?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Potvrdit pøepsání souboru"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
}
|
||||
|
||||
/* columns in the shellview */
|
||||
|
|
|
@ -173,8 +173,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_TRASHFOLDER_TEXT "Sind Sie sich sicher, dass Sie '%1' und seinen Inhalt in den Müll verschieben möchten?"
|
||||
IDS_TRASHMULTIPLE_TEXT "Sind Sie sich sicher, dass Sie diese %1 Dateien in den Müll verschieben möchten?"
|
||||
IDS_CANTTRASH_TEXT "Das Objekt '%1' kann nicht in den Müll verschoben werden. Möchten Sie es stattdessen löschen?"
|
||||
IDS_OVERWRITEFILE_TEXT "Möchten Sie, dass die Datei '%1' überschrieben wird ?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Bestätigung: Datei überschreiben"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Neustarten"
|
||||
|
|
|
@ -185,8 +185,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_TRASHFOLDER_TEXT "Are you sure that you want to send '%1' and all it's content to the Trash?"
|
||||
IDS_TRASHMULTIPLE_TEXT "Are you sure that you want to send these %1 items to the Trash?"
|
||||
IDS_CANTTRASH_TEXT "The item '%1' can't be sent to Trash. Do you want to delete it instead?"
|
||||
IDS_OVERWRITEFILE_TEXT "OverWrite File %1?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Confirm File OverWrite"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Confirm file overwrite"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Restart"
|
||||
|
|
|
@ -163,8 +163,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_DELETEFOLDER_CAPTION "Konfirmu forigon de dosierujo"
|
||||
IDS_DELETEITEM_TEXT "Æu vi estas certa pri forigo de '%1'?"
|
||||
IDS_DELETEMULTIPLE_TEXT "Æu vi estas certa pri forigo de æi tiuj %1 komponantoj?"
|
||||
IDS_OVERWRITEFILE_TEXT "Æu vi supreskribas la dosieron %1?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Konfirmu supreskribiton de dosieron"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
}
|
||||
|
||||
/* columns in the shellview */
|
||||
|
@ -222,4 +226,3 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_COMMON_VIDEO "Documents\\Video"
|
||||
IDS_CDBURN_AREA "Local Settings\\Application Data\\Microsoft\\CD Burning"
|
||||
}
|
||||
|
||||
|
|
|
@ -162,8 +162,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_DELETEFOLDER_CAPTION "Confirmar eliminación de carpeta"
|
||||
IDS_DELETEITEM_TEXT "¿Seguro que desea eliminar '%1'?"
|
||||
IDS_DELETEMULTIPLE_TEXT "¿Seguro que desea eliminar estos %1 elementos?"
|
||||
IDS_OVERWRITEFILE_TEXT "¿Sobreescribir el archivo '%1'?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Confirmar sobreescritura de archivo"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
}
|
||||
|
||||
/* columns in the shellview */
|
||||
|
|
|
@ -164,8 +164,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_DELETEFOLDER_CAPTION "Vahvista kansion tuhoaminen"
|
||||
IDS_DELETEITEM_TEXT "Haluatko varmasti tuhota '%1':n?"
|
||||
IDS_DELETEMULTIPLE_TEXT "Haluatko varmasti tuhota nämä %1?"
|
||||
IDS_OVERWRITEFILE_TEXT "Ylikirjoita tiedosto %1?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Vahvista tiedoston ylikirjoitus"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Käynnistä uudelleen"
|
||||
|
|
|
@ -176,8 +176,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_TRASHFOLDER_TEXT "Êtes-vous sûr de vouloir mettre « %1 » et tout ce qu'il contient dans la corbeille ?"
|
||||
IDS_TRASHMULTIPLE_TEXT "Êtes-vous sûr de vouloir mettre ces %1 éléments dans la corbeille ?"
|
||||
IDS_CANTTRASH_TEXT "L'élément « %1 » ne peut pas être mis dans la corbeille. Souhaitez-vous le supprimer à la place ?"
|
||||
IDS_OVERWRITEFILE_TEXT "Écraser le fichier %1 ?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Confirmer l'écrasement du fichier"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Redémarrer"
|
||||
|
|
|
@ -164,8 +164,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_DELETEFOLDER_CAPTION "Confermare la cancellazione della cartella"
|
||||
IDS_DELETEITEM_TEXT "Sei sicuro di voler cancellare '%1'?"
|
||||
IDS_DELETEMULTIPLE_TEXT "Sei sicuro di voler cancellare questi %1 elementi?"
|
||||
IDS_OVERWRITEFILE_TEXT "Sovrascrivere il File %1?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Confermare la sovrascrizione del File"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Riavvia"
|
||||
|
|
|
@ -173,8 +173,12 @@ IDS_TRASHITEM_TEXT "
|
|||
IDS_TRASHFOLDER_TEXT "당신은 '%1' 과 그 안의 내용을 휴지통으로 보내기를 바랍니까?"
|
||||
IDS_TRASHMULTIPLE_TEXT "당신은 '%1' 들을(를) 휴지통으로 보내기를 바랍니까?"
|
||||
IDS_CANTTRASH_TEXT "The item '%1' can't be sent to Trash. Do you want to delete it instead?"
|
||||
IDS_OVERWRITEFILE_TEXT "파일 %1을 덮어쓰겠습니까?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "파일 덮어쓰기 확인"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "다시 시작"
|
||||
|
|
|
@ -172,8 +172,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_TRASHFOLDER_TEXT "Virkelig legge «%1» og alt innholdet i papirkurven?"
|
||||
IDS_TRASHMULTIPLE_TEXT "Virkelig legge disse %1 valgte elementene i papirkurven?"
|
||||
IDS_CANTTRASH_TEXT "Elementet «%1» kan ikke legges i papirkurven. Vil du slette det i stedet?"
|
||||
IDS_OVERWRITEFILE_TEXT "Overskrive filen «%1»?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Bekreft overskriving av fil"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Starte på nytt"
|
||||
|
|
|
@ -173,8 +173,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_TRASHFOLDER_TEXT "Czy jesteś pewien, że chcesz umieścić folder '%1' i całą jego zawartość w koszu"
|
||||
IDS_TRASHMULTIPLE_TEXT "Elementów: %1 - czy na pewno chcesz je umieścić w Koszu?"
|
||||
IDS_CANTTRASH_TEXT "Nie mogę przenieść elementu '%1' do Kosza. Czy chcesz go zamiast tego usunąć?"
|
||||
IDS_OVERWRITEFILE_TEXT "Zast¹piæ plik %1?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Potwierdź zastąpienie pliku"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Uruchom ponownie"
|
||||
|
|
|
@ -256,8 +256,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_DELETEFOLDER_CAPTION "Confirmar exclusão de pasta"
|
||||
IDS_DELETEITEM_TEXT "Você tem certeza que deseja excluir '%1'?"
|
||||
IDS_DELETEMULTIPLE_TEXT "Você tem certeza que deseja excluir estes %1 itens?"
|
||||
IDS_OVERWRITEFILE_TEXT "Sobreescrever arquivo %1?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Confirmar sobreescrever arquivo"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Reiniciar"
|
||||
|
|
|
@ -165,8 +165,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_DELETEFOLDER_CAPTION "Подтверждение удаления папки"
|
||||
IDS_DELETEITEM_TEXT "Удалить '%1'?"
|
||||
IDS_DELETEMULTIPLE_TEXT "Удалить эти обьекты (%1?"
|
||||
IDS_OVERWRITEFILE_TEXT "Заменить файл(ы) %1?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Подтверждение замены файла"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Перезагрузить"
|
||||
|
|
|
@ -172,8 +172,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_TRASHFOLDER_TEXT "'%1' adlı öğeyi ve tüm içeriğini çöpe göndermek istediğinizden emin misiniz?"
|
||||
IDS_TRASHMULTIPLE_TEXT "Bu %1 öğeyi çöpe göndermek istediğinizden emin misiniz?"
|
||||
IDS_CANTTRASH_TEXT "'%1' adlı öğe çöpe gönderilemiyor. Tamamen silmek ister misiniz?"
|
||||
IDS_OVERWRITEFILE_TEXT "%1 dosyasının üzerine yazmak istiyor musunuz?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "Dosya Üzerine Yazmayı Onayla"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
|
||||
/* message box strings */
|
||||
IDS_RESTART_TITLE "Yeniden Başlat"
|
||||
|
|
|
@ -161,8 +161,12 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_DELETEFOLDER_CAPTION "ϳäòâåðäæåííÿ âèëó÷åííÿ òåêè"
|
||||
IDS_DELETEITEM_TEXT "Âè âïåâíåí³, ùî õî÷åòå âèëó÷èòè '%1'?"
|
||||
IDS_DELETEMULTIPLE_TEXT "Âè âïåâíåí³, ùî õî÷åòå âèëó÷èòè ö³ %1 åëåìåíòè(³â)?"
|
||||
IDS_OVERWRITEFILE_TEXT "Ïåðåïèñàòè Ôàéë %1?"
|
||||
IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?"
|
||||
IDS_OVERWRITEFILE_CAPTION "ϳäòâåðäæåííÿ Ïåðåçàïèñó Ôàéëó"
|
||||
IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\
|
||||
"If the files in the destination folder have the same names as files in the\n"\
|
||||
"selected folder they will be replaced. Do you still want to move or copy\n"\
|
||||
"the folder?"
|
||||
}
|
||||
|
||||
/* columns in the shellview */
|
||||
|
|
|
@ -153,9 +153,10 @@ void FreeChangeNotifications(void);
|
|||
#define ASK_TRASH_FOLDER 8
|
||||
#define ASK_TRASH_MULTIPLE_ITEM 9
|
||||
#define ASK_CANT_TRASH_ITEM 10
|
||||
#define ASK_OVERWRITE_FOLDER 11
|
||||
|
||||
BOOL SHELL_DeleteDirectoryW(HWND hwnd, LPCWSTR pwszDir, BOOL bShowUI);
|
||||
BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir);
|
||||
BOOL SHELL_ConfirmYesNoW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir);
|
||||
|
||||
/* 16-bit functions */
|
||||
void WINAPI DragAcceptFiles16(HWND16 hWnd, BOOL16 b);
|
||||
|
|
|
@ -1829,7 +1829,7 @@ static HRESULT UNIXFS_delete_with_syscalls(UnixFolder *This, UINT cidl, LPCITEMI
|
|||
static const WCHAR empty[] = {0};
|
||||
int i;
|
||||
|
||||
if (!SHELL_ConfirmDialogW(GetActiveWindow(), ASK_DELETE_SELECTED, empty))
|
||||
if (!SHELL_ConfirmYesNoW(GetActiveWindow(), ASK_DELETE_SELECTED, empty))
|
||||
return S_OK;
|
||||
|
||||
lstrcpyA(szAbsolute, This->m_pszPath);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
@ -65,6 +66,14 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest);
|
|||
static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists);
|
||||
static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SHFILEOPSTRUCTW *req;
|
||||
DWORD dwYesToAllMask;
|
||||
BOOL bManyItems;
|
||||
BOOL bCancelled;
|
||||
} FILE_OPERATION;
|
||||
|
||||
/* Confirm dialogs with an optional "Yes To All" as used in file operations confirmations
|
||||
*/
|
||||
static const WCHAR CONFIRM_MSG_PROP[] = {'W','I','N','E','_','C','O','N','F','I','R','M',0};
|
||||
|
@ -251,21 +260,31 @@ static BOOL SHELL_ConfirmIDs(int nKindOfDialog, SHELL_ConfirmIDstruc *ids)
|
|||
ids->caption_resource_id = IDS_OVERWRITEFILE_CAPTION;
|
||||
ids->text_resource_id = IDS_OVERWRITEFILE_TEXT;
|
||||
return TRUE;
|
||||
case ASK_OVERWRITE_FOLDER:
|
||||
ids->hIconInstance = NULL;
|
||||
ids->icon_resource_id = IDI_WARNING;
|
||||
ids->caption_resource_id = IDS_OVERWRITEFILE_CAPTION;
|
||||
ids->text_resource_id = IDS_OVERWRITEFOLDER_TEXT;
|
||||
return TRUE;
|
||||
default:
|
||||
FIXME(" Unhandled nKindOfDialog %d stub\n", nKindOfDialog);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir)
|
||||
static BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir, FILE_OPERATION *op)
|
||||
{
|
||||
WCHAR szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
|
||||
SHELL_ConfirmIDstruc ids;
|
||||
DWORD_PTR args[1];
|
||||
HICON hIcon;
|
||||
int ret;
|
||||
|
||||
if (!SHELL_ConfirmIDs(nKindOfDialog, &ids))
|
||||
return FALSE;
|
||||
assert(nKindOfDialog >= 0 && nKindOfDialog < 32);
|
||||
if (op && (op->dwYesToAllMask & (1 << nKindOfDialog)))
|
||||
return IDYES;
|
||||
|
||||
assert(SHELL_ConfirmIDs(nKindOfDialog, &ids));
|
||||
|
||||
LoadStringW(shell32_hInstance, ids.caption_resource_id, szCaption, sizeof(szCaption)/sizeof(WCHAR));
|
||||
LoadStringW(shell32_hInstance, ids.text_resource_id, szText, sizeof(szText)/sizeof(WCHAR));
|
||||
|
@ -275,7 +294,23 @@ BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir)
|
|||
szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)args);
|
||||
hIcon = LoadIconW(ids.hIconInstance, (LPWSTR)MAKEINTRESOURCE(ids.icon_resource_id));
|
||||
|
||||
return (IDYES == SHELL_ConfirmMsgBox(hWnd, szBuffer, szCaption, hIcon, FALSE));
|
||||
ret = SHELL_ConfirmMsgBox(hWnd, szBuffer, szCaption, hIcon, op && op->bManyItems);
|
||||
if (op) {
|
||||
if (ret == IDD_YESTOALL) {
|
||||
op->dwYesToAllMask |= (1 << nKindOfDialog);
|
||||
ret = IDYES;
|
||||
}
|
||||
if (ret == IDCANCEL)
|
||||
op->bCancelled = TRUE;
|
||||
if (ret != IDYES)
|
||||
op->req->fAnyOperationsAborted = TRUE;
|
||||
}
|
||||
return ret == IDYES;
|
||||
}
|
||||
|
||||
BOOL SHELL_ConfirmYesNoW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir)
|
||||
{
|
||||
return SHELL_ConfirmDialogW(hWnd, nKindOfDialog, szDir, NULL);
|
||||
}
|
||||
|
||||
static DWORD SHELL32_AnsiToUnicodeBuf(LPCSTR aPath, LPWSTR *wPath, DWORD minChars)
|
||||
|
@ -324,7 +359,7 @@ BOOL SHELL_DeleteDirectoryW(HWND hwnd, LPCWSTR pszDir, BOOL bShowUI)
|
|||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
if (!bShowUI || (ret = SHELL_ConfirmDialogW(hwnd, ASK_DELETE_FOLDER, pszDir)))
|
||||
if (!bShowUI || (ret = SHELL_ConfirmDialogW(hwnd, ASK_DELETE_FOLDER, pszDir, NULL)))
|
||||
{
|
||||
do
|
||||
{
|
||||
|
@ -1047,7 +1082,7 @@ static void destroy_file_list(FILE_LIST *flList)
|
|||
HeapFree(GetProcessHeap(), 0, flList->feFiles);
|
||||
}
|
||||
|
||||
static void copy_dir_to_dir(LPSHFILEOPSTRUCTW lpFileOp, FILE_ENTRY *feFrom, LPWSTR szDestPath)
|
||||
static void copy_dir_to_dir(FILE_OPERATION *op, FILE_ENTRY *feFrom, LPWSTR szDestPath)
|
||||
{
|
||||
WCHAR szFrom[MAX_PATH], szTo[MAX_PATH];
|
||||
SHFILEOPSTRUCTW fileOp;
|
||||
|
@ -1062,22 +1097,48 @@ static void copy_dir_to_dir(LPSHFILEOPSTRUCTW lpFileOp, FILE_ENTRY *feFrom, LPWS
|
|||
else
|
||||
lstrcpyW(szTo, szDestPath);
|
||||
|
||||
if (!(op->req->fFlags & FOF_NOCONFIRMATION) && PathFileExistsW(szTo)) {
|
||||
if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FOLDER, feFrom->szFilename, op))
|
||||
{
|
||||
/* Vista returns an ERROR_CANCELLED even if user pressed "No" */
|
||||
if (!op->bManyItems)
|
||||
op->bCancelled = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
szTo[lstrlenW(szTo) + 1] = '\0';
|
||||
SHNotifyCreateDirectoryW(szTo, NULL);
|
||||
|
||||
PathCombineW(szFrom, feFrom->szFullPath, wildCardFiles);
|
||||
szFrom[lstrlenW(szFrom) + 1] = '\0';
|
||||
|
||||
memcpy(&fileOp, lpFileOp, sizeof(fileOp));
|
||||
memcpy(&fileOp, op->req, sizeof(fileOp));
|
||||
fileOp.pFrom = szFrom;
|
||||
fileOp.pTo = szTo;
|
||||
fileOp.fFlags &= ~FOF_MULTIDESTFILES; /* we know we're copying to one dir */
|
||||
|
||||
/* Don't ask the user about overwriting files when he accepted to overwrite the
|
||||
folder. FIXME: this is not exactly what Windows does - e.g. there would be
|
||||
an additional confirmation for a nested folder */
|
||||
fileOp.fFlags |= FOF_NOCONFIRMATION;
|
||||
|
||||
SHFileOperationW(&fileOp);
|
||||
}
|
||||
|
||||
static BOOL copy_file_to_file(FILE_OPERATION *op, WCHAR *szFrom, WCHAR *szTo)
|
||||
{
|
||||
if (!(op->req->fFlags & FOF_NOCONFIRMATION) && PathFileExistsW(szTo))
|
||||
{
|
||||
if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FILE, PathFindFileNameW(szTo), op))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SHNotifyCopyFileW(szFrom, szTo, FALSE) == 0;
|
||||
}
|
||||
|
||||
/* copy a file or directory to another directory */
|
||||
static void copy_to_dir(LPSHFILEOPSTRUCTW lpFileOp, FILE_ENTRY *feFrom, FILE_ENTRY *feTo)
|
||||
static void copy_to_dir(FILE_OPERATION *op, FILE_ENTRY *feFrom, FILE_ENTRY *feTo)
|
||||
{
|
||||
if (!PathFileExistsW(feTo->szFullPath))
|
||||
SHNotifyCreateDirectoryW(feTo->szFullPath, NULL);
|
||||
|
@ -1087,10 +1148,10 @@ static void copy_to_dir(LPSHFILEOPSTRUCTW lpFileOp, FILE_ENTRY *feFrom, FILE_ENT
|
|||
WCHAR szDestPath[MAX_PATH];
|
||||
|
||||
PathCombineW(szDestPath, feTo->szFullPath, feFrom->szFilename);
|
||||
SHNotifyCopyFileW(feFrom->szFullPath, szDestPath, FALSE);
|
||||
copy_file_to_file(op, feFrom->szFullPath, szDestPath);
|
||||
}
|
||||
else if (!(lpFileOp->fFlags & FOF_FILESONLY && feFrom->bFromWildcard))
|
||||
copy_dir_to_dir(lpFileOp, feFrom, feTo->szFullPath);
|
||||
else if (!(op->req->fFlags & FOF_FILESONLY && feFrom->bFromWildcard))
|
||||
copy_dir_to_dir(op, feFrom, feTo->szFullPath);
|
||||
}
|
||||
|
||||
static void create_dest_dirs(LPWSTR szDestDir)
|
||||
|
@ -1113,7 +1174,7 @@ static void create_dest_dirs(LPWSTR szDestDir)
|
|||
}
|
||||
|
||||
/* the FO_COPY operation */
|
||||
static HRESULT copy_files(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LIST *flTo)
|
||||
static HRESULT copy_files(FILE_OPERATION *op, FILE_LIST *flFrom, FILE_LIST *flTo)
|
||||
{
|
||||
DWORD i;
|
||||
FILE_ENTRY *entryToCopy;
|
||||
|
@ -1123,13 +1184,13 @@ static HRESULT copy_files(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LI
|
|||
if (flFrom->bAnyDontExist)
|
||||
return ERROR_SHELL_INTERNAL_FILE_NOT_FOUND;
|
||||
|
||||
if (lpFileOp->fFlags & FOF_MULTIDESTFILES && flFrom->bAnyFromWildcard)
|
||||
if (op->req->fFlags & FOF_MULTIDESTFILES && flFrom->bAnyFromWildcard)
|
||||
return ERROR_CANCELLED;
|
||||
|
||||
if (!(lpFileOp->fFlags & FOF_MULTIDESTFILES) && flTo->dwNumFiles != 1)
|
||||
if (!(op->req->fFlags & FOF_MULTIDESTFILES) && flTo->dwNumFiles != 1)
|
||||
return ERROR_CANCELLED;
|
||||
|
||||
if (lpFileOp->fFlags & FOF_MULTIDESTFILES && flFrom->dwNumFiles != 1 &&
|
||||
if (op->req->fFlags & FOF_MULTIDESTFILES && flFrom->dwNumFiles != 1 &&
|
||||
flFrom->dwNumFiles != flTo->dwNumFiles)
|
||||
{
|
||||
return ERROR_CANCELLED;
|
||||
|
@ -1145,11 +1206,11 @@ static HRESULT copy_files(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LI
|
|||
if (flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1 && fileDest->bFromRelative &&
|
||||
!PathFileExistsW(fileDest->szFullPath))
|
||||
{
|
||||
lpFileOp->fAnyOperationsAborted = TRUE;
|
||||
op->req->fAnyOperationsAborted = TRUE;
|
||||
return ERROR_CANCELLED;
|
||||
}
|
||||
|
||||
if (!(lpFileOp->fFlags & FOF_MULTIDESTFILES) && flFrom->dwNumFiles != 1 &&
|
||||
if (!(op->req->fFlags & FOF_MULTIDESTFILES) && flFrom->dwNumFiles != 1 &&
|
||||
PathFileExistsW(fileDest->szFullPath) &&
|
||||
IsAttribFile(fileDest->attributes))
|
||||
{
|
||||
|
@ -1160,7 +1221,7 @@ static HRESULT copy_files(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LI
|
|||
{
|
||||
entryToCopy = &flFrom->feFiles[i];
|
||||
|
||||
if (lpFileOp->fFlags & FOF_MULTIDESTFILES)
|
||||
if (op->req->fFlags & FOF_MULTIDESTFILES)
|
||||
fileDest = &flTo->feFiles[i];
|
||||
|
||||
if (IsAttribDir(entryToCopy->attributes) &&
|
||||
|
@ -1185,22 +1246,28 @@ static HRESULT copy_files(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom, FILE_LI
|
|||
if ((flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1) ||
|
||||
(flFrom->dwNumFiles == 1 && IsAttribDir(fileDest->attributes)))
|
||||
{
|
||||
copy_to_dir(lpFileOp, entryToCopy, fileDest);
|
||||
copy_to_dir(op, entryToCopy, fileDest);
|
||||
}
|
||||
else if (IsAttribDir(entryToCopy->attributes))
|
||||
{
|
||||
copy_dir_to_dir(lpFileOp, entryToCopy, fileDest->szFullPath);
|
||||
copy_dir_to_dir(op, entryToCopy, fileDest->szFullPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SHNotifyCopyFileW(entryToCopy->szFullPath, fileDest->szFullPath, TRUE))
|
||||
if (!copy_file_to_file(op, entryToCopy->szFullPath, fileDest->szFullPath))
|
||||
{
|
||||
lpFileOp->fAnyOperationsAborted = TRUE;
|
||||
op->req->fAnyOperationsAborted = TRUE;
|
||||
return ERROR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Vista return code. XP would return e.g. ERROR_FILE_NOT_FOUND, ERROR_ALREADY_EXISTS */
|
||||
if (op->bCancelled)
|
||||
return ERROR_CANCELLED;
|
||||
}
|
||||
|
||||
/* Vista return code. On XP if the used pressed "No" for the last item,
|
||||
* ERROR_ARENA_TRASHED would be returned */
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1212,16 +1279,16 @@ static BOOL confirm_delete_list(HWND hWnd, DWORD fFlags, BOOL fTrash, FILE_LIST
|
|||
const WCHAR format[] = {'%','d',0};
|
||||
|
||||
wnsprintfW(tmp, sizeof(tmp)/sizeof(tmp[0]), format, flFrom->dwNumFiles);
|
||||
return SHELL_ConfirmDialogW(hWnd, (fTrash?ASK_TRASH_MULTIPLE_ITEM:ASK_DELETE_MULTIPLE_ITEM), tmp);
|
||||
return SHELL_ConfirmDialogW(hWnd, (fTrash?ASK_TRASH_MULTIPLE_ITEM:ASK_DELETE_MULTIPLE_ITEM), tmp, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE_ENTRY *fileEntry = &flFrom->feFiles[0];
|
||||
|
||||
if (IsAttribFile(fileEntry->attributes))
|
||||
return SHELL_ConfirmDialogW(hWnd, (fTrash?ASK_TRASH_FILE:ASK_DELETE_FILE), fileEntry->szFullPath);
|
||||
return SHELL_ConfirmDialogW(hWnd, (fTrash?ASK_TRASH_FILE:ASK_DELETE_FILE), fileEntry->szFullPath, NULL);
|
||||
else if (!(fFlags & FOF_FILESONLY && fileEntry->bFromWildcard))
|
||||
return SHELL_ConfirmDialogW(hWnd, (fTrash?ASK_TRASH_FOLDER:ASK_DELETE_FOLDER), fileEntry->szFullPath);
|
||||
return SHELL_ConfirmDialogW(hWnd, (fTrash?ASK_TRASH_FOLDER:ASK_DELETE_FOLDER), fileEntry->szFullPath, NULL);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1265,7 +1332,7 @@ static HRESULT delete_files(LPSHFILEOPSTRUCTW lpFileOp, FILE_LIST *flFrom)
|
|||
|
||||
/* Note: Windows silently deletes the file in such a situation, we show a dialog */
|
||||
if (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_WANTNUKEWARNING))
|
||||
bDelete = SHELL_ConfirmDialogW(lpFileOp->hwnd, ASK_CANT_TRASH_ITEM, fileEntry->szFullPath);
|
||||
bDelete = SHELL_ConfirmDialogW(lpFileOp->hwnd, ASK_CANT_TRASH_ITEM, fileEntry->szFullPath, NULL);
|
||||
else
|
||||
bDelete = TRUE;
|
||||
|
||||
|
@ -1423,6 +1490,7 @@ static void check_flags(FILEOP_FLAGS fFlags)
|
|||
*/
|
||||
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
|
||||
{
|
||||
FILE_OPERATION op;
|
||||
FILE_LIST flFrom, flTo;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -1440,10 +1508,14 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
|
|||
if (lpFileOp->wFunc != FO_DELETE)
|
||||
parse_file_list(&flTo, lpFileOp->pTo);
|
||||
|
||||
ZeroMemory(&op, sizeof(op));
|
||||
op.req = lpFileOp;
|
||||
op.bManyItems = (flFrom.dwNumFiles > 1);
|
||||
|
||||
switch (lpFileOp->wFunc)
|
||||
{
|
||||
case FO_COPY:
|
||||
ret = copy_files(lpFileOp, &flFrom, &flTo);
|
||||
ret = copy_files(&op, &flFrom, &flTo);
|
||||
break;
|
||||
case FO_DELETE:
|
||||
ret = delete_files(lpFileOp, &flFrom);
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
#define IDS_TRASHITEM_TEXT 138
|
||||
#define IDS_TRASHMULTIPLE_TEXT 139
|
||||
#define IDS_CANTTRASH_TEXT 140
|
||||
#define IDS_OVERWRITEFOLDER_TEXT 141
|
||||
|
||||
/* Note: this string is referenced from the registry*/
|
||||
#define IDS_RECYCLEBIN_FOLDER_NAME 8964
|
||||
|
|
|
@ -63,6 +63,21 @@ static BOOL file_exists(const CHAR *name)
|
|||
return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
static BOOL file_has_content(const CHAR *name, const CHAR *content)
|
||||
{
|
||||
CHAR buf[MAX_PATH];
|
||||
HANDLE file;
|
||||
DWORD read;
|
||||
|
||||
file = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
ReadFile(file, buf, MAX_PATH - 1, &read, NULL);
|
||||
buf[read] = 0;
|
||||
CloseHandle(file);
|
||||
return strcmp(buf, content)==0;
|
||||
}
|
||||
|
||||
/* initializes the tests */
|
||||
static void init_shfo_tests(void)
|
||||
{
|
||||
|
@ -92,6 +107,7 @@ static void clean_after_shfo_tests(void)
|
|||
DeleteFileA("test2.txt");
|
||||
DeleteFileA("test3.txt");
|
||||
DeleteFileA("test_5.txt");
|
||||
DeleteFileA("one.txt");
|
||||
DeleteFileA("test4.txt\\test1.txt");
|
||||
DeleteFileA("test4.txt\\test2.txt");
|
||||
DeleteFileA("test4.txt\\test3.txt");
|
||||
|
@ -761,6 +777,45 @@ static void test_copy(void)
|
|||
ok(retval == 1026, "Expected 1026, got %d\n", retval);
|
||||
ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
|
||||
ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
|
||||
|
||||
/* Overwrite tests */
|
||||
clean_after_shfo_tests();
|
||||
init_shfo_tests();
|
||||
shfo.fFlags = FOF_NOCONFIRMATION;
|
||||
shfo.pFrom = "test1.txt\0";
|
||||
shfo.pTo = "test2.txt\0";
|
||||
shfo.fAnyOperationsAborted = FALSE;
|
||||
/* without FOF_NOCOFIRMATION the confirmation is Yes/No */
|
||||
retval = SHFileOperation(&shfo);
|
||||
ok(retval == 0, "Expected 0, got %d\n", retval);
|
||||
ok(file_has_content("test2.txt", "test1.txt\n"), "The file was not copied\n");
|
||||
|
||||
shfo.pFrom = "test3.txt\0test1.txt\0";
|
||||
shfo.pTo = "test2.txt\0one.txt\0";
|
||||
shfo.fFlags = FOF_NOCONFIRMATION | FOF_MULTIDESTFILES;
|
||||
/* without FOF_NOCOFIRMATION the confirmation is Yes/Yes to All/No/Cancel */
|
||||
retval = SHFileOperation(&shfo);
|
||||
ok(retval == 0, "Expected 0, got %d\n", retval);
|
||||
ok(file_has_content("test2.txt", "test3.txt\n"), "The file was not copied\n");
|
||||
|
||||
shfo.pFrom = "one.txt\0";
|
||||
shfo.pTo = "testdir2\0";
|
||||
shfo.fFlags = FOF_NOCONFIRMATION;
|
||||
/* without FOF_NOCOFIRMATION the confirmation is Yes/No */
|
||||
retval = SHFileOperation(&shfo);
|
||||
ok(retval == 0, "Expected 0, got %d\n", retval);
|
||||
ok(file_has_content("testdir2\\one.txt", "test1.txt\n"), "The file was not copied\n");
|
||||
|
||||
createTestFile("test4.txt\\test1.txt");
|
||||
shfo.pFrom = "test4.txt\0";
|
||||
shfo.pTo = "testdir2\0";
|
||||
shfo.fFlags = FOF_NOCONFIRMATION;
|
||||
ok(!SHFileOperation(&shfo), "First SHFileOperation failed\n");
|
||||
createTestFile("test4.txt\\.\\test1.txt"); /* modify the content of the file */
|
||||
/* without FOF_NOCOFIRMATION the confirmation is "This folder already contains a folder named ..." */
|
||||
retval = SHFileOperation(&shfo);
|
||||
ok(retval == 0, "Expected 0, got %d\n", retval);
|
||||
ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n");
|
||||
}
|
||||
|
||||
/* tests the FO_MOVE action */
|
||||
|
|
Loading…
Reference in New Issue