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