ReactOS 0.4.16-dev-974-g5022a45
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-2023 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
38typedef struct
39{
44 IProgressDialog *progress;
47 WCHAR szBuilderString[50];
53
54#define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND 1026
55
56typedef struct
57{
66
67typedef struct
68{
75} FILE_LIST;
76
82static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly);
83static HRESULT copy_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, FILE_LIST *flTo);
84static DWORD move_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, const FILE_LIST *flTo);
85
87static BOOL _FileOpCount(FILE_OPERATION *op, LPWSTR pwszBuf, BOOL bFolder, DWORD *ticks);
88
89static HRESULT SHELL32_FileOpErrorToHResult(int err, BOOL AnyOperationsAborted = FALSE)
90{
91 enum { de_min = DE_SAMEFILE, de_max = 0xB7 /*DE_ERROR_MAX*/ };
92 const bool IsDeErr = (err & ~ERRORONDEST) >= de_min && (err & ~ERRORONDEST) <= de_max;
93 if (err == DE_OPCANCELLED || AnyOperationsAborted)
102 return HRESULT_FROM_WIN32(err);
103 return IsDeErr ? E_FAIL : HRESULT_FROM_WIN32(err);
104}
105
107{
108 if ((fos.fFlags & FOF_SILENT) && !fos.hwnd)
109 return FALSE;
110 return !(fos.fFlags & FOF_NOERRORUI);
111}
112
114{
115 // Refresh the parent folder if somebody changes the desktop.ini inside
117 if ((Name[0] | 32) != 'd' || _wcsicmp(Name, L"desktop.ini"))
118 return;
119 WCHAR Dir[MAX_PATH];
121 return;
124 return;
126}
127
128/* Confirm dialogs with an optional "Yes To All" as used in file operations confirmations
129 */
131{
136};
137
138/* as some buttons may be hidden and the dialog height may change we may need
139 * to move the controls */
140static void confirm_msg_move_button(HWND hDlg, INT iId, INT *xPos, INT yOffset, BOOL bShow)
141{
142 HWND hButton = GetDlgItem(hDlg, iId);
143 RECT r;
144
145 if (bShow)
146 {
147 POINT pt;
148 int width;
149
150 GetWindowRect(hButton, &r);
151 width = r.right - r.left;
152 pt.x = r.left;
153 pt.y = r.top;
154 ScreenToClient(hDlg, &pt);
155 MoveWindow(hButton, *xPos - width, pt.y - yOffset, width, r.bottom - r.top, FALSE);
156 *xPos -= width + 5;
157 }
158 else
159 ShowWindow(hButton, SW_HIDE);
160}
161
162/* Note: we paint the text manually and don't use the static control to make
163 * sure the text has the same height as the one computed in WM_INITDIALOG
164 */
166{
167 PAINTSTRUCT ps;
168 HFONT hOldFont;
169 RECT r;
170 HDC hdc;
171
172 BeginPaint(hDlg, &ps);
173 hdc = ps.hdc;
176
178 /* this will remap the rect to dialog coords */
182 SelectObject(hdc, hOldFont);
183 EndPaint(hDlg, &ps);
184
185 return TRUE;
186}
187
189{
190 struct confirm_msg_info *info = (struct confirm_msg_info *)lParam;
191 INT xPos, yOffset;
192 int width, height;
193 HFONT hOldFont;
194 HDC hdc;
195 RECT r;
196
197 SetWindowTextW(hDlg, info->lpszCaption);
199 SetWindowLongPtrW(hDlg, DWLP_USER, (LONG_PTR)info->lpszText);
201
202 /* compute the text height and resize the dialog */
204 hdc = GetDC(hDlg);
205 yOffset = r.bottom;
208 SelectObject(hdc, hOldFont);
209 yOffset -= r.bottom;
210 yOffset = min(yOffset, 35); /* don't make the dialog too small */
211 ReleaseDC(hDlg, hdc);
212
213 GetClientRect(hDlg, &r);
214 xPos = r.right - 7;
215 GetWindowRect(hDlg, &r);
216 width = r.right - r.left;
217 height = r.bottom - r.top - yOffset;
220
221 confirm_msg_move_button(hDlg, IDCANCEL, &xPos, yOffset, info->bYesToAll);
223 confirm_msg_move_button(hDlg, IDC_YESTOALL, &xPos, yOffset, info->bYesToAll);
225
226 return TRUE;
227}
228
230{
231 switch (uMsg)
232 {
233 case WM_INITDIALOG:
234 return ConfirmMsgBox_Init(hDlg, lParam);
235 case WM_PAINT:
236 return ConfirmMsgBox_Paint(hDlg);
237 case WM_COMMAND:
238 EndDialog(hDlg, wParam);
239 break;
240 case WM_CLOSE:
241 EndDialog(hDlg, IDCANCEL);
242 break;
243 }
244 return FALSE;
245}
246
248{
249 struct confirm_msg_info info;
250
251 info.lpszText = lpszText;
252 info.lpszCaption = lpszCaption;
253 info.hIcon = hIcon;
254 info.bYesToAll = bYesToAll;
256}
257
258/* confirmation dialogs content */
259typedef struct
260{
263 UINT caption_resource_id, text_resource_id;
265
267{
268 ids->hIconInstance = shell32_hInstance;
269 switch (nKindOfDialog)
270 {
271 case ASK_DELETE_FILE:
272 ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
273 ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
274 ids->text_resource_id = IDS_DELETEITEM_TEXT;
275 return TRUE;
276
278 ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
279 ids->caption_resource_id = IDS_DELETEFOLDER_CAPTION;
280 ids->text_resource_id = IDS_DELETEITEM_TEXT;
281 return TRUE;
282
284 ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
285 ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
286 ids->text_resource_id = IDS_DELETEMULTIPLE_TEXT;
287 return TRUE;
288
289 case ASK_TRASH_FILE:
290 ids->icon_resource_id = IDI_SHELL_TRASH_FILE;
291 ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
292 ids->text_resource_id = IDS_TRASHITEM_TEXT;
293 return TRUE;
294
295 case ASK_TRASH_FOLDER:
296 ids->icon_resource_id = IDI_SHELL_TRASH_FILE;
297 ids->caption_resource_id = IDS_DELETEFOLDER_CAPTION;
298 ids->text_resource_id = IDS_TRASHFOLDER_TEXT;
299 return TRUE;
300
302 ids->icon_resource_id = IDI_SHELL_TRASH_FILE;
303 ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
304 ids->text_resource_id = IDS_TRASHMULTIPLE_TEXT;
305 return TRUE;
306
308 ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
309 ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
310 ids->text_resource_id = IDS_CANTTRASH_TEXT;
311 return TRUE;
312
314 ids->icon_resource_id = IDI_SHELL_CONFIRM_DELETE;
315 ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
316 ids->text_resource_id = IDS_DELETESELECTED_TEXT;
317 return TRUE;
318
320 ids->icon_resource_id = IDI_SHELL_FOLDER_MOVE2;
321 ids->caption_resource_id = IDS_OVERWRITEFILE_CAPTION;
322 ids->text_resource_id = IDS_OVERWRITEFILE_TEXT;
323 return TRUE;
324
326 ids->icon_resource_id = IDI_SHELL_FOLDER_MOVE2;
327 ids->caption_resource_id = IDS_OVERWRITEFILE_CAPTION;
328 ids->text_resource_id = IDS_OVERWRITEFOLDER_TEXT;
329 return TRUE;
330
331 default:
332 FIXME(" Unhandled nKindOfDialog %d stub\n", nKindOfDialog);
333 }
334 return FALSE;
335}
336
337static BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir, FILE_OPERATION *op)
338{
339 WCHAR szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
341 DWORD_PTR args[1];
342 HICON hIcon;
343 int ret;
344
345 assert(nKindOfDialog >= 0 && nKindOfDialog < 32);
346 if (op && (op->dwYesToAllMask & (1 << nKindOfDialog)))
347 return TRUE;
348
349 if (!SHELL_ConfirmIDs(nKindOfDialog, &ids)) return FALSE;
350
351 LoadStringW(shell32_hInstance, ids.caption_resource_id, szCaption, sizeof(szCaption)/sizeof(WCHAR));
352 LoadStringW(shell32_hInstance, ids.text_resource_id, szText, sizeof(szText)/sizeof(WCHAR));
353
354 args[0] = (DWORD_PTR)szDir;
356 szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)args);
357 hIcon = LoadIconW(ids.hIconInstance, (LPWSTR)MAKEINTRESOURCE(ids.icon_resource_id));
358
359 ret = SHELL_ConfirmMsgBox(hWnd, szBuffer, szCaption, hIcon, op && op->bManyItems);
360 if (op)
361 {
362 if (ret == IDC_YESTOALL)
363 {
364 op->dwYesToAllMask |= (1 << nKindOfDialog);
365 ret = IDYES;
366 }
367 if (ret == IDCANCEL)
368 op->bCancelled = TRUE;
369 if (ret != IDYES)
370 op->req->fAnyOperationsAborted = TRUE;
371 }
372 return ret == IDYES;
373}
374
375BOOL SHELL_ConfirmYesNoW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir)
376{
377 return SHELL_ConfirmDialogW(hWnd, nKindOfDialog, szDir, NULL);
378}
379
380static DWORD SHELL32_AnsiToUnicodeBuf(LPCSTR aPath, LPWSTR *wPath, DWORD minChars)
381{
382 DWORD len = MultiByteToWideChar(CP_ACP, 0, aPath, -1, NULL, 0);
383
384 if (len < minChars)
385 len = minChars;
386
387 *wPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
388 if (*wPath)
389 {
390 MultiByteToWideChar(CP_ACP, 0, aPath, -1, *wPath, len);
391 return NO_ERROR;
392 }
393 return E_OUTOFMEMORY;
394}
395
397{
398 HeapFree(GetProcessHeap(), 0, wPath);
399}
400
402{
403 FIXME("(%s, %p) stub\n", debugstr_w(path), status);
404 return E_FAIL;
405}
406
409{
411 {
417 {
420 }
421 }
422
423 HRESULT hr = S_OK;
424 if (op->Callback)
425 {
426 hr = op->Callback(Event, Source, Destination, Attributes, hrOp, op->CallerCallbackData);
428 op->bCancelled = TRUE;
429 }
430 return hr;
431}
432
433/**************************************************************************
434 * SHELL_DeleteDirectory() [internal]
435 *
436 * Asks for confirmation when bShowUI is true and deletes the directory and
437 * all its subdirectories and files if necessary.
438 */
440{
441 BOOL ret = TRUE;
442 HANDLE hFind;
444 WCHAR szTemp[MAX_PATH];
445
446 /* Make sure the directory exists before eventually prompting the user */
447 PathCombineW(szTemp, pszDir, L"*");
448 hFind = FindFirstFileW(szTemp, &wfd);
449 if (hFind == INVALID_HANDLE_VALUE)
450 return FALSE;
451
452 if (FAILED(FileOpCallback(op, FOCE_PREDELETEITEM, pszDir, NULL, wfd.dwFileAttributes)))
453 return FALSE;
454
455 if (!bShowUI || (ret = SHELL_ConfirmDialogW(op->hWndOwner, ASK_DELETE_FOLDER, pszDir, NULL)))
456 {
457 do
458 {
459 if (IsDotDir(wfd.cFileName))
460 continue;
461 PathCombineW(szTemp, pszDir, wfd.cFileName);
462 if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
464 else
465 ret = (SHNotifyDeleteFileW(op, szTemp) == ERROR_SUCCESS);
466
467 if (op->progress != NULL)
468 op->bCancelled |= op->progress->HasUserCancelled();
469 } while (ret && FindNextFileW(hFind, &wfd) && !op->bCancelled);
470 }
471 FindClose(hFind);
472 if (ret)
474 FileOpCallback(op, FOCE_POSTDELETEITEM, pszDir, NULL, wfd.dwFileAttributes, ret ? S_OK : E_FAIL);
475 return ret;
476}
477
478/**************************************************************************
479 * Win32CreateDirectory [SHELL32.93]
480 *
481 * Creates a directory. Also triggers a change notify if one exists.
482 *
483 * PARAMS
484 * path [I] path to directory to create
485 *
486 * RETURNS
487 * TRUE if successful, FALSE otherwise
488 */
489
491{
492 TRACE("(%s, %p)\n", debugstr_w(path), sec);
493
494 if (CreateDirectoryW(path, sec))
495 {
497 return ERROR_SUCCESS;
498 }
499 return GetLastError();
500}
501
502/**********************************************************************/
503
505{
507}
508
509/************************************************************************
510 * Win32RemoveDirectory [SHELL32.94]
511 *
512 * Deletes a directory. Also triggers a change notify if one exists.
513 *
514 * PARAMS
515 * path [I] path to directory to delete
516 *
517 * RETURNS
518 * TRUE if successful, FALSE otherwise
519 */
521{
522 BOOL ret;
523 TRACE("(%s)\n", debugstr_w(path));
524
526 if (!ret)
527 {
528 /* Directory may be write protected */
529 DWORD dwAttr = GetFileAttributesW(path);
533 }
534 if (ret)
535 {
537 return ERROR_SUCCESS;
538 }
539 return GetLastError();
540}
541
542/***********************************************************************/
543
545{
547}
548
550 if (op->progress == NULL)
551 return;
552 WCHAR szTitle[50], szPreflight[50];
553 UINT animation_id = NULL;
554
555 switch (op->req->wFunc)
556 {
557 case FO_COPY:
559 LoadStringW(shell32_hInstance, IDS_FILEOOP_FROM_TO, op->szBuilderString, sizeof( op->szBuilderString)/sizeof(WCHAR));
560 animation_id = IDA_SHELL_COPY;
561 break;
562 case FO_DELETE:
564 LoadStringW(shell32_hInstance, IDS_FILEOOP_FROM, op->szBuilderString, sizeof( op->szBuilderString)/sizeof(WCHAR));
565 animation_id = IDA_SHELL_DELETE;
566 break;
567 case FO_MOVE:
569 LoadStringW(shell32_hInstance, IDS_FILEOOP_FROM_TO, op->szBuilderString, sizeof( op->szBuilderString)/sizeof(WCHAR));
570 animation_id = IDA_SHELL_COPY;
571 break;
572 default:
573 return;
574 }
575 LoadStringW(shell32_hInstance, IDS_FILEOOP_PREFLIGHT, szPreflight, sizeof(szPreflight)/sizeof(WCHAR));
576
577 op->progress->SetTitle(szTitle);
578 op->progress->SetLine(1, szPreflight, false, NULL);
579 op->progress->SetAnimation(shell32_hInstance, animation_id);
580}
581
583 if (op->progress == NULL || src == NULL)
584 return;
585 LPWSTR fileSpecS, pathSpecS, fileSpecD, pathSpecD;
586 WCHAR szFolderS[50], szFolderD[50], szFinalString[260];
587
588 DWORD_PTR args[2];
589
590 fileSpecS = (pathSpecS = (LPWSTR) src);
591 fileSpecD = (pathSpecD = (LPWSTR) dest);
592
593 // March across the string to get the file path and it's parent dir.
594 for (LPWSTR ptr = (LPWSTR) src; *ptr; ptr++) {
595 if (*ptr == '\\') {
596 pathSpecS = fileSpecS;
597 fileSpecS = ptr+1;
598 }
599 }
600 lstrcpynW(szFolderS, pathSpecS, min(50, fileSpecS - pathSpecS));
601 args[0] = (DWORD_PTR) szFolderS;
602
603 switch (op->req->wFunc)
604 {
605 case FO_COPY:
606 case FO_MOVE:
607 if (dest == NULL)
608 return;
609 for (LPWSTR ptr = (LPWSTR) dest; *ptr; ptr++) {
610 if (*ptr == '\\') {
611 pathSpecD = fileSpecD;
612 fileSpecD = ptr + 1;
613 }
614 }
615 lstrcpynW(szFolderD, pathSpecD, min(50, fileSpecD - pathSpecD));
616 args[1] = (DWORD_PTR) szFolderD;
617 break;
618 case FO_DELETE:
619 break;
620 default:
621 return;
622 }
623
625 op->szBuilderString, 0, 0, szFinalString, sizeof(szFinalString), (va_list*)args);
626
627 op->progress->SetLine(1, fileSpecS, false, NULL);
628 op->progress->SetLine(2, szFinalString, false, NULL);
629}
630
631
633 LARGE_INTEGER TotalFileSize,
634 LARGE_INTEGER TotalBytesTransferred,
635 LARGE_INTEGER StreamSize,
636 LARGE_INTEGER StreamBytesTransferred,
637 DWORD dwStreamNumber,
638 DWORD dwCallbackReason,
639 HANDLE hSourceFile,
640 HANDLE hDestinationFile,
641 LPVOID lpData
642) {
643 FILE_OPERATION *op = (FILE_OPERATION *) lpData;
644
645 if (op->progress) {
646 /*
647 * This is called at the start of each file. To keop less state,
648 * I'm adding the file to the completed size here, and the re-subtracting
649 * it when drawing the progress bar.
650 */
651 if (dwCallbackReason & CALLBACK_STREAM_SWITCH)
652 op->completedSize.QuadPart += TotalFileSize.QuadPart;
653
654 op->progress->SetProgress64(op->completedSize.QuadPart -
655 TotalFileSize.QuadPart +
656 TotalBytesTransferred.QuadPart
657 , op->totalSize.QuadPart);
658
659
660 op->bCancelled = op->progress->HasUserCancelled();
661 }
662
663 return 0;
664}
665
666
667/************************************************************************
668 * SHNotifyDeleteFileW [internal]
669 *
670 * Deletes a file. Also triggers a change notify if one exists.
671 *
672 * PARAMS
673 * op [I] File Operation context
674 * path [I] path to source file to move
675 *
676 * RETURNS
677 * ERORR_SUCCESS if successful
678 */
680{
681 BOOL ret;
682
683 TRACE("(%s)\n", debugstr_w(path));
684
686
688 FileSize.QuadPart = 0;
689
692 if (hFile != INVALID_HANDLE_VALUE && IsAttribFile(wfd.dwFileAttributes)) {
693 ULARGE_INTEGER tmp;
694 tmp.u.LowPart = wfd.nFileSizeLow;
695 tmp.u.HighPart = wfd.nFileSizeHigh;
697 }
698 UINT attrib = hFile != INVALID_HANDLE_VALUE ? wfd.dwFileAttributes : 0;
699 BOOL aborted = FAILED(FileOpCallback(op, FOCE_PREDELETEITEM, path, NULL, attrib));
701 if (aborted)
702 return ERROR_CANCELLED;
703
705 if (!ret)
706 {
707 /* File may be write protected or a system file */
708 DWORD dwAttr = GetFileAttributesW(path);
712 }
714 if (ret)
715 {
716 // Bit of a hack to make the progress bar move. We don't have progress inside the file, so inform when done.
719 return ERROR_SUCCESS;
720 }
721 return GetLastError();
722}
723
724/************************************************************************
725 * Win32DeleteFile [SHELL32.164]
726 *
727 * Deletes a file. Also triggers a change notify if one exists.
728 *
729 * PARAMS
730 * path [I] path to file to delete
731 *
732 * RETURNS
733 * TRUE if successful, FALSE otherwise
734 */
736{
738}
739
740/************************************************************************
741 * CheckForError [internal]
742 *
743 * Show message box if operation failed
744 *
745 * PARAMS
746 * op [I] File Operation context
747 * error [I] Error code
748 * src [I] Source file full name
749 *
750 */
752{
753 CStringW strTitle, strMask, strText;
754 LPWSTR lpMsgBuffer;
755
756 if (error == ERROR_SUCCESS || !CanShowFileOpErrorUI(*op->req))
757 return error;
758
759 strTitle.LoadStringW(op->req->wFunc == FO_COPY ? IDS_COPYERRORTITLE : IDS_MOVEERRORTITLE);
760
762 NULL,
763 error,
765 (LPWSTR)&lpMsgBuffer,
766 0,
767 NULL);
768
769 strText.Format(op->req->wFunc == FO_COPY ? IDS_COPYERROR : IDS_MOVEERROR,
771 lpMsgBuffer);
772
773 MessageBoxW(op->hWndOwner, strText, strTitle, MB_ICONERROR);
774 LocalFree(lpMsgBuffer);
775 op->bHasDisplayedError++;
776 return error;
777}
778
779/************************************************************************
780 * SHNotifyMoveFile [internal]
781 *
782 * Moves a file. Also triggers a change notify if one exists.
783 *
784 * PARAMS
785 * op [I] File Operation context
786 * src [I] path to source file to move
787 * dest [I] path to target file to move to
788 *
789 * RETURNS
790 * ERROR_SUCCESS if successful
791 */
793{
794 BOOL ret;
795
796 TRACE("(%s %s)\n", debugstr_w(src), debugstr_w(dest));
797
799
800 const BOOL IsRen = op->req->wFunc == FO_RENAME;
801 UINT attrib = GetFileAttributesW(src);
802 if (attrib == INVALID_FILE_ATTRIBUTES)
805 return ERROR_CANCELLED;
806
808
809 /* MOVEFILE_REPLACE_EXISTING fails with dirs, so try MoveFile */
810 if (!ret)
811 ret = MoveFileW(src, dest);
812 DWORD LastError = GetLastError();
813
814 if (!ret)
815 {
816 DWORD dwAttr = SHFindAttrW(dest, FALSE);
817 if (INVALID_FILE_ATTRIBUTES == dwAttr)
818 {
819 /* Source file may be write protected or a system file */
820 dwAttr = GetFileAttributesW(src);
822 {
824 {
825 ret = MoveFileW(src, dest);
826 LastError = GetLastError();
827 SetFileAttributesW(ret ? dest : src, dwAttr);
828 }
829 }
830 }
831 }
833 if (ret)
834 {
835 if (IsRen)
836 {
838 }
839 else
840 {
843 }
844 return ERROR_SUCCESS;
845 }
846 return CheckForError(op, LastError, src);
847}
848
850{
851 WCHAR tmp[] = { L"A:\\" };
852
853 if (!path || !path[0])
854 return FALSE;
855
856 if (path[1] != UNICODE_NULL && path[1] != ':')
857 return FALSE;
858
859 tmp[0] = path[0];
860
861 return GetDriveTypeW(tmp) == DRIVE_CDROM;
862}
863
864/************************************************************************
865 * SHNotifyCopyFile [internal]
866 *
867 * Copies a file. Also triggers a change notify if one exists.
868 *
869 * PARAMS
870 * src [I] path to source file to move
871 * dest [I] path to target file to move to
872 * bFailIfExists [I] if TRUE, the target file will not be overwritten if
873 * a file with this name already exists
874 *
875 * RETURNS
876 * ERROR_SUCCESS if successful
877 */
879{
880 BOOL ret;
882
883 TRACE("(%s %s %s)\n", debugstr_w(src), debugstr_w(dest), bFailIfExists ? "failIfExists" : "");
884
886
887 /* Destination file may already exist with read only attribute */
890 return ERROR_CANCELLED;
891
894
896 {
899 {
900 TRACE("[shell32, SHNotifyCopyFileW] STILL SHIT\n");
901 }
902 }
903
904 ret = CopyFileExW(src, dest, SHCopyProgressRoutine, op, &op->bCancelled, bFailIfExists);
905 const DWORD error = ret ? 0 : GetLastError();
907 if (!error)
908 {
909 // We are copying from a CD-ROM volume, which is readonly
910 if (SHIsCdRom(src))
911 {
913 attribs &= ~FILE_ATTRIBUTE_READONLY;
915 }
916
918 return ERROR_SUCCESS;
919 }
920 return CheckForError(op, error, src);
921}
922
923/*************************************************************************
924 * SHCreateDirectory [SHELL32.165]
925 *
926 * This function creates a file system folder whose fully qualified path is
927 * given by path. If one or more of the intermediate folders do not exist,
928 * they will be created as well.
929 *
930 * PARAMS
931 * hWnd [I]
932 * path [I] path of directory to create
933 *
934 * RETURNS
935 * ERROR_SUCCESS or one of the following values:
936 * ERROR_BAD_PATHNAME if the path is relative
937 * ERROR_FILE_EXISTS when a file with that name exists
938 * ERROR_PATH_NOT_FOUND can't find the path, probably invalid
939 * ERROR_INVALID_NAME if the path contains invalid chars
940 * ERROR_ALREADY_EXISTS when the directory already exists
941 * ERROR_FILENAME_EXCED_RANGE if the filename was to long to process
942 *
943 * NOTES
944 * exported by ordinal
945 * Win9x exports ANSI
946 * WinNT/2000 exports Unicode
947 */
949{
951}
952
953/*************************************************************************
954 * SHCreateDirectoryExA [SHELL32.@]
955 *
956 * This function creates a file system folder whose fully qualified path is
957 * given by path. If one or more of the intermediate folders do not exist,
958 * they will be created as well.
959 *
960 * PARAMS
961 * hWnd [I]
962 * path [I] path of directory to create
963 * sec [I] security attributes to use or NULL
964 *
965 * RETURNS
966 * ERROR_SUCCESS or one of the following values:
967 * ERROR_BAD_PATHNAME or ERROR_PATH_NOT_FOUND if the path is relative
968 * ERROR_INVALID_NAME if the path contains invalid chars
969 * ERROR_FILE_EXISTS when a file with that name exists
970 * ERROR_ALREADY_EXISTS when the directory already exists
971 * ERROR_FILENAME_EXCED_RANGE if the filename was too long to process
972 *
973 * FIXME: Not implemented yet;
974 * SHCreateDirectoryEx also verifies that the files in the directory will be visible
975 * if the path is a network path to deal with network drivers which might have a limited
976 * but unknown maximum path length. If not:
977 *
978 * If hWnd is set to a valid window handle, a message box is displayed warning
979 * the user that the files may not be accessible. If the user chooses not to
980 * proceed, the function returns ERROR_CANCELLED.
981 *
982 * If hWnd is set to NULL, no user interface is displayed and the function
983 * returns ERROR_CANCELLED.
984 */
986{
987 LPWSTR wPath;
988 DWORD retCode;
989
990 TRACE("(%s, %p)\n", debugstr_a(path), sec);
991
992 retCode = SHELL32_AnsiToUnicodeBuf(path, &wPath, 0);
993 if (!retCode)
994 {
995 retCode = SHCreateDirectoryExW(hWnd, wPath, sec);
997 }
998 return retCode;
999}
1000
1001/*************************************************************************
1002 * SHCreateDirectoryExW [SHELL32.@]
1003 *
1004 * See SHCreateDirectoryExA.
1005 */
1007{
1008 int ret = ERROR_BAD_PATHNAME;
1009 TRACE("(%p, %s, %p)\n", hWnd, debugstr_w(path), sec);
1010
1011 if (PathIsRelativeW(path))
1012 {
1014 }
1015 else
1016 {
1018 /* Refuse to work on certain error codes before trying to create directories recursively */
1019 if (ret != ERROR_SUCCESS &&
1023 {
1024 WCHAR *pEnd, *pSlash, szTemp[MAX_PATH + 1]; /* extra for PathAddBackslash() */
1025
1026 lstrcpynW(szTemp, path, MAX_PATH);
1027 pEnd = PathAddBackslashW(szTemp);
1028 pSlash = szTemp + 3;
1029
1030 while (*pSlash)
1031 {
1032 while (*pSlash && *pSlash != '\\') pSlash++;
1033 if (*pSlash)
1034 {
1035 *pSlash = 0; /* terminate path at separator */
1036
1037 ret = SHNotifyCreateDirectoryW(szTemp, pSlash + 1 == pEnd ? sec : NULL);
1038 }
1039 *pSlash++ = '\\'; /* put the separator back */
1040 }
1041 }
1042
1043 if (ret && hWnd && (ERROR_CANCELLED != ret && ERROR_ALREADY_EXISTS != ret))
1044 {
1048 }
1049 }
1050
1051 return ret;
1052}
1053
1054/*************************************************************************
1055 * SHFindAttrW [internal]
1056 *
1057 * Get the Attributes for a file or directory. The difference to GetAttributes()
1058 * is that this function will also work for paths containing wildcard characters
1059 * in its filename.
1060
1061 * PARAMS
1062 * path [I] path of directory or file to check
1063 * fileOnly [I] TRUE if only files should be found
1064 *
1065 * RETURNS
1066 * INVALID_FILE_ATTRIBUTES if the path does not exist, the actual attributes of
1067 * the first file or directory found otherwise
1068 */
1070{
1071 WIN32_FIND_DATAW wfd;
1072 BOOL b_FileMask = fileOnly && (NULL != StrPBrkW(pName, L"*?"));
1074 HANDLE hFind = FindFirstFileW(pName, &wfd);
1075
1076 TRACE("%s %d\n", debugstr_w(pName), fileOnly);
1077 if (INVALID_HANDLE_VALUE != hFind)
1078 {
1079 do
1080 {
1081 if (b_FileMask && IsAttribDir(wfd.dwFileAttributes))
1082 continue;
1083 dwAttr = wfd.dwFileAttributes;
1084 break;
1085 } while (FindNextFileW(hFind, &wfd));
1086
1087 FindClose(hFind);
1088 }
1089 return dwAttr;
1090}
1091
1092/*************************************************************************
1093 *
1094 * _ConvertAtoW helper function for SHFileOperationA
1095 *
1096 * Converts a string or string-list to unicode.
1097 */
1098static DWORD _ConvertAtoW(PCSTR strSrc, PCWSTR* pStrDest, BOOL isList)
1099{
1100 *pStrDest = NULL;
1101
1102 // If the input is null, nothing to convert.
1103 if (!strSrc)
1104 return 0;
1105
1106 // Measure the total size, depending on if it's a zero-terminated list.
1107 int sizeA = 0;
1108 if (isList)
1109 {
1110 PCSTR tmpSrc = strSrc;
1111 int size;
1112 do
1113 {
1114 size = lstrlenA(tmpSrc) + 1;
1115 sizeA += size;
1116 tmpSrc += size;
1117 } while (size != 1);
1118 }
1119 else
1120 {
1121 sizeA = lstrlenA(strSrc) + 1;
1122 }
1123
1124 // Measure the needed allocation size.
1125 int sizeW = MultiByteToWideChar(CP_ACP, 0, strSrc, sizeA, NULL, 0);
1126 if (!sizeW)
1127 return GetLastError();
1128
1129 PWSTR strDest = (PWSTR) HeapAlloc(GetProcessHeap(), 0, sizeW * sizeof(WCHAR));
1130 if (!strDest)
1131 return ERROR_OUTOFMEMORY;
1132
1133 int err = MultiByteToWideChar(CP_ACP, 0, strSrc, sizeA, strDest, sizeW);
1134 if (!err)
1135 {
1136 HeapFree(GetProcessHeap(), 0, strDest);
1137 return GetLastError();
1138 }
1139
1140 *pStrDest = strDest;
1141 return 0;
1142}
1143
1144/*************************************************************************
1145 * SHFileOperationA [SHELL32.@]
1146 *
1147 * Function to copy, move, delete and create one or more files with optional
1148 * user prompts.
1149 *
1150 * PARAMS
1151 * lpFileOp [I/O] pointer to a structure containing all the necessary information
1152 *
1153 * RETURNS
1154 * Success: ERROR_SUCCESS.
1155 * Failure: ERROR_CANCELLED.
1156 *
1157 * NOTES
1158 * exported by name
1159 */
1161{
1162 int errCode, retCode;
1163 SHFILEOPSTRUCTW nFileOp = { 0 };
1164
1165 // Convert A information to W
1166 nFileOp.hwnd = lpFileOp->hwnd;
1167 nFileOp.wFunc = lpFileOp->wFunc;
1168 nFileOp.fFlags = lpFileOp->fFlags;
1169
1170 errCode = _ConvertAtoW(lpFileOp->pFrom, &nFileOp.pFrom, TRUE);
1171 if (errCode != 0)
1172 goto cleanup;
1173
1174 if (FO_DELETE != (nFileOp.wFunc & FO_MASK))
1175 {
1176 errCode = _ConvertAtoW(lpFileOp->pTo, &nFileOp.pTo, TRUE);
1177 if (errCode != 0)
1178 goto cleanup;
1179 }
1180
1181 if (nFileOp.fFlags & FOF_SIMPLEPROGRESS)
1182 {
1183 errCode = _ConvertAtoW(lpFileOp->lpszProgressTitle, &nFileOp.lpszProgressTitle, FALSE);
1184 if (errCode != 0)
1185 goto cleanup;
1186 }
1187
1188 // Call the actual function
1189 retCode = SHFileOperationW(&nFileOp);
1190 if (retCode)
1191 {
1192 ERR("SHFileOperationW failed with 0x%x\n", retCode);
1193 }
1194
1195 // Cleanup
1196cleanup:
1197 if (nFileOp.pFrom)
1198 HeapFree(GetProcessHeap(), 0, (PVOID) nFileOp.pFrom);
1199 if (nFileOp.pTo)
1200 HeapFree(GetProcessHeap(), 0, (PVOID) nFileOp.pTo);
1201 if (nFileOp.lpszProgressTitle)
1203
1204 if (errCode != 0)
1205 {
1206 lpFileOp->fAnyOperationsAborted = TRUE;
1207 SetLastError(errCode);
1208
1209 return errCode;
1210 }
1211
1212 // Thankfully, starting with NT4 the name mappings are always unicode, so no need to convert.
1213 lpFileOp->hNameMappings = nFileOp.hNameMappings;
1214 lpFileOp->fAnyOperationsAborted = nFileOp.fAnyOperationsAborted;
1215 return retCode;
1216}
1217
1219{
1221 list->num_alloc * 2 * sizeof(*newx) );
1222 list->feFiles = newx;
1223 list->num_alloc *= 2;
1224}
1225
1226/* adds a file to the FILE_ENTRY struct
1227 */
1228static void add_file_to_entry(FILE_ENTRY *feFile, LPCWSTR szFile)
1229{
1230 DWORD dwLen = lstrlenW(szFile) + 1;
1231 LPCWSTR ptr;
1232 LPCWSTR ptr2;
1233
1234 feFile->szFullPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
1235 lstrcpyW(feFile->szFullPath, szFile);
1236
1237 ptr = StrRChrW(szFile, NULL, '\\');
1238 ptr2 = StrRChrW(szFile, NULL, '/');
1239 if (!ptr || ptr < ptr2)
1240 ptr = ptr2;
1241 if (ptr)
1242 {
1243 dwLen = ptr - szFile + 1;
1244 feFile->szDirectory = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
1245 lstrcpynW(feFile->szDirectory, szFile, dwLen);
1246
1247 dwLen = lstrlenW(feFile->szFullPath) - dwLen + 1;
1248 feFile->szFilename = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
1249 lstrcpyW(feFile->szFilename, ptr + 1); /* skip over backslash */
1250 }
1251 feFile->bFromWildcard = FALSE;
1252}
1253
1254static LPWSTR wildcard_to_file(LPCWSTR szWildCard, LPCWSTR szFileName)
1255{
1256 LPCWSTR ptr;
1257 LPCWSTR ptr2;
1258 LPWSTR szFullPath;
1259 DWORD dwDirLen, dwFullLen;
1260
1261 ptr = StrRChrW(szWildCard, NULL, '\\');
1262 ptr2 = StrRChrW(szWildCard, NULL, '/');
1263 if (!ptr || ptr < ptr2)
1264 ptr = ptr2;
1265 dwDirLen = ptr - szWildCard + 1;
1266
1267 dwFullLen = dwDirLen + lstrlenW(szFileName) + 1;
1268 szFullPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dwFullLen * sizeof(WCHAR));
1269
1270 lstrcpynW(szFullPath, szWildCard, dwDirLen + 1);
1271 lstrcatW(szFullPath, szFileName);
1272
1273 return szFullPath;
1274}
1275
1276static void parse_wildcard_files(FILE_LIST *flList, LPCWSTR szFile, LPDWORD pdwListIndex)
1277{
1278 WIN32_FIND_DATAW wfd;
1279 HANDLE hFile = FindFirstFileW(szFile, &wfd);
1281 LPWSTR szFullPath;
1282 BOOL res;
1283
1284 if (hFile == INVALID_HANDLE_VALUE) return;
1285
1286 for (res = TRUE; res; res = FindNextFileW(hFile, &wfd))
1287 {
1288 if (IsDotDir(wfd.cFileName))
1289 continue;
1290
1291 if (*pdwListIndex >= flList->num_alloc)
1292 grow_list( flList );
1293
1294 szFullPath = wildcard_to_file(szFile, wfd.cFileName);
1295 file = &flList->feFiles[(*pdwListIndex)++];
1296 add_file_to_entry(file, szFullPath);
1297 file->bFromWildcard = TRUE;
1298 file->attributes = wfd.dwFileAttributes;
1299
1300 if (IsAttribDir(file->attributes))
1301 flList->bAnyDirectories = TRUE;
1302
1303 HeapFree(GetProcessHeap(), 0, szFullPath);
1304 }
1305
1307}
1308
1309/* takes the null-separated file list and fills out the FILE_LIST */
1311{
1312 LPCWSTR ptr = szFiles;
1313 WCHAR szCurFile[MAX_PATH];
1314 DWORD i = 0;
1315
1316 if (!szFiles)
1318
1319 flList->bAnyFromWildcard = FALSE;
1320 flList->bAnyDirectories = FALSE;
1321 flList->bAnyDontExist = FALSE;
1322 flList->num_alloc = 32;
1323 flList->dwNumFiles = 0;
1324
1325 /* empty list */
1326 if (!szFiles[0])
1327 return ERROR_ACCESS_DENIED;
1328
1330 flList->num_alloc * sizeof(FILE_ENTRY));
1331
1332 while (*ptr)
1333 {
1334 if (i >= flList->num_alloc) grow_list( flList );
1335
1336 /* change relative to absolute path */
1337 if (PathIsRelativeW(ptr))
1338 {
1339 GetCurrentDirectoryW(MAX_PATH, szCurFile);
1340 PathCombineW(szCurFile, szCurFile, ptr);
1341 flList->feFiles[i].bFromRelative = TRUE;
1342 }
1343 else
1344 {
1345 lstrcpyW(szCurFile, ptr);
1346 flList->feFiles[i].bFromRelative = FALSE;
1347 }
1348
1349 /* parse wildcard files if they are in the filename */
1350 if (StrPBrkW(szCurFile, L"*?"))
1351 {
1352 parse_wildcard_files(flList, szCurFile, &i);
1353 flList->bAnyFromWildcard = TRUE;
1354 i--;
1355 }
1356 else
1357 {
1358 FILE_ENTRY *file = &flList->feFiles[i];
1359 add_file_to_entry(file, szCurFile);
1360 file->attributes = GetFileAttributesW( file->szFullPath );
1361 file->bExists = (file->attributes != INVALID_FILE_ATTRIBUTES);
1362
1363 if (!file->bExists)
1364 flList->bAnyDontExist = TRUE;
1365
1366 if (IsAttribDir(file->attributes))
1367 flList->bAnyDirectories = TRUE;
1368 }
1369
1370 /* advance to the next string */
1371 ptr += lstrlenW(ptr) + 1;
1372 i++;
1373 }
1374 flList->dwNumFiles = i;
1375
1376 return S_OK;
1377}
1378
1379/* free the FILE_LIST */
1380static void destroy_file_list(FILE_LIST *flList)
1381{
1382 DWORD i;
1383
1384 if (!flList || !flList->feFiles)
1385 return;
1386
1387 for (i = 0; i < flList->dwNumFiles; i++)
1388 {
1390 HeapFree(GetProcessHeap(), 0, flList->feFiles[i].szFilename);
1391 HeapFree(GetProcessHeap(), 0, flList->feFiles[i].szFullPath);
1392 }
1393
1394 HeapFree(GetProcessHeap(), 0, flList->feFiles);
1395}
1396
1398{
1399 CStringW mask(szDestPath);
1400 CStringW ext(PathFindExtensionW(szDestPath));
1401
1402 // cut off extension before inserting a "new file" mask
1403 if (!ext.IsEmpty())
1404 {
1405 mask = mask.Left(mask.GetLength() - ext.GetLength());
1406 }
1407 mask += L" (%d)" + ext;
1408
1409 CStringW newName;
1410
1411 // trying to find new file name
1412 for (int i = 1; i < NEW_FILENAME_ON_COPY_TRIES; i++)
1413 {
1414 newName.Format(mask, i);
1415
1416 if (!PathFileExistsW(newName))
1417 {
1418 return newName;
1419 }
1420 }
1421
1422 return CStringW();
1423}
1424
1425static void copy_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath)
1426{
1427 WCHAR szFrom[MAX_PATH], szTo[MAX_PATH];
1428 FILE_LIST flFromNew, flToNew;
1429
1430 if (feFrom->szFilename && IsDotDir(feFrom->szFilename))
1431 return;
1432
1433 if (PathFileExistsW(szDestPath))
1434 PathCombineW(szTo, szDestPath, feFrom->szFilename);
1435 else
1436 lstrcpyW(szTo, szDestPath);
1437
1438 if (PathFileExistsW(szTo))
1439 {
1440 if (op->req->fFlags & FOF_RENAMEONCOLLISION)
1441 {
1442 CStringW newPath = try_find_new_name(szTo);
1443 if (!newPath.IsEmpty())
1444 {
1445 StringCchCopyW(szTo, _countof(szTo), newPath);
1446 }
1447 }
1448 else if (!(op->req->fFlags & FOF_NOCONFIRMATION))
1449 {
1450 if (!SHELL_ConfirmDialogW(op->hWndOwner, ASK_OVERWRITE_FOLDER, feFrom->szFilename, op))
1451 {
1452 /* Vista returns an ERROR_CANCELLED even if user pressed "No" */
1453 if (!op->bManyItems)
1454 op->bCancelled = TRUE;
1455 return;
1456 }
1457 }
1458 }
1459
1460 szTo[lstrlenW(szTo) + 1] = '\0';
1462
1463 PathCombineW(szFrom, feFrom->szFullPath, L"*.*");
1464 szFrom[lstrlenW(szFrom) + 1] = '\0';
1465
1466 ZeroMemory(&flFromNew, sizeof(FILE_LIST));
1467 ZeroMemory(&flToNew, sizeof(FILE_LIST));
1468 parse_file_list(&flFromNew, szFrom);
1469 parse_file_list(&flToNew, szTo);
1470
1471 copy_files(op, FALSE, &flFromNew, &flToNew);
1472
1473 destroy_file_list(&flFromNew);
1474 destroy_file_list(&flToNew);
1475}
1476
1477static BOOL copy_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCHAR *szTo)
1478{
1479 if (PathFileExistsW(szTo))
1480 {
1481 if (op->req->fFlags & FOF_RENAMEONCOLLISION)
1482 {
1483 CStringW newPath = try_find_new_name(szTo);
1484 if (!newPath.IsEmpty())
1485 {
1486 return SHNotifyCopyFileW(op, szFrom, newPath, FALSE) == 0;
1487 }
1488 }
1489 else if (!(op->req->fFlags & FOF_NOCONFIRMATION))
1490 {
1492 return FALSE;
1493 }
1494 }
1495
1496 return SHNotifyCopyFileW(op, szFrom, szTo, FALSE) == 0;
1497}
1498
1499/* copy a file or directory to another directory */
1500static void copy_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, const FILE_ENTRY *feTo)
1501{
1502 if (!PathFileExistsW(feTo->szFullPath))
1504
1505 if (IsAttribFile(feFrom->attributes))
1506 {
1507 WCHAR szDestPath[MAX_PATH];
1508
1509 PathCombineW(szDestPath, feTo->szFullPath, feFrom->szFilename);
1510 copy_file_to_file(op, feFrom->szFullPath, szDestPath);
1511 }
1512 else if (!(op->req->fFlags & FOF_FILESONLY && feFrom->bFromWildcard))
1513 copy_dir_to_dir(op, feFrom, feTo->szFullPath);
1514}
1515
1516static void create_dest_dirs(LPCWSTR szDestDir)
1517{
1519 LPCWSTR ptr = StrChrW(szDestDir, '\\');
1520
1521 /* make sure all directories up to last one are created */
1522 while (ptr && (ptr = StrChrW(ptr + 1, '\\')))
1523 {
1524 lstrcpynW(dir, szDestDir, ptr - szDestDir + 1);
1525
1526 if (!PathFileExistsW(dir))
1528 }
1529
1530 /* create last directory */
1531 if (!PathFileExistsW(szDestDir))
1532 SHNotifyCreateDirectoryW(szDestDir, NULL);
1533}
1534
1535/* the FO_COPY operation */
1536static HRESULT copy_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, FILE_LIST *flTo)
1537{
1538 DWORD i;
1539 const FILE_ENTRY *entryToCopy;
1540 const FILE_ENTRY *fileDest = &flTo->feFiles[0];
1541
1542 if (flFrom->bAnyDontExist)
1544
1545 if (flTo->dwNumFiles == 0)
1546 {
1547 /* If the destination is empty, SHFileOperation should use the current directory */
1548 WCHAR curdir[MAX_PATH+1];
1549
1551 curdir[lstrlenW(curdir)+1] = 0;
1552
1553 destroy_file_list(flTo);
1554 ZeroMemory(flTo, sizeof(FILE_LIST));
1555 parse_file_list(flTo, curdir);
1556 fileDest = &flTo->feFiles[0];
1557 }
1558
1559 if (multiDest)
1560 {
1561 if (flFrom->bAnyFromWildcard)
1562 return ERROR_CANCELLED;
1563
1564 if (flFrom->dwNumFiles != flTo->dwNumFiles)
1565 {
1566 if (flFrom->dwNumFiles != 1 && !IsAttribDir(fileDest->attributes))
1567 return ERROR_CANCELLED;
1568
1569 /* Free all but the first entry. */
1570 for (i = 1; i < flTo->dwNumFiles; i++)
1571 {
1575 }
1576
1577 flTo->dwNumFiles = 1;
1578 }
1579 else if (IsAttribDir(fileDest->attributes))
1580 {
1581 for (i = 1; i < flTo->dwNumFiles; i++)
1582 if (!IsAttribDir(flTo->feFiles[i].attributes) ||
1583 !IsAttribDir(flFrom->feFiles[i].attributes))
1584 {
1585 return ERROR_CANCELLED;
1586 }
1587 }
1588 }
1589 else if (flFrom->dwNumFiles != 1)
1590 {
1591 if (flTo->dwNumFiles != 1 && !IsAttribDir(fileDest->attributes))
1592 return ERROR_CANCELLED;
1593
1594 if (PathFileExistsW(fileDest->szFullPath) &&
1595 IsAttribFile(fileDest->attributes))
1596 {
1597 return ERROR_CANCELLED;
1598 }
1599
1600 if (flTo->dwNumFiles == 1 && fileDest->bFromRelative &&
1601 !PathFileExistsW(fileDest->szFullPath))
1602 {
1603 return ERROR_CANCELLED;
1604 }
1605 }
1606
1607 for (i = 0; i < flFrom->dwNumFiles; i++)
1608 {
1609 entryToCopy = &flFrom->feFiles[i];
1610
1611 if ((multiDest) &&
1612 flTo->dwNumFiles > 1)
1613 {
1614 fileDest = &flTo->feFiles[i];
1615 }
1616
1617 if (IsAttribDir(entryToCopy->attributes) &&
1618 !lstrcmpiW(entryToCopy->szFullPath, fileDest->szDirectory))
1619 {
1620 return ERROR_SUCCESS;
1621 }
1622
1623 create_dest_dirs(fileDest->szDirectory);
1624
1625 if (!lstrcmpiW(entryToCopy->szFullPath, fileDest->szFullPath))
1626 {
1627 if (IsAttribFile(entryToCopy->attributes))
1629 else
1630 return ERROR_SUCCESS;
1631 }
1632
1633 if ((flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1) ||
1634 IsAttribDir(fileDest->attributes))
1635 {
1636 copy_to_dir(op, entryToCopy, fileDest);
1637 }
1638 else if (IsAttribDir(entryToCopy->attributes))
1639 {
1640 copy_dir_to_dir(op, entryToCopy, fileDest->szFullPath);
1641 }
1642 else
1643 {
1644 if (!copy_file_to_file(op, entryToCopy->szFullPath, fileDest->szFullPath))
1645 {
1646 op->req->fAnyOperationsAborted = TRUE;
1647 return ERROR_CANCELLED;
1648 }
1649 }
1650
1651 if (op->progress != NULL)
1652 op->bCancelled |= op->progress->HasUserCancelled();
1653 /* Vista return code. XP would return e.g. ERROR_FILE_NOT_FOUND, ERROR_ALREADY_EXISTS */
1654 if (op->bCancelled)
1655 return ERROR_CANCELLED;
1656 }
1657
1658 /* Vista return code. On XP if the used pressed "No" for the last item,
1659 * ERROR_ARENA_TRASHED would be returned */
1660 return ERROR_SUCCESS;
1661}
1662
1663static BOOL confirm_delete_list(HWND hWnd, DWORD fFlags, BOOL fTrash, const FILE_LIST *flFrom)
1664{
1665 if (flFrom->dwNumFiles > 1)
1666 {
1667 WCHAR tmp[8];
1668
1669 wnsprintfW(tmp, sizeof(tmp)/sizeof(tmp[0]), L"%d", flFrom->dwNumFiles);
1671 }
1672 else
1673 {
1674 const FILE_ENTRY *fileEntry = &flFrom->feFiles[0];
1675
1676 if (IsAttribFile(fileEntry->attributes))
1678 else if (!(fFlags & FOF_FILESONLY && fileEntry->bFromWildcard))
1680 }
1681 return TRUE;
1682}
1683
1684/* the FO_DELETE operation */
1686{
1687 const FILE_ENTRY *fileEntry;
1688 DWORD i;
1689 BOOL bPathExists;
1690 BOOL bTrash;
1691
1692 if (!flFrom->dwNumFiles)
1693 return ERROR_SUCCESS;
1694
1695 /* Windows also checks only the first item */
1696 bTrash = (op->req->fFlags & FOF_ALLOWUNDO)
1697 && TRASH_CanTrashFile(flFrom->feFiles[0].szFullPath);
1698
1699 BOOL confirm = !(op->req->fFlags & FOF_NOCONFIRMATION);
1700 if (bTrash && SHELL_GetSetting(SSF_NOCONFIRMRECYCLE, fNoConfirmRecycle))
1701 confirm = FALSE;
1702 if (confirm || (!bTrash && op->req->fFlags & FOF_WANTNUKEWARNING))
1703 if (!confirm_delete_list(op->hWndOwner, op->req->fFlags, bTrash, flFrom))
1704 {
1705 op->req->fAnyOperationsAborted = TRUE;
1706 return 0;
1707 }
1708
1709 /* Check files. Do not delete one if one file does not exists */
1710 for (i = 0; i < flFrom->dwNumFiles; i++)
1711 {
1712 fileEntry = &flFrom->feFiles[i];
1713
1714 if (fileEntry->attributes == (ULONG)-1)
1715 {
1716 // This is a windows 2003 server specific value which has been removed.
1717 // Later versions of windows return ERROR_FILE_NOT_FOUND.
1719 }
1720 }
1721
1722 for (i = 0; i < flFrom->dwNumFiles; i++)
1723 {
1724 bPathExists = TRUE;
1725 fileEntry = &flFrom->feFiles[i];
1726
1727 if (!IsAttribFile(fileEntry->attributes) &&
1728 (op->req->fFlags & FOF_FILESONLY && fileEntry->bFromWildcard))
1729 continue;
1730
1731 if (bTrash)
1732 {
1733 BOOL bDelete;
1734 if (TRASH_TrashFile(fileEntry->szFullPath))
1735 {
1736 UINT event = IsAttribFile(fileEntry->attributes) ? SHCNE_DELETE : SHCNE_RMDIR;
1738 continue;
1739 }
1740
1741 /* Note: Windows silently deletes the file in such a situation, we show a dialog */
1742 if (!(op->req->fFlags & FOF_NOCONFIRMATION) || (op->req->fFlags & FOF_WANTNUKEWARNING))
1743 bDelete = SHELL_ConfirmDialogW(op->hWndOwner, ASK_CANT_TRASH_ITEM, fileEntry->szFullPath, NULL);
1744 else
1745 bDelete = TRUE;
1746
1747 if (!bDelete)
1748 {
1749 op->req->fAnyOperationsAborted = TRUE;
1750 break;
1751 }
1752 }
1753
1754 /* delete the file or directory */
1755 if (IsAttribFile(fileEntry->attributes))
1756 bPathExists = (ERROR_SUCCESS == SHNotifyDeleteFileW(op, fileEntry->szFullPath));
1757 else
1758 bPathExists = SHELL_DeleteDirectoryW(op, fileEntry->szFullPath, FALSE);
1759
1760 if (!bPathExists)
1761 {
1763
1765 {
1766 // This is a windows 2003 server specific value which ahs been removed.
1767 // Later versions of windows return ERROR_FILE_NOT_FOUND.
1769 }
1770 else
1771 {
1772 return err;
1773 }
1774 }
1775
1776 if (op->progress != NULL)
1777 op->bCancelled |= op->progress->HasUserCancelled();
1778 /* Should fire on progress dialog only */
1779 if (op->bCancelled)
1780 return ERROR_CANCELLED;
1781 }
1782
1783 return ERROR_SUCCESS;
1784}
1785
1786static void move_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath)
1787{
1788 WCHAR szFrom[MAX_PATH], szTo[MAX_PATH];
1789 FILE_LIST flFromNew, flToNew;
1790
1791 if (feFrom->szFilename && IsDotDir(feFrom->szFilename))
1792 return;
1793
1795 if (FAILED(FileOpCallback(op, FOCE_PREMOVEITEM, feFrom->szFullPath, szDestPath, attrib)))
1796 return;
1797
1798 SHNotifyCreateDirectoryW(szDestPath, NULL);
1799
1800 PathCombineW(szFrom, feFrom->szFullPath, L"*.*");
1801 szFrom[lstrlenW(szFrom) + 1] = '\0';
1802
1803 lstrcpyW(szTo, szDestPath);
1804 szTo[lstrlenW(szDestPath) + 1] = '\0';
1805
1806 ZeroMemory(&flFromNew, sizeof(FILE_LIST));
1807 ZeroMemory(&flToNew, sizeof(FILE_LIST));
1808 parse_file_list(&flFromNew, szFrom);
1809 parse_file_list(&flToNew, szTo);
1810
1811 move_files(op, FALSE, &flFromNew, &flToNew);
1812
1813 destroy_file_list(&flFromNew);
1814 destroy_file_list(&flToNew);
1815
1816 BOOL success = FALSE;
1817 if (PathIsDirectoryEmptyW(feFrom->szFullPath))
1819 FileOpCallback(op, FOCE_POSTMOVEITEM, feFrom->szFullPath, szDestPath, attrib, success ? S_OK : E_FAIL);
1820}
1821
1822static BOOL move_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCHAR *szTo)
1823{
1824 if (PathFileExistsW(szTo))
1825 {
1826 if (op->req->fFlags & FOF_RENAMEONCOLLISION)
1827 {
1828 CStringW newPath = try_find_new_name(szTo);
1829 if (!newPath.IsEmpty())
1830 {
1831 return SHNotifyMoveFileW(op, szFrom, newPath, FALSE) == 0;
1832 }
1833 }
1834 else if (!(op->req->fFlags & FOF_NOCONFIRMATION))
1835 {
1837 return FALSE;
1838 }
1839 }
1840
1841 return SHNotifyMoveFileW(op, szFrom, szTo, FALSE) == 0;
1842}
1843
1844/* moves a file or directory to another directory */
1845static void move_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, const FILE_ENTRY *feTo)
1846{
1847 if (feFrom->attributes == INVALID_FILE_ATTRIBUTES)
1848 return;
1849
1850 if (!PathFileExistsW(feTo->szFullPath))
1852
1853 WCHAR szDestPath[MAX_PATH];
1854 PathCombineW(szDestPath, feTo->szFullPath, feFrom->szFilename);
1855
1856 if (IsAttribFile(feFrom->attributes))
1857 move_file_to_file(op, feFrom->szFullPath, szDestPath);
1858 else if (!(op->req->fFlags & FOF_FILESONLY && feFrom->bFromWildcard))
1859 move_dir_to_dir(op, feFrom, szDestPath);
1860}
1861
1862/* the FO_MOVE operation */
1863static DWORD move_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, const FILE_LIST *flTo)
1864{
1865 DWORD i;
1866 INT mismatched = 0;
1867
1868 const FILE_ENTRY *entryToMove;
1869 const FILE_ENTRY *fileDest;
1870
1871 if (!flFrom->dwNumFiles)
1872 return ERROR_SUCCESS;
1873
1874 if (!flTo->dwNumFiles)
1875 return ERROR_FILE_NOT_FOUND;
1876
1877 if (flFrom->bAnyDontExist)
1879
1880 if (!(multiDest) &&
1881 flTo->dwNumFiles > 1 && flFrom->dwNumFiles > 1)
1882 {
1883 return ERROR_CANCELLED;
1884 }
1885
1886 if (!(multiDest) &&
1887 !flFrom->bAnyDirectories &&
1888 flFrom->dwNumFiles > flTo->dwNumFiles &&
1889 !(flTo->bAnyDirectories && flTo->dwNumFiles == 1))
1890 {
1891 return ERROR_CANCELLED;
1892 }
1893
1894 if (!PathFileExistsW(flTo->feFiles[0].szDirectory))
1895 return ERROR_CANCELLED;
1896
1897 if (multiDest)
1898 mismatched = flFrom->dwNumFiles - flTo->dwNumFiles;
1899
1900 fileDest = &flTo->feFiles[0];
1901 for (i = 0; i < flFrom->dwNumFiles; i++)
1902 {
1903 entryToMove = &flFrom->feFiles[i];
1904
1905 if (!PathFileExistsW(fileDest->szDirectory))
1906 return ERROR_CANCELLED;
1907
1908 if (multiDest)
1909 {
1910 if (i >= flTo->dwNumFiles)
1911 break;
1912 fileDest = &flTo->feFiles[i];
1913 if (mismatched && !fileDest->bExists)
1914 {
1916 flTo->feFiles[i].bExists = TRUE;
1918 }
1919 }
1920
1921 if ((flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1) ||
1922 IsAttribDir(fileDest->attributes))
1923 {
1924 move_to_dir(op, entryToMove, fileDest);
1925 }
1926 else if (IsAttribDir(entryToMove->attributes))
1927 {
1928 move_dir_to_dir(op, entryToMove, fileDest->szFullPath);
1929 }
1930 else
1931 {
1932 if (!move_file_to_file(op, entryToMove->szFullPath, fileDest->szFullPath))
1933 {
1934 op->req->fAnyOperationsAborted = TRUE;
1935 return ERROR_CANCELLED;
1936 }
1937 }
1938
1939 if (op->progress != NULL)
1940 op->bCancelled |= op->progress->HasUserCancelled();
1941 /* Should fire on progress dialog only */
1942 if (op->bCancelled)
1943 return ERROR_CANCELLED;
1944
1945 }
1946
1947 if (mismatched > 0)
1948 {
1949 if (flFrom->bAnyDirectories)
1950 return DE_DESTSAMETREE;
1951 else
1952 return DE_SAMEFILE;
1953 }
1954
1955 return ERROR_SUCCESS;
1956}
1957
1958/* the FO_RENAME files */
1959static HRESULT rename_files(FILE_OPERATION *op, const FILE_LIST *flFrom, const FILE_LIST *flTo)
1960{
1961 const FILE_ENTRY *feFrom;
1962 const FILE_ENTRY *feTo;
1963
1964 if (flFrom->dwNumFiles != 1)
1965 return ERROR_GEN_FAILURE;
1966
1967 if (flTo->dwNumFiles != 1)
1968 return ERROR_CANCELLED;
1969
1970 feFrom = &flFrom->feFiles[0];
1971 feTo= &flTo->feFiles[0];
1972
1973 /* fail if destination doesn't exist */
1974 if (!feFrom->bExists)
1976
1977 /* fail if destination already exists */
1978 if (feTo->bExists)
1979 return ERROR_ALREADY_EXISTS;
1980
1981 return SHNotifyMoveFileW(op, feFrom->szFullPath, feTo->szFullPath, IsAttribDir(feFrom->attributes));
1982}
1983
1984/* alert the user if an unsupported flag is used */
1985static void check_flags(FILEOP_FLAGS fFlags)
1986{
1987 WORD wUnsupportedFlags = FOF_NO_CONNECTED_ELEMENTS |
1990
1991 if (fFlags & wUnsupportedFlags)
1992 FIXME("Unsupported flags: %04x\n", fFlags);
1993}
1994
1995#define GET_FILENAME(fe) ((fe)->szFilename[0] ? (fe)->szFilename : (fe)->szFullPath)
1996
1997static DWORD
1999{
2000 DWORD i, k, dwNumDest;
2001 WCHAR szFrom[MAX_PATH], szTo[MAX_PATH];
2002 CStringW strTitle, strText;
2003 const FILE_ENTRY *feFrom;
2004 const FILE_ENTRY *feTo;
2005 const SHFILEOPSTRUCTW *lpFileOp = op.req;
2006 UINT wFunc = lpFileOp->wFunc;
2007
2008 dwNumDest = flTo->dwNumFiles;
2009
2010 if (wFunc != FO_COPY && wFunc != FO_MOVE)
2011 return ERROR_SUCCESS;
2012
2013 for (k = 0; k < dwNumDest; ++k)
2014 {
2015 feTo = &flTo->feFiles[k];
2016 for (i = 0; i < flFrom->dwNumFiles; ++i)
2017 {
2018 feFrom = &flFrom->feFiles[i];
2019 StringCbCopyW(szFrom, sizeof(szFrom), feFrom->szFullPath);
2020 StringCbCopyW(szTo, sizeof(szTo), feTo->szFullPath);
2021 if (IsAttribDir(feTo->attributes))
2022 {
2023 PathAppendW(szTo, feFrom->szFilename);
2024 }
2025
2026 // same path?
2027 if (lstrcmpiW(szFrom, szTo) == 0 &&
2028 (wFunc == FO_MOVE || !(lpFileOp->fFlags & FOF_RENAMEONCOLLISION)))
2029 {
2030 if (CanShowFileOpErrorUI(*lpFileOp))
2031 {
2032 if (wFunc == FO_MOVE)
2033 {
2034 strTitle.LoadStringW(IDS_MOVEERRORTITLE);
2035 if (IsAttribDir(feFrom->attributes))
2037 else
2038 strText.Format(IDS_MOVEERRORSAME, GET_FILENAME(feFrom));
2039 }
2040 else
2041 {
2042 strTitle.LoadStringW(IDS_COPYERRORTITLE);
2043 strText.Format(IDS_COPYERRORSAME, GET_FILENAME(feFrom));
2044 return ERROR_SUCCESS;
2045 }
2046 MessageBoxW(op.hWndOwner, strText, strTitle, MB_ICONERROR);
2047 op.bHasDisplayedError++;
2048 return DE_SAMEFILE;
2049 }
2050 return DE_OPCANCELLED;
2051 }
2052
2053 // subfolder?
2054 if (IsAttribDir(feFrom->attributes))
2055 {
2056 size_t cchFrom = PathAddBackslashW(szFrom) - szFrom;
2057 size_t cchTo = PathAddBackslashW(szTo) - szTo;
2058 if (cchFrom < cchTo)
2059 {
2060 WCHAR ch = szTo[cchFrom];
2061 szTo[cchFrom] = 0;
2062 int compare = lstrcmpiW(szFrom, szTo);
2063 szTo[cchFrom] = ch;
2064
2065 if (compare == 0)
2066 {
2067 if (CanShowFileOpErrorUI(*lpFileOp))
2068 {
2069 if (wFunc == FO_MOVE)
2070 {
2071 strTitle.LoadStringW(IDS_MOVEERRORTITLE);
2072 strText.Format(IDS_MOVEERRORSUBFOLDER, GET_FILENAME(feFrom));
2073 }
2074 else
2075 {
2076 strTitle.LoadStringW(IDS_COPYERRORTITLE);
2077 strText.Format(IDS_COPYERRORSUBFOLDER, GET_FILENAME(feFrom));
2078 }
2079 MessageBoxW(op.hWndOwner, strText, strTitle, MB_ICONERROR);
2080 op.bHasDisplayedError++;
2081 return DE_DESTSUBTREE;
2082 }
2083 return DE_OPCANCELLED;
2084 }
2085 }
2086 }
2087 }
2088 }
2089
2090 return ERROR_SUCCESS;
2091}
2092
2094{
2096 FILE_LIST flFrom, flTo;
2097 int ret = 0;
2098
2099 if (!lpFileOp)
2101
2103 if (FAILED(ret))
2104 return ret;
2105
2106 lpFileOp->fAnyOperationsAborted = FALSE;
2107 check_flags(lpFileOp->fFlags);
2108
2109 ZeroMemory(&flFrom, sizeof(FILE_LIST));
2110 ZeroMemory(&flTo, sizeof(FILE_LIST));
2111
2112 if ((ret = parse_file_list(&flFrom, lpFileOp->pFrom)))
2113 return ret;
2114
2115 if (lpFileOp->wFunc != FO_DELETE)
2116 parse_file_list(&flTo, lpFileOp->pTo);
2117
2118 ZeroMemory(&op, sizeof(op));
2119 op.req = lpFileOp;
2120 op.totalSize.QuadPart = 0ull;
2121 op.completedSize.QuadPart = 0ull;
2122 op.bManyItems = (flFrom.dwNumFiles > 1);
2123 op.Callback = Callback;
2124 op.CallerCallbackData = CallerData;
2125 op.hWndOwner = GetAncestor(lpFileOp->hwnd, GA_ROOT);
2126
2127 ret = validate_operation(op, &flFrom, &flTo);
2128 if (ret)
2129 goto cleanup;
2130
2131 if (lpFileOp->wFunc != FO_RENAME && !(lpFileOp->fFlags & FOF_SILENT)) {
2132 ret = CoCreateInstance(CLSID_ProgressDialog,
2133 NULL,
2134 CLSCTX_INPROC_SERVER,
2135 IID_PPV_ARG(IProgressDialog, &op.progress));
2136 if (FAILED(ret))
2137 goto cleanup;
2138
2139 op.progress->StartProgressDialog(op.hWndOwner, NULL, PROGDLG_NORMAL & PROGDLG_AUTOTIME, NULL);
2141 _FileOpCountManager(&op, &flFrom);
2142 }
2143
2145
2146 switch (lpFileOp->wFunc)
2147 {
2148 case FO_COPY:
2149 ret = copy_files(&op, op.req->fFlags & FOF_MULTIDESTFILES, &flFrom, &flTo);
2150 break;
2151 case FO_DELETE:
2152 ret = delete_files(&op, &flFrom);
2153 break;
2154 case FO_MOVE:
2155 ret = move_files(&op, op.req->fFlags & FOF_MULTIDESTFILES, &flFrom, &flTo);
2156 break;
2157 case FO_RENAME:
2158 ret = rename_files(&op, &flFrom, &flTo);
2159 break;
2160 default:
2162 break;
2163 }
2164
2165 if (op.progress) {
2166 op.progress->StopProgressDialog();
2167 op.progress->Release();
2168 }
2169
2170cleanup:
2171 destroy_file_list(&flFrom);
2172
2173 if (lpFileOp->wFunc != FO_DELETE)
2174 destroy_file_list(&flTo);
2175 else if (lpFileOp->fFlags & FOF_ALLOWUNDO)
2177
2178 if (ret == ERROR_CANCELLED)
2179 lpFileOp->fAnyOperationsAborted = TRUE;
2182
2184 TRACE("SHFO FINISHOPERATIONS %#x (%d)\n", hr, ret);
2186
2187 if (FAILED(hr) && CanShowFileOpErrorUI(*op.req) && !op.bHasDisplayedError)
2188 SHELL_ErrorBox(op.hWndOwner, hr);
2189
2191
2192 return ret;
2193}
2194
2195/*************************************************************************
2196 * SHFileOperationW [SHELL32.@]
2197 *
2198 * See SHFileOperationA
2199 */
2201{
2202 return SHELL32_FileOperation(lpFileOp, NULL, NULL);
2203}
2204
2205// Used by SHFreeNameMappings
2206static int CALLBACK _DestroyCallback(void *p, void *pData)
2207{
2209
2210 SHFree(lp->pszOldPath);
2211 SHFree(lp->pszNewPath);
2212
2213 return TRUE;
2214}
2215
2216/*************************************************************************
2217 * SHFreeNameMappings [shell32.246]
2218 *
2219 * Free the mapping handle returned by SHFileOperation if FOF_WANTSMAPPINGHANDLE
2220 * was specified.
2221 *
2222 * PARAMS
2223 * hNameMapping [I] handle to the name mappings used during renaming of files
2224 *
2225 * RETURNS
2226 * Nothing
2227 */
2229{
2230 if (hNameMapping)
2231 {
2233 }
2234}
2235
2236/*************************************************************************
2237 * SheGetDirA [SHELL32.@]
2238 *
2239 * drive = 0: returns the current directory path
2240 * drive > 0: returns the current directory path of the specified drive
2241 * drive=1 -> A: drive=2 -> B: ...
2242 * returns 0 if successful
2243*/
2245{
2246 WCHAR org_path[MAX_PATH];
2247 DWORD ret;
2248 char drv_path[3];
2249
2250 /* change current directory to the specified drive */
2251 if (drive) {
2252 strcpy(drv_path, "A:");
2253 drv_path[0] += (char)drive-1;
2254
2255 GetCurrentDirectoryW(MAX_PATH, org_path);
2256
2257 SetCurrentDirectoryA(drv_path);
2258 }
2259
2260 /* query current directory path of the specified drive */
2262
2263 /* back to the original drive */
2264 if (drive)
2265 SetCurrentDirectoryW(org_path);
2266
2267 if (!ret)
2268 return GetLastError();
2269
2270 return 0;
2271}
2272
2273/*************************************************************************
2274 * SheGetDirW [SHELL32.@]
2275 *
2276 * drive = 0: returns the current directory path
2277 * drive > 0: returns the current directory path of the specified drive
2278 * drive=1 -> A: drive=2 -> B: ...
2279 * returns 0 if successful
2280 */
2282{
2283 WCHAR org_path[MAX_PATH];
2284 DWORD ret;
2285 char drv_path[3];
2286
2287 /* change current directory to the specified drive */
2288 if (drive)
2289 {
2290 strcpy(drv_path, "A:");
2291 drv_path[0] += (char)drive-1;
2292
2293 GetCurrentDirectoryW(MAX_PATH, org_path);
2294
2295 SetCurrentDirectoryA(drv_path);
2296 }
2297
2298 /* query current directory path of the specified drive */
2300
2301 /* back to the original drive */
2302 if (drive)
2303 SetCurrentDirectoryW(org_path);
2304
2305 if (!ret)
2306 return GetLastError();
2307
2308 return 0;
2309}
2310
2311/*************************************************************************
2312 * SheChangeDirA [SHELL32.@]
2313 *
2314 * changes the current directory to the specified path
2315 * and returns 0 if successful
2316 */
2318{
2320 return 0;
2321 else
2322 return GetLastError();
2323}
2324
2325/*************************************************************************
2326 * SheChangeDirW [SHELL32.@]
2327 *
2328 * changes the current directory to the specified path
2329 * and returns 0 if successful
2330 */
2332{
2334 return 0;
2335 else
2336 return GetLastError();
2337}
2338
2339/*************************************************************************
2340 * IsNetDrive [SHELL32.66]
2341 */
2343{
2344 char root[4];
2345 strcpy(root, "A:\\");
2346 root[0] += (char)drive;
2347 return (GetDriveTypeA(root) == DRIVE_REMOTE);
2348}
2349
2350
2351/*************************************************************************
2352 * RealDriveType [SHELL32.524]
2353 */
2355{
2356 char root[] = "A:\\";
2357 root[0] += (char)drive;
2358 return GetDriveTypeA(root);
2359}
2360
2361/***********************************************************************
2362 * SHPathPrepareForWriteW (SHELL32.@)
2363 */
2365{
2366 DWORD res;
2367 DWORD err;
2368 LPCWSTR realpath;
2369 int len;
2370 WCHAR* last_slash;
2371 WCHAR* temppath=NULL;
2372
2373 TRACE("%p %p %s 0x%08x\n", hwnd, modless, debugstr_w(path), flags);
2374
2376 FIXME("unimplemented flags 0x%08x\n", flags);
2377
2378 /* cut off filename if necessary */
2380 {
2381 last_slash = StrRChrW(path, NULL, '\\');
2382 if (last_slash == NULL)
2383 len = 1;
2384 else
2385 len = last_slash - path + 1;
2386 temppath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2387 if (!temppath)
2388 return E_OUTOFMEMORY;
2389 StrCpyNW(temppath, path, len);
2390 realpath = temppath;
2391 }
2392 else
2393 {
2394 realpath = path;
2395 }
2396
2397 /* try to create the directory if asked to */
2399 {
2401 FIXME("treating SHPPFW_ASKDIRCREATE as SHPPFW_DIRCREATE\n");
2402
2403 SHCreateDirectoryExW(0, realpath, NULL);
2404 }
2405
2406 /* check if we can access the directory */
2407 res = GetFileAttributesW(realpath);
2408
2409 HeapFree(GetProcessHeap(), 0, temppath);
2410
2412 {
2413 err = GetLastError();
2416 return HRESULT_FROM_WIN32(err);
2417 }
2418 else if (res & FILE_ATTRIBUTE_DIRECTORY)
2419 return S_OK;
2420 else
2422}
2423
2424/***********************************************************************
2425 * SHPathPrepareForWriteA (SHELL32.@)
2426 */
2428{
2429 WCHAR wpath[MAX_PATH];
2430 MultiByteToWideChar( CP_ACP, 0, path, -1, wpath, MAX_PATH);
2431 return SHPathPrepareForWriteW(hwnd, modless, wpath, flags);
2432}
2433
2435{
2436 SIZE_T len = wcslen(Input), cb = (len + 2) * sizeof(*Input);
2438 if (Output)
2439 {
2440 CopyMemory(Output, Input, cb - sizeof(*Input));
2441 Output[len + 1] = UNICODE_NULL;
2442 }
2443 return Output;
2444}
2445
2447{
2448 HRESULT hr = S_OK;
2449 if ((Src = SHELL_DupSZZ(Src)) == NULL)
2450 hr = E_OUTOFMEMORY;
2451 if (Dest && (Dest = SHELL_DupSZZ(Dest)) == NULL)
2452 hr = E_OUTOFMEMORY;
2453
2454 SHFILEOPSTRUCTW fos = { hWnd, Op, Src, Dest, (FILEOP_FLAGS)Flags };
2455 if (ppNewName)
2456 {
2457 *ppNewName = NULL;
2459 }
2460
2461 if (SUCCEEDED(hr))
2462 {
2463 int err = SHFileOperationW(&fos);
2465 }
2466 else if (CanShowFileOpErrorUI(fos))
2467 {
2469 }
2470 SHFree(const_cast<PWSTR>(Src));
2471 SHFree(const_cast<PWSTR>(Dest));
2472
2473 if (fos.hNameMappings)
2474 {
2475 if (SUCCEEDED(hr) && ppNewName)
2476 {
2479 if ((*ppNewName = SHELL_DupSZZ(pMap->pszNewPath)) == NULL)
2480 hr = S_FALSE;
2481 }
2483 }
2484 return hr;
2485}
2486
2487
2488/*
2489 * The two following background operations were modified from filedefext.cpp
2490 * They use an inordinate amount of mutable state across the string functions,
2491 * so are not easy to follow and care is required when modifying.
2492 */
2493
2496{
2497 DWORD ticks = GetTickCount();
2498 FILE_ENTRY *entryToCount;
2499
2500 for (UINT i = 0; i < from->dwNumFiles; i++)
2501 {
2502 entryToCount = &from->feFiles[i];
2503
2504 WCHAR theFileName[MAX_PATH];
2505 StringCchCopyW(theFileName, MAX_PATH, entryToCount->szFullPath);
2506 _FileOpCount(op, theFileName, IsAttribDir(entryToCount->attributes), &ticks);
2507 }
2508 return 0;
2509}
2510
2511// All path manipulations, even when this function is nested, occur on the one buffer.
2512static BOOL
2513_FileOpCount(FILE_OPERATION *op, LPWSTR pwszBuf, BOOL bFolder, DWORD *ticks)
2514{
2515 /* Find filename position */
2516 UINT cchBuf = wcslen(pwszBuf);
2517 WCHAR *pwszFilename = pwszBuf + cchBuf;
2518 size_t cchFilenameMax = MAX_PATH - cchBuf;
2519 if (!cchFilenameMax)
2520 return FALSE;
2521
2522 if (bFolder) {
2523 *(pwszFilename++) = '\\';
2524 --cchFilenameMax;
2525 /* Find all files, FIXME: shouldn't be "*"? */
2526 StringCchCopyW(pwszFilename, cchFilenameMax, L"*");
2527 }
2528
2529 WIN32_FIND_DATAW wfd;
2530 HANDLE hFind = FindFirstFileW(pwszBuf, &wfd);
2531 if (hFind == INVALID_HANDLE_VALUE)
2532 {
2533 ERR("FindFirstFileW %ls failed\n", pwszBuf);
2534 return FALSE;
2535 }
2536
2537 do
2538 {
2539 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
2540 {
2541 /* Don't process "." and ".." items */
2542 if (!wcscmp(wfd.cFileName, L".") || !wcscmp(wfd.cFileName, L".."))
2543 continue;
2544
2545 StringCchCopyW(pwszFilename, cchFilenameMax, wfd.cFileName);
2546 _FileOpCount(op, pwszBuf, TRUE, ticks);
2547 }
2548 else
2549 {
2551 FileSize.u.LowPart = wfd.nFileSizeLow;
2552 FileSize.u.HighPart = wfd.nFileSizeHigh;
2553 op->totalSize.QuadPart += FileSize.QuadPart;
2554 }
2555 if (GetTickCount() - *ticks > (DWORD) 500)
2556 {
2557 // Check if the dialog has ended. If it has, we'll spin down.
2558 if (op->progress != NULL)
2559 op->bCancelled = op->progress->HasUserCancelled();
2560
2561 if (op->bCancelled)
2562 break;
2563 *ticks = GetTickCount();
2564 }
2565 } while(FindNextFileW(hFind, &wfd));
2566
2567 FindClose(hFind);
2568 return TRUE;
2569}
BOOL TRASH_TrashFile(LPCWSTR wszPath)
EXTERN_C HRESULT WINAPI SHUpdateRecycleBinIcon(void)
BOOL TRASH_CanTrashFile(LPCWSTR wszPath)
PRTL_UNICODE_STRING_BUFFER Path
#define shell32_hInstance
#define __inline
Definition: _wctype.cpp:15
char * va_list
Definition: acmsvcex.h:78
unsigned int dir
Definition: maze.c:112
int yOffset
Definition: appswitch.c:59
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
int confirm(const char *cmd, const char *file)
Definition: cmds.c:1636
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define EXTERN_C
Definition: basetyps.h:12
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
bool IsEmpty() const noexcept
Definition: atlsimpstr.h:394
void __cdecl Format(UINT nFormatID,...)
Definition: cstringt.h:818
Definition: list.h:37
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define NO_ERROR
Definition: dderror.h:5
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
#define IDS_OVERWRITEFILE_TEXT
Definition: resource.h:67
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
LPWSTR WINAPI StrRChrW(LPCWSTR str, LPCWSTR end, WORD ch)
Definition: string.c:552
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR *const ext[]
Definition: module.c:53
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
static void cleanup(void)
Definition: main.c:1335
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
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
UINT WINAPI GetDriveTypeA(IN LPCSTR lpRootPathName)
Definition: disk.c:468
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
BOOL WINAPI MoveFileWithProgressW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN LPPROGRESS_ROUTINE lpProgressRoutine, IN LPVOID lpData, IN DWORD dwFlags)
Definition: move.c:718
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1104
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2249
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
static const WCHAR sizeW[]
Definition: editor.c:79
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define ShellMessageBoxW
Definition: precomp.h:63
enum _FILEOPCALLBACKEVENT FILEOPCALLBACKEVENT
@ FOCE_PRERENAMEITEM
Definition: precomp.h:330
@ FOCE_POSTDELETEITEM
Definition: precomp.h:329
@ FOCE_PREMOVEITEM
Definition: precomp.h:324
@ FOCE_STARTOPERATIONS
Definition: precomp.h:322
@ FOCE_FINISHOPERATIONS
Definition: precomp.h:323
@ FOCE_POSTRENAMEITEM
Definition: precomp.h:331
@ FOCE_POSTMOVEITEM
Definition: precomp.h:325
@ FOCE_PRECOPYITEM
Definition: precomp.h:326
@ FOCE_PREDELETEITEM
Definition: precomp.h:328
@ FOCE_POSTCOPYITEM
Definition: precomp.h:327
HRESULT(CALLBACK * FILEOPCALLBACK)(FILEOPCALLBACKEVENT Event, LPCWSTR Source, LPCWSTR Destination, UINT Attributes, HRESULT hr, void *CallerData)
Definition: precomp.h:335
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394
BOOL WINAPI PathIsDirectoryEmptyW(LPCWSTR lpszPath)
Definition: path.c:3937
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1783
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
Definition: path.c:1585
LPWSTR WINAPI StrPBrkW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
Definition: string.c:1284
LPWSTR WINAPI StrCpyNW(LPWSTR dst, LPCWSTR src, int count)
Definition: string.c:536
int WINAPIV wnsprintfW(LPWSTR lpOut, int cchLimitIn, LPCWSTR lpFmt,...)
Definition: wsprintf.c:564
unsigned char
Definition: typeof.h:29
#define assert(x)
Definition: debug.h:53
#define pt(x, y)
Definition: drawing.c:79
LPVOID WINAPI DSA_GetItemPtr(HDSA hdsa, INT nIndex)
Definition: dsa.c:162
void WINAPI DSA_DestroyCallback(HDSA hdsa, PFNDSAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dsa.c:432
#define MOVEFILE_REPLACE_EXISTING
Definition: filesup.h:28
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
struct _cl_event * event
Definition: glext.h:7739
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint * ids
Definition: glext.h:5907
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum GLint GLuint mask
Definition: glext.h:6028
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
const GLint * attribs
Definition: glext.h:10538
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
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define LOBYTE(W)
Definition: jmemdos.c:487
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define DRIVE_CDROM
Definition: machpc98.h:119
TCHAR szTitle[MAX_LOADSTRING]
Definition: magnifier.c:35
#define error(str)
Definition: mkdosfs.c:1605
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
HDC hdc
Definition: main.c:9
static LPSTR pName
Definition: security.c:75
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static char * dest
Definition: rtl.c:135
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
HICON hIcon
Definition: msconfig.c:44
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
_In_ HANDLE hFile
Definition: mswsock.h:90
CAtlStringW CStringW
Definition: atlstr.h:130
unsigned int UINT
Definition: ndis.h:50
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3043
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define UNICODE_NULL
INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)
Definition: defwnd.c:16
#define L(x)
Definition: ntvdm.h:50
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
#define PathCombineW
Definition: pathcch.h:317
#define PathAddBackslashW
Definition: pathcch.h:301
#define PathAppendW
Definition: pathcch.h:309
#define DSA_GetItemCount(hdsa)
Definition: commctrl.h:4831
#define err(...)
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_DEFAULT
Definition: nls.h:168
@ Input
Definition: arc.h:84
@ Output
Definition: arc.h:85
strcpy
Definition: string.h:131
#define ASK_TRASH_FOLDER
Definition: shell32_main.h:143
#define ASK_OVERWRITE_FILE
Definition: shell32_main.h:140
#define ASK_DELETE_MULTIPLE_ITEM
Definition: shell32_main.h:138
#define ASK_OVERWRITE_FOLDER
Definition: shell32_main.h:146
#define ASK_DELETE_FILE
Definition: shell32_main.h:136
#define ASK_TRASH_FILE
Definition: shell32_main.h:142
#define ASK_DELETE_SELECTED
Definition: shell32_main.h:141
#define ASK_DELETE_FOLDER
Definition: shell32_main.h:137
#define ASK_CANT_TRASH_ITEM
Definition: shell32_main.h:145
#define ASK_TRASH_MULTIPLE_ITEM
Definition: shell32_main.h:144
#define FOF_WANTNUKEWARNING
Definition: shellapi.h:156
#define FOF_NOCOPYSECURITYATTRIBS
Definition: shellapi.h:153
#define FO_RENAME
Definition: shellapi.h:140
#define FOF_MULTIDESTFILES
Definition: shellapi.h:142
#define FOF_ALLOWUNDO
Definition: shellapi.h:148
#define FO_DELETE
Definition: shellapi.h:139
#define FO_COPY
Definition: shellapi.h:138
#define FOF_RENAMEONCOLLISION
Definition: shellapi.h:145
_In_ LPCSTR pszDir
Definition: shellapi.h:585
#define FOF_FILESONLY
Definition: shellapi.h:149
#define FOF_NOERRORUI
Definition: shellapi.h:152
WORD FILEOP_FLAGS
Definition: shellapi.h:214
#define FOF_NOCONFIRMATION
Definition: shellapi.h:146
#define FO_MOVE
Definition: shellapi.h:137
#define FOF_SIMPLEPROGRESS
Definition: shellapi.h:150
#define FOF_NO_CONNECTED_ELEMENTS
Definition: shellapi.h:155
#define FOF_NORECURSEREPARSE
Definition: shellapi.h:157
#define FOF_SILENT
Definition: shellapi.h:144
#define FOF_WANTMAPPINGHANDLE
Definition: shellapi.h:147
#define SHELL_GetSetting(pss, ssf, field)
Definition: shellutils.h:830
#define SHELL_ErrorBox
Definition: shellutils.h:126
#define DE_DESTSUBTREE
Definition: shlfileop.c:46
#define DE_DESTSAMETREE
Definition: shlfileop.c:48
#define DE_SAMEFILE
Definition: shlfileop.c:42
#define DE_OPCANCELLED
Definition: shlfileop.c:45
#define FO_MASK
Definition: shlfileop.cpp:34
BOOL SHELL_DeleteDirectoryW(FILE_OPERATION *op, LPCWSTR pszDir, BOOL bShowUI)
Definition: shlfileop.cpp:439
static LPWSTR wildcard_to_file(LPCWSTR szWildCard, LPCWSTR szFileName)
Definition: shlfileop.cpp:1254
static HRESULT rename_files(FILE_OPERATION *op, const FILE_LIST *flFrom, const FILE_LIST *flTo)
Definition: shlfileop.cpp:1959
#define IsAttrib(x, y)
Definition: shlfileop.cpp:29
EXTERN_C DWORD WINAPI SheGetDirA(DWORD drive, LPSTR buffer)
Definition: shlfileop.cpp:2244
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:632
#define NEW_FILENAME_ON_COPY_TRIES
Definition: shlfileop.cpp:36
#define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND
Definition: shlfileop.cpp:54
static void move_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, const FILE_ENTRY *feTo)
Definition: shlfileop.cpp:1845
static BOOL confirm_delete_list(HWND hWnd, DWORD fFlags, BOOL fTrash, const FILE_LIST *flFrom)
Definition: shlfileop.cpp:1663
static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly)
Definition: shlfileop.cpp:1069
static void parse_wildcard_files(FILE_LIST *flList, LPCWSTR szFile, LPDWORD pdwListIndex)
Definition: shlfileop.cpp:1276
EXTERN_C DWORD WINAPI SheChangeDirW(LPWSTR path)
Definition: shlfileop.cpp:2331
static BOOL CanShowFileOpErrorUI(const SHFILEOPSTRUCTW &fos)
Definition: shlfileop.cpp:106
static HRESULT copy_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, FILE_LIST *flTo)
Definition: shlfileop.cpp:1536
EXTERN_C int WINAPI IsNetDrive(int drive)
Definition: shlfileop.cpp:2342
static void confirm_msg_move_button(HWND hDlg, INT iId, INT *xPos, INT yOffset, BOOL bShow)
Definition: shlfileop.cpp:140
int WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:985
static HRESULT parse_file_list(FILE_LIST *flList, LPCWSTR szFiles)
Definition: shlfileop.cpp:1310
static DWORD _ConvertAtoW(PCSTR strSrc, PCWSTR *pStrDest, BOOL isList)
Definition: shlfileop.cpp:1098
#define IsDotDir(x)
Definition: shlfileop.cpp:32
static INT_PTR ConfirmMsgBox_Init(HWND hDlg, LPARAM lParam)
Definition: shlfileop.cpp:188
static DWORD SHNotifyDeleteFileW(FILE_OPERATION *op, LPCWSTR path)
Definition: shlfileop.cpp:679
EXTERN_C DWORD WINAPI Win32DeleteFileW(LPCWSTR path)
Definition: shlfileop.cpp:735
#define IsAttribFile(x)
Definition: shlfileop.cpp:30
static BOOL move_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCHAR *szTo)
Definition: shlfileop.cpp:1822
static int CALLBACK _DestroyCallback(void *p, void *pData)
Definition: shlfileop.cpp:2206
static void destroy_file_list(FILE_LIST *flList)
Definition: shlfileop.cpp:1380
static PWSTR SHELL_DupSZZ(PCWSTR Input)
Definition: shlfileop.cpp:2434
EXTERN_C HRESULT WINAPI SHIsFileAvailableOffline(LPCWSTR path, LPDWORD status)
Definition: shlfileop.cpp:401
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:2200
void WINAPI SHFreeNameMappings(HANDLE hNameMapping)
Definition: shlfileop.cpp:2228
static INT_PTR CALLBACK ConfirmMsgBoxProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: shlfileop.cpp:229
int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp)
Definition: shlfileop.cpp:1160
static void copy_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, const FILE_ENTRY *feTo)
Definition: shlfileop.cpp:1500
static CStringW try_find_new_name(LPCWSTR szDestPath)
Definition: shlfileop.cpp:1397
static DWORD SHNotifyRemoveDirectoryW(LPCWSTR path)
Definition: shlfileop.cpp:520
EXTERN_C DWORD WINAPI SheChangeDirA(LPSTR path)
Definition: shlfileop.cpp:2317
EXTERN_C INT WINAPI RealDriveType(INT drive, BOOL bQueryNet)
Definition: shlfileop.cpp:2354
static void __inline grow_list(FILE_LIST *list)
Definition: shlfileop.cpp:1218
EXTERN_C DWORD WINAPI SheGetDirW(DWORD drive, LPWSTR buffer)
Definition: shlfileop.cpp:2281
EXTERN_C BOOL WINAPI Win32RemoveDirectoryW(LPCWSTR path)
Definition: shlfileop.cpp:544
BOOL SHELL_ConfirmYesNoW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir)
Definition: shlfileop.cpp:375
static void add_file_to_entry(FILE_ENTRY *feFile, LPCWSTR szFile)
Definition: shlfileop.cpp:1228
#define IsAttribDir(x)
Definition: shlfileop.cpp:31
EXTERN_C HRESULT WINAPI SHPathPrepareForWriteA(HWND hwnd, IUnknown *modless, LPCSTR path, DWORD flags)
Definition: shlfileop.cpp:2427
int SHELL32_FileOperation(LPSHFILEOPSTRUCTW lpFileOp, FILEOPCALLBACK Callback, void *CallerData)
Definition: shlfileop.cpp:2093
static DWORD validate_operation(FILE_OPERATION &op, FILE_LIST *flFrom, FILE_LIST *flTo)
Definition: shlfileop.cpp:1998
static void create_dest_dirs(LPCWSTR szDestDir)
Definition: shlfileop.cpp:1516
static DWORD CheckForError(FILE_OPERATION *op, DWORD error, LPCWSTR src)
Definition: shlfileop.cpp:751
static BOOL copy_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCHAR *szTo)
Definition: shlfileop.cpp:1477
static HRESULT FileOpCallback(FILE_OPERATION *op, FILEOPCALLBACKEVENT Event, LPCWSTR Source, LPCWSTR Destination, UINT Attributes, HRESULT hrOp=S_OK)
Definition: shlfileop.cpp:407
static BOOL SHELL_ConfirmDialogW(HWND hWnd, int nKindOfDialog, LPCWSTR szDir, FILE_OPERATION *op)
Definition: shlfileop.cpp:337
EXTERN_C HRESULT WINAPI SHPathPrepareForWriteW(HWND hwnd, IUnknown *modless, LPCWSTR path, DWORD flags)
Definition: shlfileop.cpp:2364
static HRESULT SHELL32_FileOpErrorToHResult(int err, BOOL AnyOperationsAborted=FALSE)
Definition: shlfileop.cpp:89
static BOOL SHELL_ConfirmIDs(int nKindOfDialog, SHELL_ConfirmIDstruc *ids)
Definition: shlfileop.cpp:266
static void SHELL32_FreeUnicodeBuf(LPWSTR wPath)
Definition: shlfileop.cpp:396
static void _SetOperationTitle(FILE_OPERATION *op)
Definition: shlfileop.cpp:549
#define GET_FILENAME(fe)
Definition: shlfileop.cpp:1995
int WINAPI SHCreateDirectory(HWND hWnd, LPCWSTR path)
Definition: shlfileop.cpp:948
HRESULT SHELL_SingleFileOperation(HWND hWnd, UINT Op, PCWSTR Src, PCWSTR Dest, UINT Flags, PWSTR *ppNewName)
Definition: shlfileop.cpp:2446
int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll)
Definition: shlfileop.cpp:247
static DWORD SHNotifyCreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:490
static INT_PTR ConfirmMsgBox_Paint(HWND hDlg)
Definition: shlfileop.cpp:165
static DWORD SHNotifyMoveFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BOOL isdir)
Definition: shlfileop.cpp:792
static HRESULT delete_files(FILE_OPERATION *op, const FILE_LIST *flFrom)
Definition: shlfileop.cpp:1685
DWORD WINAPI _FileOpCountManager(FILE_OPERATION *op, const FILE_LIST *flFrom)
Definition: shlfileop.cpp:2495
static DWORD move_files(FILE_OPERATION *op, BOOL multiDest, const FILE_LIST *flFrom, const FILE_LIST *flTo)
Definition: shlfileop.cpp:1863
static void copy_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath)
Definition: shlfileop.cpp:1425
static BOOL _FileOpCount(FILE_OPERATION *op, LPWSTR pwszBuf, BOOL bFolder, DWORD *ticks)
Definition: shlfileop.cpp:2513
static void _SetOperationTexts(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest)
Definition: shlfileop.cpp:582
static void move_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath)
Definition: shlfileop.cpp:1786
EXTERN_C BOOL WINAPI Win32CreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:504
int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:1006
static void check_flags(FILEOP_FLAGS fFlags)
Definition: shlfileop.cpp:1985
static DWORD SHELL32_AnsiToUnicodeBuf(LPCSTR aPath, LPWSTR *wPath, DWORD minChars)
Definition: shlfileop.cpp:380
static void HandleDesktopIniOp(PCWSTR Path)
Definition: shlfileop.cpp:113
static DWORD SHNotifyCopyFileW(FILE_OPERATION *op, LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists)
Definition: shlfileop.cpp:878
static BOOL SHIsCdRom(LPCWSTR path)
Definition: shlfileop.cpp:849
HRESULT hr
Definition: shlfolder.c:183
#define SHCNE_RMDIR
Definition: shlobj.h:1902
#define SHCNE_DELETE
Definition: shlobj.h:1900
#define SHCNE_MKDIR
Definition: shlobj.h:1901
#define SHCNE_UPDATEITEM
Definition: shlobj.h:1911
#define SHCNE_RENAMEITEM
Definition: shlobj.h:1898
#define SHCNE_CREATE
Definition: shlobj.h:1899
#define SHPPFW_IGNOREFILENAME
Definition: shlobj.h:341
#define SHCNE_RENAMEFOLDER
Definition: shlobj.h:1915
#define SHPPFW_ASKDIRCREATE
Definition: shlobj.h:340
#define SSF_NOCONFIRMRECYCLE
Definition: shlobj.h:1626
#define PROGDLG_AUTOTIME
Definition: shlobj.h:974
#define SHPPFW_DIRCREATE
Definition: shlobj.h:338
#define PROGDLG_NORMAL
Definition: shlobj.h:972
#define SHCNF_PATHW
Definition: shlobj.h:1933
#define IDD_YESTOALL_MSGBOX
Definition: shresdef.h:453
#define IDS_DELETESELECTED_TEXT
Definition: shresdef.h:128
#define IDA_SHELL_DELETE
Definition: shresdef.h:837
#define IDI_SHELL_FOLDER_MOVE2
Definition: shresdef.h:729
#define IDS_MOVEERROR
Definition: shresdef.h:257
#define IDI_SHELL_CONFIRM_DELETE
Definition: shresdef.h:656
#define IDS_MOVEERRORSUBFOLDER
Definition: shresdef.h:255
#define IDS_OVERWRITEFOLDER_TEXT
Definition: shresdef.h:133
#define IDS_FILEOOP_FROM
Definition: shresdef.h:240
#define IDS_FILEOOP_FROM_TO
Definition: shresdef.h:239
#define IDS_CREATEFOLDER_DENIED
Definition: shresdef.h:120
#define IDS_OVERWRITEFILE_CAPTION
Definition: shresdef.h:126
#define IDS_FILEOOP_MOVING
Definition: shresdef.h:237
#define IDS_COPYERRORSUBFOLDER
Definition: shresdef.h:256
#define IDC_YESTOALL_MESSAGE
Definition: shresdef.h:456
#define IDS_CREATEFOLDER_CAPTION
Definition: shresdef.h:121
#define IDS_CANTTRASH_TEXT
Definition: shresdef.h:132
#define IDS_MOVEERRORSAME
Definition: shresdef.h:253
#define IDS_TRASHITEM_TEXT
Definition: shresdef.h:130
#define IDS_DELETEITEM_CAPTION
Definition: shresdef.h:122
#define IDS_FILEOOP_DELETING
Definition: shresdef.h:238
#define IDS_TRASHMULTIPLE_TEXT
Definition: shresdef.h:131
#define IDC_YESTOALL_ICON
Definition: shresdef.h:455
#define IDS_TRASHFOLDER_TEXT
Definition: shresdef.h:129
#define IDS_FILEOOP_COPYING
Definition: shresdef.h:236
#define IDS_DELETEFOLDER_CAPTION
Definition: shresdef.h:123
#define IDS_DELETEITEM_TEXT
Definition: shresdef.h:124
#define IDS_COPYERROR
Definition: shresdef.h:258
#define IDC_YESTOALL
Definition: shresdef.h:454
#define IDI_SHELL_TRASH_FILE
Definition: shresdef.h:641
#define IDS_COPYERRORTITLE
Definition: shresdef.h:251
#define IDS_COPYERRORSAME
Definition: shresdef.h:254
#define IDS_FILEOOP_PREFLIGHT
Definition: shresdef.h:241
#define IDS_MOVEERRORTITLE
Definition: shresdef.h:250
#define IDS_DELETEMULTIPLE_TEXT
Definition: shresdef.h:125
#define IDA_SHELL_COPY
Definition: shresdef.h:833
#define IDS_MOVEERRORSAMEFOLDER
Definition: shresdef.h:252
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
Definition: shlfileop.cpp:57
BOOL bFromWildcard
Definition: shlfileop.cpp:62
DWORD attributes
Definition: shlfileop.cpp:58
LPWSTR szFilename
Definition: shlfileop.cpp:60
BOOL bExists
Definition: shlfileop.cpp:64
LPWSTR szFullPath
Definition: shlfileop.cpp:61
BOOL bFromRelative
Definition: shlfileop.cpp:63
LPWSTR szDirectory
Definition: shlfileop.cpp:59
DWORD dwNumFiles
Definition: shlfileop.cpp:71
FILE_ENTRY * feFiles
Definition: shlfileop.cpp:69
BOOL bAnyFromWildcard
Definition: shlfileop.cpp:72
DWORD num_alloc
Definition: shlfileop.cpp:70
BOOL bAnyDirectories
Definition: shlfileop.cpp:73
BOOL bAnyDontExist
Definition: shlfileop.cpp:74
SHFILEOPSTRUCTW * req
Definition: shlfileop.cpp:40
DWORD dwYesToAllMask
Definition: shlfileop.cpp:41
IProgressDialog * progress
Definition: shlfileop.cpp:44
ULARGE_INTEGER totalSize
Definition: shlfileop.cpp:46
ULARGE_INTEGER completedSize
Definition: shlfileop.cpp:45
BOOL bHasDisplayedError
Definition: shlfileop.cpp:51
FILEOPCALLBACK Callback
Definition: shlfileop.cpp:48
void * CallerCallbackData
Definition: shlfileop.cpp:49
HINSTANCE hIconInstance
Definition: shlfileop.cpp:261
Definition: dsa.c:45
PVOID hNameMappings
Definition: shellapi.h:352
LPCSTR lpszProgressTitle
Definition: shellapi.h:353
FILEOP_FLAGS fFlags
Definition: shellapi.h:350
BOOL fAnyOperationsAborted
Definition: shellapi.h:351
PVOID hNameMappings
Definition: shellapi.h:362
LPCWSTR pFrom
Definition: shellapi.h:358
BOOL fAnyOperationsAborted
Definition: shellapi.h:361
FILEOP_FLAGS fFlags
Definition: shellapi.h:360
LPCWSTR lpszProgressTitle
Definition: shellapi.h:363
LPWSTR pszOldPath
Definition: shellapi.h:391
LPWSTR pszNewPath
Definition: shellapi.h:392
struct _ULARGE_INTEGER::@4266 u
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: match.c:390
Definition: bug.cpp:8
Definition: fci.c:127
Definition: ps.c:97
#define DWORD_PTR
Definition: treelist.c:76
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
uint16_t * PWSTR
Definition: typedefs.h:56
int32_t INT_PTR
Definition: typedefs.h:64
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint32_t DWORD_PTR
Definition: typedefs.h:65
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG
Definition: typedefs.h:59
#define ERRORONDEST
Definition: undocshell.h:579
#define DE_ACCESSDENIEDSRC
Definition: undocshell.h:563
#define DE_FILENAMETOOLONG
Definition: undocshell.h:570
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2379 u
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
int ret
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
#define success(from, fromstr, to, tostr)
#define ZeroMemory
Definition: winbase.h:1743
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_FROM_STRING
Definition: winbase.h:447
#define DRIVE_REMOTE
Definition: winbase.h:279
#define CopyMemory
Definition: winbase.h:1741
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:449
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:445
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:450
#define CALLBACK_STREAM_SWITCH
Definition: winbase.h:152
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define ERROR_NO_MORE_SEARCH_HANDLES
Definition: winerror.h:187
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_DIRECTORY
Definition: winerror.h:295
#define ERROR_BAD_PATHNAME
Definition: winerror.h:233
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define ERROR_CANCELLED
Definition: winerror.h:726
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define TRANSPARENT
Definition: wingdi.h:950
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:918
#define WM_PAINT
Definition: winuser.h:1631
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
DWORD WINAPI GetSysColor(_In_ int)
#define SW_HIDE
Definition: winuser.h:779
#define WM_CLOSE
Definition: winuser.h:1632
#define DT_NOPREFIX
Definition: winuser.h:537
#define COLOR_BTNTEXT
Definition: winuser.h:944
#define DWLP_USER
Definition: winuser.h:883
#define GetWindowLongPtrW
Definition: winuser.h:4840
#define GA_ROOT
Definition: winuser.h:2800
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define SM_CYSCREEN
Definition: winuser.h:971
#define STM_SETICON
Definition: winuser.h:2103
#define IDCANCEL
Definition: winuser.h:842
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define WM_COMMAND
Definition: winuser.h:1751
#define WM_INITDIALOG
Definition: winuser.h:1750
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
#define WM_GETFONT
Definition: winuser.h:1662
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define MB_ICONERROR
Definition: winuser.h:798
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define DT_WORDBREAK
Definition: winuser.h:544
#define IDNO
Definition: winuser.h:847
HDC WINAPI GetDC(_In_opt_ HWND)
#define MB_ICONEXCLAMATION
Definition: winuser.h:796
#define MB_OK
Definition: winuser.h:801
#define SM_CXSCREEN
Definition: winuser.h:970
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define IDYES
Definition: winuser.h:846
#define DT_CALCRECT
Definition: winuser.h:526
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
#define SetWindowLongPtrW
Definition: winuser.h:5366
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2413
int WINAPI GetSystemMetrics(_In_ int)
HWND WINAPI GetAncestor(_In_ HWND, _In_ UINT)
BOOL WINAPI MoveWindow(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ BOOL)
#define DT_PATH_ELLIPSIS
Definition: winuser.h:530
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define IID_PPV_ARG(Itype, ppType)
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185