ReactOS  0.4.13-dev-249-gcba1a2f
shlfileop.cpp
Go to the documentation of this file.
1 /*
2  * SHFileOperation
3  *
4  * Copyright 2000 Juergen Schmied
5  * Copyright 2002 Andriy Palamarchuk
6  * Copyright 2004 Dietrich Teickner (from Odin)
7  * Copyright 2004 Rolf Kalbermatter
8  * Copyright 2019 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include "precomp.h"
26 
28 
29 #define IsAttrib(x, y) ((INVALID_FILE_ATTRIBUTES != (x)) && ((x) & (y)))
30 #define IsAttribFile(x) (!((x) & FILE_ATTRIBUTE_DIRECTORY))
31 #define IsAttribDir(x) IsAttrib(x, FILE_ATTRIBUTE_DIRECTORY)
32 #define IsDotDir(x) ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
33 
34 #define FO_MASK 0xF
35 
36 #define NEW_FILENAME_ON_COPY_TRIES 100
37 
38 static const WCHAR wWildcardFile[] = {'*',0};
39 static const WCHAR wWildcardChars[] = {'*','?',0};
40 
41 typedef struct
42 {
47  IProgressDialog *progress;
50  WCHAR szBuilderString[50];
52 
53 #define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND 1026
54 
55 typedef struct
56 {
64 } FILE_ENTRY;
65 
66 typedef struct
67 {
74 } FILE_LIST;
75 
81 static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly);
82 static HRESULT copy_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, FILE_LIST *flTo);
83 static DWORD move_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, const FILE_LIST *flTo);
84 
86 static BOOL _FileOpCount(FILE_OPERATION *op, LPWSTR pwszBuf, BOOL bFolder, DWORD *ticks);
87 
88 /* Confirm dialogs with an optional "Yes To All" as used in file operations confirmations
89  */
90 static const WCHAR CONFIRM_MSG_PROP[] = {'W','I','N','E','_','C','O','N','F','I','R','M',0};
91 
93 {
98 };
99 
100 /* as some buttons may be hidden and the dialog height may change we may need
101  * to move the controls */
102 static void confirm_msg_move_button(HWND hDlg, INT iId, INT *xPos, INT yOffset, BOOL bShow)
103 {
104  HWND hButton = GetDlgItem(hDlg, iId);
105  RECT r;
106 
107  if (bShow)
108  {
109  POINT pt;
110  int width;
111 
112  GetWindowRect(hButton, &r);
113  width = r.right - r.left;
114  pt.x = r.left;
115  pt.y = r.top;
116  ScreenToClient(hDlg, &pt);
117  MoveWindow(hButton, *xPos - width, pt.y - yOffset, width, r.bottom - r.top, FALSE);
118  *xPos -= width + 5;
119  }
120  else
121  ShowWindow(hButton, SW_HIDE);
122 }
123 
124 /* Note: we paint the text manually and don't use the static control to make
125  * sure the text has the same height as the one computed in WM_INITDIALOG
126  */
128 {
129  PAINTSTRUCT ps;
130  HFONT hOldFont;
131  RECT r;
132  HDC hdc;
133 
134  BeginPaint(hDlg, &ps);
135  hdc = ps.hdc;
137 
139  /* this will remap the rect to dialog coords */
143  SelectObject(hdc, hOldFont);
144  EndPaint(hDlg, &ps);
145 
146  return TRUE;
147 }
148 
150 {
151  struct confirm_msg_info *info = (struct confirm_msg_info *)lParam;
152  INT xPos, yOffset;
153  int width, height;
154  HFONT hOldFont;
155  HDC hdc;
156  RECT r;
157 
158  SetWindowTextW(hDlg, info->lpszCaption);
160  SetPropW(hDlg, CONFIRM_MSG_PROP, info->lpszText);
162 
163  /* compute the text height and resize the dialog */
165  hdc = GetDC(hDlg);
166  yOffset = r.bottom;
169  SelectObject(hdc, hOldFont);
170  yOffset -= r.bottom;
171  yOffset = min(yOffset, 35); /* don't make the dialog too small */
172  ReleaseDC(hDlg, hdc);
173 
174  GetClientRect(hDlg, &r);
175  xPos = r.right - 7;
176  GetWindowRect(hDlg, &r);
177  width = r.right - r.left;
178  height = r.bottom - r.top - yOffset;
181 
182  confirm_msg_move_button(hDlg, IDCANCEL, &xPos, yOffset, info->bYesToAll);
183  confirm_msg_move_button(hDlg, IDNO, &xPos, yOffset, TRUE);
184  confirm_msg_move_button(hDlg, IDC_YESTOALL, &xPos, yOffset, info->bYesToAll);
185  confirm_msg_move_button(hDlg, IDYES, &xPos, yOffset, TRUE);
186 
187  return TRUE;
188 }
189 
191 {
192  switch (uMsg)
193  {
194  case WM_INITDIALOG:
195  return ConfirmMsgBox_Init(hDlg, lParam);
196  case WM_PAINT:
197  return ConfirmMsgBox_Paint(hDlg);
198  case WM_COMMAND:
199  EndDialog(hDlg, wParam);
200  break;
201  case WM_CLOSE:
202  EndDialog(hDlg, IDCANCEL);
203  break;
204  }
205  return FALSE;
206 }
207 
209 {
210  struct confirm_msg_info info;
211 
212  info.lpszText = lpszText;
213  info.lpszCaption = lpszCaption;
214  info.hIcon = hIcon;
215  info.bYesToAll = bYesToAll;
217 }
218 
219 /* confirmation dialogs content */
220 typedef struct
221 {
224  UINT caption_resource_id, text_resource_id;
226 
227 static BOOL SHELL_ConfirmIDs(int nKindOfDialog, SHELL_ConfirmIDstruc *ids)
228 {
229  ids->hIconInstance = shell32_hInstance;
230  switch (nKindOfDialog)
231  {
232  case ASK_DELETE_FILE:
233  ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
234  ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
235  ids->text_resource_id = IDS_DELETEITEM_TEXT;
236  return TRUE;
237 
238  case ASK_DELETE_FOLDER:
239  ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
240  ids->caption_resource_id = IDS_DELETEFOLDER_CAPTION;
241  ids->text_resource_id = IDS_DELETEITEM_TEXT;
242  return TRUE;
243 
245  ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
246  ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
247  ids->text_resource_id = IDS_DELETEMULTIPLE_TEXT;
248  return TRUE;
249 
250  case ASK_TRASH_FILE:
251  ids->icon_resource_id = IDI_SHELL_TRASH_FILE;
252  ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
253  ids->text_resource_id = IDS_TRASHITEM_TEXT;
254  return TRUE;
255 
256  case ASK_TRASH_FOLDER:
257  ids->icon_resource_id = IDI_SHELL_TRASH_FILE;
258  ids->caption_resource_id = IDS_DELETEFOLDER_CAPTION;
259  ids->text_resource_id = IDS_TRASHFOLDER_TEXT;
260  return TRUE;
261 
263  ids->icon_resource_id = IDI_SHELL_TRASH_FILE;
264  ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
265  ids->text_resource_id = IDS_TRASHMULTIPLE_TEXT;
266  return TRUE;
267 
268  case ASK_CANT_TRASH_ITEM:
269  ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
270  ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
271  ids->text_resource_id = IDS_CANTTRASH_TEXT;
272  return TRUE;
273 
274  case ASK_DELETE_SELECTED:
275  ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
276  ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
277  ids->text_resource_id = IDS_DELETESELECTED_TEXT;
278  return TRUE;
279 
280  case ASK_OVERWRITE_FILE:
281  ids->icon_resource_id = IDI_SHELL_FOLDER_MOVE2;
282  ids->caption_resource_id = IDS_OVERWRITEFILE_CAPTION;
283  ids->text_resource_id = IDS_OVERWRITEFILE_TEXT;
284  return TRUE;
285 
287  ids->icon_resource_id = IDI_SHELL_FOLDER_MOVE2;
288  ids->caption_resource_id = IDS_OVERWRITEFILE_CAPTION;
289  ids->text_resource_id = IDS_OVERWRITEFOLDER_TEXT;
290  return TRUE;
291 
292  default:
293  FIXME(" Unhandled nKindOfDialog %d stub\n", nKindOfDialog);
294  }
295  return FALSE;
296 }
297 
298 static BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir, FILE_OPERATION *op)
299 {
300  WCHAR szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
302  DWORD_PTR args[1];
303  HICON hIcon;
304  int ret;
305 
306  assert(nKindOfDialog >= 0 && nKindOfDialog < 32);
307  if (op && (op->dwYesToAllMask & (1 << nKindOfDialog)))
308  return TRUE;
309 
310  if (!SHELL_ConfirmIDs(nKindOfDialog, &ids)) return FALSE;
311 
312  LoadStringW(shell32_hInstance, ids.caption_resource_id, szCaption, sizeof(szCaption)/sizeof(WCHAR));
313  LoadStringW(shell32_hInstance, ids.text_resource_id, szText, sizeof(szText)/sizeof(WCHAR));
314 
315  args[0] = (DWORD_PTR)szDir;
317  szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)args);
318  hIcon = LoadIconW(ids.hIconInstance, (LPWSTR)MAKEINTRESOURCE(ids.icon_resource_id));
319 
320  ret = SHELL_ConfirmMsgBox(hWnd, szBuffer, szCaption, hIcon, op && op->bManyItems);
321  if (op)
322  {
323  if (ret == IDC_YESTOALL)
324  {
325  op->dwYesToAllMask |= (1 << nKindOfDialog);
326  ret = IDYES;
327  }
328  if (ret == IDCANCEL)
329  op->bCancelled = TRUE;
330  if (ret != IDYES)
331  op->req->fAnyOperationsAborted = TRUE;
332  }
333  return ret == IDYES;
334 }
335 
336 BOOL SHELL_ConfirmYesNoW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir)
337 {
338  return SHELL_ConfirmDialogW(hWnd, nKindOfDialog, szDir, NULL);
339 }
340 
341 static DWORD SHELL32_AnsiToUnicodeBuf(LPCSTR aPath, LPWSTR *wPath, DWORD minChars)
342 {
343  DWORD len = MultiByteToWideChar(CP_ACP, 0, aPath, -1, NULL, 0);
344 
345  if (len < minChars)
346  len = minChars;
347 
348  *wPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
349  if (*wPath)
350  {
351  MultiByteToWideChar(CP_ACP, 0, aPath, -1, *wPath, len);
352  return NO_ERROR;
353  }
354  return E_OUTOFMEMORY;
355 }
356 
357 static void SHELL32_FreeUnicodeBuf(LPWSTR wPath)
358 {
359  HeapFree(GetProcessHeap(), 0, wPath);
360 }
361 
363 {
364  FIXME("(%s, %p) stub\n", debugstr_w(path), status);
365  return E_FAIL;
366 }
367 
368 /**************************************************************************
369  * SHELL_DeleteDirectory() [internal]
370  *
371  * Asks for confirmation when bShowUI is true and deletes the directory and
372  * all its subdirectories and files if necessary.
373  */
375 {
376  BOOL ret = TRUE;
377  HANDLE hFind;
378  WIN32_FIND_DATAW wfd;
379  WCHAR szTemp[MAX_PATH];
380 
381  /* Make sure the directory exists before eventually prompting the user */
383  hFind = FindFirstFileW(szTemp, &wfd);
384  if (hFind == INVALID_HANDLE_VALUE)
385  return FALSE;
386 
387  if (!bShowUI || (ret = SHELL_ConfirmDialogW(op->req->hwnd, ASK_DELETE_FOLDER, pszDir, NULL)))
388  {
389  do
390  {
391  if (IsDotDir(wfd.cFileName))
392  continue;
393  PathCombineW(szTemp, pszDir, wfd.cFileName);
394  if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
395  ret = SHELL_DeleteDirectoryW(op, szTemp, FALSE);
396  else
397  ret = (SHNotifyDeleteFileW(op, szTemp) == ERROR_SUCCESS);
398 
399  if (op->progress != NULL)
400  op->bCancelled |= op->progress->HasUserCancelled();
401  } while (ret && FindNextFileW(hFind, &wfd) && !op->bCancelled);
402  }
403  FindClose(hFind);
404  if (ret)
406  return ret;
407 }
408 
409 /**************************************************************************
410  * Win32CreateDirectory [SHELL32.93]
411  *
412  * Creates a directory. Also triggers a change notify if one exists.
413  *
414  * PARAMS
415  * path [I] path to directory to create
416  *
417  * RETURNS
418  * TRUE if successful, FALSE otherwise
419  */
420 
422 {
423  TRACE("(%s, %p)\n", debugstr_w(path), sec);
424 
425  if (CreateDirectoryW(path, sec))
426  {
428  return ERROR_SUCCESS;
429  }
430  return GetLastError();
431 }
432 
433 /**********************************************************************/
434 
436 {
437  return (SHNotifyCreateDirectoryW(path, sec) == ERROR_SUCCESS);
438 }
439 
440 /************************************************************************
441  * Win32RemoveDirectory [SHELL32.94]
442  *
443  * Deletes a directory. Also triggers a change notify if one exists.
444  *
445  * PARAMS
446  * path [I] path to directory to delete
447  *
448  * RETURNS
449  * TRUE if successful, FALSE otherwise
450  */
452 {
453  BOOL ret;
454  TRACE("(%s)\n", debugstr_w(path));
455 
457  if (!ret)
458  {
459  /* Directory may be write protected */
460  DWORD dwAttr = GetFileAttributesW(path);
461  if (IsAttrib(dwAttr, FILE_ATTRIBUTE_READONLY))
464  }
465  if (ret)
466  {
468  return ERROR_SUCCESS;
469  }
470  return GetLastError();
471 }
472 
473 /***********************************************************************/
474 
476 {
478 }
479 
481  if (op->progress == NULL)
482  return;
483  WCHAR szTitle[50], szPreflight[50];
484  UINT animation_id = NULL;
485 
486  switch (op->req->wFunc)
487  {
488  case FO_COPY:
490  LoadStringW(shell32_hInstance, IDS_FILEOOP_FROM_TO, op->szBuilderString, sizeof( op->szBuilderString)/sizeof(WCHAR));
491  animation_id = IDA_SHELL_COPY;
492  break;
493  case FO_DELETE:
495  LoadStringW(shell32_hInstance, IDS_FILEOOP_FROM, op->szBuilderString, sizeof( op->szBuilderString)/sizeof(WCHAR));
496  animation_id = IDA_SHELL_DELETE;
497  break;
498  case FO_MOVE:
500  LoadStringW(shell32_hInstance, IDS_FILEOOP_FROM_TO, op->szBuilderString, sizeof( op->szBuilderString)/sizeof(WCHAR));
501  animation_id = IDA_SHELL_COPY;
502  break;
503  default:
504  return;
505  }
506  LoadStringW(shell32_hInstance, IDS_FILEOOP_PREFLIGHT, szPreflight, sizeof(szPreflight)/sizeof(WCHAR));
507 
508  op->progress->SetTitle(szTitle);
509  op->progress->SetLine(1, szPreflight, false, NULL);
510  op->progress->SetAnimation(shell32_hInstance, animation_id);
511 }
512 
514  if (op->progress == NULL || src == NULL)
515  return;
516  LPWSTR fileSpecS, pathSpecS, fileSpecD, pathSpecD;
517  WCHAR szFolderS[50], szFolderD[50], szFinalString[260];
518 
519  DWORD_PTR args[2];
520 
521  fileSpecS = (pathSpecS = (LPWSTR) src);
522  fileSpecD = (pathSpecD = (LPWSTR) dest);
523 
524  // March across the string to get the file path and it's parent dir.
525  for (LPWSTR ptr = (LPWSTR) src; *ptr; ptr++) {
526  if (*ptr == '\\') {
527  pathSpecS = fileSpecS;
528  fileSpecS = ptr+1;
529  }
530  }
531  lstrcpynW(szFolderS, pathSpecS, min(50, fileSpecS - pathSpecS));
532  args[0] = (DWORD_PTR) szFolderS;
533 
534  switch (op->req->wFunc)
535  {
536  case FO_COPY:
537  case FO_MOVE:
538  if (dest == NULL)
539  return;
540  for (LPWSTR ptr = (LPWSTR) dest; *ptr; ptr++) {
541  if (*ptr == '\\') {
542  pathSpecD = fileSpecD;
543  fileSpecD = ptr + 1;
544  }
545  }
546  lstrcpynW(szFolderD, pathSpecD, min(50, fileSpecD - pathSpecD));
547  args[1] = (DWORD_PTR) szFolderD;
548  break;
549  case FO_DELETE:
550  break;
551  default:
552  return;
553  }
554 
556  op->szBuilderString, 0, 0, szFinalString, sizeof(szFinalString), (va_list*)args);
557 
558  op->progress->SetLine(1, fileSpecS, false, NULL);
559  op->progress->SetLine(2, szFinalString, false, NULL);
560 }
561 
562 
564  LARGE_INTEGER TotalFileSize,
565  LARGE_INTEGER TotalBytesTransferred,
566  LARGE_INTEGER StreamSize,
567  LARGE_INTEGER StreamBytesTransferred,
568  DWORD dwStreamNumber,
569  DWORD dwCallbackReason,
570  HANDLE hSourceFile,
571  HANDLE hDestinationFile,
572  LPVOID lpData
573 ) {
574  FILE_OPERATION *op = (FILE_OPERATION *) lpData;
575 
576  if (op->progress) {
577  /*
578  * This is called at the start of each file. To keop less state,
579  * I'm adding the file to the completed size here, and the re-subtracting
580  * it when drawing the progress bar.
581  */
582  if (dwCallbackReason & CALLBACK_STREAM_SWITCH)
583  op->completedSize.QuadPart += TotalFileSize.QuadPart;
584 
585  op->progress->SetProgress64(op->completedSize.QuadPart -
586  TotalFileSize.QuadPart +
587  TotalBytesTransferred.QuadPart
588  , op->totalSize.QuadPart);
589 
590 
591  op->bCancelled = op->progress->HasUserCancelled();
592  }
593 
594  return 0;
595 }
596 
597 
598 /************************************************************************
599  * SHNotifyDeleteFileW [internal]
600  *
601  * Deletes a file. Also triggers a change notify if one exists.
602  *
603  * PARAMS
604  * op [I] File Operation context
605  * path [I] path to source file to move
606  *
607  * RETURNS
608  * ERORR_SUCCESS if successful
609  */
611 {
612  BOOL ret;
613 
614  TRACE("(%s)\n", debugstr_w(path));
615 
617 
619  FileSize.QuadPart = 0;
620 
621  WIN32_FIND_DATAW wfd;
622  HANDLE hFile = FindFirstFileW(path, &wfd);
623  if (hFile != INVALID_HANDLE_VALUE && IsAttribFile(wfd.dwFileAttributes)) {
624  ULARGE_INTEGER tmp;
625  tmp.u.LowPart = wfd.nFileSizeLow;
626  tmp.u.HighPart = wfd.nFileSizeHigh;
627  FileSize.QuadPart = tmp.QuadPart;
628  }
629  FindClose(hFile);
630 
631  ret = DeleteFileW(path);
632  if (!ret)
633  {
634  /* File may be write protected or a system file */
635  DWORD dwAttr = GetFileAttributesW(path);
638  ret = DeleteFileW(path);
639  }
640  if (ret)
641  {
642  // Bit of a hack to make the progress bar move. We don't have progress inside the file, so inform when done.
645  return ERROR_SUCCESS;
646  }
647  return GetLastError();
648 }
649 
650 /************************************************************************
651  * Win32DeleteFile [SHELL32.164]
652  *
653  * Deletes a file. Also triggers a change notify if one exists.
654  *
655  * PARAMS
656  * path [I] path to file to delete
657  *
658  * RETURNS
659  * TRUE if successful, FALSE otherwise
660  */
662 {
664 }
665 
666 /************************************************************************
667  * SHNotifyMoveFile [internal]
668  *
669  * Moves a file. Also triggers a change notify if one exists.
670  *
671  * PARAMS
672  * op [I] File Operation context
673  * src [I] path to source file to move
674  * dest [I] path to target file to move to
675  *
676  * RETURNS
677  * ERROR_SUCCESS if successful
678  */
680 {
681  BOOL ret;
682 
683  TRACE("(%s %s)\n", debugstr_w(src), debugstr_w(dest));
684 
686 
688 
689  /* MOVEFILE_REPLACE_EXISTING fails with dirs, so try MoveFile */
690  if (!ret)
691  ret = MoveFileW(src, dest);
692 
693  if (!ret)
694  {
695  DWORD dwAttr;
696 
697  dwAttr = SHFindAttrW(dest, FALSE);
698  if (INVALID_FILE_ATTRIBUTES == dwAttr)
699  {
700  /* Source file may be write protected or a system file */
701  dwAttr = GetFileAttributesW(src);
704  ret = MoveFileW(src, dest);
705  }
706  }
707  if (ret)
708  {
711  return ERROR_SUCCESS;
712  }
713  return GetLastError();
714 }
715 
716 /************************************************************************
717  * SHNotifyCopyFile [internal]
718  *
719  * Copies a file. Also triggers a change notify if one exists.
720  *
721  * PARAMS
722  * src [I] path to source file to move
723  * dest [I] path to target file to move to
724  * bFailIfExists [I] if TRUE, the target file will not be overwritten if
725  * a file with this name already exists
726  *
727  * RETURNS
728  * ERROR_SUCCESS if successful
729  */
731 {
732  BOOL ret;
733  DWORD attribs;
734 
735  TRACE("(%s %s %s)\n", debugstr_w(src), debugstr_w(dest), bFailIfExists ? "failIfExists" : "");
736 
738 
739  /* Destination file may already exist with read only attribute */
743 
745  {
748  {
749  TRACE("[shell32, SHNotifyCopyFileW] STILL SHIT\n");
750  }
751  }
752 
753  ret = CopyFileExW(src, dest, SHCopyProgressRoutine, op, &op->bCancelled, bFailIfExists);
754  if (ret)
755  {
757  return ERROR_SUCCESS;
758  }
759 
760  return GetLastError();
761 }
762 
763 /*************************************************************************
764  * SHCreateDirectory [SHELL32.165]
765  *
766  * This function creates a file system folder whose fully qualified path is
767  * given by path. If one or more of the intermediate folders do not exist,
768  * they will be created as well.
769  *
770  * PARAMS
771  * hWnd [I]
772  * path [I] path of directory to create
773  *
774  * RETURNS
775  * ERROR_SUCCESS or one of the following values:
776  * ERROR_BAD_PATHNAME if the path is relative
777  * ERROR_FILE_EXISTS when a file with that name exists
778  * ERROR_PATH_NOT_FOUND can't find the path, probably invalid
779  * ERROR_INVALID_NAME if the path contains invalid chars
780  * ERROR_ALREADY_EXISTS when the directory already exists
781  * ERROR_FILENAME_EXCED_RANGE if the filename was to long to process
782  *
783  * NOTES
784  * exported by ordinal
785  * Win9x exports ANSI
786  * WinNT/2000 exports Unicode
787  */
789 {
791 }
792 
793 /*************************************************************************
794  * SHCreateDirectoryExA [SHELL32.@]
795  *
796  * This function creates a file system folder whose fully qualified path is
797  * given by path. If one or more of the intermediate folders do not exist,
798  * they will be created as well.
799  *
800  * PARAMS
801  * hWnd [I]
802  * path [I] path of directory to create
803  * sec [I] security attributes to use or NULL
804  *
805  * RETURNS
806  * ERROR_SUCCESS or one of the following values:
807  * ERROR_BAD_PATHNAME or ERROR_PATH_NOT_FOUND if the path is relative
808  * ERROR_INVALID_NAME if the path contains invalid chars
809  * ERROR_FILE_EXISTS when a file with that name exists
810  * ERROR_ALREADY_EXISTS when the directory already exists
811  * ERROR_FILENAME_EXCED_RANGE if the filename was too long to process
812  *
813  * FIXME: Not implemented yet;
814  * SHCreateDirectoryEx also verifies that the files in the directory will be visible
815  * if the path is a network path to deal with network drivers which might have a limited
816  * but unknown maximum path length. If not:
817  *
818  * If hWnd is set to a valid window handle, a message box is displayed warning
819  * the user that the files may not be accessible. If the user chooses not to
820  * proceed, the function returns ERROR_CANCELLED.
821  *
822  * If hWnd is set to NULL, no user interface is displayed and the function
823  * returns ERROR_CANCELLED.
824  */
826 {
827  LPWSTR wPath;
828  DWORD retCode;
829 
830  TRACE("(%s, %p)\n", debugstr_a(path), sec);
831 
832  retCode = SHELL32_AnsiToUnicodeBuf(path, &wPath, 0);
833  if (!retCode)
834  {
835  retCode = SHCreateDirectoryExW(hWnd, wPath, sec);
836  SHELL32_FreeUnicodeBuf(wPath);
837  }
838  return retCode;
839 }
840 
841 /*************************************************************************
842  * SHCreateDirectoryExW [SHELL32.@]
843  *
844  * See SHCreateDirectoryExA.
845  */
847 {
848  int ret = ERROR_BAD_PATHNAME;
849  TRACE("(%p, %s, %p)\n", hWnd, debugstr_w(path), sec);
850 
851  if (PathIsRelativeW(path))
852  {
853  SetLastError(ret);
854  }
855  else
856  {
858  /* Refuse to work on certain error codes before trying to create directories recursively */
859  if (ret != ERROR_SUCCESS &&
860  ret != ERROR_FILE_EXISTS &&
863  {
864  WCHAR *pEnd, *pSlash, szTemp[MAX_PATH + 1]; /* extra for PathAddBackslash() */
865 
866  lstrcpynW(szTemp, path, MAX_PATH);
867  pEnd = PathAddBackslashW(szTemp);
868  pSlash = szTemp + 3;
869 
870  while (*pSlash)
871  {
872  while (*pSlash && *pSlash != '\\') pSlash++;
873  if (*pSlash)
874  {
875  *pSlash = 0; /* terminate path at separator */
876 
877  ret = SHNotifyCreateDirectoryW(szTemp, pSlash + 1 == pEnd ? sec : NULL);
878  }
879  *pSlash++ = '\\'; /* put the separator back */
880  }
881  }
882 
883  if (ret && hWnd && (ERROR_CANCELLED != ret))
884  {
888  }
889  }
890 
891  return ret;
892 }
893 
894 /*************************************************************************
895  * SHFindAttrW [internal]
896  *
897  * Get the Attributes for a file or directory. The difference to GetAttributes()
898  * is that this function will also work for paths containing wildcard characters
899  * in its filename.
900 
901  * PARAMS
902  * path [I] path of directory or file to check
903  * fileOnly [I] TRUE if only files should be found
904  *
905  * RETURNS
906  * INVALID_FILE_ATTRIBUTES if the path does not exist, the actual attributes of
907  * the first file or directory found otherwise
908  */
909 static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly)
910 {
911  WIN32_FIND_DATAW wfd;
912  BOOL b_FileMask = fileOnly && (NULL != StrPBrkW(pName, wWildcardChars));
914  HANDLE hFind = FindFirstFileW(pName, &wfd);
915 
916  TRACE("%s %d\n", debugstr_w(pName), fileOnly);
917  if (INVALID_HANDLE_VALUE != hFind)
918  {
919  do
920  {
921  if (b_FileMask && IsAttribDir(wfd.dwFileAttributes))
922  continue;
923  dwAttr = wfd.dwFileAttributes;
924  break;
925  } while (FindNextFileW(hFind, &wfd));
926 
927  FindClose(hFind);
928  }
929  return dwAttr;
930 }
931 
932 /*************************************************************************
933  *
934  * _ConvertAtoW helper function for SHFileOperationA
935  *
936  * Converts a string or string-list to unicode.
937  */
938 static DWORD _ConvertAtoW(PCSTR strSrc, PCWSTR* pStrDest, BOOL isList)
939 {
940  *pStrDest = NULL;
941 
942  // If the input is null, nothing to convert.
943  if (!strSrc)
944  return 0;
945 
946  // Measure the total size, depending on if it's a zero-terminated list.
947  int sizeA = 0;
948  if (isList)
949  {
950  PCSTR tmpSrc = strSrc;
951  int size;
952  do
953  {
954  size = lstrlenA(tmpSrc) + 1;
955  sizeA += size;
956  tmpSrc += size;
957  } while (size != 1);
958  }
959  else
960  {
961  sizeA = lstrlenA(strSrc) + 1;
962  }
963 
964  // Measure the needed allocation size.
965  int sizeW = MultiByteToWideChar(CP_ACP, 0, strSrc, sizeA, NULL, 0);
966  if (!sizeW)
967  return GetLastError();
968 
969  PWSTR strDest = (PWSTR) HeapAlloc(GetProcessHeap(), 0, sizeW * sizeof(WCHAR));
970  if (!strDest)
971  return ERROR_OUTOFMEMORY;
972 
973  int err = MultiByteToWideChar(CP_ACP, 0, strSrc, sizeA, strDest, sizeW);
974  if (!err)
975  {
976  HeapFree(GetProcessHeap(), 0, strDest);
977  return GetLastError();
978  }
979 
980  *pStrDest = strDest;
981  return 0;
982 }
983 
984 /*************************************************************************
985  * SHFileOperationA [SHELL32.@]
986  *
987  * Function to copy, move, delete and create one or more files with optional
988  * user prompts.
989  *
990  * PARAMS
991  * lpFileOp [I/O] pointer to a structure containing all the necessary information
992  *
993  * RETURNS
994  * Success: ERROR_SUCCESS.
995  * Failure: ERROR_CANCELLED.
996  *
997  * NOTES
998  * exported by name
999  */
1001 {
1002  int errCode, retCode;
1003  SHFILEOPSTRUCTW nFileOp = { 0 };
1004 
1005  // Convert A information to W
1006  nFileOp.hwnd = lpFileOp->hwnd;
1007  nFileOp.wFunc = lpFileOp->wFunc;
1008  nFileOp.fFlags = lpFileOp->fFlags;
1009 
1010  errCode = _ConvertAtoW(lpFileOp->pFrom, &nFileOp.pFrom, TRUE);
1011  if (errCode != 0)
1012  goto cleanup;
1013 
1014  if (FO_DELETE != (nFileOp.wFunc & FO_MASK))
1015  {
1016  errCode = _ConvertAtoW(lpFileOp->pTo, &nFileOp.pTo, TRUE);
1017  if (errCode != 0)
1018  goto cleanup;
1019  }
1020 
1021  if (nFileOp.fFlags & FOF_SIMPLEPROGRESS)
1022  {
1023  errCode = _ConvertAtoW(lpFileOp->lpszProgressTitle, &nFileOp.lpszProgressTitle, FALSE);
1024  if (errCode != 0)
1025  goto cleanup;
1026  }
1027 
1028  // Call the actual function
1029  retCode = SHFileOperationW(&nFileOp);
1030 
1031  // Cleanup
1032 cleanup:
1033  if (nFileOp.pFrom)
1034  HeapFree(GetProcessHeap(), 0, (PVOID) nFileOp.pFrom);
1035  if (nFileOp.pTo)
1036  HeapFree(GetProcessHeap(), 0, (PVOID) nFileOp.pTo);
1037  if (nFileOp.lpszProgressTitle)
1039 
1040  if (errCode != 0)
1041  {
1042  lpFileOp->fAnyOperationsAborted = TRUE;
1043  SetLastError(errCode);
1044 
1045  return errCode;
1046  }
1047 
1048  // Thankfully, starting with NT4 the name mappings are always unicode, so no need to convert.
1049  lpFileOp->hNameMappings = nFileOp.hNameMappings;
1050  lpFileOp->fAnyOperationsAborted = nFileOp.fAnyOperationsAborted;
1051  return retCode;
1052 }
1053 
1054 static void __inline grow_list(FILE_LIST *list)
1055 {
1057  list->num_alloc * 2 * sizeof(*newx) );
1058  list->feFiles = newx;
1059  list->num_alloc *= 2;
1060 }
1061 
1062 /* adds a file to the FILE_ENTRY struct
1063  */
1064 static void add_file_to_entry(FILE_ENTRY *feFile, LPCWSTR szFile)
1065 {
1066  DWORD dwLen = lstrlenW(szFile) + 1;
1067  LPCWSTR ptr;
1068  LPCWSTR ptr2;
1069 
1070  feFile->szFullPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
1071  lstrcpyW(feFile->szFullPath, szFile);
1072 
1073  ptr = StrRChrW(szFile, NULL, '\\');
1074  ptr2 = StrRChrW(szFile, NULL, '/');
1075  if (!ptr || ptr < ptr2)
1076  ptr = ptr2;
1077  if (ptr)
1078  {
1079  dwLen = ptr - szFile + 1;
1080  feFile->szDirectory = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
1081  lstrcpynW(feFile->szDirectory, szFile, dwLen);
1082 
1083  dwLen = lstrlenW(feFile->szFullPath) - dwLen + 1;
1084  feFile->szFilename = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
1085  lstrcpyW(feFile->szFilename, ptr + 1); /* skip over backslash */
1086  }
1087  feFile->bFromWildcard = FALSE;
1088 }
1089 
1090 static LPWSTR wildcard_to_file(LPCWSTR szWildCard, LPCWSTR szFileName)
1091 {
1092  LPCWSTR ptr;
1093  LPCWSTR ptr2;
1094  LPWSTR szFullPath;
1095  DWORD dwDirLen, dwFullLen;
1096 
1097  ptr = StrRChrW(szWildCard, NULL, '\\');
1098  ptr2 = StrRChrW(szWildCard, NULL, '/');
1099  if (!ptr || ptr < ptr2)
1100  ptr = ptr2;
1101  dwDirLen = ptr - szWildCard + 1;
1102 
1103  dwFullLen = dwDirLen + lstrlenW(szFileName) + 1;
1104  szFullPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwFullLen * sizeof(WCHAR));
1105 
1106  lstrcpynW(szFullPath, szWildCard, dwDirLen + 1);
1107  lstrcatW(szFullPath, szFileName);
1108 
1109  return szFullPath;
1110 }
1111 
1112 static void parse_wildcard_files(FILE_LIST *flList, LPCWSTR szFile, LPDWORD pdwListIndex)
1113 {
1114  WIN32_FIND_DATAW wfd;
1115  HANDLE hFile = FindFirstFileW(szFile, &wfd);
1116  FILE_ENTRY *file;
1117  LPWSTR szFullPath;
1118  BOOL res;
1119 
1120  if (hFile == INVALID_HANDLE_VALUE) return;
1121 
1122  for (res = TRUE; res; res = FindNextFileW(hFile, &wfd))
1123  {
1124  if (IsDotDir(wfd.cFileName))
1125  continue;
1126 
1127  if (*pdwListIndex >= flList->num_alloc)
1128  grow_list( flList );
1129 
1130  szFullPath = wildcard_to_file(szFile, wfd.cFileName);
1131  file = &flList->feFiles[(*pdwListIndex)++];
1132  add_file_to_entry(file, szFullPath);
1133  file->bFromWildcard = TRUE;
1134  file->attributes = wfd.dwFileAttributes;
1135 
1136  if (IsAttribDir(file->attributes))
1137  flList->bAnyDirectories = TRUE;
1138 
1139  HeapFree(GetProcessHeap(), 0, szFullPath);
1140  }
1141 
1142  FindClose(hFile);
1143 }
1144 
1145 /* takes the null-separated file list and fills out the FILE_LIST */
1147 {
1148  LPCWSTR ptr = szFiles;
1149  WCHAR szCurFile[MAX_PATH];
1150  DWORD i = 0;
1151 
1152  if (!szFiles)
1153  return ERROR_INVALID_PARAMETER;
1154 
1155  flList->bAnyFromWildcard = FALSE;
1156  flList->bAnyDirectories = FALSE;
1157  flList->bAnyDontExist = FALSE;
1158  flList->num_alloc = 32;
1159  flList->dwNumFiles = 0;
1160 
1161  /* empty list */
1162  if (!szFiles[0])
1163  return ERROR_ACCESS_DENIED;
1164 
1166  flList->num_alloc * sizeof(FILE_ENTRY));
1167 
1168  while (*ptr)
1169  {
1170  if (i >= flList->num_alloc) grow_list( flList );
1171 
1172  /* change relative to absolute path */
1173  if (PathIsRelativeW(ptr))
1174  {
1175  GetCurrentDirectoryW(MAX_PATH, szCurFile);
1176  PathCombineW(szCurFile, szCurFile, ptr);
1177  flList->feFiles[i].bFromRelative = TRUE;
1178  }
1179  else
1180  {
1181  lstrcpyW(szCurFile, ptr);
1182  flList->feFiles[i].bFromRelative = FALSE;
1183  }
1184 
1185  /* parse wildcard files if they are in the filename */
1186  if (StrPBrkW(szCurFile, wWildcardChars))
1187  {
1188  parse_wildcard_files(flList, szCurFile, &i);
1189  flList->bAnyFromWildcard = TRUE;
1190  i--;
1191  }
1192  else
1193  {
1194  FILE_ENTRY *file = &flList->feFiles[i];
1195  add_file_to_entry(file, szCurFile);
1196  file->attributes = GetFileAttributesW( file->szFullPath );
1197  file->bExists = (file->attributes != INVALID_FILE_ATTRIBUTES);
1198 
1199  if (!file->bExists)
1200  flList->bAnyDontExist = TRUE;
1201 
1202  if (IsAttribDir(file->attributes))
1203  flList->bAnyDirectories = TRUE;
1204  }
1205 
1206  /* advance to the next string */
1207  ptr += lstrlenW(ptr) + 1;
1208  i++;
1209  }
1210  flList->dwNumFiles = i;
1211 
1212  return S_OK;
1213 }
1214 
1215 /* free the FILE_LIST */
1216 static void destroy_file_list(FILE_LIST *flList)
1217 {
1218  DWORD i;
1219 
1220  if (!flList || !flList->feFiles)
1221  return;
1222 
1223  for (i = 0; i < flList->dwNumFiles; i++)
1224  {
1225  HeapFree(GetProcessHeap(), 0, flList->feFiles[i].szDirectory);
1226  HeapFree(GetProcessHeap(), 0, flList->feFiles[i].szFilename);
1227  HeapFree(GetProcessHeap(), 0, flList->feFiles[i].szFullPath);
1228  }
1229 
1230  HeapFree(GetProcessHeap(), 0, flList->feFiles);
1231 }
1232 
1234 {
1235  CStringW mask(szDestPath);
1236  CStringW ext(PathFindExtensionW(szDestPath));
1237 
1238  // cut off extension before inserting a "new file" mask
1239  if (!ext.IsEmpty())
1240  {
1241  mask = mask.Left(mask.GetLength() - ext.GetLength());
1242  }
1243  mask += L" (%d)" + ext;
1244 
1245  CStringW newName;
1246 
1247  // trying to find new file name
1248  for (int i = 1; i < NEW_FILENAME_ON_COPY_TRIES; i++)
1249  {
1250  newName.Format(mask, i);
1251 
1252  if (!PathFileExistsW(newName))
1253  {
1254  return newName;
1255  }
1256  }
1257 
1258  return CStringW();
1259 }
1260 
1261 static void copy_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath)
1262 {
1263  WCHAR szFrom[MAX_PATH], szTo[MAX_PATH];
1264  FILE_LIST flFromNew, flToNew;
1265 
1266  static const WCHAR wildCardFiles[] = {'*','.','*',0};
1267 
1268  if (IsDotDir(feFrom->szFilename))
1269  return;
1270 
1271  if (PathFileExistsW(szDestPath))
1272  PathCombineW(szTo, szDestPath, feFrom->szFilename);
1273  else
1274  lstrcpyW(szTo, szDestPath);
1275 
1276  if (!(op->req->fFlags & FOF_NOCONFIRMATION) && PathFileExistsW(szTo))
1277  {
1278  CStringW newPath;
1279  if (lstrcmp(feFrom->szDirectory, szDestPath) == 0 && !(newPath = try_find_new_name(szTo)).IsEmpty())
1280  {
1281  StringCchCopyW(szTo, _countof(szTo), newPath);
1282  }
1283  else
1284  {
1285  if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FOLDER, feFrom->szFilename, op))
1286  {
1287  /* Vista returns an ERROR_CANCELLED even if user pressed "No" */
1288  if (!op->bManyItems)
1289  op->bCancelled = TRUE;
1290  return;
1291  }
1292  }
1293  }
1294 
1295  szTo[lstrlenW(szTo) + 1] = '\0';
1297 
1298  PathCombineW(szFrom, feFrom->szFullPath, wildCardFiles);
1299  szFrom[lstrlenW(szFrom) + 1] = '\0';
1300 
1301  ZeroMemory(&flFromNew, sizeof(FILE_LIST));
1302  ZeroMemory(&flToNew, sizeof(FILE_LIST));
1303  parse_file_list(&flFromNew, szFrom);
1304  parse_file_list(&flToNew, szTo);
1305 
1306  copy_files(op, FALSE, &flFromNew, &flToNew);
1307 
1308  destroy_file_list(&flFromNew);
1309  destroy_file_list(&flToNew);
1310 }
1311 
1313 {
1314  if (!(op->req->fFlags & FOF_NOCONFIRMATION) && PathFileExistsW(szTo))
1315  {
1316  CStringW newPath;
1317  if (lstrcmp(szFrom, szTo) == 0 && !(newPath = try_find_new_name(szTo)).IsEmpty())
1318  {
1319  return SHNotifyCopyFileW(op, szFrom, newPath, FALSE) == 0;
1320  }
1321 
1323  return FALSE;
1324  }
1325 
1326  return SHNotifyCopyFileW(op, szFrom, szTo, FALSE) == 0;
1327 }
1328 
1329 /* copy a file or directory to another directory */
1330 static void copy_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, const FILE_ENTRY *feTo)
1331 {
1332  if (!PathFileExistsW(feTo->szFullPath))
1334 
1335  if (IsAttribFile(feFrom->attributes))
1336  {
1337  WCHAR szDestPath[MAX_PATH];
1338 
1339  PathCombineW(szDestPath, feTo->szFullPath, feFrom->szFilename);
1340  copy_file_to_file(op, feFrom->szFullPath, szDestPath);
1341  }
1342  else if (!(op->req->fFlags & FOF_FILESONLY && feFrom->bFromWildcard))
1343  copy_dir_to_dir(op, feFrom, feTo->szFullPath);
1344 }
1345 
1346 static void create_dest_dirs(LPCWSTR szDestDir)
1347 {
1348  WCHAR dir[MAX_PATH];
1349  LPCWSTR ptr = StrChrW(szDestDir, '\\');
1350 
1351  /* make sure all directories up to last one are created */
1352  while (ptr && (ptr = StrChrW(ptr + 1, '\\')))
1353  {
1354  lstrcpynW(dir, szDestDir, ptr - szDestDir + 1);
1355 
1356  if (!PathFileExistsW(dir))
1358  }
1359 
1360  /* create last directory */
1361  if (!PathFileExistsW(szDestDir))
1362  SHNotifyCreateDirectoryW(szDestDir, NULL);
1363 }
1364 
1365 /* the FO_COPY operation */
1366 static HRESULT copy_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, FILE_LIST *flTo)
1367 {
1368  DWORD i;
1369  const FILE_ENTRY *entryToCopy;
1370  const FILE_ENTRY *fileDest = &flTo->feFiles[0];
1371 
1372  if (flFrom->bAnyDontExist)
1374 
1375  if (flTo->dwNumFiles == 0)
1376  {
1377  /* If the destination is empty, SHFileOperation should use the current directory */
1378  WCHAR curdir[MAX_PATH+1];
1379 
1380  GetCurrentDirectoryW(MAX_PATH, curdir);
1381  curdir[lstrlenW(curdir)+1] = 0;
1382 
1383  destroy_file_list(flTo);
1384  ZeroMemory(flTo, sizeof(FILE_LIST));
1385  parse_file_list(flTo, curdir);
1386  fileDest = &flTo->feFiles[0];
1387  }
1388 
1389  if (multiDest)
1390  {
1391  if (flFrom->bAnyFromWildcard)
1392  return ERROR_CANCELLED;
1393 
1394  if (flFrom->dwNumFiles != flTo->dwNumFiles)
1395  {
1396  if (flFrom->dwNumFiles != 1 && !IsAttribDir(fileDest->attributes))
1397  return ERROR_CANCELLED;
1398 
1399  /* Free all but the first entry. */
1400  for (i = 1; i < flTo->dwNumFiles; i++)
1401  {
1403  HeapFree(GetProcessHeap(), 0, flTo->feFiles[i].szFilename);
1404  HeapFree(GetProcessHeap(), 0, flTo->feFiles[i].szFullPath);
1405  }
1406 
1407  flTo->dwNumFiles = 1;
1408  }
1409  else if (IsAttribDir(fileDest->attributes))
1410  {
1411  for (i = 1; i < flTo->dwNumFiles; i++)
1412  if (!IsAttribDir(flTo->feFiles[i].attributes) ||
1413  !IsAttribDir(flFrom->feFiles[i].attributes))
1414  {
1415  return ERROR_CANCELLED;
1416  }
1417  }
1418  }
1419  else if (flFrom->dwNumFiles != 1)
1420  {
1421  if (flTo->dwNumFiles != 1 && !IsAttribDir(fileDest->attributes))
1422  return ERROR_CANCELLED;
1423 
1424  if (PathFileExistsW(fileDest->szFullPath) &&
1425  IsAttribFile(fileDest->attributes))
1426  {
1427  return ERROR_CANCELLED;
1428  }
1429 
1430  if (flTo->dwNumFiles == 1 && fileDest->bFromRelative &&
1431  !PathFileExistsW(fileDest->szFullPath))
1432  {
1433  return ERROR_CANCELLED;
1434  }
1435  }
1436 
1437  for (i = 0; i < flFrom->dwNumFiles; i++)
1438  {
1439  entryToCopy = &flFrom->feFiles[i];
1440 
1441  if ((multiDest) &&
1442  flTo->dwNumFiles > 1)
1443  {
1444  fileDest = &flTo->feFiles[i];
1445  }
1446 
1447  if (IsAttribDir(entryToCopy->attributes) &&
1448  !lstrcmpiW(entryToCopy->szFullPath, fileDest->szDirectory))
1449  {
1450  return ERROR_SUCCESS;
1451  }
1452 
1453  create_dest_dirs(fileDest->szDirectory);
1454 
1455  if (!lstrcmpiW(entryToCopy->szFullPath, fileDest->szFullPath))
1456  {
1457  if (IsAttribFile(entryToCopy->attributes))
1459  else
1460  return ERROR_SUCCESS;
1461  }
1462 
1463  if ((flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1) ||
1464  IsAttribDir(fileDest->attributes))
1465  {
1466  copy_to_dir(op, entryToCopy, fileDest);
1467  }
1468  else if (IsAttribDir(entryToCopy->attributes))
1469  {
1470  copy_dir_to_dir(op, entryToCopy, fileDest->szFullPath);
1471  }
1472  else
1473  {
1474  if (!copy_file_to_file(op, entryToCopy->szFullPath, fileDest->szFullPath))
1475  {
1476  op->req->fAnyOperationsAborted = TRUE;
1477  return ERROR_CANCELLED;
1478  }
1479  }
1480 
1481  if (op->progress != NULL)
1482  op->bCancelled |= op->progress->HasUserCancelled();
1483  /* Vista return code. XP would return e.g. ERROR_FILE_NOT_FOUND, ERROR_ALREADY_EXISTS */
1484  if (op->bCancelled)
1485  return ERROR_CANCELLED;
1486  }
1487 
1488  /* Vista return code. On XP if the used pressed "No" for the last item,
1489  * ERROR_ARENA_TRASHED would be returned */
1490  return ERROR_SUCCESS;
1491 }
1492 
1493 static BOOL confirm_delete_list(HWND hWnd, DWORD fFlags, BOOL fTrash, const FILE_LIST *flFrom)
1494 {
1495  if (flFrom->dwNumFiles > 1)
1496  {
1497  WCHAR tmp[8];
1498  const WCHAR format[] = {'%','d',0};
1499 
1500  wnsprintfW(tmp, sizeof(tmp)/sizeof(tmp[0]), format, flFrom->dwNumFiles);
1502  }
1503  else
1504  {
1505  const FILE_ENTRY *fileEntry = &flFrom->feFiles[0];
1506 
1507  if (IsAttribFile(fileEntry->attributes))
1508  return SHELL_ConfirmDialogW(hWnd, (fTrash?ASK_TRASH_FILE:ASK_DELETE_FILE), fileEntry->szFullPath, NULL);
1509  else if (!(fFlags & FOF_FILESONLY && fileEntry->bFromWildcard))
1511  }
1512  return TRUE;
1513 }
1514 
1515 /* the FO_DELETE operation */
1517 {
1518  const FILE_ENTRY *fileEntry;
1519  DWORD i;
1520  BOOL bPathExists;
1521  BOOL bTrash;
1522 
1523  if (!flFrom->dwNumFiles)
1524  return ERROR_SUCCESS;
1525 
1526  /* Windows also checks only the first item */
1527  bTrash = (op->req->fFlags & FOF_ALLOWUNDO)
1528  && TRASH_CanTrashFile(flFrom->feFiles[0].szFullPath);
1529 
1530  if (!(op->req->fFlags & FOF_NOCONFIRMATION) || (!bTrash && op->req->fFlags & FOF_WANTNUKEWARNING))
1531  if (!confirm_delete_list(op->req->hwnd, op->req->fFlags, bTrash, flFrom))
1532  {
1533  op->req->fAnyOperationsAborted = TRUE;
1534  return 0;
1535  }
1536 
1537  /* Check files. Do not delete one if one file does not exists */
1538  for (i = 0; i < flFrom->dwNumFiles; i++)
1539  {
1540  fileEntry = &flFrom->feFiles[i];
1541 
1542  if (fileEntry->attributes == (ULONG)-1)
1543  {
1544  // This is a windows 2003 server specific value which has been removed.
1545  // Later versions of windows return ERROR_FILE_NOT_FOUND.
1547  }
1548  }
1549 
1550  for (i = 0; i < flFrom->dwNumFiles; i++)
1551  {
1552  bPathExists = TRUE;
1553  fileEntry = &flFrom->feFiles[i];
1554 
1555  if (!IsAttribFile(fileEntry->attributes) &&
1556  (op->req->fFlags & FOF_FILESONLY && fileEntry->bFromWildcard))
1557  continue;
1558 
1559  if (bTrash)
1560  {
1561  BOOL bDelete;
1562  if (TRASH_TrashFile(fileEntry->szFullPath))
1563  {
1565  continue;
1566  }
1567 
1568  /* Note: Windows silently deletes the file in such a situation, we show a dialog */
1569  if (!(op->req->fFlags & FOF_NOCONFIRMATION) || (op->req->fFlags & FOF_WANTNUKEWARNING))
1570  bDelete = SHELL_ConfirmDialogW(op->req->hwnd, ASK_CANT_TRASH_ITEM, fileEntry->szFullPath, NULL);
1571  else
1572  bDelete = TRUE;
1573 
1574  if (!bDelete)
1575  {
1576  op->req->fAnyOperationsAborted = TRUE;
1577  break;
1578  }
1579  }
1580 
1581  /* delete the file or directory */
1582  if (IsAttribFile(fileEntry->attributes))
1583  {
1584  bPathExists = (ERROR_SUCCESS == SHNotifyDeleteFileW(op, fileEntry->szFullPath));
1585  }
1586  else
1587  bPathExists = SHELL_DeleteDirectoryW(op, fileEntry->szFullPath, FALSE);
1588 
1589  if (!bPathExists)
1590  {
1591  DWORD err = GetLastError();
1592 
1593  if (ERROR_FILE_NOT_FOUND == err)
1594  {
1595  // This is a windows 2003 server specific value which ahs been removed.
1596  // Later versions of windows return ERROR_FILE_NOT_FOUND.
1598  }
1599  else
1600  {
1601  return err;
1602  }
1603  }
1604 
1605  if (op->progress != NULL)
1606  op->bCancelled |= op->progress->HasUserCancelled();
1607  /* Should fire on progress dialog only */
1608  if (op->bCancelled)
1609  return ERROR_CANCELLED;
1610  }
1611 
1612  return ERROR_SUCCESS;
1613 }
1614 
1615 static void move_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath)
1616 {
1617  WCHAR szFrom[MAX_PATH], szTo[MAX_PATH];
1618  FILE_LIST flFromNew, flToNew;
1619 
1620  static const WCHAR wildCardFiles[] = {'*','.','*',0};
1621 
1622  if (IsDotDir(feFrom->szFilename))
1623  return;
1624 
1625  SHNotifyCreateDirectoryW(szDestPath, NULL);
1626 
1627  PathCombineW(szFrom, feFrom->szFullPath, wildCardFiles);
1628  szFrom[lstrlenW(szFrom) + 1] = '\0';
1629 
1630  lstrcpyW(szTo, szDestPath);
1631  szTo[lstrlenW(szDestPath) + 1] = '\0';
1632 
1633  ZeroMemory(&flFromNew, sizeof(FILE_LIST));
1634  ZeroMemory(&flToNew, sizeof(FILE_LIST));
1635  parse_file_list(&flFromNew, szFrom);
1636  parse_file_list(&flToNew, szTo);
1637 
1638  move_files(op, FALSE, &flFromNew, &flToNew);
1639 
1640  destroy_file_list(&flFromNew);
1641  destroy_file_list(&flToNew);
1642 
1643  if (PathIsDirectoryEmptyW(feFrom->szFullPath))
1645 }
1646 
1647 /* moves a file or directory to another directory */
1648 static void move_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, const FILE_ENTRY *feTo)
1649 {
1650  WCHAR szDestPath[MAX_PATH];
1651 
1652  PathCombineW(szDestPath, feTo->szFullPath, feFrom->szFilename);
1653 
1654  if (IsAttribFile(feFrom->attributes))
1655  SHNotifyMoveFileW(op, feFrom->szFullPath, szDestPath, FALSE);
1656  else if (!(op->req->fFlags & FOF_FILESONLY && feFrom->bFromWildcard))
1657  move_dir_to_dir(op, feFrom, szDestPath);
1658 }
1659 
1660 /* the FO_MOVE operation */
1661 static DWORD move_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, const FILE_LIST *flTo)
1662 {
1663  DWORD i;
1664  INT mismatched = 0;
1665 
1666  const FILE_ENTRY *entryToMove;
1667  const FILE_ENTRY *fileDest;
1668 
1669  if (!flFrom->dwNumFiles)
1670  return ERROR_SUCCESS;
1671 
1672  if (!flTo->dwNumFiles)
1673  return ERROR_FILE_NOT_FOUND;
1674 
1675  if (!(multiDest) &&
1676  flTo->dwNumFiles > 1 && flFrom->dwNumFiles > 1)
1677  {
1678  return ERROR_CANCELLED;
1679  }
1680 
1681  if (!(multiDest) &&
1682  !flFrom->bAnyDirectories &&
1683  flFrom->dwNumFiles > flTo->dwNumFiles &&
1684  !(flTo->bAnyDirectories && flTo->dwNumFiles == 1))
1685  {
1686  return ERROR_CANCELLED;
1687  }
1688 
1689  if (!PathFileExistsW(flTo->feFiles[0].szDirectory))
1690  return ERROR_CANCELLED;
1691 
1692  if (multiDest)
1693  mismatched = flFrom->dwNumFiles - flTo->dwNumFiles;
1694 
1695  fileDest = &flTo->feFiles[0];
1696  for (i = 0; i < flFrom->dwNumFiles; i++)
1697  {
1698  entryToMove = &flFrom->feFiles[i];
1699 
1700  if (!PathFileExistsW(fileDest->szDirectory))
1701  return ERROR_CANCELLED;
1702 
1703  if (multiDest)
1704  {
1705  if (i >= flTo->dwNumFiles)
1706  break;
1707  fileDest = &flTo->feFiles[i];
1708  if (mismatched && !fileDest->bExists)
1709  {
1711  flTo->feFiles[i].bExists = TRUE;
1713  }
1714  }
1715 
1716  if (fileDest->bExists && IsAttribDir(fileDest->attributes))
1717  move_to_dir(op, entryToMove, fileDest);
1718  else
1719  SHNotifyMoveFileW(op, entryToMove->szFullPath, fileDest->szFullPath, IsAttribDir(entryToMove->attributes));
1720 
1721  if (op->progress != NULL)
1722  op->bCancelled |= op->progress->HasUserCancelled();
1723  /* Should fire on progress dialog only */
1724  if (op->bCancelled)
1725  return ERROR_CANCELLED;
1726 
1727  }
1728 
1729  if (mismatched > 0)
1730  {
1731  if (flFrom->bAnyDirectories)
1732  return DE_DESTSAMETREE;
1733  else
1734  return DE_SAMEFILE;
1735  }
1736 
1737  return ERROR_SUCCESS;
1738 }
1739 
1740 /* the FO_RENAME files */
1741 static HRESULT rename_files(FILE_OPERATION *op, const FILE_LIST *flFrom, const FILE_LIST *flTo)
1742 {
1743  const FILE_ENTRY *feFrom;
1744  const FILE_ENTRY *feTo;
1745 
1746  if (flFrom->dwNumFiles != 1)
1747  return ERROR_GEN_FAILURE;
1748 
1749  if (flTo->dwNumFiles != 1)
1750  return ERROR_CANCELLED;
1751 
1752  feFrom = &flFrom->feFiles[0];
1753  feTo= &flTo->feFiles[0];
1754 
1755  /* fail if destination doesn't exist */
1756  if (!feFrom->bExists)
1758 
1759  /* fail if destination already exists */
1760  if (feTo->bExists)
1761  return ERROR_ALREADY_EXISTS;
1762 
1763  return SHNotifyMoveFileW(op, feFrom->szFullPath, feTo->szFullPath, IsAttribDir(feFrom->attributes));
1764 }
1765 
1766 /* alert the user if an unsupported flag is used */
1767 static void check_flags(FILEOP_FLAGS fFlags)
1768 {
1769  WORD wUnsupportedFlags = FOF_NO_CONNECTED_ELEMENTS |
1772 
1773  if (fFlags & wUnsupportedFlags)
1774  FIXME("Unsupported flags: %04x\n", fFlags);
1775 }
1776 
1777 /*************************************************************************
1778  * SHFileOperationW [SHELL32.@]
1779  *
1780  * See SHFileOperationA
1781  */
1783 {
1785  FILE_LIST flFrom, flTo;
1786  int ret = 0;
1787 
1788  if (!lpFileOp)
1789  return ERROR_INVALID_PARAMETER;
1790 
1791  ret = CoInitialize(NULL);
1792  if (FAILED(ret))
1793  return ret;
1794 
1795  lpFileOp->fAnyOperationsAborted = FALSE;
1796  check_flags(lpFileOp->fFlags);
1797 
1798  ZeroMemory(&flFrom, sizeof(FILE_LIST));
1799  ZeroMemory(&flTo, sizeof(FILE_LIST));
1800 
1801  if ((ret = parse_file_list(&flFrom, lpFileOp->pFrom)))
1802  return ret;
1803 
1804  if (lpFileOp->wFunc != FO_DELETE)
1805  parse_file_list(&flTo, lpFileOp->pTo);
1806 
1807  ZeroMemory(&op, sizeof(op));
1808  op.req = lpFileOp;
1809  op.totalSize.QuadPart = 0ull;
1810  op.completedSize.QuadPart = 0ull;
1811  op.bManyItems = (flFrom.dwNumFiles > 1);
1812 
1813  if (lpFileOp->wFunc != FO_RENAME && !(lpFileOp->fFlags & FOF_SILENT)) {
1814  ret = CoCreateInstance(CLSID_ProgressDialog,
1815  NULL,
1816  CLSCTX_INPROC_SERVER,
1817  IID_PPV_ARG(IProgressDialog, &op.progress));
1818  if (FAILED(ret))
1819  goto cleanup;
1820 
1821  op.progress->StartProgressDialog(op.req->hwnd, NULL, PROGDLG_NORMAL & PROGDLG_AUTOTIME, NULL);
1823  _FileOpCountManager(&op, &flFrom);
1824  }
1825 
1826  switch (lpFileOp->wFunc)
1827  {
1828  case FO_COPY:
1829  ret = copy_files(&op, op.req->fFlags & FOF_MULTIDESTFILES, &flFrom, &flTo);
1830  break;
1831  case FO_DELETE:
1832  ret = delete_files(&op, &flFrom);
1833  break;
1834  case FO_MOVE:
1835  ret = move_files(&op, op.req->fFlags & FOF_MULTIDESTFILES, &flFrom, &flTo);
1836  break;
1837  case FO_RENAME:
1838  ret = rename_files(&op, &flFrom, &flTo);
1839  break;
1840  default:
1842  break;
1843  }
1844 
1845  if (op.progress) {
1846  op.progress->StopProgressDialog();
1847  op.progress->Release();
1848  }
1849 
1850 cleanup:
1851  destroy_file_list(&flFrom);
1852 
1853  if (lpFileOp->wFunc != FO_DELETE)
1854  destroy_file_list(&flTo);
1855 
1856  if (ret == ERROR_CANCELLED)
1857  lpFileOp->fAnyOperationsAborted = TRUE;
1858 
1859  CoUninitialize();
1860 
1861  return ret;
1862 }
1863 
1864 // Used by SHFreeNameMappings
1865 static int CALLBACK _DestroyCallback(void *p, void *pData)
1866 {
1868 
1869  SHFree(lp->pszOldPath);
1870  SHFree(lp->pszNewPath);
1871 
1872  return TRUE;
1873 }
1874 
1875 /*************************************************************************
1876  * SHFreeNameMappings [shell32.246]
1877  *
1878  * Free the mapping handle returned by SHFileOperation if FOF_WANTSMAPPINGHANDLE
1879  * was specified.
1880  *
1881  * PARAMS
1882  * hNameMapping [I] handle to the name mappings used during renaming of files
1883  *
1884  * RETURNS
1885  * Nothing
1886  */
1888 {
1889  if (hNameMapping)
1890  {
1891  DSA_DestroyCallback((HDSA) hNameMapping, _DestroyCallback, NULL);
1892  }
1893 }
1894 
1895 /*************************************************************************
1896  * SheGetDirA [SHELL32.@]
1897  *
1898  * drive = 0: returns the current directory path
1899  * drive > 0: returns the current directory path of the specified drive
1900  * drive=1 -> A: drive=2 -> B: ...
1901  * returns 0 if successful
1902 */
1904 {
1905  WCHAR org_path[MAX_PATH];
1906  DWORD ret;
1907  char drv_path[3];
1908 
1909  /* change current directory to the specified drive */
1910  if (drive) {
1911  strcpy(drv_path, "A:");
1912  drv_path[0] += (char)drive-1;
1913 
1914  GetCurrentDirectoryW(MAX_PATH, org_path);
1915 
1916  SetCurrentDirectoryA(drv_path);
1917  }
1918 
1919  /* query current directory path of the specified drive */
1921 
1922  /* back to the original drive */
1923  if (drive)
1924  SetCurrentDirectoryW(org_path);
1925 
1926  if (!ret)
1927  return GetLastError();
1928 
1929  return 0;
1930 }
1931 
1932 /*************************************************************************
1933  * SheGetDirW [SHELL32.@]
1934  *
1935  * drive = 0: returns the current directory path
1936  * drive > 0: returns the current directory path of the specified drive
1937  * drive=1 -> A: drive=2 -> B: ...
1938  * returns 0 if successful
1939  */
1941 {
1942  WCHAR org_path[MAX_PATH];
1943  DWORD ret;
1944  char drv_path[3];
1945 
1946  /* change current directory to the specified drive */
1947  if (drive)
1948  {
1949  strcpy(drv_path, "A:");
1950  drv_path[0] += (char)drive-1;
1951 
1952  GetCurrentDirectoryW(MAX_PATH, org_path);
1953 
1954  SetCurrentDirectoryA(drv_path);
1955  }
1956 
1957  /* query current directory path of the specified drive */
1959 
1960  /* back to the original drive */
1961  if (drive)
1962  SetCurrentDirectoryW(org_path);
1963 
1964  if (!ret)
1965  return GetLastError();
1966 
1967  return 0;
1968 }
1969 
1970 /*************************************************************************
1971  * SheChangeDirA [SHELL32.@]
1972  *
1973  * changes the current directory to the specified path
1974  * and returns 0 if successful
1975  */
1977 {
1979  return 0;
1980  else
1981  return GetLastError();
1982 }
1983 
1984 /*************************************************************************
1985  * SheChangeDirW [SHELL32.@]
1986  *
1987  * changes the current directory to the specified path
1988  * and returns 0 if successful
1989  */
1991 {
1993  return 0;
1994  else
1995  return GetLastError();
1996 }
1997 
1998 /*************************************************************************
1999  * IsNetDrive [SHELL32.66]
2000  */
2002 {
2003  char root[4];
2004  strcpy(root, "A:\\");
2005  root[0] += (char)drive;
2006  return (GetDriveTypeA(root) == DRIVE_REMOTE);
2007 }
2008 
2009 
2010 /*************************************************************************
2011  * RealDriveType [SHELL32.524]
2012  */
2014 {
2015  char root[] = "A:\\";
2016  root[0] += (char)drive;
2017  return GetDriveTypeA(root);
2018 }
2019 
2020 /***********************************************************************
2021  * SHPathPrepareForWriteW (SHELL32.@)
2022  */
2024 {
2025  DWORD res;
2026  DWORD err;
2027  LPCWSTR realpath;
2028  int len;
2029  WCHAR* last_slash;
2030  WCHAR* temppath=NULL;
2031 
2032  TRACE("%p %p %s 0x%08x\n", hwnd, modless, debugstr_w(path), flags);
2033 
2035  FIXME("unimplemented flags 0x%08x\n", flags);
2036 
2037  /* cut off filename if necessary */
2039  {
2040  last_slash = StrRChrW(path, NULL, '\\');
2041  if (last_slash == NULL)
2042  len = 1;
2043  else
2044  len = last_slash - path + 1;
2045  temppath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2046  if (!temppath)
2047  return E_OUTOFMEMORY;
2048  StrCpyNW(temppath, path, len);
2049  realpath = temppath;
2050  }
2051  else
2052  {
2053  realpath = path;
2054  }
2055 
2056  /* try to create the directory if asked to */
2058  {
2059  if (flags & SHPPFW_ASKDIRCREATE)
2060  FIXME("treating SHPPFW_ASKDIRCREATE as SHPPFW_DIRCREATE\n");
2061 
2062  SHCreateDirectoryExW(0, realpath, NULL);
2063  }
2064 
2065  /* check if we can access the directory */
2066  res = GetFileAttributesW(realpath);
2067 
2068  HeapFree(GetProcessHeap(), 0, temppath);
2069 
2071  {
2072  err = GetLastError();
2073  if (err == ERROR_FILE_NOT_FOUND)
2075  return HRESULT_FROM_WIN32(err);
2076  }
2077  else if (res & FILE_ATTRIBUTE_DIRECTORY)
2078  return S_OK;
2079  else
2081 }
2082 
2083 /***********************************************************************
2084  * SHPathPrepareForWriteA (SHELL32.@)
2085  */
2087 {
2088  WCHAR wpath[MAX_PATH];
2089  MultiByteToWideChar( CP_ACP, 0, path, -1, wpath, MAX_PATH);
2090  return SHPathPrepareForWriteW(hwnd, modless, wpath, flags);
2091 }
2092 
2093 
2094 /*
2095  * The two following background operations were modified from filedefext.cpp
2096  * They use an inordinate amount of mutable state across the string functions,
2097  * so are not easy to follow and care is required when modifying.
2098  */
2099 
2100 DWORD WINAPI
2102 {
2103  DWORD ticks = GetTickCount();
2104  FILE_ENTRY *entryToCount;
2105 
2106  for (UINT i = 0; i < from->dwNumFiles; i++)
2107  {
2108  entryToCount = &from->feFiles[i];
2109 
2110  WCHAR theFileName[MAX_PATH];
2111  StringCchCopyW(theFileName, MAX_PATH, entryToCount->szFullPath);
2112  _FileOpCount(op, theFileName, IsAttribDir(entryToCount->attributes), &ticks);
2113  }
2114  return 0;
2115 }
2116 
2117 // All path manipulations, even when this function is nested, occur on the one buffer.
2118 static BOOL
2119 _FileOpCount(FILE_OPERATION *op, LPWSTR pwszBuf, BOOL bFolder, DWORD *ticks)
2120 {
2121  /* Find filename position */
2122  UINT cchBuf = wcslen(pwszBuf);
2123  WCHAR *pwszFilename = pwszBuf + cchBuf;
2124  size_t cchFilenameMax = MAX_PATH - cchBuf;
2125  if (!cchFilenameMax)
2126  return FALSE;
2127 
2128  if (bFolder) {
2129  *(pwszFilename++) = '\\';
2130  --cchFilenameMax;
2131  /* Find all files, FIXME: shouldn't be "*"? */
2132  StringCchCopyW(pwszFilename, cchFilenameMax, L"*");
2133  }
2134 
2135  WIN32_FIND_DATAW wfd;
2136  HANDLE hFind = FindFirstFileW(pwszBuf, &wfd);
2137  if (hFind == INVALID_HANDLE_VALUE)
2138  {
2139  ERR("FindFirstFileW %ls failed\n", pwszBuf);
2140  return FALSE;
2141  }
2142 
2143  do
2144  {
2145  if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
2146  {
2147  /* Don't process "." and ".." items */
2148  if (!wcscmp(wfd.cFileName, L".") || !wcscmp(wfd.cFileName, L".."))
2149  continue;
2150 
2151  StringCchCopyW(pwszFilename, cchFilenameMax, wfd.cFileName);
2152  _FileOpCount(op, pwszBuf, TRUE, ticks);
2153  }
2154  else
2155  {
2157  FileSize.u.LowPart = wfd.nFileSizeLow;
2158  FileSize.u.HighPart = wfd.nFileSizeHigh;
2159  op->totalSize.QuadPart += FileSize.QuadPart;
2160  }
2161  if (GetTickCount() - *ticks > (DWORD) 500)
2162  {
2163  // Check if the dialog has ended. If it has, we'll spin down.
2164  if (op->progress != NULL)
2165  op->bCancelled = op->progress->HasUserCancelled();
2166 
2167  if (op->bCancelled)
2168  break;
2169  *ticks = GetTickCount();
2170  }
2171  } while(FindNextFileW(hFind, &wfd));
2172 
2173  FindClose(hFind);
2174  return TRUE;
2175 }
static HRESULT parse_file_list(FILE_LIST *flList, LPCWSTR szFiles)
Definition: shlfileop.cpp:1146
HINSTANCE hIconInstance
Definition: shlfileop.cpp:222
#define SHCNE_MKDIR
Definition: shlobj.h:1723
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:944
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
#define IDS_FILEOOP_MOVING
Definition: shresdef.h:220
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
static const WCHAR CONFIRM_MSG_PROP[]
Definition: shlfileop.cpp:90
#define ASK_CANT_TRASH_ITEM
Definition: shell32_main.h:121
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define STM_SETICON
Definition: winuser.h:2053
static HRESULT rename_files(FILE_OPERATION *op, const FILE_LIST *flFrom, const FILE_LIST *flTo)
Definition: shlfileop.cpp:1741
#define MAKEINTRESOURCE
Definition: winuser.h:591
static void SHELL32_FreeUnicodeBuf(LPWSTR wPath)
Definition: shlfileop.cpp:357
const uint16_t * PCWSTR
Definition: typedefs.h:55
LPWSTR WINAPI StrPBrkW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
Definition: string.c:1276
GLint GLint GLsizei width
Definition: gl.h:1546
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define FOF_NOCOPYSECURITYATTRIBS
Definition: shellapi.h:149
static HICON
Definition: imagelist.c:84
#define FOF_NO_CONNECTED_ELEMENTS
Definition: shellapi.h:151
#define TRUE
Definition: types.h:120
#define SHCNE_RMDIR
Definition: shlobj.h:1724
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
Definition: path.c:1558
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
UINT WINAPI GetDriveTypeA(IN LPCSTR lpRootPathName)
Definition: disk.c:468
#define IDI_SHELL_CONFIRM_DELETE
Definition: shresdef.h:537
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
DWORD WINAPI _FileOpCountManager(FILE_OPERATION *op, const FILE_LIST *flFrom)
Definition: shlfileop.cpp:2101
SHFILEOPSTRUCTW * req
Definition: shlfileop.cpp:43
#define ERROR_SUCCESS
Definition: deptool.c:10
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
#define DWORD_PTR
Definition: treelist.c:76
#define IDYES
Definition: winuser.h:829
ULARGE_INTEGER totalSize
Definition: shlfileop.cpp:49
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static INT_PTR ConfirmMsgBox_Paint(HWND hDlg)
Definition: shlfileop.cpp:127
#define MOVEFILE_REPLACE_EXISTING
Definition: filesup.h:28
PVOID hNameMappings
Definition: shellapi.h:359
HDC WINAPI GetDC(_In_opt_ HWND)
LPWSTR szFullPath
Definition: shlfileop.cpp:60
#define pt(x, y)
Definition: drawing.c:79
#define IDS_FILEOOP_FROM
Definition: shresdef.h:223
GLsizei const GLchar ** path
Definition: glext.h:7234
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define SW_HIDE
Definition: winuser.h:762
static INT_PTR ConfirmMsgBox_Init(HWND hDlg, LPARAM lParam)
Definition: shlfileop.cpp:149
FILEOP_FLAGS fFlags
Definition: shellapi.h:347
uint16_t * PWSTR
Definition: typedefs.h:54
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define FO_COPY
Definition: shellapi.h:134
static DWORD SHELL32_AnsiToUnicodeBuf(LPCSTR aPath, LPWSTR *wPath, DWORD minChars)
Definition: shlfileop.cpp:341
#define ASK_DELETE_FILE
Definition: shell32_main.h:112
#define FOF_SILENT
Definition: shellapi.h:140
#define IDD_YESTOALL_MSGBOX
Definition: shresdef.h:352
#define CP_ACP
Definition: compat.h:99
const GLint * attribs
Definition: glext.h:10538
#define _countof(array)
Definition: fontsub.cpp:30
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:405
#define FORMAT_MESSAGE_FROM_STRING
Definition: winbase.h:402
#define IDS_OVERWRITEFILE_CAPTION
Definition: shresdef.h:118
#define ASK_TRASH_FILE
Definition: shell32_main.h:118
#define DT_WORDBREAK
Definition: winuser.h:544
#define IDS_DELETEITEM_CAPTION
Definition: shresdef.h:114
LPWSTR WINAPI StrCpyNW(LPWSTR dst, LPCWSTR src, int count)
Definition: string.c:536
static const WCHAR szFrom[]
Definition: http.c:100
static void confirm_msg_move_button(HWND hDlg, INT iId, INT *xPos, INT yOffset, BOOL bShow)
Definition: shlfileop.cpp:102
static HDC
Definition: imagelist.c:92
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:413
#define CALLBACK
Definition: compat.h:27
#define ASK_DELETE_SELECTED
Definition: shell32_main.h:117
HWND hWnd
Definition: settings.c:17
#define ERROR_NO_MORE_SEARCH_HANDLES
Definition: winerror.h:187
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
static CStringW try_find_new_name(LPCWSTR szDestPath)
Definition: shlfileop.cpp:1233
#define FO_MASK
Definition: shlfileop.cpp:34
#define FOF_ALLOWUNDO
Definition: shellapi.h:144
static HRESULT delete_files(FILE_OPERATION *op, const FILE_LIST *flFrom)
Definition: shlfileop.cpp:1516
#define IDS_OVERWRITEFOLDER_TEXT
Definition: shresdef.h:125
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define ASK_TRASH_FOLDER
Definition: shell32_main.h:119
#define FOF_WANTNUKEWARNING
Definition: shellapi.h:152
#define CALLBACK_STREAM_SWITCH
Definition: winbase.h:151
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL bAnyFromWildcard
Definition: shlfileop.cpp:71
#define ZeroMemory
Definition: winbase.h:1635
EXTERN_C DWORD WINAPI SheGetDirW(DWORD drive, LPWSTR buffer)
Definition: shlfileop.cpp:1940
void __cdecl Format(UINT nFormatID,...)
Definition: cstringt.h:668
GLuint buffer
Definition: glext.h:5915
BOOL SHELL_ConfirmYesNoW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir)
Definition: shlfileop.cpp:336
DWORD attributes
Definition: shlfileop.cpp:57
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
UINT_PTR WPARAM
Definition: windef.h:207
#define ASK_TRASH_MULTIPLE_ITEM
Definition: shell32_main.h:120
const TCHAR * szFiles[]
Definition: CImage.cpp:37
void WINAPI SHFreeNameMappings(HANDLE hNameMapping)
Definition: shlfileop.cpp:1887
static DWORD SHNotifyMoveFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BOOL isdir)
Definition: shlfileop.cpp:679
EXTERN_C INT WINAPI RealDriveType(INT drive, BOOL bQueryNet)
Definition: shlfileop.cpp:2013
BOOL bFromRelative
Definition: shlfileop.cpp:62
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
static HRESULT copy_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, FILE_LIST *flTo)
Definition: shlfileop.cpp:1366
ULARGE_INTEGER completedSize
Definition: shlfileop.cpp:48
int32_t INT_PTR
Definition: typedefs.h:62
char * LPSTR
Definition: xmlstorage.h:182
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
FILEOP_FLAGS fFlags
Definition: shellapi.h:357
#define FO_RENAME
Definition: shellapi.h:136
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_DIRECTORY
Definition: winerror.h:295
#define DT_NOPREFIX
Definition: winuser.h:537
#define lstrlenW
Definition: compat.h:407
#define IID_PPV_ARG(Itype, ppType)
#define E_FAIL
Definition: ddrawi.h:102
static void _SetOperationTitle(FILE_OPERATION *op)
Definition: shlfileop.cpp:480
Definition: match.c:390
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int32_t INT
Definition: typedefs.h:56
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:1782
#define IDI_SHELL_FOLDER_MOVE2
Definition: shresdef.h:610
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
WPARAM wParam
Definition: combotst.c:138
EXTERN_C int WINAPI IsNetDrive(int drive)
Definition: shlfileop.cpp:2001
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define lstrcpynW
Definition: compat.h:397
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
BOOL bExists
Definition: shlfileop.cpp:63
#define FO_MOVE
Definition: shellapi.h:133
EXTERN_C HRESULT WINAPI SHPathPrepareForWriteW(HWND hwnd, IUnknown *modless, LPCWSTR path, DWORD flags)
Definition: shlfileop.cpp:2023
#define MB_ICONEXCLAMATION
Definition: winuser.h:779
#define IDS_DELETEFOLDER_CAPTION
Definition: shresdef.h:115
#define DT_PATH_ELLIPSIS
Definition: winuser.h:530
IProgressDialog * progress
Definition: shlfileop.cpp:47
GLuint * ids
Definition: glext.h:5907
BOOL fAnyOperationsAborted
Definition: shellapi.h:358
static BOOL _FileOpCount(FILE_OPERATION *op, LPWSTR pwszBuf, BOOL bFolder, DWORD *ticks)
Definition: shlfileop.cpp:2119
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1032
#define SM_CXSCREEN
Definition: winuser.h:949
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void check_flags(FILEOP_FLAGS fFlags)
Definition: shlfileop.cpp:1767
#define DRIVE_REMOTE
Definition: winbase.h:250
#define IDC_YESTOALL_MESSAGE
Definition: shresdef.h:355
#define IDS_CREATEFOLDER_DENIED
Definition: shresdef.h:112
GLenum GLint GLuint mask
Definition: glext.h:6028
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
Definition: dsa.c:44
static DWORD SHNotifyCreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:421
HINSTANCE shell32_hInstance
Definition: misc.cpp:82
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
static const WCHAR szText[]
Definition: dialog.c:139
#define DT_CALCRECT
Definition: winuser.h:526
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
Definition: path.c:289
#define SHPPFW_DIRCREATE
Definition: shlobj.h:303
unsigned int BOOL
Definition: ntddk_ex.h:94
static const WCHAR wWildcardChars[]
Definition: shlfileop.cpp:39
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:802
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
DWORD num_alloc
Definition: shlfileop.cpp:69
EXTERN_C BOOL WINAPI Win32RemoveDirectoryW(LPCWSTR path)
Definition: shlfileop.cpp:475
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define debugstr_w
Definition: kernel32.h:32
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define FIXME(fmt,...)
Definition: debug.h:110
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1044
BOOL bAnyDirectories
Definition: shlfileop.cpp:72
static PVOID ptr
Definition: dispmode.c:27
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
LPCSTR lpszProgressTitle
Definition: shellapi.h:350
DWORD dwNumFiles
Definition: shlfileop.cpp:70
#define TRANSPARENT
Definition: wingdi.h:949
static void destroy_file_list(FILE_LIST *flList)
Definition: shlfileop.cpp:1216
static DWORD move_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, const FILE_LIST *flTo)
Definition: shlfileop.cpp:1661
#define FOF_NOCONFIRMATION
Definition: shellapi.h:142
#define IDA_SHELL_DELETE
Definition: shresdef.h:718
smooth NULL
Definition: ftsmooth.c:416
#define WM_GETFONT
Definition: winuser.h:1633
char ext[3]
Definition: mkdosfs.c:358
LPCWSTR lpszProgressTitle
Definition: shellapi.h:360
unsigned char
Definition: typeof.h:29
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:389
LONG_PTR LPARAM
Definition: windef.h:208
char * va_list
Definition: acmsvcex.h:78
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1756
#define IDS_FILEOOP_DELETING
Definition: shresdef.h:221
static INT_PTR CALLBACK ConfirmMsgBoxProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: shlfileop.cpp:190
static const WCHAR sizeW[]
Definition: editor.c:79
static void copy_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, const FILE_ENTRY *feTo)
Definition: shlfileop.cpp:1330
DWORD dwYesToAllMask
Definition: shlfileop.cpp:44
unsigned int dir
Definition: maze.c:112
const char * LPCSTR
Definition: xmlstorage.h:183
static BOOL SHELL_ConfirmIDs(int nKindOfDialog, SHELL_ConfirmIDstruc *ids)
Definition: shlfileop.cpp:227
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:442
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static void parse_wildcard_files(FILE_LIST *flList, LPCWSTR szFile, LPDWORD pdwListIndex)
Definition: shlfileop.cpp:1112
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
#define ASK_DELETE_FOLDER
Definition: shell32_main.h:113
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define IDS_DELETEITEM_TEXT
Definition: shresdef.h:116
struct _ULARGE_INTEGER::@3737 u
static void __inline grow_list(FILE_LIST *list)
Definition: shlfileop.cpp:1054
#define FOF_WANTMAPPINGHANDLE
Definition: shellapi.h:143
static int CALLBACK _DestroyCallback(void *p, void *pData)
Definition: shlfileop.cpp:1865
#define SM_CYSCREEN
Definition: winuser.h:950
static const WCHAR wWildcardFile[]
Definition: shlfileop.cpp:38
LPWSTR szFilename
Definition: shlfileop.cpp:59
#define TRACE(s)
Definition: solgame.cpp:4
static LPSTR pName
Definition: security.c:75
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
LPWSTR pszNewPath
Definition: shellapi.h:389
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI SetPropW(_In_ HWND, _In_ LPCWSTR, _In_opt_ HANDLE)
static void add_file_to_entry(FILE_ENTRY *feFile, LPCWSTR szFile)
Definition: shlfileop.cpp:1064
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WINE_DEFAULT_DEBUG_CHANNEL(shell)
#define debugstr_a
Definition: kernel32.h:31
LONG HRESULT
Definition: typedefs.h:77
#define ASK_DELETE_MULTIPLE_ITEM
Definition: shell32_main.h:114
#define WM_CLOSE
Definition: winuser.h:1603
#define FOF_FILESONLY
Definition: shellapi.h:145
_In_ LPCSTR pszDir
Definition: shellapi.h:580
#define IDI_SHELL_TRASH_FILE
Definition: shresdef.h:522
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
const char file[]
Definition: icontest.c:11
#define SHPPFW_ASKDIRCREATE
Definition: shlobj.h:305
int ShellMessageBoxW(HINSTANCE hInstance, HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,...)
Definition: shellord.c:337
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
unsigned short WORD
Definition: ntddk_ex.h:93
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
int WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:825
#define SetLastError(x)
Definition: compat.h:409
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define PROGDLG_AUTOTIME
Definition: shlobj.h:884
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
#define PROGDLG_NORMAL
Definition: shlobj.h:882
static BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir, FILE_OPERATION *op)
Definition: shlfileop.cpp:298
#define IDS_TRASHFOLDER_TEXT
Definition: shresdef.h:121
TCHAR szTitle[MAX_LOADSTRING]
Definition: magnifier.c:37
static DWORD SHNotifyRemoveDirectoryW(LPCWSTR path)
Definition: shlfileop.cpp:451
GLbitfield flags
Definition: glext.h:7161
static BOOL copy_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCHAR *szTo)
Definition: shlfileop.cpp:1312
#define WM_PAINT
Definition: winuser.h:1602
#define DE_DESTSAMETREE
Definition: shlfileop.c:48
BOOL bFromWildcard
Definition: shlfileop.cpp:61
#define IDS_FILEOOP_COPYING
Definition: shresdef.h:219
#define FOF_SIMPLEPROGRESS
Definition: shellapi.h:146
BOOL fAnyOperationsAborted
Definition: shellapi.h:348
static void create_dest_dirs(LPCWSTR szDestDir)
Definition: shlfileop.cpp:1346
static void move_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath)
Definition: shlfileop.cpp:1615
PVOID hNameMappings
Definition: shellapi.h:349
LPCWSTR pFrom
Definition: shellapi.h:355
int ret
EXTERN_C DWORD WINAPI SheChangeDirA(LPSTR path)
Definition: shlfileop.cpp:1976
static DWORD SHNotifyCopyFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists)
Definition: shlfileop.cpp:730
static const WCHAR L[]
Definition: oid.c:1250
HDC hdc
Definition: main.c:9
#define ASK_OVERWRITE_FILE
Definition: shell32_main.h:116
#define IDA_SHELL_COPY
Definition: shresdef.h:714
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2205
#define IDS_OVERWRITEFILE_TEXT
Definition: resource.h:50
#define IDS_CREATEFOLDER_CAPTION
Definition: shresdef.h:113
GLenum GLsizei len
Definition: glext.h:6722
#define IDS_DELETEMULTIPLE_TEXT
Definition: shresdef.h:117
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
EXTERN_C DWORD WINAPI SheChangeDirW(LPWSTR path)
Definition: shlfileop.cpp:1990
BOOL WINAPI CopyFileExW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, IN LPVOID lpData OPTIONAL, IN LPBOOL pbCancel OPTIONAL, IN DWORD dwCopyFlags)
Definition: copy.c:318
#define FOF_NORECURSEREPARSE
Definition: shellapi.h:154
#define IDS_FILEOOP_PREFLIGHT
Definition: shresdef.h:224
GLenum src
Definition: glext.h:6340
#define err(...)
#define WM_COMMAND
Definition: winuser.h:1716
#define IDC_YESTOALL_ICON
Definition: shresdef.h:354
void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
Definition: changenotify.c:340
int WINAPIV wnsprintfW(LPWSTR lpOut, int cchLimitIn, LPCWSTR lpFmt,...)
Definition: wsprintf.c:564
uint32_t DWORD_PTR
Definition: typedefs.h:63
_In_ HANDLE hFile
Definition: mswsock.h:90
BOOL WINAPI MoveWindow(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ BOOL)
static DWORD SHNotifyDeleteFileW(FILE_OPERATION *op, LPCWSTR path)
Definition: shlfileop.cpp:610
EXTERN_C BOOL WINAPI Win32CreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:435
Definition: shlfileop.cpp:55
#define lstrcmp
Definition: winbase.h:3686
EXTERN_C DWORD WINAPI Win32DeleteFileW(LPCWSTR path)
Definition: shlfileop.cpp:661
EXTERN_C HRESULT WINAPI SHPathPrepareForWriteA(HWND hwnd, IUnknown *modless, LPCSTR path, DWORD flags)
Definition: shlfileop.cpp:2086
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
DWORD CALLBACK SHCopyProgressRoutine(LARGE_INTEGER TotalFileSize, LARGE_INTEGER TotalBytesTransferred, LARGE_INTEGER StreamSize, LARGE_INTEGER StreamBytesTransferred, DWORD dwStreamNumber, DWORD dwCallbackReason, HANDLE hSourceFile, HANDLE hDestinationFile, LPVOID lpData)
Definition: shlfileop.cpp:563
LPWSTR szDirectory
Definition: shlfileop.cpp:58
#define SHCNF_PATHW
Definition: shlobj.h:1755
#define FOF_RENAMEONCOLLISION
Definition: shellapi.h:141
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3234
#define ERR(fmt,...)
Definition: debug.h:109
int WINAPI SHCreateDirectory(HWND hWnd, LPCWSTR path)
Definition: shlfileop.cpp:788
void WINAPI DSA_DestroyCallback(HDSA hdsa, PFNDSAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dsa.c:432
static BOOL confirm_delete_list(HWND hWnd, DWORD fFlags, BOOL fTrash, const FILE_LIST *flFrom)
Definition: shlfileop.cpp:1493
#define IsAttribDir(x)
Definition: shlfileop.cpp:31
static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly)
Definition: shlfileop.cpp:909
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define S_OK
Definition: intsafe.h:59
BOOL WINAPI PathIsDirectoryEmptyW(LPCWSTR lpszPath)
Definition: path.c:3910
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define IDC_YESTOALL
Definition: shresdef.h:353
#define lstrcpyW
Definition: compat.h:406
#define ERROR_CANCELLED
Definition: winerror.h:726
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
HICON hIcon
Definition: msconfig.c:44
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1991
int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:846
#define SHCNE_DELETE
Definition: shlobj.h:1722
BOOL TRASH_TrashFile(LPCWSTR wszPath)
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2248
#define NEW_FILENAME_ON_COPY_TRIES
Definition: shlfileop.cpp:36
#define HeapReAlloc
Definition: compat.h:393
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
Definition: services.c:325
#define list
Definition: rosglue.h:35
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:468
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define IDS_DELETESELECTED_TEXT
Definition: shresdef.h:120
#define MB_OK
Definition: winuser.h:784
HANDLE WINAPI GetPropW(_In_ HWND, _In_ LPCWSTR)
BOOL WINAPI MoveFileWithProgressW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN LPPROGRESS_ROUTINE lpProgressRoutine, IN LPVOID lpData, IN DWORD dwFlags)
Definition: move.c:667
#define IsAttrib(x, y)
Definition: shlfileop.cpp:29
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define ASK_OVERWRITE_FOLDER
Definition: shell32_main.h:122
#define MultiByteToWideChar
Definition: compat.h:100
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp)
Definition: shlfileop.cpp:1000
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:331
static DWORD _ConvertAtoW(PCSTR strSrc, PCWSTR *pStrDest, BOOL isList)
Definition: shlfileop.cpp:938
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1897
struct _LARGE_INTEGER::@2192 u
#define IsDotDir(x)
Definition: shlfileop.cpp:32
EXTERN_C HRESULT WINAPI SHIsFileAvailableOffline(LPCWSTR path, LPDWORD status)
Definition: shlfileop.cpp:362
BOOL SHELL_DeleteDirectoryW(FILE_OPERATION *op, LPCWSTR pszDir, BOOL bShowUI)
Definition: shlfileop.cpp:374
GLuint res
Definition: glext.h:9613
LPWSTR pszOldPath
Definition: shellapi.h:388
uint32_t * LPDWORD
Definition: typedefs.h:57
#define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND
Definition: shlfileop.cpp:53
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2044
#define IDS_TRASHMULTIPLE_TEXT
Definition: shresdef.h:123
WORD FILEOP_FLAGS
Definition: shellapi.h:211
char * cleanup(char *str)
Definition: wpickclick.c:99
CAtlStringW CStringW
Definition: atlstr.h:130
#define DE_SAMEFILE
Definition: shlfileop.c:42
#define SHPPFW_IGNOREFILENAME
Definition: shlobj.h:306
BOOL TRASH_CanTrashFile(LPCWSTR wszPath)
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
UINT op
Definition: effect.c:223
static char * dest
Definition: rtl.c:135
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
static LPWSTR wildcard_to_file(LPCWSTR szWildCard, LPCWSTR szFileName)
Definition: shlfileop.cpp:1090
#define IDS_TRASHITEM_TEXT
Definition: shresdef.h:122
const char * PCSTR
Definition: typedefs.h:51
int yOffset
Definition: appswitch.c:59
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define SHCNE_CREATE
Definition: shlobj.h:1721
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define FOF_MULTIDESTFILES
Definition: shellapi.h:138
#define IDNO
Definition: winuser.h:830
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
static void _SetOperationTexts(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest)
Definition: shlfileop.cpp:513
LPWSTR lpszCaption
Definition: shlfileop.cpp:95
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IDCANCEL
Definition: winuser.h:825
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
#define IsAttribFile(x)
Definition: shlfileop.cpp:30
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
CardRegion * from
Definition: spigame.cpp:19
LPWSTR WINAPI StrRChrW(LPCWSTR str, LPCWSTR end, WORD ch)
Definition: string.c:556
#define EXTERN_C
Definition: basetyps.h:12
LPWSTR WINAPI PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
Definition: path.c:189
int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll)
Definition: shlfileop.cpp:208
#define FO_DELETE
Definition: shellapi.h:135
#define ERROR_BAD_PATHNAME
Definition: winerror.h:233
#define WM_INITDIALOG
Definition: winuser.h:1715
LPARAM lParam
Definition: combotst.c:139
#define IDS_CANTTRASH_TEXT
Definition: shresdef.h:124
static void copy_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath)
Definition: shlfileop.cpp:1261
static void move_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, const FILE_ENTRY *feTo)
Definition: shlfileop.cpp:1648
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394
BOOL bAnyDontExist
Definition: shlfileop.cpp:73
#define IDS_FILEOOP_FROM_TO
Definition: shresdef.h:222
EXTERN_C DWORD WINAPI SheGetDirA(DWORD drive, LPSTR buffer)
Definition: shlfileop.cpp:1903
LONGLONG QuadPart
Definition: typedefs.h:112
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)
Definition: defwnd.c:17
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263
Definition: fci.c:126
struct _FILE_ENTRY FILE_ENTRY
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
FILE_ENTRY * feFiles
Definition: shlfileop.cpp:68
Definition: ps.c:97