- Timestamp:
- Feb 14, 2003, 11:07:19 AM (23 years ago)
- Location:
- trunk/src/shell32
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/shell32/changenotify.c
r9408 r9805 1 /* $Id: changenotify.c,v 1. 8 2002-11-13 14:42:27 sandervl Exp $ */1 /* $Id: changenotify.c,v 1.9 2003-02-14 10:07:17 sandervl Exp $ */ 2 2 /* 3 3 * shell change notification 4 4 * 5 * Juergen Schmied <juergen.schmied@debitel.de> 6 * 5 * Copyright 2000 Juergen Schmied 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 20 */ 8 21 #ifdef __WIN32OS2__ … … 13 26 #include <string.h> 14 27 15 #include " debugtools.h"28 #include "wine/debug.h" 16 29 #include "pidl.h" 17 30 #include "shell32_main.h" 18 31 #include "undocshell.h" 19 32 20 DEFAULT_DEBUG_CHANNEL(shell);33 WINE_DEFAULT_DEBUG_CHANNEL(shell); 21 34 22 35 static CRITICAL_SECTION SHELL32_ChangenotifyCS = CRITICAL_SECTION_INIT("SHELL32_ChangenotifyCS"); … … 56 69 while(ptr != &tail) 57 70 { 58 inti;71 UINT i; 59 72 item = ptr; 60 73 ptr = ptr->next; … … 106 119 107 120 ptr = head.next; 108 #ifdef __WIN32OS2__ 109 while((ptr != &tail)/* && (ret == FALSE) see the rant below */) 110 #else 111 while((ptr != &tail) && (ret == FALSE)) 112 #endif 121 while(ptr != &tail) 113 122 { 114 123 TRACE("ptr=%p\n", ptr); … … 116 125 if (ptr == item) 117 126 { 118 inti;127 UINT i; 119 128 120 129 TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next); … … 128 137 SHFree(item->apidl); 129 138 SHFree(item); 130 #ifdef __WIN32OS2__ 131 /* 132 * Anyway, ptr == item, we free item hence the memory shouldn't be 133 * accessed by us any longer. We have to break here so we do NOT do 134 * the next operation below! 135 * -bird- 136 */ 137 ret = TRUE; 138 break; 139 #else 140 ret = TRUE; 141 #endif 139 140 ret = TRUE; 141 break; 142 142 } 143 143 ptr = ptr->next; … … 167 167 item = SHAlloc(sizeof(NOTIFICATIONLIST)); 168 168 169 TRACE("( 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p) item=%p\n",169 TRACE("(%p,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p) item=%p\n", 170 170 hwnd,dwFlags,wEventMask,uMsg,cItems,lpItems,item); 171 171 … … 191 191 */ 192 192 BOOL WINAPI 193 SHChangeNotifyDeregister( 194 HANDLE hNotify) 195 { 196 TRACE("(0x%08x)\n",hNotify); 197 198 return DeleteNode((LPNOTIFICATIONLIST)hNotify);; 193 SHChangeNotifyDeregister(HANDLE hNotify) 194 { 195 TRACE("(%p)\n",hNotify); 196 197 return DeleteNode((LPNOTIFICATIONLIST)hNotify); 199 198 } 200 199 … … 215 214 * SHChangeNotify [SHELL32.239] 216 215 */ 217 void WINAPI SHChangeNotify W (LONG wEventId, UINTuFlags, LPCVOID dwItem1, LPCVOID dwItem2)218 { 219 LPITEMIDLIST pidl1=(LPITEMIDLIST)dwItem1, pidl2=(LPITEMIDLIST)dwItem2;216 void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2) 217 { 218 LPITEMIDLIST Pidls[2]; 220 219 LPNOTIFICATIONLIST ptr; 221 222 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2); 220 DWORD dummy; 221 UINT typeFlag = uFlags & SHCNF_TYPE; 222 223 Pidls[0] = (LPITEMIDLIST)dwItem1; 224 Pidls[1] = (LPITEMIDLIST)dwItem2; 225 226 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId, uFlags, dwItem1, dwItem2); 223 227 224 228 /* convert paths in IDLists*/ 225 if(uFlags & SHCNF_PATHA) 226 { 227 DWORD dummy; 228 if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &pidl1, &dummy); 229 if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &pidl2, &dummy); 230 } 231 229 switch (typeFlag) 230 { 231 case SHCNF_PATHA: 232 if (dwItem1) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy); 233 if (dwItem2) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy); 234 break; 235 case SHCNF_PATHW: 236 if (dwItem1) SHILCreateFromPathW((LPCWSTR)dwItem1, &Pidls[0], &dummy); 237 if (dwItem2) SHILCreateFromPathW((LPCWSTR)dwItem2, &Pidls[1], &dummy); 238 break; 239 case SHCNF_PRINTERA: 240 case SHCNF_PRINTERW: 241 FIXME("SHChangeNotify with (uFlags & SHCNF_PRINTER)"); 242 break; 243 } 244 232 245 EnterCriticalSection(&SHELL32_ChangenotifyCS); 233 246 234 247 /* loop through the list */ 235 248 ptr = head.next; 236 while (ptr != &tail)249 while (ptr != &tail) 237 250 { 238 251 TRACE("trying %p\n", ptr); 239 240 if(wEventId & ptr->wEventMask) 241 { 242 TRACE("notifying\n"); 243 SendMessageA(ptr->hwnd, ptr->uMsg, (WPARAM)pidl1, (LPARAM)pidl2); 244 } 245 ptr = ptr->next; 246 } 247 248 LeaveCriticalSection(&SHELL32_ChangenotifyCS); 249 250 if(uFlags & SHCNF_PATHA) 251 { 252 if (pidl1) SHFree(pidl1); 253 if (pidl2) SHFree(pidl2); 254 } 255 } 256 257 /************************************************************************* 258 * SHChangeNotify [SHELL32.239] 259 */ 260 void WINAPI SHChangeNotifyA (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2) 261 { 262 LPITEMIDLIST Pidls[2]; 263 LPNOTIFICATIONLIST ptr; 264 265 Pidls[0] = (LPITEMIDLIST)dwItem1; 266 Pidls[1] = (LPITEMIDLIST)dwItem2; 267 268 TRACE("(0x%08lx,0x%08x,%p,%p):stub.\n", wEventId,uFlags,dwItem1,dwItem2); 269 270 /* convert paths in IDLists*/ 271 if(uFlags & SHCNF_PATHA) 272 { 273 DWORD dummy; 274 if (Pidls[0]) SHILCreateFromPathA((LPCSTR)dwItem1, &Pidls[0], &dummy); 275 if (Pidls[1]) SHILCreateFromPathA((LPCSTR)dwItem2, &Pidls[1], &dummy); 276 } 277 278 EnterCriticalSection(&SHELL32_ChangenotifyCS); 279 280 /* loop through the list */ 281 ptr = head.next; 282 while(ptr != &tail) 283 { 284 TRACE("trying %p\n", ptr); 285 286 if(wEventId & ptr->wEventMask) 252 253 if (wEventId & ptr->wEventMask) 287 254 { 288 255 TRACE("notifying\n"); … … 291 258 ptr = ptr->next; 292 259 } 293 260 294 261 LeaveCriticalSection(&SHELL32_ChangenotifyCS); 295 262 296 263 /* if we allocated it, free it */ 297 if(uFlags & SHCNF_PATHA) 298 { 299 if (Pidls[0]) SHFree(Pidls[0]); 300 if (Pidls[1]) SHFree(Pidls[1]); 301 } 302 } 303 304 /************************************************************************* 305 * SHChangeNotifyAW [SHELL32.239] 306 */ 307 void WINAPI SHChangeNotifyAW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2) 308 { 309 if(SHELL_OsIsUnicode()) 310 SHChangeNotifyW (wEventId, uFlags, dwItem1, dwItem2); 311 else 312 SHChangeNotifyA (wEventId, uFlags, dwItem1, dwItem2); 264 if ((typeFlag == SHCNF_PATHA) || (typeFlag == SHCNF_PATHW)) 265 { 266 if (Pidls[0]) SHFree(Pidls[0]); 267 if (Pidls[1]) SHFree(Pidls[1]); 268 } 313 269 } 314 270 … … 327 283 LPNOTIFYREGISTER idlist) 328 284 { 329 FIXME("( 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n",285 FIXME("(%p,0x%08lx,0x%08lx,0x%08lx,0x%08x,%p):stub.\n", 330 286 hwnd,events1,events2,msg,count,idlist); 331 287 return 0; -
trunk/src/shell32/dbgwrap.cpp
r8586 r9805 40 40 DEBUGWRAP4(ILGlobalClone) 41 41 DEBUGWRAP8(ILIsEqual) 42 NODEF_DEBUGWRAP16(Control_RunDLL) 42 NODEF_DEBUGWRAP16(Control_RunDLLA) 43 NODEF_DEBUGWRAP16(Control_RunDLLW) 43 44 DEBUGWRAP12(ILIsParent) 44 45 DEBUGWRAP8(ILFindChild) … … 174 175 DEBUGWRAP4(SHSimpleIDListFromPathAW) 175 176 NODEF_DEBUGWRAP8(StrToOleStr) 176 NODEF_DEBUGWRAP4(Win32DeleteFile )177 NODEF_DEBUGWRAP8(SHCreateDirectory)177 NODEF_DEBUGWRAP4(Win32DeleteFileAW) 178 DEBUGWRAP8(SHCreateDirectory) 178 179 NODEF_DEBUGWRAP12(SHAddFromPropSheetExtArray) 179 180 NODEF_DEBUGWRAP12(SHCreatePropSheetExtArray) … … 214 215 DEBUGWRAP4(SHBrowseForFolderA) 215 216 DEBUGWRAP4(SHBrowseForFolderW) 216 NODEF_DEBUGWRAP16(SHChangeNotifyAW)217 DEBUGWRAP16(SHChangeNotify) 217 218 NODEF_DEBUGWRAP12(SHEmptyRecycleBinA) 218 219 NODEF_DEBUGWRAP12(SHEmptyRecycleBinW) -
trunk/src/shell32/shell32.def
r8586 r9805 1 ; $Id: shell32.def,v 1.3 8 2002-06-07 08:21:43sandervl Exp $1 ; $Id: shell32.def,v 1.39 2003-02-14 10:07:18 sandervl Exp $ 2 2 3 3 ; Based on Windows 95 … … 29 29 ILGlobalClone = _ILGlobalClone@4 @20 30 30 ILIsEqual = _ILIsEqual@8 @21 31 Control_RunDLL = _Control_RunDLL @16@2231 Control_RunDLL = _Control_RunDLLA@16 @22 32 32 ILIsParent = _ILIsParent@12 @23 33 33 ILFindChild = _ILFindChild@8 @24 … … 48 48 PathIsUNC = _PathIsUNCAW@4 @39 49 49 PathIsRelative = _PathIsRelativeAW@4 @40 50 ;Control_RunDLLA = _Control_RunDLLA@16 @4151 ;Control_RunDLLW = _Control_RunDLLW@16 @4250 Control_RunDLLA = _Control_RunDLLA@16 @41 51 Control_RunDLLW = _Control_RunDLLW@16 @42 52 52 PathIsExe = _PathIsExeAW@4 @43 53 53 DoEnvironmentSubstA = _DoEnvironmentSubstA@8 @44 … … 173 173 SHSimpleIDListFromPath = _SHSimpleIDListFromPathAW@4 @162 174 174 StrToOleStr = _StrToOleStr@8 @163 175 Win32DeleteFile = _Win32DeleteFile @4@164175 Win32DeleteFile = _Win32DeleteFileAW@4 @164 176 176 SHCreateDirectory = _SHCreateDirectory@8 @165 177 177 ; CallCPLEntry16 = _CallCPLEntry16@? @166 … … 248 248 SHBrowseForFolderA = _SHBrowseForFolderA@4 @237 249 249 SHBrowseForFolderW = _SHBrowseForFolderW@4 @238 250 SHChangeNotify = _SHChangeNotify AW@16@239250 SHChangeNotify = _SHChangeNotify@16 @239 251 251 SHEmptyRecycleBinA = _SHEmptyRecycleBinA@12 @240 252 252 SHEmptyRecycleBinW = _SHEmptyRecycleBinW@12 @241 -
trunk/src/shell32/shell32dbg.def
r8586 r9805 1 ; $Id: shell32dbg.def,v 1. 3 2002-06-07 08:21:43sandervl Exp $1 ; $Id: shell32dbg.def,v 1.4 2003-02-14 10:07:18 sandervl Exp $ 2 2 3 3 ; Based on Windows 95 … … 29 29 ILGlobalClone = _DbgILGlobalClone@4 @20 30 30 ILIsEqual = _DbgILIsEqual@8 @21 31 Control_RunDLL = _DbgControl_RunDLL @16@2231 Control_RunDLL = _DbgControl_RunDLLA@16 @22 32 32 ILIsParent = _DbgILIsParent@12 @23 33 33 ILFindChild = _DbgILFindChild@8 @24 … … 48 48 PathIsUNC = _DbgPathIsUNCAW@4 @39 49 49 PathIsRelative = _DbgPathIsRelativeAW@4 @40 50 ;Control_RunDLLA = _DbgControl_RunDLLA@16 @4151 ;Control_RunDLLW = _DbgControl_RunDLLW@16 @4250 Control_RunDLLA = _DbgControl_RunDLLA@16 @41 51 Control_RunDLLW = _DbgControl_RunDLLW@16 @42 52 52 PathIsExe = _DbgPathIsExeAW@4 @43 53 53 DoEnvironmentSubstA = _DbgDoEnvironmentSubstA@8 @44 … … 173 173 SHSimpleIDListFromPath = _DbgSHSimpleIDListFromPathAW@4 @162 174 174 StrToOleStr = _DbgStrToOleStr@8 @163 175 Win32DeleteFile = _DbgWin32DeleteFile @4@164175 Win32DeleteFile = _DbgWin32DeleteFileAW@4 @164 176 176 SHCreateDirectory = _DbgSHCreateDirectory@8 @165 177 177 ; CallCPLEntry16 = _DbgCallCPLEntry16@? @166 … … 248 248 SHBrowseForFolderA = _DbgSHBrowseForFolderA@4 @237 249 249 SHBrowseForFolderW = _DbgSHBrowseForFolderW@4 @238 250 SHChangeNotify = _DbgSHChangeNotify AW@16@239250 SHChangeNotify = _DbgSHChangeNotify@16 @239 251 251 SHEmptyRecycleBinA = _DbgSHEmptyRecycleBinA@12 @240 252 252 SHEmptyRecycleBinW = _DbgSHEmptyRecycleBinW@12 @241 -
trunk/src/shell32/shlfileop.c
r9552 r9805 5 5 * Copyright 2002 Andriy Palamarchuk 6 6 * Copyright 2002 Dietrich Teickner (from Odin) 7 * Copyright 2002 Rolf Kalbermatter 7 8 * 8 9 * This library is free software; you can redistribute it and/or … … 25 26 26 27 #include <string.h> 28 #include <ctype.h> 27 29 28 30 #include "winreg.h" … … 39 41 BOOL SHELL_ConfirmDialog (int nKindOfDialog, LPCSTR szDir) 40 42 { 41 43 char szCaption[255], szText[255], szBuffer[MAX_PATH + 256]; 42 44 UINT caption_resource_id, text_resource_id; 43 45 44 45 46 47 caption_resource_id= IDS_DELETEITEM_CAPTION;48 text_resource_id= IDS_DELETEITEM_TEXT;49 50 51 caption_resource_id= IDS_DELETEFOLDER_CAPTION;52 text_resource_id= IDS_DELETEITEM_TEXT;53 54 55 caption_resource_id= IDS_DELETEITEM_CAPTION;56 text_resource_id= IDS_DELETEMULTIPLE_TEXT;57 58 59 caption_resource_id= IDS_OVERWRITEFILE_CAPTION;60 text_resource_id= IDS_OVERWRITEFILE_TEXT;61 62 63 64 65 66 67 68 69 70 71 72 73 46 switch(nKindOfDialog) { 47 48 case ASK_DELETE_FILE: 49 caption_resource_id = IDS_DELETEITEM_CAPTION; 50 text_resource_id = IDS_DELETEITEM_TEXT; 51 break; 52 case ASK_DELETE_FOLDER: 53 caption_resource_id = IDS_DELETEFOLDER_CAPTION; 54 text_resource_id = IDS_DELETEITEM_TEXT; 55 break; 56 case ASK_DELETE_MULTIPLE_ITEM: 57 caption_resource_id = IDS_DELETEITEM_CAPTION; 58 text_resource_id = IDS_DELETEMULTIPLE_TEXT; 59 break; 60 case ASK_OVERWRITE_FILE: 61 caption_resource_id = IDS_OVERWRITEFILE_CAPTION; 62 text_resource_id = IDS_OVERWRITEFILE_TEXT; 63 break; 64 default: 65 FIXME(" Unhandled nKindOfDialog %d stub\n", nKindOfDialog); 66 return FALSE; 67 } 68 69 LoadStringA(shell32_hInstance, caption_resource_id, szCaption, sizeof(szCaption)); 70 LoadStringA(shell32_hInstance, text_resource_id, szText, sizeof(szText)); 71 72 FormatMessageA(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY, 73 szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)&szDir); 74 75 return (IDOK == MessageBoxA(GetActiveWindow(), szBuffer, szCaption, MB_OKCANCEL | MB_ICONEXCLAMATION)); 74 76 } 75 77 76 78 /************************************************************************** 77 * 79 * SHELL_DeleteDirectoryA() 78 80 * 79 81 * like rm -r 80 82 */ 81 82 83 BOOL SHELL_DeleteDirectoryA(LPCSTR pszDir, BOOL bShowUI) 83 84 { 84 BOOL ret = FALSE; 85 HANDLE hFind; 86 WIN32_FIND_DATAA wfd; 87 char szTemp[MAX_PATH]; 88 89 strcpy(szTemp, pszDir); 90 PathAddBackslashA(szTemp); 91 strcat(szTemp, "*.*"); 92 93 if (bShowUI && !SHELL_ConfirmDialog(ASK_DELETE_FOLDER, pszDir)) 94 return FALSE; 95 96 if(INVALID_HANDLE_VALUE != (hFind = FindFirstFileA(szTemp, &wfd))) 97 { 98 do 99 { 100 if(strcasecmp(wfd.cFileName, ".") && strcasecmp(wfd.cFileName, "..")) 101 { 102 strcpy(szTemp, pszDir); 103 PathAddBackslashA(szTemp); 104 strcat(szTemp, wfd.cFileName); 105 106 if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) 107 SHELL_DeleteDirectoryA(szTemp, FALSE); 108 else 109 DeleteFileA(szTemp); 110 } 111 } while(FindNextFileA(hFind, &wfd)); 112 113 FindClose(hFind); 114 ret = RemoveDirectoryA(pszDir); 115 } 116 117 return ret; 85 BOOL ret = FALSE; 86 HANDLE hFind; 87 WIN32_FIND_DATAA wfd; 88 char szTemp[MAX_PATH]; 89 90 strcpy(szTemp, pszDir); 91 PathAddBackslashA(szTemp); 92 strcat(szTemp, "*.*"); 93 94 hFind = FindFirstFileA(szTemp, &wfd); 95 96 ret = (INVALID_HANDLE_VALUE != hFind); 97 98 if (ret && (!bShowUI || SHELL_ConfirmDialog(ASK_DELETE_FOLDER, pszDir))) 99 { 100 do 101 { 102 if(strcasecmp(wfd.cFileName, ".") && strcasecmp(wfd.cFileName, "..")) 103 { 104 strcpy(szTemp, pszDir); 105 PathAddBackslashA(szTemp); 106 strcat(szTemp, wfd.cFileName); 107 108 if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) 109 SHELL_DeleteDirectoryA(szTemp, FALSE); 110 else 111 DeleteFileA(szTemp); 112 } 113 } while(FindNextFileA(hFind, &wfd)); 114 FindClose(hFind); 115 ret = RemoveDirectoryA(pszDir); 116 } 117 return ret; 118 118 } 119 119 120 120 /************************************************************************** 121 * 121 * SHELL_DeleteFileA() 122 122 */ 123 123 124 124 BOOL SHELL_DeleteFileA(LPCSTR pszFile, BOOL bShowUI) 125 125 { 126 if (bShowUI && !SHELL_ConfirmDialog(ASK_DELETE_FILE, pszFile)) 127 return FALSE; 128 126 if (bShowUI && !SHELL_ConfirmDialog(ASK_DELETE_FILE, pszFile)) 127 return FALSE; 129 128 return DeleteFileA(pszFile); 130 129 } 131 130 132 131 /************************************************************************* 133 * SHCreateDirectory 132 * SHCreateDirectory [SHELL32.165] 134 133 * 135 134 * NOTES 136 135 * exported by ordinal 137 * not sure about LPSECURITY_ATTRIBUTES 138 */ 139 DWORD WINAPI SHCreateDirectory(LPSECURITY_ATTRIBUTES sec,LPCSTR path) 136 * WinNT/2000 exports Unicode 137 */ 138 DWORD WINAPI SHCreateDirectory(HWND hWnd, LPCVOID path) 139 { 140 if (SHELL_OsIsUnicode()) 141 return SHCreateDirectoryExW(hWnd, path, NULL); 142 return SHCreateDirectoryExA(hWnd, path, NULL); 143 } 144 145 /************************************************************************* 146 * SHCreateDirectoryExA [SHELL32.@] 147 */ 148 DWORD WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES sec) 140 149 { 141 150 DWORD ret; 142 TRACE("(%p,%s)\n",sec,path); 143 if ((ret = CreateDirectoryA(path,sec))) 151 TRACE("(%p, %s, %p)\n",hWnd, path, sec); 152 ret = CreateDirectoryA(path, sec); 153 if (ret) 144 154 { 145 SHChangeNotify A(SHCNE_MKDIR, SHCNF_PATHA, path, NULL);155 SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHA, path, NULL); 146 156 } 157 else if (hWnd) 158 FIXME("Semi-stub, non zero hWnd should be used as parent for error dialog!"); 147 159 return ret; 148 160 } 149 161 162 /************************************************************************* 163 * SHCreateDirectoryExW [SHELL32.@] 164 */ 165 DWORD WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec) 166 { 167 DWORD ret; 168 TRACE("(%p, %s, %p)\n",hWnd, debugstr_w(path), sec); 169 ret = CreateDirectoryW(path, sec); 170 if (ret) 171 { 172 SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW, path, NULL); 173 } 174 else if (hWnd) 175 FIXME("Semi-stub, non zero hWnd should be used as parent for error dialog!"); 176 return ret; 177 } 178 150 179 /************************************************************************ 151 * Win32DeleteFile [SHELL32.164] 152 * 153 * Deletes a file. Also triggers a change notify if one exists. 154 * 155 * FIXME: 156 * Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be 157 * ANSI. Is this Unicode on NT? 158 * 159 */ 160 161 BOOL WINAPI Win32DeleteFile(LPSTR fName) 162 { 180 * Win32DeleteFile [SHELL32.164] 181 * 182 * Deletes a file. Also triggers a change notify if one exists. 183 * 184 * NOTES: 185 * Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI. 186 * This is Unicode on NT/2000 187 */ 188 static BOOL Win32DeleteFileA(LPCSTR fName) 189 { 190 DWORD ret; 163 191 TRACE("%p(%s)\n", fName, fName); 164 192 165 DeleteFileA(fName); 166 SHChangeNotifyA(SHCNE_DELETE, SHCNF_PATHA, fName, NULL); 167 return TRUE; 168 } 169 170 /************************************************************************* 171 * 172 * SHFileTyp (internal) 173 * 174 */ 175 DWORD SHFileTyp(LPSTR pFromTo, long *len, LPSTR pTemp, long *lenTemp, LPSTR *pFile, DWORD *PathAttr, DWORD *Attr) { 176 #define TypisBad -1 177 #define TypisUnkn 0 178 #define TypisNewPath 1 179 #define TypisRoot 2 180 #define TypisDirS 3 181 #define TypisDir 4 182 #define TypisFile 5 183 #define TypisName 6 184 #define TypisNameS 7 185 #define TypisMask 8 186 DWORD Typ = TypisUnkn; 187 DWORD i_Attr; 188 DWORD i_PathAttr; 189 BOOL i_Slash = FALSE; 190 LPSTR i_pFile; 191 LPSTR i_pLastSlash; 192 long i_lenTemp; 193 long i_len = *len = strlen(pFromTo); 194 if (i_len == 0) return TypisUnkn; 195 strcpy(pTemp,pFromTo); 196 if (pTemp[1] == ':' && pTemp[0] >= 'a' && pTemp[0] <= 'z') pTemp[0] = (pTemp[0] & (0xff - ' ')); 197 *pFile = i_pFile = &pTemp[i_len]; 198 pTemp[i_len+1] = '\0'; 199 if (i_len == 0) return /* ?? */ TypisBad; 200 if (PathIsRootA(pFromTo)) Typ = TypisRoot; 201 i_pLastSlash = strrchr(pTemp,'\\'); 202 if (i_pLastSlash == NULL) return TypisBad /* ??? */; 203 i_Slash = (i_pLastSlash[1] == '\0'); 204 *lenTemp = i_lenTemp = strlen(pTemp) - i_Slash; 205 *pFile = i_pFile = &pTemp[i_lenTemp]; 206 if (Typ != TypisRoot) i_pFile[0] = '\0'; 207 *PathAttr = *Attr = i_PathAttr = i_Attr = GetFileAttributesA(pTemp); 208 if (i_Attr == -1) { 209 if (Typ == TypisRoot) Typ = TypisBad; 210 } else { 211 if (i_Attr & FILE_ATTRIBUTE_DIRECTORY) { 212 if (Typ == TypisUnkn) { 213 Typ = TypisDir; 214 if (i_Slash) Typ = TypisDirS; 215 } 216 } else { 217 if (Typ == TypisUnkn && !i_Slash) { 218 Typ = TypisFile; 219 } else Typ = TypisBad; 220 } 193 if (!(ret = DeleteFileA(fName))) 194 { 195 /* File may be write protected or a system file */ 196 DWORD dwAttr = GetFileAttributesA(fName); 197 if ((dwAttr != -1) && (dwAttr & FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)) 198 if (SetFileAttributesA(fName, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))) 199 ret = DeleteFileA(fName); 221 200 } 222 // is the directory exists with \*.* ? 223 i_pFile = strrchr(pTemp,'\\'); 224 if (NULL == i_pFile) Typ = TypisBad; 225 if (Typ == TypisUnkn || Typ == TypisFile) { 226 PathRemoveFileSpecA(pTemp); 227 // mask in Path ? 228 if (NULL != strpbrk(pTemp,"*?\0")) { 229 Typ = TypisBad; 230 } else { 231 while (-1 == (i_PathAttr = GetFileAttributesA(pTemp)) && !PathIsRootA(pTemp)) { 232 PathRemoveFileSpecA(pTemp); 233 Typ = TypisNewPath; 234 } 235 i_lenTemp = strlen(pTemp); 236 if (pTemp[i_lenTemp - 1] == '\\') i_lenTemp--; 237 *lenTemp = i_lenTemp; 238 *pFile = i_pFile = &pTemp[i_lenTemp]; 239 *PathAttr = i_PathAttr; 240 if (-1 == i_PathAttr || !(i_PathAttr & FILE_ATTRIBUTE_DIRECTORY)) Typ = TypisBad; 241 } 242 strcpy(&pTemp[1],&pFromTo[1]); 243 if (Typ == TypisUnkn && i_PathAttr != -1 && (i_PathAttr & FILE_ATTRIBUTE_DIRECTORY)) { 244 if (NULL == strpbrk(i_pFile,"*?\0")) { 245 if (!i_Slash) { 246 *lenTemp = i_lenTemp = strlen(pTemp); 247 *pFile = &pTemp[i_lenTemp]; 248 Typ = TypisName; 249 } else Typ = TypisNameS; 250 } else Typ = TypisMask; 251 } 201 if (ret) 202 SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, fName, NULL); 203 return ret; 204 } 205 206 static BOOL Win32DeleteFileW(LPCWSTR fName) 207 { 208 BOOL ret; 209 TRACE("%p(%s)\n", fName, debugstr_w(fName)); 210 211 if (!(ret = DeleteFileW(fName))) 212 { 213 /* File may be write protected or a system file */ 214 DWORD dwAttr = GetFileAttributesW(fName); 215 if ((dwAttr != -1) && (dwAttr & FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)) 216 if (SetFileAttributesW(fName, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))) 217 ret = DeleteFileW(fName); 252 218 } 253 i_pLastSlash[0] = '\\'; 254 return Typ; 255 } 256 257 /************************************************************************* 258 * SHFileOperationA [SHELL32.@] 219 if (ret) 220 SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW, fName, NULL); 221 return ret; 222 } 223 224 BOOL WINAPI Win32DeleteFileAW(LPCVOID fName) 225 { 226 if (SHELL_OsIsUnicode()) 227 return Win32DeleteFileW(fName); 228 return Win32DeleteFileA(fName); 229 } 230 231 /************************************************************************* 232 * 233 * SHFileStrCpyCat HelperFunction for SHFileOperationA 234 * 235 */ 236 LPSTR SHFileStrCpyCatA(LPSTR pTo, LPCSTR pFrom, LPCSTR pCatStr) 237 { 238 LPSTR pToFile = NULL; 239 int i_len; 240 241 if (pTo) 242 { 243 if (pFrom) 244 lstrcpyA(pTo, pFrom); 245 if (pCatStr) /* lstrcatA(pTo, pCatStr); ?? */ 246 { 247 i_len = lstrlenA(pTo); 248 if ((i_len) && (pCatStr[0] == '\\') && (pTo[--i_len] == '\\')) 249 pTo[i_len] = '\0'; 250 lstrcatA(pTo, pCatStr); 251 } 252 pToFile = strrchr(pTo,'\\'); 253 /* !! termination of the new string-group */ 254 pTo[(lstrlenA(pTo)) + 1] = '\0'; 255 } 256 return pToFile; 257 } 258 259 /************************************************************************* 260 * 261 * SHFileStrICmp HelperFunction for SHFileOperationA 262 * 263 */ 264 BOOL SHFileStrICmpA(LPSTR p1,LPSTR p2, LPSTR p1End, LPSTR p2End) 265 { 266 CHAR C1 = '\0'; 267 CHAR C2 = '\0'; 268 int i_Temp = -1; 269 int i_len1 = lstrlenA(p1); 270 int i_len2 = lstrlenA(p2); 271 272 if (p1End && (&p1[i_len1] >= p1End) && ('\\' == p1End[0])) 273 { 274 C1 = p1End[0]; 275 p1End[0] = '\0'; 276 i_len1 = lstrlenA(p1); 277 } 278 if (p2End) 279 { 280 if ((&p2[i_len2] >= p2End) && ('\\' == p2End[0])) 281 { 282 C2 = p2End[0]; 283 if (C2) 284 p2End[0] = '\0'; 285 } 286 } 287 else 288 { 289 if ((i_len1 <= i_len2) && ('\\' == p2[i_len1])) 290 { 291 C2 = p2[i_len1]; 292 if (C2) 293 p2[i_len1] = '\0'; 294 } 295 } 296 i_len2 = lstrlenA(p2); 297 if (i_len1 == i_len2) 298 i_Temp = lstrcmpiA(p1,p2); 299 if (C1) 300 p1[i_len1] = C1; 301 if (C2) 302 p2[i_len2] = C2; 303 return !(i_Temp); 304 } 305 306 #define IsAttribFile(x) (!(x == -1) && !(x & FILE_ATTRIBUTE_DIRECTORY)) 307 #define IsAttribDir(x) (!(x == -1) && (x & FILE_ATTRIBUTE_DIRECTORY)) 308 #define TextFromPtr(x) (x ? x:"NULL") 309 /************************************************************************* 310 * SHFileOperationA [SHELL32.@] 259 311 * 260 312 * NOTES … … 263 315 DWORD WINAPI SHFileOperationA (LPSHFILEOPSTRUCTA lpFileOp) 264 316 { 265 LPSTR pFrom = (LPSTR)lpFileOp->pFrom; 266 LPSTR pTo = (LPSTR)lpFileOp->pTo; 267 LPSTR pTempTo; 268 DWORD FromAttr; 269 DWORD ToAttr; 270 DWORD FromPathAttr; 271 DWORD ToPathAttr; 272 DWORD FromTyp; 273 DWORD ToTyp = TypisBad; 274 DWORD zTyp; 275 LPSTR pFromFile; 276 LPSTR pToFile; 277 LPSTR pTempFrom = NULL; 278 LPSTR pToSlash; 279 LPSTR pToFuncTXT = "FO_COPY"; 280 FILEOP_FLAGS OFl = ((FILEOP_FLAGS)lpFileOp->fFlags & 0x7ff); 281 BOOL Multi = ((lpFileOp->fFlags & FOF_MULTIDESTFILES) != 0); 282 BOOL MakeDir = FALSE; 283 BOOL not_overwrite; 284 BOOL TargetisDir; 285 BOOL ask_overwrite; 286 BOOL ToSingle; 287 BOOL recurseinto; 288 long lenFrom = -1; 289 long lenTo = -1; 290 long lenTempFrom; 291 long lenTempTo; 292 long retCode = 0x75; 293 long TempretCode = 0; 294 long where = 0; 295 long FuncSwitch = (lpFileOp->wFunc & 15); 296 SHFILEOPSTRUCTA nlpFileOp = *(lpFileOp); 297 long level= nlpFileOp.wFunc>>4; 298 HANDLE hFind; 299 WIN32_FIND_DATAA wfd; 300 301 /* default no error 302 */ 303 lpFileOp->fAnyOperationsAborted=FALSE; 304 nlpFileOp.fAnyOperationsAborted=FALSE; 305 level++; 306 nlpFileOp.wFunc = (level<<4) + FuncSwitch; 307 if (level == 1) 308 TRACE("flags (0x%04x) : %s%s%s%s%s%s%s%s%s%s%s%s \n", lpFileOp->fFlags, 309 lpFileOp->fFlags & FOF_MULTIDESTFILES ? "FOF_MULTIDESTFILES " : "", 310 lpFileOp->fFlags & FOF_CONFIRMMOUSE ? "FOF_CONFIRMMOUSE " : "", 311 lpFileOp->fFlags & FOF_SILENT ? "FOF_SILENT " : "", 312 lpFileOp->fFlags & FOF_RENAMEONCOLLISION ? "FOF_RENAMEONCOLLISION " : "", 313 lpFileOp->fFlags & FOF_NOCONFIRMATION ? "FOF_NOCONFIRMATION " : "", 314 lpFileOp->fFlags & FOF_WANTMAPPINGHANDLE ? "FOF_WANTMAPPINGHANDLE " : "", 315 lpFileOp->fFlags & FOF_ALLOWUNDO ? "FOF_ALLOWUNDO " : "", 316 lpFileOp->fFlags & FOF_FILESONLY ? "FOF_FILESONLY " : "", 317 lpFileOp->fFlags & FOF_SIMPLEPROGRESS ? "FOF_SIMPLEPROGRESS " : "", 318 lpFileOp->fFlags & FOF_NOCONFIRMMKDIR ? "FOF_NOCONFIRMMKDIR " : "", 319 lpFileOp->fFlags & FOF_NOERRORUI ? "FOF_NOERRORUI " : "", 320 lpFileOp->fFlags & 0xf800 ? "MORE-UNKNOWN-Flags" : ""); 321 switch(FuncSwitch) { 322 case FO_MOVE: 323 retCode = 0xb7; 324 pToFuncTXT = "FO_MOVE"; 325 case FO_COPY: 326 { 317 SHFILEOPSTRUCTA nlpFileOp = *(lpFileOp); 318 319 LPCSTR pNextFrom = nlpFileOp.pFrom; 320 LPCSTR pNextTo = nlpFileOp.pTo; 321 LPCSTR pFrom = pNextFrom; 322 LPCSTR pTo = NULL; 323 HANDLE hFind = INVALID_HANDLE_VALUE; 324 WIN32_FIND_DATAA wfd; 325 LPSTR pTempFrom = NULL; 326 LPSTR pTempTo = NULL; 327 LPSTR pFromFile; 328 LPSTR pToFile; 329 long retCode = 0; 330 DWORD ToAttr; 331 DWORD ToPathAttr; 332 FILEOP_FLAGS OFl = ((FILEOP_FLAGS)lpFileOp->fFlags & 0x7ff); 333 334 BOOL b_Multi = (nlpFileOp.fFlags & FOF_MULTIDESTFILES); 335 336 BOOL b_MultiTo = (FO_DELETE != (lpFileOp->wFunc & 0xf)); 337 BOOL b_MultiFrom = FALSE; 338 BOOL not_overwrite; 339 BOOL ask_overwrite; 340 BOOL b_SameRoot; 341 BOOL b_SameTailName; 342 BOOL b_ToInvalidTail; 343 BOOL b_ToValid; /* for W98-Bug for FO_MOVE with source and taget in same rootdrive */ 344 BOOL b_Mask; /* wird als Schalter benutzt, vieleicht finde ich die richtige bitposition */ 345 BOOL b_ToTailSlash; 346 LPSTR pToFuncTXT; 347 348 long FuncSwitch = (nlpFileOp.wFunc & 0xf); 349 long level= nlpFileOp.wFunc>>4; 350 351 /* default no error */ 352 nlpFileOp.fAnyOperationsAborted=FALSE; 353 354 switch(FuncSwitch) 355 { 356 case FO_MOVE: 357 pToFuncTXT = "FO_MOVE";break; 358 case FO_COPY: 359 pToFuncTXT = "FO_COPY";break; 360 case FO_DELETE: 361 pToFuncTXT = "FO_DELETE";break; 362 case FO_RENAME: 363 pToFuncTXT = "FO_RENAME";break; 364 default: 365 pToFuncTXT = "FO_????"; 366 goto shfileop_normal; 367 } 368 369 if (level == 0) 370 TRACE("%s: flags (0x%04x) : %s%s%s%s%s%s%s%s%s%s%s%s \n",pToFuncTXT, nlpFileOp.fFlags, 371 nlpFileOp.fFlags & FOF_MULTIDESTFILES ? "FOF_MULTIDESTFILES " : "", 372 nlpFileOp.fFlags & FOF_CONFIRMMOUSE ? "FOF_CONFIRMMOUSE " : "", 373 nlpFileOp.fFlags & FOF_SILENT ? "FOF_SILENT " : "", 374 nlpFileOp.fFlags & FOF_RENAMEONCOLLISION ? "FOF_RENAMEONCOLLISION " : "", 375 nlpFileOp.fFlags & FOF_NOCONFIRMATION ? "FOF_NOCONFIRMATION " : "", 376 nlpFileOp.fFlags & FOF_WANTMAPPINGHANDLE ? "FOF_WANTMAPPINGHANDLE " : "", 377 nlpFileOp.fFlags & FOF_ALLOWUNDO ? "FOF_ALLOWUNDO " : "", 378 nlpFileOp.fFlags & FOF_FILESONLY ? "FOF_FILESONLY " : "", 379 nlpFileOp.fFlags & FOF_SIMPLEPROGRESS ? "FOF_SIMPLEPROGRESS " : "", 380 nlpFileOp.fFlags & FOF_NOCONFIRMMKDIR ? "FOF_NOCONFIRMMKDIR " : "", 381 nlpFileOp.fFlags & FOF_NOERRORUI ? "FOF_NOERRORUI " : "", 382 nlpFileOp.fFlags & 0xf800 ? "MORE-UNKNOWN-Flags" : ""); 383 ; 384 { 327 385 /* establish when pTo is interpreted as the name of the destination file 328 386 * or the directory where the Fromfile should be copied to. … … 341 399 * create dir 0 0 0 0 0 0 1 0 342 400 */ 343 nlpFileOp.pFrom = pTempFrom = HeapAlloc(GetProcessHeap(), 0, 3 * MAX_PATH+6);344 nlpFileOp.pTo = pTempTo = &pTempFrom[MAX_PATH+4];345 401 /* 346 * FOF_MULTIDESTFILES, FOF_NOCONFIRMATION, FOF_FILESONLY areimplemented347 * FOF_CONFIRMMOUSE, FOF_SILENT, FOF_NOCONFIRMMKDIR, FOF_SIMPLEPROGRESS 348 * FOF_RENAMEONCOLLISION areimplemented partially and breaks if file exist349 * FOF_ALLOWUNDO, FOF_WANTMAPPINGHANDLE 402 * FOF_MULTIDESTFILES, FOF_NOCONFIRMATION, FOF_FILESONLY are implemented 403 * FOF_CONFIRMMOUSE, FOF_SILENT, FOF_NOCONFIRMMKDIR, FOF_SIMPLEPROGRESS are not implemented and ignored 404 * FOF_RENAMEONCOLLISION are implemented partially and breaks if file exist 405 * FOF_ALLOWUNDO, FOF_WANTMAPPINGHANDLE are not implemented and breaks 350 406 * if any other flag set, an error occurs 351 407 */ 352 TRACE(__FUNCTION__" %s level=%d lpFileOp->fFlags=0x%x\n", pToFuncTXT, level, lpFileOp->fFlags); 353 // OFl = (OFl & (-1 - (FOF_MULTIDESTFILES | FOF_FILESONLY))); 354 // OFl = (OFl ^ (FOF_SILENT | FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMMKDIR)); 355 OFl = (OFl & ( ~ (FOF_MULTIDESTFILES | FOF_NOCONFIRMATION | FOF_FILESONLY))); // implemented 356 OFl = (OFl ^ (FOF_SILENT | FOF_NOCONFIRMMKDIR)); // ignored, if one 357 OFl = (OFl & ( ~ FOF_SIMPLEPROGRESS)); // ignored, only with FOF_SILENT 358 if (OFl) { 359 if (OFl & ( ~ (FOF_CONFIRMMOUSE | FOF_SILENT | FOF_RENAMEONCOLLISION | FOF_NOCONFIRMMKDIR))) { 360 TRACE(__FUNCTION__" %s level=%d lpFileOp->fFlags=0x%x not implemented, Aborted=TRUE, stub\n", pToFuncTXT, level, OFl); 361 nlpFileOp.fAnyOperationsAborted=TRUE; 362 } else { 363 TRACE(__FUNCTION__" %s level=%d lpFileOp->fFlags=0x%x not full implemented ,stub\n", pToFuncTXT, level, OFl); 364 } /* endif */ 365 } /* endif */ 366 367 ask_overwrite = (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) && !(lpFileOp->fFlags & FOF_RENAMEONCOLLISION)); 368 not_overwrite = (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_RENAMEONCOLLISION)); 369 370 // need break at error before change sourcepointer 371 while(!nlpFileOp.fAnyOperationsAborted && (pFrom+=lenFrom+1)[0]) { 372 373 if (Multi) pTo += lenTo + 1; 374 if(!pTo[0]) { 375 nlpFileOp.fAnyOperationsAborted=TRUE; 376 where = 200; 377 break; 378 } /* endif */ 379 380 FromTyp = SHFileTyp(pFrom, &lenFrom, 381 pTempFrom, &lenTempFrom, 382 &pFromFile, 383 &FromPathAttr, &FromAttr); 384 385 zTyp = ToTyp; 386 ToTyp = SHFileTyp(pTo, &lenTo, 387 pTempTo, &lenTempTo, 388 &pToFile, 389 &ToPathAttr, &ToAttr); 390 391 TRACE(__FUNCTION__" %s level=%d From='%s'(%d,%d,%d) To='%s'(%d,%d,%d)\n", pToFuncTXT, 392 level, pTempFrom, FromTyp, lenFrom, lenTempFrom, pTempTo, ToTyp, lenTo, lenTempTo); 393 394 /* Check Source */ 395 if (FromTyp != TypisDir 396 && FromTyp != TypisFile 397 && FromTyp != TypisMask) { 398 nlpFileOp.fAnyOperationsAborted=TRUE; 399 where = 201; 400 retCode=0x402; 401 break; 402 } /* endif */ 403 /* fix for more then one source for one target */ 404 if (ToTyp == TypisUnkn 405 && zTyp < TypisFile 406 && zTyp > TypisUnkn 407 && lenTo == 0) { 408 pToFile[0] = '\0'; 409 ToTyp = zTyp; 410 lenTo = strlen(pTempTo); 411 } /* endif */ 412 /* recursiv creating from directorys are not valid for FO_MOVE. */ 413 if (FuncSwitch == FO_MOVE && ToTyp == TypisNewPath) ToTyp = TypisUnkn; 414 /* Check Target */ 415 if (ToTyp == TypisMask) { 416 nlpFileOp.fAnyOperationsAborted=TRUE; 417 where = 202; 418 if (FromTyp != TypisMask) { 419 retCode=0x10003; 420 } else { 421 if ((lpFileOp->wFunc & 0xf) == FO_MOVE) TempretCode = 0x2; 422 } 423 break; 424 } /* endif */ 425 if (ToTyp == TypisBad) { 426 nlpFileOp.fAnyOperationsAborted=TRUE; 427 where = 203; 428 retCode=0x402; 429 break; 430 } /* endif */ 431 TargetisDir = (ToTyp == TypisDir || ToTyp == TypisDirS || ToTyp == TypisRoot); 432 ToSingle = (pTo[lenTo+1]=='\0'); 433 if (Multi && ToSingle) { 434 Multi = (!(pFrom[lenFrom+1]!='\0')); 435 } 436 437 switch(FromTyp) { 438 case TypisFile: { /* Source is File */ 439 if (ToTyp == TypisName) { 440 if (ToSingle && pFrom[lenFrom+1] == '\0') break; 441 if (Multi) break; 442 } 443 if (ToTyp == TypisFile) { 444 if (0 == strcmp(pTempFrom,pTempTo)) { /* target is the same as source ? */ 445 nlpFileOp.fAnyOperationsAborted=TRUE; 446 retCode = 0x71; 447 where = 221; 448 break; 449 } /* endif */ 450 if (ask_overwrite && SHELL_ConfirmDialog (ASK_OVERWRITE_FILE, pTempTo)) break; 451 if (!not_overwrite) break; 452 if (FuncSwitch == FO_MOVE && (!Multi)) TempretCode = 0x75; 453 } 454 if (!Multi && TargetisDir) { 455 strcpy(pToFile,pFromFile); 456 pTempTo[strlen(pTempTo)+1] = '\0'; 457 ToAttr = GetFileAttributesA(pTempTo); 458 if (ToAttr == -1) break; 459 if (!(ToAttr & FILE_ATTRIBUTE_DIRECTORY)) break; 460 } 461 if (FuncSwitch == FO_MOVE && (ToTyp == TypisUnkn || ToTyp == TypisName || ToTyp == TypisNameS)) TempretCode = 0x75; 462 nlpFileOp.fAnyOperationsAborted=TRUE; 463 where = 210 + TypisFile; 464 break; 465 } 466 case TypisMask: { /* Source is Mask */ 467 if (TargetisDir) break; 468 nlpFileOp.fAnyOperationsAborted=TRUE; 469 where = 210 + TypisMask; 470 break; 471 } 472 case TypisRoot: /* Source is Root, only small test with this */ 473 case TypisDir: { /* Source is Dir */ 474 if (TargetisDir) { 475 /* From Root to Root not full tested, also no Comparsion in W98 */ 476 MakeDir = (!(lpFileOp->fFlags & FOF_MULTIDESTFILES) && ToTyp != TypisRoot); 477 break; 478 } 479 MakeDir = TRUE; 480 if ((ToTyp == TypisName || ToTyp == TypisNameS || ToTyp == TypisNewPath)) break; 481 nlpFileOp.fAnyOperationsAborted=TRUE; 482 where = 210 + TypisDir; 483 break; 484 } 485 default: { 486 nlpFileOp.fAnyOperationsAborted=TRUE; 487 where = 210 + FromTyp; 488 /* retCode=0x750; */ 489 break; 490 } 491 } 492 if (nlpFileOp.fAnyOperationsAborted) { 493 if (FuncSwitch == FO_MOVE && (ToTyp == TypisUnkn || ToTyp == TypisName || ToTyp == TypisNameS)) TempretCode = 0x75; 494 break; 495 } 496 497 recurseinto = FALSE; 498 499 if (FuncSwitch == FO_MOVE && ToTyp == TypisName && (FromTyp == TypisDir || FromTyp == TypisFile)) { 500 if (':' == pTempFrom[1] && ':' == pTempTo[1] && pTempFrom[0] == pTempTo[0]) { 501 if (MoveFileA(pTempFrom, pTempTo)) continue; 502 } 503 } 504 if (FromTyp == TypisDir && TargetisDir && MakeDir) { 505 PathRemoveFileSpecA(pTempFrom); 506 lenTempTo = strlen(pTempFrom); 507 strcpy(&pTempFrom[1],&pFrom[1]); 508 if (pTempFrom[lenTempTo-1] == '\\') lenTempTo--; 509 strcpy(pToFile,&pFrom[lenTempTo]); 510 lenTempTo = strlen(pTempTo); 511 pTempTo[lenTempTo+1] = '\0'; 512 } 513 514 if (MakeDir) { 515 pToSlash = NULL; 516 if ((ToTyp == TypisNameS || ToTyp == TypisNewPath)) { 517 pToSlash = strchr(&pToFile[1],'\\'); 518 if (NULL != pToSlash) pToSlash[0] = '\0'; 519 } 520 TRACE(__FUNCTION__" %s level=%d Creating Directory '%s'\n", pToFuncTXT, level, pTempTo); 521 SHCreateDirectory(NULL,pTempTo); 522 ToPathAttr = GetFileAttributesA(pTempTo); 523 if (NULL != pToSlash) pToSlash[0] = '\\'; 524 if (ToPathAttr == -1) { 525 nlpFileOp.fAnyOperationsAborted=TRUE; 526 retCode=0x10004; 527 where = 220; 528 break; 529 } 530 recurseinto = TRUE; 531 } 532 if (ToTyp != TypisNewPath) { 533 if (FromTyp == TypisDir || FromTyp == TypisRoot) { 534 strcpy(pFromFile,"\\*.*"); 535 pTempFrom[strlen(pTempFrom)+1] = '\0'; 536 recurseinto = TRUE; 537 } else { 538 if (FromTyp == TypisFile) { 539 if (TargetisDir) { 540 recurseinto = TRUE; 541 } else { 542 if (CopyFileA(pTempFrom, pTempTo, FALSE)) { 543 if (FuncSwitch == FO_COPY) continue; 544 if (DeleteFileA(pTempFrom)) continue; 545 } 546 nlpFileOp.fAnyOperationsAborted=TRUE; 547 where = 222; 548 break; 549 } 550 } /* endif */ 551 } 552 } 553 if (recurseinto) { 554 TRACE(__FUNCTION__" %s level=%d Entering into Directory '%s'\n", pToFuncTXT, level, pTempTo); 555 TempretCode = SHFileOperationA (&nlpFileOp); 556 if (nlpFileOp.fAnyOperationsAborted) {where = 223;break;} 557 if (FuncSwitch == FO_MOVE && FromTyp == TypisDir) { 558 if (!(RemoveDirectoryA(pFrom))) { 559 nlpFileOp.fAnyOperationsAborted=TRUE; 560 where = 100; 561 break; 562 } 563 } 564 continue; /* next pTo/pFrom */ 565 } 566 if (FromTyp == TypisMask) { 567 hFind = FindFirstFileA(pTempFrom, &wfd); 568 if (INVALID_HANDLE_VALUE == hFind) { 569 nlpFileOp.fAnyOperationsAborted=TRUE; 570 retCode=0x79; 571 where = 224; 572 break; 573 } 574 575 TRACE(__FUNCTION__" %s level=%d between Subdir %s -> %s'\n", pToFuncTXT, level, nlpFileOp.pFrom, nlpFileOp.pTo); 576 nlpFileOp.fFlags = (nlpFileOp.fFlags & (-1 - (FOF_MULTIDESTFILES))); 577 578 do { 579 TRACE(__FUNCTION__" %s level=%d find '%s'\n", pToFuncTXT, level, wfd.cFileName); 580 if (0==strcmp(wfd.cFileName,".")) continue; 581 if (0==strcmp(wfd.cFileName,"..")) continue; 582 if ((nlpFileOp.fFlags & FOF_FILESONLY) && (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)) { 583 continue; /* next name in pFrom(dir) */ 584 } /* endif */ 585 586 strcpy(&pFromFile[1],wfd.cFileName); 587 pTempFrom[strlen(pTempFrom)+1]='\0'; 588 589 TempretCode = SHFileOperationA (&nlpFileOp); 590 591 if (nlpFileOp.fAnyOperationsAborted) {where = 230;break;} 592 593 } while(FindNextFileA(hFind, &wfd)); 594 } 595 } 596 break; 597 } 598 599 case FO_DELETE: 600 TRACE(__FUNCTION__" FO_DELETE level=%d\n",level); 601 /* need break at error before change sourcepointer */ 602 while(!nlpFileOp.fAnyOperationsAborted && (pFrom+=lenFrom+1)[0]) { 603 lenFrom=strlen(pFrom); 604 FromAttr = GetFileAttributesA(pFrom); 605 if (!(FromAttr & FILE_ATTRIBUTE_DIRECTORY)) { 606 TRACE(__FUNCTION__" FO_DELETE level=%d File='%s'\n",level , pFrom); 607 if (DeleteFileA(pFrom)) continue; 608 nlpFileOp.fAnyOperationsAborted=TRUE; 609 /* retCode = 0x71; */ 610 where = 301; 611 break; 612 } 613 if (!(pTempFrom)) pTempFrom = HeapAlloc(GetProcessHeap(), 0, MAX_PATH+2); 614 strcpy(pTempFrom,pFrom); 615 PathRemoveBackslashA(pTempFrom); 616 FromAttr = GetFileAttributesA(pTempFrom); 617 if (!(FromAttr & FILE_ATTRIBUTE_DIRECTORY) ) { 618 nlpFileOp.fAnyOperationsAborted=TRUE; 619 /* retCode = 0x71; */ 620 where = 302; 621 break; 622 } 623 /* is Source an existing directory\*.* ? */ 624 if (FromAttr == -1) { 625 PathRemoveFileSpecA(pTempFrom); 626 FromAttr = GetFileAttributesA(pTempFrom); 627 } 628 629 PathAddBackslashA(pTempFrom); 630 lenTempFrom = strlen(pTempFrom); 631 pFromFile=&pTempFrom[lenTempFrom]; 632 633 if (FromAttr == -1 || 634 ((lenTempFrom==lenFrom) && !PathIsRootA(pFrom)) || 635 !(FromAttr & FILE_ATTRIBUTE_DIRECTORY) || 636 !(('\0'==pFrom[lenTempFrom]) || (0==strcmp(&pFrom[lenTempFrom],"*.*"))) ) { 637 retCode=0x402; 638 nlpFileOp.fAnyOperationsAborted=TRUE; 639 where = 303; 640 break; 641 } 642 strcpy(pFromFile, "*.*"); 643 lenTempFrom = strlen(pTempFrom); 644 if (lenFrom < lenTempFrom) { 645 /* Source is without \*.* */ 646 pTempFrom[lenTempFrom+1]='\0'; 647 nlpFileOp.pFrom = pTempFrom; 648 649 TRACE(__FUNCTION__" FO_DELETE level=%d Entering Directory '%s'\n",level , nlpFileOp.pFrom); 650 TempretCode = SHFileOperationA (&nlpFileOp); 651 652 if (nlpFileOp.fAnyOperationsAborted) {break;} 653 /* Call SHELL_DeleteDirectoryA ? */ 654 if (RemoveDirectoryA(pFrom)) continue; 655 nlpFileOp.fAnyOperationsAborted=TRUE; 656 where = 304; 657 break; 658 } 659 hFind = FindFirstFileA(pTempFrom, &wfd); 660 if (INVALID_HANDLE_VALUE == hFind) { 661 nlpFileOp.fAnyOperationsAborted=TRUE; 662 retCode=0x79; 663 where = 303; 664 break; 665 } 666 667 nlpFileOp.pFrom = pTempFrom; 668 669 nlpFileOp.fFlags = (nlpFileOp.fFlags & (-1 - (FOF_MULTIDESTFILES))); 670 671 TRACE(__FUNCTION__" FO_DELETE level=%d Delete in Subdir %s'\n",level , nlpFileOp.pFrom); 672 673 do { 674 TRACE(__FUNCTION__" FO_DELETE level=%d find '%s'\n",level , wfd.cFileName); 675 if (0==strcmp(wfd.cFileName,".")) continue; 676 if (0==strcmp(wfd.cFileName,"..")) continue; 677 if ((nlpFileOp.fFlags & FOF_FILESONLY) && (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)) { 678 continue; 679 } /* endif */ 680 681 strcpy(pFromFile,wfd.cFileName); 682 pTempFrom[strlen(pTempFrom)+1]='\0'; 683 684 TempretCode = SHFileOperationA (&nlpFileOp); 685 686 if (nlpFileOp.fAnyOperationsAborted) {where = 304;break;} 687 688 } while(FindNextFileA(hFind, &wfd)); 689 690 FindClose(hFind); 691 if (nlpFileOp.fAnyOperationsAborted) {where = 305;break;} 692 continue; 693 } 694 break; 695 case 0: 696 break; 697 case FO_RENAME: 698 TRACE("File Rename:\n"); 699 if (pFrom[strlen(pFrom) + 1] != '\0') 408 TRACE(__FUNCTION__" %s level=%d nlpFileOp.fFlags=0x%x\n", pToFuncTXT, level, lpFileOp->fFlags); 409 410 /* OFl &= (-1 - (FOF_MULTIDESTFILES | FOF_FILESONLY)); 411 /* OFl ^= (FOF_SILENT | FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMMKDIR); */ 412 OFl &= (~(FOF_MULTIDESTFILES | FOF_NOCONFIRMATION | FOF_FILESONLY)); /* implemented */ 413 OFl ^= (FOF_SILENT | FOF_NOCONFIRMMKDIR); /* ignored, if one */ 414 OFl &= (~FOF_SIMPLEPROGRESS); /* ignored, only wit FOF_SILEN */ 415 if (OFl) 416 { 417 if (OFl & ( ~ (FOF_CONFIRMMOUSE | FOF_SILENT | FOF_RENAMEONCOLLISION | FOF_NOCONFIRMMKDIR))) 418 { 419 TRACE("%s level=%d lpFileOp->fFlags=0x%x not implemented, Aborted=TRUE, stub\n", pToFuncTXT, level, OFl); 420 retCode = 0x403; /* we need a extension of shlfileop */ 421 nlpFileOp.fAnyOperationsAborted=TRUE; 422 } 423 else 424 { 425 TRACE("%s level=%d lpFileOp->fFlags=0x%x not full implemented ,stub\n", pToFuncTXT, level, OFl); 426 } /* endif */ 427 } /* endif */ 428 429 if ((pNextFrom) && (!(b_MultiTo) || (pNextTo))) 430 { 431 nlpFileOp.pFrom = pTempFrom = HeapAlloc(GetProcessHeap(), 0, (1+2*(b_MultiTo)) * MAX_PATH+6); 432 if (b_MultiTo) pTempTo = &pTempFrom[MAX_PATH+4]; 433 nlpFileOp.pTo = pTempTo; 434 ask_overwrite = (!(nlpFileOp.fFlags & FOF_NOCONFIRMATION) && !(nlpFileOp.fFlags & FOF_RENAMEONCOLLISION)); 435 not_overwrite = (!(nlpFileOp.fFlags & FOF_NOCONFIRMATION) || (nlpFileOp.fFlags & FOF_RENAMEONCOLLISION)); 436 } 437 else 438 { 439 nlpFileOp.fAnyOperationsAborted=TRUE; 440 retCode = 0x402; 441 goto shfileop_error; 442 } 443 /* need break at error before change sourcepointer */ 444 while(!nlpFileOp.fAnyOperationsAborted && (pNextFrom[0])) 445 { 446 nlpFileOp.wFunc = ((level+1)<<4) + FuncSwitch; 447 nlpFileOp.fFlags = lpFileOp->fFlags; 448 449 if (b_MultiTo) 450 { 451 pTo = pNextTo; 452 pNextTo = &pNextTo[lstrlenA(pTo)+1]; 453 b_MultiTo = (b_Multi && pNextTo[0]); 454 } 455 456 pFrom = pNextFrom; 457 pNextFrom = &pNextFrom[lstrlenA(pNextFrom)+1]; 458 if (!b_MultiFrom && !b_MultiTo) 459 b_MultiFrom = (pNextFrom[0]); 460 461 pFromFile = SHFileStrCpyCatA(pTempFrom, pFrom, NULL); 462 463 if (pTo) 464 { 465 pToFile = SHFileStrCpyCatA(pTempTo, pTo, NULL); 466 if (!(pToFile)) 467 { 468 nlpFileOp.fAnyOperationsAborted=TRUE; 469 retCode = 0x402; 470 goto shfileop_error; 471 } /* endif */ 472 b_ToTailSlash = (!pToFile[1]); 473 if (b_ToTailSlash) 474 { 475 pToFile[0] = '\0'; 476 if (strchr(pTempTo,'\\')) 477 { 478 pToFile = SHFileStrCpyCatA(pTempTo, NULL, NULL); 479 } 480 } 481 b_ToInvalidTail = (NULL != strpbrk(&pToFile[1],"*?")); 482 } 483 484 if (FO_RENAME == FuncSwitch) 485 { 486 /* temporr only for FO_RENAME */ 487 b_Mask = (NULL != strpbrk(pFrom,"*?")); 488 if (b_MultiTo || (pNextFrom[0]) || (b_Mask && !b_ToInvalidTail)) 489 { 490 /* no work, only RC=0 */ 491 // /* ???? */ nlpFileOp.fAnyOperationsAborted=TRUE; 492 goto shfileop_normal; 493 } 494 } 495 496 hFind = (!(pFromFile) || !(pFromFile[1])) ? INVALID_HANDLE_VALUE : FindFirstFileA(pFrom, &wfd); 497 if (INVALID_HANDLE_VALUE == hFind) 498 { 499 /* root (without mask) is also not allowed as source, tested in W98 */ 500 nlpFileOp.fAnyOperationsAborted=TRUE; 501 retCode = 0x402; 502 goto shfileop_error; 503 } /* endif */ 504 505 /* for all */ 506 #define HIGH_ADR (LPSTR)0xffffffff 507 b_Mask = (!SHFileStrICmpA(&pFromFile[1], &wfd.cFileName[0], HIGH_ADR, HIGH_ADR)); 508 509 if (!pTo) /* FO_DELETE */ 510 { 511 do 512 { 513 if (wfd.cFileName[0] == '.') 514 { 515 if (wfd.cFileName[1] == '\0') 516 continue; 517 if (wfd.cFileName[1] == '.' && wfd.cFileName[2] == '\0') 518 continue; 519 } 520 SHFileStrCpyCatA(&pFromFile[1], &wfd.cFileName[0], NULL); 521 if (IsAttribFile(wfd.dwFileAttributes)) 522 { 523 nlpFileOp.fAnyOperationsAborted = (!Win32DeleteFileA(pTempFrom)); 524 retCode = 0x78; /* value unknown */ 525 } 526 else 527 { 528 nlpFileOp.fAnyOperationsAborted = (!SHELL_DeleteDirectoryA(pTempFrom,FALSE)); 529 retCode = 0x78; /* value unknown */ 530 } 531 } while(!nlpFileOp.fAnyOperationsAborted && FindNextFileA(hFind, &wfd)); 532 FindClose(hFind); 533 hFind = INVALID_HANDLE_VALUE; 534 if (nlpFileOp.fAnyOperationsAborted) 535 { 536 goto shfileop_error; 537 } 538 continue; 539 } /* FO_DELETE ends, pTo must be every valid from here */ 540 541 b_SameRoot = (toupper(pTempFrom[0]) == toupper(pTempTo[0])); 542 b_SameTailName = SHFileStrICmpA(pToFile, pFromFile, NULL, NULL); 543 544 /* W98 Bug with FO_MOVE(/RENAME ?) different to FO_COPY, better the same as FO_COPY */ 545 546 b_ToValid = ((b_SameTailName && b_SameRoot && (FO_COPY == FuncSwitch)) || 547 (b_SameTailName && !b_SameRoot) || (b_ToInvalidTail)); 548 549 ToPathAttr = ToAttr = GetFileAttributesA(pTempTo); 550 if (!b_Mask && /* IsAttribDir(wfd.dwFileAttributes) && */(ToAttr -1)) 551 { 552 if (pToFile) 553 { 554 pToFile[0] = '\0'; 555 ToPathAttr = GetFileAttributesA(pTempTo); 556 /* if (-1 != ToPathAttr) */ pToFile[0] = '\\'; 557 } 558 } 559 if (FO_RENAME == FuncSwitch) 560 { 561 if (!b_SameRoot || b_Mask /* FO_RENAME works not with Mask */ 562 || !SHFileStrICmpA(pTempFrom, pTempTo, pFromFile, NULL) 563 || (SHFileStrICmpA(pTempFrom, pTempTo, pFromFile, HIGH_ADR) && !b_ToTailSlash)) 564 { 565 retCode = 0x73; 566 nlpFileOp.fAnyOperationsAborted=TRUE; 567 goto shfileop_error; 568 } 569 if (b_ToInvalidTail) 570 { 571 nlpFileOp.fAnyOperationsAborted=TRUE; 572 retCode=0x2; 573 goto shfileop_error; 574 } 575 if (IsAttribDir(wfd.dwFileAttributes) && IsAttribDir(ToAttr)) 576 { 577 if (b_ToTailSlash) 578 { 579 retCode = 0xb7; 580 } 581 else 582 { 583 retCode = 0x7b; 584 } 585 nlpFileOp.fAnyOperationsAborted=TRUE; 586 goto shfileop_error; 587 } 588 if (-1 == ToPathAttr) 589 { 590 nlpFileOp.fAnyOperationsAborted=TRUE; 591 retCode = 0x75; 592 goto shfileop_error; 593 } /* endif */ 594 if (!MoveFileA(pTempFrom, pTempTo)) 595 { 596 nlpFileOp.fAnyOperationsAborted=TRUE; 597 /* we need still the value for the returncode, we use the mostly assumed */ 598 retCode = 0xb7; 599 goto shfileop_error; 600 } 601 goto shfileop_normal; 602 } 603 604 if (!b_Mask && IsAttribDir(wfd.dwFileAttributes) && (ToAttr -1)) 605 { 606 if (pToFile) 607 { 608 pToFile[0] = '\0'; 609 ToPathAttr = GetFileAttributesA(pTempTo); 610 if ((ToPathAttr == -1) && b_ToValid) 611 { 612 /* create dir knnte hier erfolgen, smple target D:\y\ *.* create with RC=10003 */ 613 if(!SHCreateDirectory(NULL,pTempTo)) 700 614 { 701 WARN("Attempt to rename more than one file\n"); 702 lpFileOp->fAnyOperationsAborted=TRUE; 703 retCode=0; 704 break; 615 nlpFileOp.fAnyOperationsAborted=TRUE; 616 retCode = 0x73;/* value unknown */ 617 goto shfileop_error; 705 618 } 706 TRACE("From %s, To %s\n", pFrom, pTo); 707 pTempFrom = HeapAlloc(GetProcessHeap(), 0, 2 * MAX_PATH+6); 708 pTempTo = &pTempFrom[MAX_PATH+4]; 709 710 FromTyp = SHFileTyp(pFrom, &lenFrom, 711 pTempFrom, &lenTempFrom, 712 &pFromFile, 713 &FromPathAttr, &FromAttr); 714 715 ToTyp = SHFileTyp(pTo, &lenTo, 716 pTempTo, &lenTempTo, 717 &pToFile, 718 &ToPathAttr, &ToAttr); 719 720 TRACE(__FUNCTION__" FO_RENAME level=%d From='%s'(%d,%d,%d) To='%s'(%d,%d,%d)\n", 721 level, pTempFrom, FromTyp, lenFrom, lenTempFrom, pTempTo, ToTyp, lenTo, lenTempTo); 722 723 /* Check Target, Target = Dir is invalid, must be befor the next SourceCheck */ 724 if (FromTyp == TypisDir && ToTyp == TypisDir) { 725 nlpFileOp.fAnyOperationsAborted=TRUE; 726 retCode=0x7b; 727 break; 728 } /* endif */ 729 /* Check Source */ 730 if (FromTyp == TypisDirS || FromTyp == TypisName 731 /* for (FromTyp == TypisNewPath) to many, all are invalid and not are retCode 0x402 */ 732 || (FromTyp == TypisNewPath && (ToTyp != TypisDir && ToTyp != TypisName))) { 733 nlpFileOp.fAnyOperationsAborted=TRUE; 734 retCode=0x402; 735 break; 736 } /* endif */ 737 /* Check Target, Target = NewDir is invalid, must be after 0x402 ? */ 738 if (ToTyp == TypisNewPath) { 739 nlpFileOp.fAnyOperationsAborted=TRUE; 740 retCode=0x75; 741 break; 742 } /* endif */ 743 if (ToTyp == TypisDirS) { 744 nlpFileOp.fAnyOperationsAborted=TRUE; 745 retCode=0xb7; 746 break; 747 } /* endif */ 748 /* What is with existing Target, can we replace it ? */ 749 if (((FromTyp == TypisFile || FromTyp == TypisDir) && ToTyp == TypisName) 750 || (FromTyp == TypisDir && ToTyp == TypisNameS)) { 751 if (ToTyp == TypisNameS) pTempTo[--lenTo] = '\0'; 752 lenTempTo = lenTempFrom = 2; 753 /* FileRename only in the same path !! ?? */ 754 if (FromTyp == TypisFile) { 755 pFromFile = strrchr(pTempFrom,'\\'); 756 pToFile = strrchr(pTempTo,'\\'); 757 if (pFromFile == NULL || pToFile == NULL) { 758 if (ToTyp == TypisNameS) pTempTo[lenTo++] = '\\'; 759 break; 760 } 761 pFromFile[0] = '\0'; 762 pToFile[0] = '\0'; 763 lenTempTo = strlen(pTempTo); 764 lenTempFrom = strlen(pTempFrom); 765 pFromFile[0] = '\\'; 766 pToFile[0] = '\\'; 767 } 768 if (lenTempTo == lenTempFrom && 0 == memcmp(pTempTo,pTempFrom,lenTempTo)) { 769 retCode = !MoveFileA(pTempFrom, pTempTo); 770 if (ToTyp == TypisNameS) pTempTo[lenTo++] = '\\'; 771 if (retCode) nlpFileOp.fAnyOperationsAborted=TRUE; 772 break; 773 } 774 } 775 776 retCode=0x73; 777 nlpFileOp.fAnyOperationsAborted=TRUE; 778 break; 779 780 default: 781 TRACE(__FUNCTION__" Unhandled shell file operation %d at level=%d stub\n",(lpFileOp->wFunc & 15), level ); 782 lpFileOp->fAnyOperationsAborted=TRUE; 783 return 1; 784 } 785 if (pTempFrom) HeapFree(GetProcessHeap(), 0, pTempFrom); 786 787 if (nlpFileOp.fAnyOperationsAborted) { 788 lpFileOp->fAnyOperationsAborted=TRUE; 789 if (TempretCode > 0 /* retCode */) { 790 retCode = TempretCode; 791 } /* endif */ 792 } 793 if (lpFileOp->fAnyOperationsAborted==TRUE) { 794 if (FO_DELETE == (lpFileOp->wFunc & 15)) { 795 TRACE(__FUNCTION__" Setting AnyOpsAborted=TRUE level=%d ret=0x%x, at=%i with %s\n",level, retCode,where,pFrom); 796 } else { 797 TRACE(__FUNCTION__" Setting AnyOpsAborted=TRUE level=%d ret=0x%x, at=%i with %s -> %s\n",level, retCode,where,pFrom,pTo); 798 } 799 return retCode; 800 } /* endif */ 801 TRACE(__FUNCTION__" Setting AnyOpsAborted=FALSE\n"); 802 return 0; 803 804 } 805 806 /************************************************************************* 807 * SHFileOperationW [SHELL32.@] 619 ToPathAttr = GetFileAttributesA(pTempTo); 620 } 621 pToFile[0] = '\\'; 622 if (b_ToInvalidTail) 623 { 624 nlpFileOp.fAnyOperationsAborted=TRUE; 625 retCode=0x10003; 626 goto shfileop_error; 627 } 628 } 629 } 630 631 /* handle mask in source */ 632 if (b_Mask) 633 { 634 if (!IsAttribDir(ToAttr)) 635 { 636 nlpFileOp.fAnyOperationsAborted=TRUE; 637 if (b_ToInvalidTail && b_SameTailName && (FO_MOVE == FuncSwitch)) 638 { 639 retCode = 0x2; 640 } 641 else 642 { 643 retCode = 0x75; 644 } 645 goto shfileop_error; 646 } 647 pToFile = SHFileStrCpyCatA(pTempTo,NULL, "\\"); 648 nlpFileOp.fFlags = (nlpFileOp.fFlags | FOF_MULTIDESTFILES); 649 do 650 { 651 if (wfd.cFileName[0] == '.') 652 { 653 if (wfd.cFileName[1] == '\0') 654 continue; 655 if (wfd.cFileName[1] == '.' && wfd.cFileName[2] == '\0') continue; 656 } 657 if (IsAttribDir(wfd.dwFileAttributes) && (nlpFileOp.fFlags & FOF_FILESONLY)) 658 { 659 continue; /* next name in pTempFrom(dir) */ 660 } 661 SHFileStrCpyCatA(&pToFile[1], &wfd.cFileName[0], NULL); 662 SHFileStrCpyCatA(&pFromFile[1], &wfd.cFileName[0], NULL); 663 retCode = SHFileOperationA (&nlpFileOp); 664 } while(!nlpFileOp.fAnyOperationsAborted && FindNextFileA(hFind, &wfd)); 665 } 666 FindClose(hFind); 667 hFind = INVALID_HANDLE_VALUE; 668 /* only FO_COPY/FO_MOVE without mask, FO_DELETE and FO_RENAME are solved */ 669 if (b_Mask) 670 continue; 671 672 /* tailling BackSlash is ever removed and pToFile points to BackSlash before */ 673 if (!b_MultiTo && (b_MultiFrom || (!(b_Multi) && IsAttribDir(ToAttr)))) 674 { 675 if ((FO_MOVE == FuncSwitch) && IsAttribDir(ToAttr) && IsAttribDir(wfd.dwFileAttributes)) 676 { 677 if (b_Multi) 678 { 679 retCode = 0x73; /* !b_Multi = 0x8 ?? */ 680 nlpFileOp.fAnyOperationsAborted=TRUE; 681 goto shfileop_error; 682 } 683 } 684 pToFile = SHFileStrCpyCatA(&pTempTo[strlen(pTempTo)], "\\", wfd.cFileName); 685 ToAttr = GetFileAttributesA(pTempTo); 686 } 687 688 if (IsAttribDir(ToAttr)) 689 { 690 if (IsAttribFile(wfd.dwFileAttributes)) 691 { 692 if (FO_COPY == FuncSwitch) 693 { 694 /* ????? */ retCode = 0x75; 695 } 696 else 697 { 698 retCode = 0xb7; 699 } 700 nlpFileOp.fAnyOperationsAborted=TRUE; 701 goto shfileop_error; 702 } 703 } 704 else 705 { 706 pToFile[0] = '\0'; 707 ToPathAttr = GetFileAttributesA(pTempTo); 708 pToFile[0] = '\\'; 709 if (IsAttribFile(ToPathAttr)) 710 { 711 /* fehler, ist das schon getestet ? */ 712 nlpFileOp.fAnyOperationsAborted=TRUE; 713 retCode = 0x777402; 714 goto shfileop_error; 715 } /* endif */ 716 } 717 718 /* singlesource + no mask */ 719 if (-1 == (ToAttr & ToPathAttr)) 720 { 721 /* Target-dir does not exist, and can not created */ 722 nlpFileOp.fAnyOperationsAborted=TRUE; 723 retCode=0x75; 724 goto shfileop_error; 725 } 726 727 switch(FuncSwitch) 728 { 729 case FO_MOVE: 730 if ((ToAttr == -1) && SHFileStrICmpA(pTempFrom, pTempTo, pFromFile, NULL)) 731 { 732 nlpFileOp.wFunc = ((level+1)<<4) + FO_RENAME; 733 retCode = SHFileOperationA(&nlpFileOp); 734 } 735 else 736 { 737 if (b_SameRoot && IsAttribDir(ToAttr) && IsAttribDir(wfd.dwFileAttributes)) 738 { 739 pToFile = SHFileStrCpyCatA(pTempFrom, NULL, "\\*.*"); 740 retCode = SHFileOperationA(&nlpFileOp); 741 ((WORD*)pToFile)[0] = '\0'; 742 } 743 else 744 { 745 nlpFileOp.wFunc = ((level+1)<<4) + FO_COPY; 746 retCode = SHFileOperationA(&nlpFileOp); 747 } /* endif */ 748 if (!nlpFileOp.fAnyOperationsAborted) 749 { 750 nlpFileOp.wFunc = ((level+1)<<4) + FO_DELETE; 751 retCode = SHFileOperationA(&nlpFileOp); 752 } /* endif */ 753 } 754 continue; 755 case FO_COPY: 756 if (SHFileStrICmpA(pTempFrom, pTempTo, NULL, NULL)) 757 { /* target is the same as source ? */ 758 nlpFileOp.fAnyOperationsAborted=TRUE; 759 /* we need still the value for the returncode, we assume 0x71 */ 760 retCode = 0x71; 761 goto shfileop_error; 762 } /* endif */ 763 if (IsAttribDir((ToAttr & wfd.dwFileAttributes))) 764 { 765 if (IsAttribDir(ToAttr) || SHCreateDirectory(NULL,pTempTo)) 766 { 767 /* ??? nlpFileOp.fFlags = (nlpFileOp.fFlags | FOF_MULTIDESTFILES); */ 768 SHFileStrCpyCatA(pTempFrom, NULL, "\\*.*"); 769 retCode = SHFileOperationA(&nlpFileOp); 770 } 771 else 772 { 773 nlpFileOp.fAnyOperationsAborted=TRUE; 774 retCode = 0x750;/* value unknown */ 775 } 776 } 777 else 778 { 779 if (!(ask_overwrite && SHELL_ConfirmDialog (ASK_OVERWRITE_FILE, pTempTo)) 780 && (not_overwrite)) 781 { 782 nlpFileOp.fAnyOperationsAborted=TRUE; 783 /* we need still the value for the returncode, we use the mostly assumed */ 784 retCode = 0x73; 785 goto shfileop_error; 786 } 787 if (!(CopyFileA(pTempFrom, pTempTo, FALSE))) 788 { 789 nlpFileOp.fAnyOperationsAborted=TRUE; 790 retCode = 0x77; /* value unknown */ 791 } 792 } 793 } /* end-switch */ 794 } /* end-while */ 795 } 796 shfileop_normal: 797 if (!(nlpFileOp.fAnyOperationsAborted)) 798 retCode = 0; 799 shfileop_error: 800 if (hFind != INVALID_HANDLE_VALUE) 801 FindClose(hFind); 802 hFind = INVALID_HANDLE_VALUE; 803 if (pTempFrom) 804 HeapFree(GetProcessHeap(), 0, pTempFrom); 805 806 TRACE("%s level=%d AnyOpsAborted=%s ret=0x%x, with %s%s%s\n", 807 pToFuncTXT, level, nlpFileOp.fAnyOperationsAborted ? "TRUE":"FALSE", 808 retCode, debugstr_a(pFrom), pTo ? " -> ":"", debugstr_a(pTo)); 809 810 lpFileOp->fAnyOperationsAborted = nlpFileOp.fAnyOperationsAborted; 811 return retCode; 812 } 813 814 /************************************************************************* 815 * SHFileOperationW [SHELL32.@] 808 816 * 809 817 * NOTES … … 812 820 DWORD WINAPI SHFileOperationW (LPSHFILEOPSTRUCTW lpFileOp) 813 821 { 814 815 816 } 817 818 /************************************************************************* 819 * SHFileOperation 822 FIXME("(%p):stub.\n", lpFileOp); 823 return 1; 824 } 825 826 /************************************************************************* 827 * SHFileOperation [SHELL32.@] 820 828 * 821 829 */ 822 830 DWORD WINAPI SHFileOperationAW(LPVOID lpFileOp) 823 831 { 824 825 826 832 if (SHELL_OsIsUnicode()) 833 return SHFileOperationW(lpFileOp); 834 return SHFileOperationA(lpFileOp); 827 835 } 828 836 … … 837 845 838 846 /************************************************************************* 839 * SheChangeDir W [SHELL32.274]840 * 841 */ 842 HRESULT WINAPI SheChangeDirW(LPWSTR u)843 { FIXME("(%s),stub\n",debugstr_w( u));847 * SheChangeDir [SHELL32.@] 848 * 849 */ 850 HRESULT WINAPI SheChangeDirW(LPWSTR path) 851 { FIXME("(%s),stub\n",debugstr_w(path)); 844 852 return 0; 845 853 } 846 854 847 /************************************************************************* 848 * IsNetDrive [SHELL32.66] 855 HRESULT WINAPI SheChangeDirA(LPSTR path) 856 { 857 WCHAR wPath[MAX_PATH]; 858 859 TRACE("(%s)\n", path); 860 861 if (!path) 862 return 0; 863 MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH); 864 return SheChangeDirW(wPath); 865 } 866 /************************************************************************* 867 * SheChangeDirEx [SHELL32.@] 868 * 869 */ 870 HRESULT WINAPI SheChangeDirExW(LPWSTR path) 871 { FIXME("(%s),stub\n",debugstr_w(path)); 872 return 0; 873 } 874 875 HRESULT WINAPI SheChangeDirExA(LPSTR path) 876 { 877 WCHAR wPath[MAX_PATH]; 878 879 TRACE("(%s)\n", path); 880 881 if (!path) 882 return 0; 883 MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH); 884 return SheChangeDirExW(wPath); 885 } 886 887 /************************************************************************* 888 * IsNetDrive [SHELL32.66] 849 889 */ 850 890 BOOL WINAPI IsNetDrive(DWORD drive) 851 891 { 852 char root[4]; 853 strcpy(root, "A:\\"); 854 root[0] += drive; 855 return (GetDriveTypeA(root) == DRIVE_REMOTE); 856 } 857 892 char root[4]; 893 strcpy(root, "A:\\"); 894 root[0] += (char)drive; 895 return (GetDriveTypeA(root) == DRIVE_REMOTE); 896 } -
trunk/src/shell32/shlfolder.c
r8650 r9805 1220 1220 { 1221 1221 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest); 1222 SHChangeNotify A( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);1222 SHChangeNotify( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest); 1223 1223 return S_OK; 1224 1224 } … … 1489 1489 1490 1490 pidl = ILCombine(This->absPidl, pidlitem); 1491 SHChangeNotify A(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);1491 SHChangeNotify(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL); 1492 1492 SHFree(pidl); 1493 1493 … … 1554 1554 } 1555 1555 pidl = ILCombine(This->absPidl, apidl[i]); 1556 SHChangeNotify A(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);1556 SHChangeNotify(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL); 1557 1557 SHFree(pidl); 1558 1558 } … … 1568 1568 } 1569 1569 pidl = ILCombine(This->absPidl, apidl[i]); 1570 SHChangeNotify A(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);1570 SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL); 1571 1571 SHFree(pidl); 1572 1572 }
Note:
See TracChangeset
for help on using the changeset viewer.