Changeset 9805 for trunk/src


Ignore:
Timestamp:
Feb 14, 2003, 11:07:19 AM (23 years ago)
Author:
sandervl
Message:

DT: Shell file operation updates

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 $ */
    22/*
    33 *      shell change notification
    44 *
    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
    720 */
    821#ifdef __WIN32OS2__
     
    1326#include <string.h>
    1427
    15 #include "debugtools.h"
     28#include "wine/debug.h"
    1629#include "pidl.h"
    1730#include "shell32_main.h"
    1831#include "undocshell.h"
    1932
    20 DEFAULT_DEBUG_CHANNEL(shell);
     33WINE_DEFAULT_DEBUG_CHANNEL(shell);
    2134
    2235static CRITICAL_SECTION SHELL32_ChangenotifyCS = CRITICAL_SECTION_INIT("SHELL32_ChangenotifyCS");
     
    5669        while(ptr != &tail)
    5770        {
    58           int i;
     71          UINT i;
    5972          item = ptr;
    6073          ptr = ptr->next;
     
    106119
    107120        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)
    113122        {
    114123          TRACE("ptr=%p\n", ptr);
     
    116125          if (ptr == item)
    117126          {
    118             int i;
     127            UINT i;
    119128       
    120129            TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
     
    128137            SHFree(item->apidl);
    129138            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;
    142142          }
    143143          ptr = ptr->next;
     
    167167        item = SHAlloc(sizeof(NOTIFICATIONLIST));
    168168
    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",
    170170                hwnd,dwFlags,wEventMask,uMsg,cItems,lpItems,item);
    171171       
     
    191191 */
    192192BOOL WINAPI
    193 SHChangeNotifyDeregister(
    194         HANDLE hNotify)
    195 {
    196         TRACE("(0x%08x)\n",hNotify);
    197 
    198         return DeleteNode((LPNOTIFICATIONLIST)hNotify);;
     193SHChangeNotifyDeregister(HANDLE hNotify)
     194{
     195        TRACE("(%p)\n",hNotify);
     196
     197        return DeleteNode((LPNOTIFICATIONLIST)hNotify);
    199198}
    200199
     
    215214 * SHChangeNotify                               [SHELL32.239]
    216215 */
    217 void WINAPI SHChangeNotifyW (LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
    218 {
    219         LPITEMIDLIST pidl1=(LPITEMIDLIST)dwItem1, pidl2=(LPITEMIDLIST)dwItem2;
     216void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
     217{
     218        LPITEMIDLIST Pidls[2];
    220219        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);
    223227
    224228        /* 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
    232245        EnterCriticalSection(&SHELL32_ChangenotifyCS);
    233        
     246
    234247        /* loop through the list */
    235248        ptr = head.next;
    236         while(ptr != &tail)
     249        while (ptr != &tail)
    237250        {
    238251          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)
    287254          {
    288255            TRACE("notifying\n");
     
    291258          ptr = ptr->next;
    292259        }
    293        
     260
    294261        LeaveCriticalSection(&SHELL32_ChangenotifyCS);
    295262
    296263        /* 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        }
    313269}
    314270
     
    327283    LPNOTIFYREGISTER idlist)
    328284{
    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",
    330286                hwnd,events1,events2,msg,count,idlist);
    331287        return 0;
  • trunk/src/shell32/dbgwrap.cpp

    r8586 r9805  
    4040DEBUGWRAP4(ILGlobalClone)
    4141DEBUGWRAP8(ILIsEqual)
    42 NODEF_DEBUGWRAP16(Control_RunDLL)
     42NODEF_DEBUGWRAP16(Control_RunDLLA)
     43NODEF_DEBUGWRAP16(Control_RunDLLW)
    4344DEBUGWRAP12(ILIsParent)
    4445DEBUGWRAP8(ILFindChild)
     
    174175DEBUGWRAP4(SHSimpleIDListFromPathAW)
    175176NODEF_DEBUGWRAP8(StrToOleStr)
    176 NODEF_DEBUGWRAP4(Win32DeleteFile)
    177 NODEF_DEBUGWRAP8(SHCreateDirectory)
     177NODEF_DEBUGWRAP4(Win32DeleteFileAW)
     178DEBUGWRAP8(SHCreateDirectory)
    178179NODEF_DEBUGWRAP12(SHAddFromPropSheetExtArray)
    179180NODEF_DEBUGWRAP12(SHCreatePropSheetExtArray)
     
    214215DEBUGWRAP4(SHBrowseForFolderA)
    215216DEBUGWRAP4(SHBrowseForFolderW)
    216 NODEF_DEBUGWRAP16(SHChangeNotifyAW)
     217DEBUGWRAP16(SHChangeNotify)
    217218NODEF_DEBUGWRAP12(SHEmptyRecycleBinA)
    218219NODEF_DEBUGWRAP12(SHEmptyRecycleBinW)
  • trunk/src/shell32/shell32.def

    r8586 r9805  
    1 ; $Id: shell32.def,v 1.38 2002-06-07 08:21:43 sandervl Exp $
     1; $Id: shell32.def,v 1.39 2003-02-14 10:07:18 sandervl Exp $
    22
    33; Based on Windows 95
     
    2929    ILGlobalClone                     = _ILGlobalClone@4                      @20
    3030    ILIsEqual                         = _ILIsEqual@8                          @21
    31     Control_RunDLL                    = _Control_RunDLL@16                    @22
     31    Control_RunDLL                    = _Control_RunDLLA@16                   @22
    3232    ILIsParent                        = _ILIsParent@12                        @23
    3333    ILFindChild                       = _ILFindChild@8                        @24
     
    4848    PathIsUNC                         = _PathIsUNCAW@4                        @39
    4949    PathIsRelative                    = _PathIsRelativeAW@4                   @40
    50 ;   Control_RunDLLA                   = _Control_RunDLLA@16                   @41
    51 ;   Control_RunDLLW                   = _Control_RunDLLW@16                   @42
     50    Control_RunDLLA                   = _Control_RunDLLA@16                   @41
     51    Control_RunDLLW                   = _Control_RunDLLW@16                   @42
    5252    PathIsExe                         = _PathIsExeAW@4                        @43
    5353    DoEnvironmentSubstA               = _DoEnvironmentSubstA@8                @44
     
    173173    SHSimpleIDListFromPath            = _SHSimpleIDListFromPathAW@4           @162
    174174    StrToOleStr                       = _StrToOleStr@8                        @163
    175     Win32DeleteFile                   = _Win32DeleteFile@4                    @164
     175    Win32DeleteFile                   = _Win32DeleteFileAW@4                  @164
    176176    SHCreateDirectory                 = _SHCreateDirectory@8                  @165
    177177;   CallCPLEntry16                    = _CallCPLEntry16@?                     @166
     
    248248    SHBrowseForFolderA                = _SHBrowseForFolderA@4                 @237
    249249    SHBrowseForFolderW                = _SHBrowseForFolderW@4                 @238
    250     SHChangeNotify                    = _SHChangeNotifyAW@16                  @239
     250    SHChangeNotify                    = _SHChangeNotify@16                    @239
    251251    SHEmptyRecycleBinA                = _SHEmptyRecycleBinA@12                @240
    252252    SHEmptyRecycleBinW                = _SHEmptyRecycleBinW@12                @241
  • trunk/src/shell32/shell32dbg.def

    r8586 r9805  
    1 ; $Id: shell32dbg.def,v 1.3 2002-06-07 08:21:43 sandervl Exp $
     1; $Id: shell32dbg.def,v 1.4 2003-02-14 10:07:18 sandervl Exp $
    22
    33; Based on Windows 95
     
    2929    ILGlobalClone                     = _DbgILGlobalClone@4                      @20
    3030    ILIsEqual                         = _DbgILIsEqual@8                          @21
    31     Control_RunDLL                    = _DbgControl_RunDLL@16                    @22
     31    Control_RunDLL                    = _DbgControl_RunDLLA@16                   @22
    3232    ILIsParent                        = _DbgILIsParent@12                        @23
    3333    ILFindChild                       = _DbgILFindChild@8                        @24
     
    4848    PathIsUNC                         = _DbgPathIsUNCAW@4                        @39
    4949    PathIsRelative                    = _DbgPathIsRelativeAW@4                   @40
    50 ;   Control_RunDLLA                   = _DbgControl_RunDLLA@16                   @41
    51 ;   Control_RunDLLW                   = _DbgControl_RunDLLW@16                   @42
     50    Control_RunDLLA                   = _DbgControl_RunDLLA@16                   @41
     51    Control_RunDLLW                   = _DbgControl_RunDLLW@16                   @42
    5252    PathIsExe                         = _DbgPathIsExeAW@4                        @43
    5353    DoEnvironmentSubstA               = _DbgDoEnvironmentSubstA@8                @44
     
    173173    SHSimpleIDListFromPath            = _DbgSHSimpleIDListFromPathAW@4           @162
    174174    StrToOleStr                       = _DbgStrToOleStr@8                        @163
    175     Win32DeleteFile                   = _DbgWin32DeleteFile@4                    @164
     175    Win32DeleteFile                   = _DbgWin32DeleteFileAW@4                  @164
    176176    SHCreateDirectory                 = _DbgSHCreateDirectory@8                  @165
    177177;   CallCPLEntry16                    = _DbgCallCPLEntry16@?                     @166
     
    248248    SHBrowseForFolderA                = _DbgSHBrowseForFolderA@4                 @237
    249249    SHBrowseForFolderW                = _DbgSHBrowseForFolderW@4                 @238
    250     SHChangeNotify                    = _DbgSHChangeNotifyAW@16                  @239
     250    SHChangeNotify                    = _DbgSHChangeNotify@16                    @239
    251251    SHEmptyRecycleBinA                = _DbgSHEmptyRecycleBinA@12                @240
    252252    SHEmptyRecycleBinW                = _DbgSHEmptyRecycleBinW@12                @241
  • trunk/src/shell32/shlfileop.c

    r9552 r9805  
    55 * Copyright 2002 Andriy Palamarchuk
    66 * Copyright 2002 Dietrich Teickner (from Odin)
     7 * Copyright 2002 Rolf Kalbermatter
    78 *
    89 * This library is free software; you can redistribute it and/or
     
    2526
    2627#include <string.h>
     28#include <ctype.h>
    2729
    2830#include "winreg.h"
     
    3941BOOL SHELL_ConfirmDialog (int nKindOfDialog, LPCSTR szDir)
    4042{
    41         char szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
     43  char szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
    4244        UINT caption_resource_id, text_resource_id;
    4345
    44         switch(nKindOfDialog) {
    45 
    46         case ASK_DELETE_FILE:
    47                 caption_resource_id     = IDS_DELETEITEM_CAPTION;
    48                 text_resource_id        = IDS_DELETEITEM_TEXT;
    49                 break;
    50         case ASK_DELETE_FOLDER:
    51                 caption_resource_id     = IDS_DELETEFOLDER_CAPTION;
    52                 text_resource_id        = IDS_DELETEITEM_TEXT;
    53                 break;
    54         case ASK_DELETE_MULTIPLE_ITEM:
    55                 caption_resource_id     = IDS_DELETEITEM_CAPTION;
    56                 text_resource_id        = IDS_DELETEMULTIPLE_TEXT;
    57                 break;
    58         case ASK_OVERWRITE_FILE:
    59                 caption_resource_id     = IDS_OVERWRITEFILE_CAPTION;
    60                 text_resource_id        = IDS_OVERWRITEFILE_TEXT;
    61                 break;
    62         default:
    63           FIXME(" Unhandled nKindOfDialog %d stub\n", nKindOfDialog);
    64                 return FALSE;
    65         }
    66 
    67         LoadStringA(shell32_hInstance, caption_resource_id, szCaption, sizeof(szCaption));
    68         LoadStringA(shell32_hInstance, text_resource_id, szText, sizeof(szText));
    69 
    70         FormatMessageA(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
    71             szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)&szDir);
    72 
    73         return (IDOK == MessageBoxA(GetActiveWindow(), szBuffer, szCaption, MB_OKCANCEL | MB_ICONEXCLAMATION));
     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));
    7476}
    7577
    7678/**************************************************************************
    77  *      SHELL_DeleteDirectoryA()
     79 *  SHELL_DeleteDirectoryA()
    7880 *
    7981 * like rm -r
    8082 */
    81 
    8283BOOL SHELL_DeleteDirectoryA(LPCSTR pszDir, BOOL bShowUI)
    8384{
    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;
    118118}
    119119
    120120/**************************************************************************
    121  *      SHELL_DeleteFileA()
     121 *  SHELL_DeleteFileA()
    122122 */
    123123
    124124BOOL SHELL_DeleteFileA(LPCSTR pszFile, BOOL bShowUI)
    125125{
    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;
    129128        return DeleteFileA(pszFile);
    130129}
    131130
    132131/*************************************************************************
    133  * SHCreateDirectory                            [SHELL32.165]
     132 * SHCreateDirectory                       [SHELL32.165]
    134133 *
    135134 * NOTES
    136135 *  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 */
     138DWORD 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 */
     148DWORD WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES sec)
    140149{
    141150        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)
    144154        {
    145           SHChangeNotifyA(SHCNE_MKDIR, SHCNF_PATHA, path, NULL);
     155          SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHA, path, NULL);
    146156        }
     157        else if (hWnd)
     158          FIXME("Semi-stub, non zero hWnd should be used as parent for error dialog!");
    147159        return ret;
    148160}
    149161
     162/*************************************************************************
     163 * SHCreateDirectoryExW                     [SHELL32.@]
     164 */
     165DWORD 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
    150179/************************************************************************
    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 */
     188static BOOL Win32DeleteFileA(LPCSTR fName)
     189{
     190        DWORD ret;
    163191        TRACE("%p(%s)\n", fName, fName);
    164192
    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);
    221200        }
    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
     206static 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);
    252218        }
    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
     224BOOL 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 */
     236LPSTR 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 */
     264BOOL 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.@]
    259311 *
    260312 * NOTES
     
    263315DWORD WINAPI SHFileOperationA (LPSHFILEOPSTRUCTA lpFileOp)
    264316{
    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  {
    327385                /* establish when pTo is interpreted as the name of the destination file
    328386                 * or the directory where the Fromfile should be copied to.
     
    341399                 * create dir              0 0 0 0 0 0 1 0
    342400                 */
    343                         nlpFileOp.pFrom = pTempFrom = HeapAlloc(GetProcessHeap(), 0, 3 * MAX_PATH+6);
    344                         nlpFileOp.pTo   = pTempTo   = &pTempFrom[MAX_PATH+4];
    345401/*
    346  * FOF_MULTIDESTFILES, FOF_NOCONFIRMATION, FOF_FILESONLY                                        are             implemented
    347  * FOF_CONFIRMMOUSE, FOF_SILENT, FOF_NOCONFIRMMKDIR, FOF_SIMPLEPROGRESS         are not implemented and ignored
    348  * FOF_RENAMEONCOLLISION                                                                                                        are             implemented partially and breaks if file exist
    349  * FOF_ALLOWUNDO, FOF_WANTMAPPINGHANDLE                                                                         are not implemented and breaks
     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
    350406 * if any other flag set, an error occurs
    351407 */ 
    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/* tempor„r 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 k”nnte hier erfolgen, smple target D:\y\ *.* create with RC=10003 */
     613            if(!SHCreateDirectory(NULL,pTempTo))
    700614            {
    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;
    705618            }
    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  }
     796shfileop_normal:
     797        if (!(nlpFileOp.fAnyOperationsAborted))
     798          retCode = 0;
     799shfileop_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.@]
    808816 *
    809817 * NOTES
     
    812820DWORD WINAPI SHFileOperationW (LPSHFILEOPSTRUCTW lpFileOp)
    813821{
    814         FIXME("(%p):stub.\n", lpFileOp);
    815         return 1;
    816 }
    817 
    818 /*************************************************************************
    819  * SHFileOperation                              [SHELL32.@]
     822  FIXME("(%p):stub.\n", lpFileOp);
     823  return 1;
     824}
     825
     826/*************************************************************************
     827 * SHFileOperation        [SHELL32.@]
    820828 *
    821829 */
    822830DWORD WINAPI SHFileOperationAW(LPVOID lpFileOp)
    823831{
    824         if (SHELL_OsIsUnicode())
    825           return SHFileOperationW(lpFileOp);
    826         return SHFileOperationA(lpFileOp);
     832  if (SHELL_OsIsUnicode())
     833    return SHFileOperationW(lpFileOp);
     834  return SHFileOperationA(lpFileOp);
    827835}
    828836
     
    837845
    838846/*************************************************************************
    839  * SheChangeDirW [SHELL32.274]
    840  *
    841  */
    842 HRESULT WINAPI SheChangeDirW(LPWSTR u)
    843 {       FIXME("(%s),stub\n",debugstr_w(u));
     847 * SheChangeDir [SHELL32.@]
     848 *
     849 */
     850HRESULT WINAPI SheChangeDirW(LPWSTR path)
     851{       FIXME("(%s),stub\n",debugstr_w(path));
    844852        return 0;
    845853}
    846854
    847 /*************************************************************************
    848  * IsNetDrive                   [SHELL32.66]
     855HRESULT 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 */
     870HRESULT WINAPI SheChangeDirExW(LPWSTR path)
     871{       FIXME("(%s),stub\n",debugstr_w(path));
     872        return 0;
     873}
     874
     875HRESULT 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]
    849889 */
    850890BOOL WINAPI IsNetDrive(DWORD drive)
    851891{
    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  
    12201220        {
    12211221          if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
    1222           SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
     1222          SHChangeNotify( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
    12231223          return S_OK;
    12241224        }
     
    14891489
    14901490          pidl = ILCombine(This->absPidl, pidlitem);
    1491           SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
     1491          SHChangeNotify(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
    14921492          SHFree(pidl);
    14931493
     
    15541554            }
    15551555            pidl = ILCombine(This->absPidl, apidl[i]);
    1556             SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
     1556            SHChangeNotify(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
    15571557            SHFree(pidl);
    15581558          }
     
    15681568            }
    15691569            pidl = ILCombine(This->absPidl, apidl[i]);
    1570             SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
     1570            SHChangeNotify(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
    15711571            SHFree(pidl);
    15721572          }
Note: See TracChangeset for help on using the changeset viewer.