source: trunk/src/shell32/shlfileop.c@ 7029

Last change on this file since 7029 was 6800, checked in by sandervl, 24 years ago

DT: small update

File size: 21.2 KB
Line 
1/*
2 * SHFileOperation
3 */
4#ifdef __WIN32OS2__
5#define ICOM_CINTERFACE 1
6#include <odin.h>
7#endif
8#include <string.h>
9#include "debugtools.h"
10#include "shellapi.h"
11#include "shlwapi.h"
12
13#include "shlobj.h"
14#include "shresdef.h"
15#include "shell32_main.h"
16#include "wine/undocshell.h"
17#include "shlwapi.h"
18
19DEFAULT_DEBUG_CHANNEL(shell);
20
21
22#ifdef __WIN32OS2__
23BOOL SHELL_ConfirmDialog (int nKindOfDialog, LPCSTR szDir)
24{
25 char szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
26 UINT caption_resource_id, text_resource_id;
27
28 switch(nKindOfDialog) {
29
30 case ASK_DELETE_FILE:
31 caption_resource_id = IDS_DELETEITEM_CAPTION;
32 text_resource_id = IDS_DELETEITEM_TEXT;
33 break;
34 case ASK_DELETE_FOLDER:
35 caption_resource_id = IDS_DELETEFOLDER_CAPTION;
36 text_resource_id = IDS_DELETEITEM_TEXT;
37 break;
38 case ASK_DELETE_MULTIPLE_ITEM:
39 caption_resource_id = IDS_DELETEITEM_CAPTION;
40 text_resource_id = IDS_DELETEMULTIPLE_TEXT;
41 break;
42 case ASK_OVERWRITE_FILE:
43 caption_resource_id = IDS_OVERWRITEFILE_CAPTION;
44 text_resource_id = IDS_OVERWRITEFILE_TEXT;
45 break;
46 default:
47 FIXME(__FUNCTION__" Unhandled nKindOfDialog %d stub\n", nKindOfDialog);
48 return FALSE;
49 }
50
51 LoadStringA(shell32_hInstance, caption_resource_id, szCaption, sizeof(szCaption));
52 LoadStringA(shell32_hInstance, text_resource_id, szText, sizeof(szText));
53#else
54BOOL SHELL_WarnItemDelete (int nKindOfDialog, LPCSTR szDir)
55{
56 char szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
57
58 if(nKindOfDialog == ASK_DELETE_FILE)
59 {
60 LoadStringA(shell32_hInstance, IDS_DELETEITEM_TEXT, szText,
61 sizeof(szText));
62 LoadStringA(shell32_hInstance, IDS_DELETEITEM_CAPTION,
63 szCaption, sizeof(szCaption));
64 }
65 else if(nKindOfDialog == ASK_DELETE_FOLDER)
66 {
67 LoadStringA(shell32_hInstance, IDS_DELETEITEM_TEXT, szText,
68 sizeof(szText));
69 LoadStringA(shell32_hInstance, IDS_DELETEFOLDER_CAPTION,
70 szCaption, sizeof(szCaption));
71 }
72 else if(nKindOfDialog == ASK_DELETE_MULTIPLE_ITEM)
73 {
74 LoadStringA(shell32_hInstance, IDS_DELETEMULTIPLE_TEXT, szText,
75 sizeof(szText));
76 LoadStringA(shell32_hInstance, IDS_DELETEITEM_CAPTION,
77 szCaption, sizeof(szCaption));
78 }
79 else {
80 FIXME("Called without a valid nKindOfDialog specified!");
81 LoadStringA(shell32_hInstance, IDS_DELETEITEM_TEXT, szText,
82 sizeof(szText));
83 LoadStringA(shell32_hInstance, IDS_DELETEITEM_CAPTION,
84 szCaption, sizeof(szCaption));
85 }
86#endif
87 FormatMessageA(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
88 szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)&szDir);
89
90 return (IDOK == MessageBoxA(GetActiveWindow(), szBuffer, szCaption, MB_OKCANCEL | MB_ICONEXCLAMATION));
91}
92
93/**************************************************************************
94 * SHELL_DeleteDirectoryA()
95 *
96 * like rm -r
97 */
98
99BOOL SHELL_DeleteDirectoryA(LPCSTR pszDir, BOOL bShowUI)
100{
101 BOOL ret = FALSE;
102 HANDLE hFind;
103 WIN32_FIND_DATAA wfd;
104 char szTemp[MAX_PATH];
105
106 strcpy(szTemp, pszDir);
107 PathAddBackslashA(szTemp);
108 strcat(szTemp, "*.*");
109
110 if (bShowUI && !SHELL_WarnItemDelete(ASK_DELETE_FOLDER, pszDir))
111 return FALSE;
112
113 if(INVALID_HANDLE_VALUE != (hFind = FindFirstFileA(szTemp, &wfd)))
114 {
115 do
116 {
117 if(strcasecmp(wfd.cFileName, ".") && strcasecmp(wfd.cFileName, ".."))
118 {
119 strcpy(szTemp, pszDir);
120 PathAddBackslashA(szTemp);
121 strcat(szTemp, wfd.cFileName);
122
123 if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
124 SHELL_DeleteDirectoryA(szTemp, FALSE);
125 else
126 DeleteFileA(szTemp);
127 }
128 } while(FindNextFileA(hFind, &wfd));
129
130 FindClose(hFind);
131 ret = RemoveDirectoryA(pszDir);
132 }
133
134 return ret;
135}
136
137/**************************************************************************
138 * SHELL_DeleteFileA()
139 */
140
141BOOL SHELL_DeleteFileA(LPCSTR pszFile, BOOL bShowUI)
142{
143 if (bShowUI && !SHELL_WarnItemDelete(ASK_DELETE_FILE, pszFile))
144 return FALSE;
145
146 return DeleteFileA(pszFile);
147}
148
149/*************************************************************************
150 * SHCreateDirectory [SHELL32.165]
151 *
152 * NOTES
153 * exported by ordinal
154 * not sure about LPSECURITY_ATTRIBUTES
155 */
156DWORD WINAPI SHCreateDirectory(LPSECURITY_ATTRIBUTES sec,LPCSTR path)
157{
158 DWORD ret;
159 TRACE("(%p,%s)\n",sec,path);
160 if ((ret = CreateDirectoryA(path,sec)))
161 {
162 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_PATHA, path, NULL);
163 }
164 return ret;
165}
166
167/************************************************************************
168 * Win32DeleteFile [SHELL32.164]
169 *
170 * Deletes a file. Also triggers a change notify if one exists.
171 *
172 * FIXME:
173 * Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be
174 * ANSI. Is this Unicode on NT?
175 *
176 */
177
178BOOL WINAPI Win32DeleteFile(LPSTR fName)
179{
180 TRACE("%p(%s)\n", fName, fName);
181
182 DeleteFileA(fName);
183 SHChangeNotifyA(SHCNE_DELETE, SHCNF_PATHA, fName, NULL);
184 return TRUE;
185}
186
187/*************************************************************************
188 * SHFileOperationA [SHELL32.243]
189 *
190 * NOTES
191 * exported by name
192 */
193DWORD WINAPI SHFileOperationA (LPSHFILEOPSTRUCTA lpFileOp)
194{
195 LPSTR pFrom = (LPSTR)lpFileOp->pFrom;
196 LPSTR pTo = (LPSTR)lpFileOp->pTo;
197#ifdef __WIN32OS2__
198 DWORD FromAttr;
199 DWORD ToAttr;
200 LPSTR pTempFrom = NULL;
201 LPSTR pTempTo;
202 LPSTR pFromFile;
203 LPSTR pToFile;
204
205 FILEOP_FLAGS OFl = ((FILEOP_FLAGS)lpFileOp->fFlags & 0x7ff);
206 BOOL Multi = TRUE;
207 BOOL withFileName;
208 BOOL not_overwrite;
209 BOOL ToSingle;
210 BOOL BothDir;
211 BOOL ToWithoutBackSlash;
212 long lenFrom = -1;
213 long lenTo = -1;
214 long lenTempFrom;
215 long lenTempTo;
216 long retCode = 0x75;
217 long TempretCode = 0;
218 long where = 0;
219 SHFILEOPSTRUCTA nlpFileOp = *(lpFileOp);
220 long level= nlpFileOp.wFunc>>4;
221 HANDLE hFind;
222 WIN32_FIND_DATAA wfd;
223
224/* default no error
225*/
226 lpFileOp->fAnyOperationsAborted=FALSE;
227 nlpFileOp.fAnyOperationsAborted=FALSE;
228 level++;
229 nlpFileOp.wFunc = (level<<4) + (lpFileOp->wFunc & 15);
230#else
231 LPSTR pTempTo;
232#endif
233#ifdef __WIN32OS2__
234 switch(lpFileOp->wFunc & 15) {
235#else
236 switch(lpFileOp->wFunc) {
237#endif
238 case FO_COPY:
239#ifdef __WIN32OS2__
240 pTempFrom = HeapAlloc(GetProcessHeap(), 0, 3 * MAX_PATH+6);
241 pTempTo = &pTempFrom[MAX_PATH+4];
242/*
243 * FOF_MULTIDESTFILES, FOF_NOCONFIRMATION, FOF_FILESONLY are implemented
244 * FOF_CONFIRMMOUSE, FOF_SILENT, FOF_NOCONFIRMMKDIR, FOF_SIMPLEPROGRESS are not implemented and ignored
245 * FOF_RENAMEONCOLLISION are implemented partially and breaks if file exist
246 * FOF_ALLOWUNDO, FOF_WANTMAPPINGHANDLE are not implemented and breaks
247 * if any other flag set, an error occurs
248 */
249 TRACE(__FUNCTION__" FO_COPY level=%d lpFileOp->fFlags=0x%x\n",level ,lpFileOp->fFlags);
250// OFl = (OFl & (-1 - (FOF_MULTIDESTFILES | FOF_FILESONLY)));
251// OFl = (OFl ^ (FOF_SILENT | FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMMKDIR));
252 OFl = (OFl & ( ~ (FOF_MULTIDESTFILES | FOF_NOCONFIRMATION | FOF_FILESONLY))); // implemented
253 OFl = (OFl ^ (FOF_SILENT | FOF_NOCONFIRMMKDIR)); // ignored, if one
254 OFl = (OFl & ( ~ FOF_SIMPLEPROGRESS)); // ignored, only with FOF_SILENT
255 if (OFl) {
256 if (OFl & ( ~ (FOF_CONFIRMMOUSE | FOF_SILENT | FOF_RENAMEONCOLLISION | FOF_NOCONFIRMMKDIR))) {
257 TRACE(__FUNCTION__" FO_COPY level=%d lpFileOp->fFlags=0x%x not implemented, Aborted=TRUE, stub\n", level, OFl);
258 nlpFileOp.fAnyOperationsAborted=TRUE;
259 } else {
260 TRACE(__FUNCTION__" FO_COPY level=%d lpFileOp->fFlags=0x%x not full implemented ,stub\n", level, OFl);
261 } /* endif */
262 } /* endif */
263
264 not_overwrite = (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_RENAMEONCOLLISION));
265
266// fix for more then one source for one target
267 pToFile = pTempTo;
268
269// need break at error before change sourcepointer
270 while(!nlpFileOp.fAnyOperationsAborted && (pFrom+=lenFrom+1)[0]) {
271
272 if (!withFileName && Multi && (pTo[lenTo+1]=='\0')) {
273// Win Bug ?
274 Multi = FALSE;
275 } /* endif */
276
277 if (Multi) pTo += lenTo + 1;
278 if(!pTo[0]) {
279 nlpFileOp.fAnyOperationsAborted=TRUE;
280 where = 213;
281 break;
282 }
283
284 TRACE(__FUNCTION__" FO_COPY level=%d From='%s' To='%s'\n", level, pFrom, pTo);
285
286// fix for more then one source for one target
287 pToFile[0] = '\0';
288 nlpFileOp.pTo = pTo;
289
290 lenFrom=strlen(pFrom);
291 strcpy(pTempFrom,pFrom);
292 FromAttr = GetFileAttributesA(pTempFrom);
293
294 if (Multi) {
295 lenTo = strlen(pTo);
296// single targetdir !Multi
297 Multi = (Multi && (lpFileOp->fFlags & FOF_MULTIDESTFILES));
298// multi target, each one for one source. ? last target + more than one source (all source files an one dir as target)
299
300 ToSingle = ((pTo[lenTo+1]=='\0') || !Multi);
301
302 strcpy(pTempTo,pTo);
303 PathRemoveBackslashA(pTempTo);
304 ToWithoutBackSlash = (strlen(pTempTo)==lenTo);
305 ToAttr = GetFileAttributesA(pTempTo);
306
307 BothDir = (Multi &&
308 ToWithoutBackSlash &&
309 (-1 != (FromAttr | ToAttr)) &&
310 (ToAttr & FromAttr & FILE_ATTRIBUTE_DIRECTORY));
311
312 withFileName = (!BothDir &&
313 (ToWithoutBackSlash || !ToSingle) &&
314 (ToAttr == -1 || !(ToAttr & FILE_ATTRIBUTE_DIRECTORY)));
315
316 if (withFileName) {
317// Target must not be an directory
318 PathRemoveFileSpecA(pTempTo);
319 ToAttr = GetFileAttributesA(pTempTo);
320 }
321 if ((ToAttr == -1) ||
322 !(ToAttr & FILE_ATTRIBUTE_DIRECTORY) ||
323 (!withFileName && !ToSingle) ) {
324 nlpFileOp.fAnyOperationsAborted=TRUE;
325 where = 201;
326 break;
327 }
328 lenTempTo = strlen(pTempTo);
329 withFileName = (((lenTempTo + 1) < lenTo) || (PathIsRootA(pTo) && lenTempTo < lenTo));
330 PathAddBackslashA(pTempTo);
331 }
332
333 if (FromAttr == -1 || BothDir) {
334// is Source an existing directory\*.* ?
335 if (FromAttr == -1) {
336 PathRemoveFileSpecA(pTempFrom);
337 FromAttr = GetFileAttributesA(pTempFrom);
338 }
339
340 PathAddBackslashA(pTempFrom);
341 lenTempFrom = strlen(pTempFrom);
342 pFromFile=&pTempFrom[lenTempFrom];
343
344 if (FromAttr == -1 ||
345 ((lenTempFrom==lenFrom) && !PathIsRootA(pFrom)) ||
346 !(FromAttr & FILE_ATTRIBUTE_DIRECTORY) ||
347 !((0==strcmp(&pFrom[lenTempFrom],"*.*")) || BothDir)) {
348 retCode=0x402;
349 nlpFileOp.fAnyOperationsAborted=TRUE;
350 where = 202;
351 break;
352 }
353
354 strcpy(pFromFile, "*.*");
355 hFind = FindFirstFileA(pTempFrom, &wfd);
356 if (INVALID_HANDLE_VALUE == hFind) {
357 nlpFileOp.fAnyOperationsAborted=TRUE;
358 retCode=0x79;
359 where = 203;
360 break;
361 }
362
363 nlpFileOp.pFrom = pTempFrom;
364// single copy never with FOF_MULTIDESTFILES, I can use lpFileOp->pTo as nlpFileOp.pTo,
365// I need no different targetarea for the name
366 TRACE(__FUNCTION__" FO_COPY level=%d Copy between Subdir %s -> %s'\n",level ,nlpFileOp.pFrom, nlpFileOp.pTo);
367 nlpFileOp.fFlags = (nlpFileOp.fFlags & (-1 - (FOF_MULTIDESTFILES)));
368
369 do {
370 TRACE(__FUNCTION__" FO_COPY level=%d find '%s'\n",level ,wfd.cFileName);
371 if (0==strcmp(wfd.cFileName,".")) continue;
372 if (0==strcmp(wfd.cFileName,"..")) continue;
373 if ((nlpFileOp.fFlags & FOF_FILESONLY) && (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)) {
374 continue;
375 } /* endif */
376
377 strcpy(pFromFile,wfd.cFileName);
378 pTempFrom[strlen(pTempFrom)+1]='\0';
379
380 TempretCode = SHFileOperationA (&nlpFileOp);
381
382 if (nlpFileOp.fAnyOperationsAborted) {where = 204;break;}
383
384 } while(FindNextFileA(hFind, &wfd));
385
386 FindClose(hFind);
387 if (nlpFileOp.fAnyOperationsAborted) {where = 205;break;}
388 continue;
389 }
390
391 lenTempTo = strlen(pTempTo);
392 pToFile = &pTempTo[lenTempTo];
393// Check Source
394 strcpy(pToFile,pTempFrom);
395 PathRemoveBackslashA(pToFile);
396 if (strlen(pToFile)<lenFrom) {
397 nlpFileOp.fAnyOperationsAborted=TRUE;
398 retCode=0x402;
399 where = 206;
400 break;
401 } /* endif */
402
403// target name in target or from source
404 pFromFile = NULL;
405 if (withFileName) {
406 if ((pFrom[lenFrom+1]=='\0') || (Multi && !(pTo[lenTo+1]=='\0'))) {
407 pFromFile = pTo;
408 } /* endif */
409 } else {
410// Multi Target
411 if (!Multi || !(pFrom[lenFrom+1]=='\0') ||
412// only target+\, target without \ has 0x402
413 (Multi && (FromAttr & ToAttr & FILE_ATTRIBUTE_DIRECTORY))) {
414 pFromFile = pTempFrom;
415 }
416 } /* endif */
417
418 if (!pFromFile) {
419 nlpFileOp.fAnyOperationsAborted=TRUE;
420 where = 207;
421 break;
422 } /* endif */
423
424// move isolated target filename
425 strcpy(pToFile,pFromFile);
426 PathRemoveFileSpecA(pToFile);
427 PathAddBackslashA(pToFile);
428
429 strcpy(pToFile,&pFromFile[strlen(pToFile)]);
430 ToAttr = GetFileAttributesA(pTempTo);
431
432 if (FromAttr == -1) {
433 TRACE(__FUNCTION__" FO_COPY level=%d with Source %s not implementiert ,stub\n",level ,pTempFrom);
434 nlpFileOp.fAnyOperationsAborted=TRUE;
435 where = 208;
436 break;
437 }
438 if (FromAttr & FILE_ATTRIBUTE_DIRECTORY) {
439 if (ToAttr == -1) {
440// Try to create an new Directory and enter in it
441 TRACE(__FUNCTION__" FO_COPY level=%d Creating Directory '%s'\n",level , pTempTo);
442 SHCreateDirectory(NULL,pTempTo);
443 ToAttr = GetFileAttributesA(pTempTo);
444 if (ToAttr == -1) {
445 nlpFileOp.fAnyOperationsAborted=TRUE;
446 retCode=0x10003;
447 where = 209;
448 break;
449 }
450
451 lenTempTo = strlen(pTempTo);
452
453 PathAddBackslashA(pTempFrom);
454 strcat(pTempFrom, "*.*");
455 pTempFrom[strlen(pTempFrom)+1]='\0';
456 nlpFileOp.pFrom = pTempFrom;
457
458 pTempTo[lenTempTo+1]='\0';
459 nlpFileOp.pTo = pTempTo;
460
461 TRACE(__FUNCTION__" FO_COPY level=%d Entering Directory '%s'\n",level , nlpFileOp.pTo);
462 TempretCode = SHFileOperationA (&nlpFileOp);
463
464 if (nlpFileOp.fAnyOperationsAborted) {break;}
465 continue;
466
467 } else {
468 TRACE(__FUNCTION__" FO_COPY level=%d unexpected with %s -> %s ? ,stub\n",level ,pTempFrom,pTo);
469 nlpFileOp.fAnyOperationsAborted=TRUE;
470 where = 210;
471 retCode=0x77;
472 break;
473
474 }
475
476 }
477
478 if (!(ToAttr == -1) && (ToAttr & FILE_ATTRIBUTE_DIRECTORY)) {
479 nlpFileOp.fAnyOperationsAborted=TRUE;
480 where = 211;
481 break;
482 }
483 if (0==strcmp(pTempFrom, pTempTo)) {
484 nlpFileOp.fAnyOperationsAborted=TRUE;
485 retCode = 0x71;
486 where = 212;
487 break;
488 }
489// first try to copy
490 if (CopyFileA(pTempFrom, pTempTo, not_overwrite)) continue;
491
492 if ((not_overwrite) && !(lpFileOp->fFlags & FOF_RENAMEONCOLLISION)) {
493 if (SHELL_ConfirmDialog (ASK_OVERWRITE_FILE, pTempTo))
494// second try to copy after confirm
495 if (CopyFileA(pTempFrom, pTempTo, FALSE)) continue;
496 } /* endif */
497
498 nlpFileOp.fAnyOperationsAborted=TRUE;
499 where = 215;
500 }
501 break;
502#else
503 while(1) {
504 if(!pFrom[0]) break;
505 if(!pTo[0]) break;
506 TRACE(" From='%s' To='%s'\n", pFrom, pTo);
507
508 pTempTo = HeapAlloc(GetProcessHeap(), 0, strlen(pTo)+1);
509 if (pTempTo)
510 {
511 strcpy( pTempTo, pTo );
512 PathRemoveFileSpecA(pTempTo);
513 TRACE(" Creating Directory '%s'\n", pTempTo);
514 SHCreateDirectory(NULL,pTempTo);
515 HeapFree(GetProcessHeap(), 0, pTempTo);
516 }
517 CopyFileA(pFrom, pTo, FALSE);
518
519 pFrom += strlen(pFrom) + 1;
520 pTo += strlen(pTo) + 1;
521 }
522 TRACE("Setting AnyOpsAborted=FALSE\n");
523 lpFileOp->fAnyOperationsAborted=FALSE;
524 return 0;
525#endif
526
527 case FO_DELETE:
528#ifdef __WIN32OS2__
529 TRACE(__FUNCTION__" FO_DELETE level=%d\n",level);
530// need break at error before change sourcepointer
531 while(!nlpFileOp.fAnyOperationsAborted && (pFrom+=lenFrom+1)[0]) {
532 lenFrom=strlen(pFrom);
533 FromAttr = GetFileAttributesA(pFrom);
534 if (!(FromAttr & FILE_ATTRIBUTE_DIRECTORY)) {
535 TRACE(__FUNCTION__" FO_DELETE level=%d File='%s'\n",level , pFrom);
536 if (DeleteFileA(pFrom)) continue;
537 nlpFileOp.fAnyOperationsAborted=TRUE;
538// retCode = 0x71;
539 where = 301;
540 break;
541 }
542 if (!(pTempFrom)) pTempFrom = HeapAlloc(GetProcessHeap(), 0, MAX_PATH+2);
543 strcpy(pTempFrom,pFrom);
544 PathRemoveBackslashA(pTempFrom);
545 FromAttr = GetFileAttributesA(pTempFrom);
546 if (!(FromAttr & FILE_ATTRIBUTE_DIRECTORY) ) {
547 nlpFileOp.fAnyOperationsAborted=TRUE;
548// retCode = 0x71;
549 where = 302;
550 break;
551 }
552// is Source an existing directory\*.* ?
553 if (FromAttr == -1) {
554 PathRemoveFileSpecA(pTempFrom);
555 FromAttr = GetFileAttributesA(pTempFrom);
556 }
557
558 PathAddBackslashA(pTempFrom);
559 lenTempFrom = strlen(pTempFrom);
560 pFromFile=&pTempFrom[lenTempFrom];
561
562 if (FromAttr == -1 ||
563 ((lenTempFrom==lenFrom) && !PathIsRootA(pFrom)) ||
564 !(FromAttr & FILE_ATTRIBUTE_DIRECTORY) ||
565 !(('\0'==pFrom[lenTempFrom]) || (0==strcmp(&pFrom[lenTempFrom],"*.*"))) ) {
566 retCode=0x402;
567 nlpFileOp.fAnyOperationsAborted=TRUE;
568 where = 303;
569 break;
570 }
571 strcpy(pFromFile, "*.*");
572 lenTempFrom = strlen(pTempFrom);
573 if (lenFrom < lenTempFrom) {
574// Source is without \*.*
575 pTempFrom[lenTempFrom+1]='\0';
576 nlpFileOp.pFrom = pTempFrom;
577
578 TRACE(__FUNCTION__" FO_DELETE level=%d Entering Directory '%s'\n",level , nlpFileOp.pFrom);
579 TempretCode = SHFileOperationA (&nlpFileOp);
580
581 if (nlpFileOp.fAnyOperationsAborted) {break;}
582// Call SHELL_DeleteDirectoryA ?
583 if (RemoveDirectoryA(pFrom)) continue;
584 nlpFileOp.fAnyOperationsAborted=TRUE;
585 where = 304;
586 break;
587 }
588 hFind = FindFirstFileA(pTempFrom, &wfd);
589 if (INVALID_HANDLE_VALUE == hFind) {
590 nlpFileOp.fAnyOperationsAborted=TRUE;
591 retCode=0x79;
592 where = 303;
593 break;
594 }
595
596 nlpFileOp.pFrom = pTempFrom;
597
598 nlpFileOp.fFlags = (nlpFileOp.fFlags & (-1 - (FOF_MULTIDESTFILES)));
599
600 TRACE(__FUNCTION__" FO_DELETE level=%d Delete in Subdir %s'\n",level , nlpFileOp.pFrom);
601
602 do {
603 TRACE(__FUNCTION__" FO_DELETE level=%d find '%s'\n",level , wfd.cFileName);
604 if (0==strcmp(wfd.cFileName,".")) continue;
605 if (0==strcmp(wfd.cFileName,"..")) continue;
606 if ((nlpFileOp.fFlags & FOF_FILESONLY) && (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)) {
607 continue;
608 } /* endif */
609
610 strcpy(pFromFile,wfd.cFileName);
611 pTempFrom[strlen(pTempFrom)+1]='\0';
612
613 TempretCode = SHFileOperationA (&nlpFileOp);
614
615 if (nlpFileOp.fAnyOperationsAborted) {where = 304;break;}
616
617 } while(FindNextFileA(hFind, &wfd));
618
619 FindClose(hFind);
620 if (nlpFileOp.fAnyOperationsAborted) {where = 305;break;}
621 continue;
622 }
623 break;
624 case FO_MOVE:
625 TRACE(__FUNCTION__" FO_MOVE level=%d File\\Tree Move: simply (Copy/Delete)\n",level);
626 nlpFileOp.wFunc = (level<<4) + FO_COPY;
627// not delete at error from copy
628 TempretCode = SHFileOperationA (&nlpFileOp);
629
630 if (nlpFileOp.fAnyOperationsAborted) {
631 if (TempretCode == 0x75) {
632// not all, the most
633 TempretCode = 0xD7;
634 retCode = 0xD7;
635 } /* endif */
636 break;
637 }
638
639 nlpFileOp.wFunc = (level<<4) + FO_DELETE;
640
641 TempretCode = SHFileOperationA (&nlpFileOp);
642
643 case 0:
644 break;
645#else
646 TRACE("File Delete:\n");
647 while(1) {
648 if(!pFrom[0]) break;
649 TRACE(" File='%s'\n", pFrom);
650 DeleteFileA(pFrom);
651 pFrom += strlen(pFrom) + 1;
652 }
653 TRACE("Setting AnyOpsAborted=FALSE\n");
654 lpFileOp->fAnyOperationsAborted=FALSE;
655 return 0;
656#endif
657
658 default:
659#ifdef __WIN32OS2__
660 TRACE(__FUNCTION__" Unhandled shell file operation %d at level=%d stub\n",(lpFileOp->wFunc & 15), level );
661 lpFileOp->fAnyOperationsAborted=TRUE;
662#else
663 FIXME("Unhandled shell file operation %d\n", lpFileOp->wFunc);
664 }
665#endif
666 return 1;
667
668#ifdef __WIN32OS2__
669 }
670 if (pTempFrom) HeapFree(GetProcessHeap(), 0, pTempFrom);
671
672 if (nlpFileOp.fAnyOperationsAborted) {
673 lpFileOp->fAnyOperationsAborted=TRUE;
674 if (TempretCode > retCode) {
675 retCode = TempretCode;
676 } /* endif */
677 }
678 if (lpFileOp->fAnyOperationsAborted==TRUE) {
679 if (FO_DELETE == (lpFileOp->wFunc & 15)) {
680 TRACE(__FUNCTION__" Setting AnyOpsAborted=TRUE level=%d ret=0x%x, at=%i with %s\n",level, retCode,where,pFrom);
681 } else {
682 TRACE(__FUNCTION__" Setting AnyOpsAborted=TRUE level=%d ret=0x%x, at=%i with %s -> %s\n",level, retCode,where,pFrom,pTo);
683 }
684 return retCode;
685 } /* endif */
686 TRACE(__FUNCTION__" Setting AnyOpsAborted=FALSE\n");
687 return 0;
688
689#endif
690}
691
692/*************************************************************************
693 * SHFileOperationW [SHELL32.244]
694 *
695 * NOTES
696 * exported by name
697 */
698DWORD WINAPI SHFileOperationW (LPSHFILEOPSTRUCTW lpFileOp)
699{
700#ifdef __WIN32OS2__
701 FIXME(__FUNCTION__"(%p) ,stub\n", lpFileOp);
702#else
703 FIXME("(%p):stub.\n", lpFileOp);
704#endif
705 return 1;
706}
707
708/*************************************************************************
709 * SHFileOperation [SHELL32.242]
710 *
711 */
712DWORD WINAPI SHFileOperationAW(LPVOID lpFileOp)
713{
714 if (SHELL_OsIsUnicode())
715 return SHFileOperationW(lpFileOp);
716 return SHFileOperationA(lpFileOp);
717}
718
719/*************************************************************************
720 * SheGetDirW [SHELL32.281]
721 *
722 */
723HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
724#ifdef __WIN32OS2__
725{ FIXME(__FUNCTION__"(%p, %p) ,stub\n",u,v);
726#else
727{ FIXME("%p %p stub\n",u,v);
728#endif
729 return 0;
730}
731
732/*************************************************************************
733 * SheChangeDirW [SHELL32.274]
734 *
735 */
736HRESULT WINAPI SheChangeDirW(LPWSTR u)
737#ifdef __WIN32OS2__
738{ FIXME(__FUNCTION__"(%s),stub\n",debugstr_w(u));
739#else
740{ FIXME("(%s),stub\n",debugstr_w(u));
741#endif
742 return 0;
743}
744
745/*************************************************************************
746 * IsNetDrive [SHELL32.66]
747 */
748BOOL WINAPI IsNetDrive(DWORD drive)
749{
750 char root[4];
751 strcpy(root, "A:\\");
752 root[0] += drive;
753 return (GetDriveTypeA(root) == DRIVE_REMOTE);
754}
755
756
Note: See TracBrowser for help on using the repository browser.