Index: trunk/src/shell32/shlfileop.c
===================================================================
--- trunk/src/shell32/shlfileop.c	(revision 5621)
+++ trunk/src/shell32/shlfileop.c	(revision 5623)
@@ -185,51 +185,4 @@
 }
 
-#ifdef __WIN32OS2__
-/************************************************************************
- *	Creation from dir for SHFileOperation (FO_COPY)
- *
- */ 
-
-LPSTR DirForFileOperationA (LPSTR pTo, DWORD *dwAttr, LPSHFILEOPSTRUCTA lpFileOp, BOOL toSingle)
-{
-
-	LPSTR pTempTo = NULL;
-	long lenTo;
-	BOOL withFileName = FALSE;
-	if(pTo[0]) {
-		lenTo = strlen(pTo);
-		pTempTo = HeapAlloc(GetProcessHeap(), 0, lenTo + MAX_PATH);
-
-	}
-        *dwAttr = -1;
-	if (pTempTo) {
-		strcpy(pTempTo,pTo);
-		PathRemoveBackslashA(pTempTo);
-                *dwAttr = GetFileAttributesA(pTempTo);
-                if (*(dwAttr) == -1 || !(*(dwAttr) & FILE_ATTRIBUTE_DIRECTORY)) {
-                        withFileName = ((lenTo == strlen(pTempTo)) || !toSingle);
-			if (withFileName) {
-// Target must not be an directory
-				PathRemoveFileSpecA(pTempTo);
-				*(dwAttr) = GetFileAttributesA(pTempTo);
-                        }
-                }
-                if ((*(dwAttr) == -1) || 
-                  ( !(*(dwAttr) & FILE_ATTRIBUTE_DIRECTORY) || (!withFileName && !toSingle) )) {
-// !toSingle == !(&pTo[strlen(pTo)+1]=="\0") redundant ?
-                        if (!withFileName && !toSingle) {
-				FIXME(__FUNCTION__" FO_COPY tagetdir and FOF_MULTIDESTFILES not implemented ? ,stub\n");
-                        };
-// never Create directory at this time
-                                HeapFree(GetProcessHeap(), 0, pTempTo);
-                                pTempTo = NULL;
-//                      }
-                }
-        }
-        if (!pTempTo) lpFileOp->fAnyOperationsAborted=TRUE;
-        return pTempTo;
-}
-#endif
-
 /*************************************************************************
  * SHFileOperationA				[SHELL32.243]
@@ -243,19 +196,34 @@
 	LPSTR pTo = (LPSTR)lpFileOp->pTo;
 #ifdef __WIN32OS2__
-	DWORD ToAttr;
-	DWORD FromAttr;
-	LPSTR pToFile;
-	LPSTR pTempTo = NULL;
-	LPSTR pTempFrom;
-
-	FILEOP_FLAGS OFl = ((FILEOP_FLAGS)lpFileOp->fFlags & 0x7ff);
-	BOOL Multi = (lpFileOp->fFlags & FOF_MULTIDESTFILES);
-	BOOL withFileName = FALSE;
-	BOOL not_overwrite;
-	BOOL copyOk;
-	long lenTo;
+        DWORD FromAttr;
+        DWORD ToAttr;
+        LPSTR pTempTo = NULL;
+        LPSTR pTempFrom;
+        LPSTR pNextFrom;
+        LPSTR pNextTo;
+        LPSTR pToFile;
+
+        FILEOP_FLAGS OFl = ((FILEOP_FLAGS)lpFileOp->fFlags & 0x7ff);
+        BOOL Multi = TRUE;
+        BOOL withFileName = FALSE;
+        BOOL not_overwrite;
+        BOOL toSingle;
+        BOOL StarStar;
+        BOOL copyOk;
+        long lenFrom = -1;
+        long lenTo   = -1;
+        long lenTempTo;
+        long retCode = 0x75;
+        long TempretCode = 0;
+        long lenNextFrom;
+        long lenNextTo;
+        SHFILEOPSTRUCTA nlpFileOp = *(lpFileOp);
+        HANDLE 	hFind;
+        WIN32_FIND_DATAA wfd;
+
 /* default no error
 */
 	lpFileOp->fAnyOperationsAborted=FALSE;
+	nlpFileOp.fAnyOperationsAborted=FALSE;
 #else
 	LPSTR pTempTo;
@@ -266,122 +234,271 @@
 		TRACE("File Copy:\n");
 #ifdef __WIN32OS2__
+            pTempTo = HeapAlloc(GetProcessHeap(), 0, 4 * MAX_PATH+4);
+            pNextFrom = &pTempTo[2*MAX_PATH+2];
+            pNextTo = &pNextFrom[MAX_PATH+1];
 /* 
- * FOF_MULTIDESTFILES, FOF_NOCONFIRMATION				are	implemented
+ * FOF_MULTIDESTFILES, FOF_NOCONFIRMATION, FOF_FILESONLY				are	implemented
  * FOF_CONFIRMMOUSE, FOF_SILENT, FOF_NOCONFIRMMKDIR, FOF_SIMPLEPROGRESS are not implemented and ignored
  * if any other flag set, an error occurs
  */  
-		OFl = (OFl & (-1 - (FOF_MULTIDESTFILES)));
-		OFl = (OFl ^ (FOF_SILENT | FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMMKDIR));
-		if (OFl) {
-			if (OFl & (-1 - (FOF_CONFIRMMOUSE | FOF_SILENT | FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMMKDIR))) {
-				FIXME(__FUNCTION__" FO_COPY with this fFlags not implemented:%2x ,stub\n",lpFileOp->fFlags);
-				lpFileOp->fAnyOperationsAborted=TRUE;
-			} else {
+            OFl = (OFl & (-1 - (FOF_MULTIDESTFILES | FOF_FILESONLY)));
+            OFl = (OFl ^ (FOF_SILENT | FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMMKDIR));
+            if (OFl) {
+                if (OFl & (-1 - (FOF_CONFIRMMOUSE | FOF_SILENT | FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS | FOF_NOCONFIRMMKDIR))) {
+                    FIXME(__FUNCTION__" FO_COPY with this fFlags not implemented:%2x ,stub\n",lpFileOp->fFlags);
+                    lpFileOp->fAnyOperationsAborted=TRUE;
+                } else {
 // not FOF_SILENT, not FOF_SIMPLEPROGRESS, not FOF_NOCONFIRMMKDIR
-				FIXME(__FUNCTION__" FO_COPY with this fFlags not full implemented:%2x ,stub\n",lpFileOp->fFlags);
-			} /* endif */              
-		} /* endif */
-
-		not_overwrite = (!(lpFileOp->fFlags & FOF_NOCONFIRMATION));
-		while(!Multi && !lpFileOp->fAnyOperationsAborted) {
-// single targetdir
-			pTempTo = DirForFileOperationA(pTo, &ToAttr, lpFileOp, TRUE);
-
-			if (!pTempTo) break;
-
-                        lenTo = strlen(pTempTo);
-                        withFileName = (((lenTo + 1) <  strlen(pTo)) || (PathIsRootA(pTo) && lenTo < strlen(pTo)));
-			PathAddBackslashA(pTempTo);
-			break;
-		}
-		if (!lpFileOp->fAnyOperationsAborted) {
-			TRACE("File Copy:\n");
-#ifdef __WIN32OS2__
-		  while(pFrom[0]) {
-#endif
-				if(!pTo[0]) break;
-
-				TRACE("   From='%s' To='%s'\n", pFrom, pTo);
-
-				if (Multi) {
-// multi target, each one for one source. ? last
-					pTempTo = DirForFileOperationA(pTo, &ToAttr, lpFileOp, FALSE);
-                                        if (pTempTo) {
-
-                                                lenTo = strlen(pTempTo);
-                                                withFileName = (((lenTo + 1) <  strlen(pTo)) || (PathIsRootA(pTo) && lenTo < strlen(pTo)));
-						PathAddBackslashA(pTempTo);
-					}
-				}
-				if (pTempTo) {
-					lenTo = strlen(pTempTo);
-					pToFile = &pTempTo[lenTo];
+                    FIXME(__FUNCTION__" FO_COPY with this lpFileOp->fFlags not full implemented:0x%2x ,stub\n",lpFileOp->fFlags);
+                } /* endif */              
+            } /* endif */
+
+            not_overwrite = (!(lpFileOp->fFlags & FOF_NOCONFIRMATION));
+
+// fix for more then one source for one target 
+            pToFile = pTempTo;
+
+            while((pFrom+=lenFrom+1)[0] && !nlpFileOp.fAnyOperationsAborted) {
+
+                if (!withFileName && Multi && (pTo[lenTo+1]=='\0')) {
+// Win Bug ?
+                    Multi = FALSE;
+                } /* endif */
+
+                if (Multi) pTo += lenTo + 1;
+                if(!pTo[0]) break;
+
+                TRACE("   From='%s' To='%s'\n", pFrom, pTo);
+
+// fix for more then one source for one target 
+                pToFile[0] = '\0';
+
+                lenFrom=strlen(pFrom);
+                strcpy(pNextFrom,pFrom);
+                FromAttr = GetFileAttributesA(pNextFrom);
+                StarStar = FALSE;
+
+                if (Multi) {
+                    lenTo = strlen(pTo);
+//  single targetdir !Multi
+                    Multi = (Multi && (lpFileOp->fFlags & FOF_MULTIDESTFILES));
+//  multi target, each one for one source. ? last target + more than one source (all source files an one dir as target)
+
+                    toSingle = ((pTo[lenTo+1]=='\0') || !Multi);
+                    withFileName = FALSE;
+
+                    strcpy(pTempTo,pTo);
+                    PathRemoveBackslashA(pTempTo);
+                    ToAttr = GetFileAttributesA(pTempTo);
+                    if (ToAttr == -1 || !(ToAttr & FILE_ATTRIBUTE_DIRECTORY)) {
+                        withFileName = ((lenTo == strlen(pTempTo)) || !toSingle);
+                        if (withFileName) {
+// Target must not be an directory
+                            PathRemoveFileSpecA(pTempTo);
+                            ToAttr = GetFileAttributesA(pTempTo);
+                        }
+                    }
+                    if (ToAttr == -1) {
+                        nlpFileOp.fAnyOperationsAborted=TRUE;
+                        break;
+                    } 
+                    if  (!(ToAttr & FILE_ATTRIBUTE_DIRECTORY) || (!withFileName && !toSingle) ) {
+// never Create directory at this time
+                        nlpFileOp.fAnyOperationsAborted=TRUE;
+                        /* retCode=0x279; */
+                        break;
+                    }
+                    lenTempTo = strlen(pTempTo);
+                    withFileName = (((lenTempTo + 1) <  lenTo) || (PathIsRootA(pTo) && lenTempTo < lenTo));
+                    PathAddBackslashA(pTempTo);
+                    StarStar = (Multi && !withFileName &&
+                        (ToAttr & FILE_ATTRIBUTE_DIRECTORY) &&
+                        (FromAttr != -1) &&
+                        (FromAttr & FILE_ATTRIBUTE_DIRECTORY) &&
+                        (0!=strcmp(pTempTo,pTo)));
+                }
+
+                if (FromAttr == -1 || StarStar) {
+// is Source an existing directory\*.* ?
+                    if (FromAttr == -1) {
+                        PathRemoveFileSpecA(pNextFrom);
+                        FromAttr = GetFileAttributesA(pNextFrom);
+                    }
+                    PathAddBackslashA(pNextFrom);
+                    lenNextFrom = strlen(pNextFrom);
+                    pToFile=&pNextFrom[lenNextFrom];
+                        
+                    if (FromAttr == -1 ||
+                       ((0==strcmp(pNextFrom,pFrom)) && !PathIsRootA(pFrom)) ||
+                      !(FromAttr & FILE_ATTRIBUTE_DIRECTORY) ||
+                      !((0==strcmp(&pFrom[lenNextFrom],"*.*")) || StarStar)) {
+                        retCode=0x402;
+                        nlpFileOp.fAnyOperationsAborted=TRUE;
+                        break;
+                    }
+
+                    strcpy(pToFile, "*.*");
+                    hFind = FindFirstFileA(pNextFrom, &wfd);
+                    if (INVALID_HANDLE_VALUE == hFind) {
+                        nlpFileOp.fAnyOperationsAborted=TRUE;
+                        retCode=0x79;
+                        break;
+                    }
+                    nlpFileOp.pFrom = pNextFrom;
+                    strcpy(pNextTo,pTo);
+                    pNextTo[strlen(pNextTo)+1]='\0';
+                    nlpFileOp.fFlags = (nlpFileOp.fFlags & (-1 - (FOF_MULTIDESTFILES)));
+
+                    TRACE(__FUNCTION__"   Copy between Subdir %s -> %s'\n", nlpFileOp.pFrom, nlpFileOp.pTo);
+
+                    do {
+                        TRACE(__FUNCTION__"   find '%s'\n", wfd.cFileName);
+                        if (0==strcmp(wfd.cFileName,".")) continue;
+                        if (0==strcmp(wfd.cFileName,"..")) continue;
+                        if ((nlpFileOp.fFlags & FOF_FILESONLY) && (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)) {
+                            continue;
+                        } /* endif */
+
+                        strcpy(pToFile,wfd.cFileName);
+                        pNextFrom[strlen(pNextFrom)+1]='\0';
+
+                        TempretCode = SHFileOperationA (&nlpFileOp);
+
+                        if (nlpFileOp.fAnyOperationsAborted) {/*retCode=0x179;*/break;}
+
+                    } while(FindNextFileA(hFind, &wfd));
+
+                    FindClose(hFind);
+                    if (nlpFileOp.fAnyOperationsAborted) break;
+                    continue;
+                }
+
+
+                lenTempTo = strlen(pTempTo);
+                pToFile = &pTempTo[lenTempTo];
+// Check Source
+                strcpy(pToFile,pNextFrom);
+                PathRemoveBackslashA(pToFile);
+                if (strlen(pToFile)<lenFrom) {
+                    nlpFileOp.fAnyOperationsAborted=TRUE;
+                    retCode=0x402;
+                    break;
+                } /* endif */
+
 // target name in target or from source
-                                        if (withFileName) {
-                                           if ((pFrom[strlen(pFrom)+1]=='\0') ||
-                                               (Multi && !(pTo[strlen(pTo)+1]=='\0'))) {
-                                                pTempFrom = pTo;
-                                           } else {
-// more then one source for one targetfile
-                                                lpFileOp->fAnyOperationsAborted=TRUE;
-                                                break;
-                                           } /* endif */
-                                        } else {
-                                                pTempFrom = pFrom;
-                                        } /* endif */
-// isolate target filename
-					strcpy(pToFile,pTempFrom);
-					PathRemoveFileSpecA(pToFile);
-					PathAddBackslashA(pToFile);
-					lenTo = strlen(pToFile);
-
-					strcpy(pToFile,&pTempFrom[lenTo]);
-                                        FromAttr = GetFileAttributesA(pFrom);
-                                        if (FromAttr & FILE_ATTRIBUTE_DIRECTORY) {
-                                           if (!(FromAttr == -1)) {
-                				FIXME(__FUNCTION__" FO_COPY only with sourcedir not implemented ,stub\n");
-                                           };
-                                           lpFileOp->fAnyOperationsAborted=TRUE;
-                                           break;
-                                        }
-                                        ToAttr = GetFileAttributesA(pTempTo);
-                                        if (!(ToAttr == -1) && (ToAttr & FILE_ATTRIBUTE_DIRECTORY)) {
-                                           lpFileOp->fAnyOperationsAborted=TRUE;
-                                           break;
-                                        }
+                pTempFrom = NULL;
+                if (withFileName) {
+                    if ((pFrom[lenFrom+1]=='\0') || (Multi && !(pTo[lenTo+1]=='\0'))) {
+                        pTempFrom = pTo;
+                    } /* endif */
+                } else {
+// Multi Target 
+                    if (!Multi || !(pFrom[lenFrom+1]=='\0') ||
+// only target+\, target without \ has 0x402
+                        (Multi && (FromAttr & FILE_ATTRIBUTE_DIRECTORY) && (ToAttr & FILE_ATTRIBUTE_DIRECTORY))) {
+                        pTempFrom = pNextFrom;
+                    }
+                } /* endif */
+
+                if (!pTempFrom) {
+                    nlpFileOp.fAnyOperationsAborted=TRUE;
+                    break;
+                } /* endif */
+
+// move isolated target filename
+                strcpy(pToFile,pTempFrom);
+                PathRemoveFileSpecA(pToFile);
+                PathAddBackslashA(pToFile);
+
+                strcpy(pToFile,&pTempFrom[strlen(pToFile)]);
+                ToAttr = GetFileAttributesA(pTempTo);
+
+
+                if (FromAttr == -1) {
+                    FIXME(__FUNCTION__" FO_COPY with Source %s not implementiert ,stub\n",pNextFrom);
+                    nlpFileOp.fAnyOperationsAborted=TRUE;
+                    retCode=0x76;
+                    break;
+                }
+                if (FromAttr & FILE_ATTRIBUTE_DIRECTORY) {
+                    if (ToAttr == -1) {
+// Try to create an new Directory and enter in it
+                        TRACE("   Creating Directory '%s'\n", pTempTo);
+                        SHCreateDirectory(NULL,pTempTo);
+                        ToAttr = GetFileAttributesA(pTempTo);
+                        if (ToAttr == -1) {
+                            nlpFileOp.fAnyOperationsAborted=TRUE;
+                            retCode=0x10003;
+                            break;
+                        }
+
+                        lenTempTo = strlen(pTempTo);
+
+                        PathAddBackslashA(pNextFrom);
+                        strcat(pNextFrom, "*.*");
+                        pNextFrom[strlen(pNextFrom)+1]='\0';
+                        nlpFileOp.pFrom = pNextFrom;
+
+                        pTempTo[lenTempTo+1]='\0';
+                        nlpFileOp.pTo = pTempTo;
+
+                        TRACE(__FUNCTION__"   Entering Directory '%s'\n", nlpFileOp.pTo);
+                        TempretCode = SHFileOperationA (&nlpFileOp);
+
+                        if (nlpFileOp.fAnyOperationsAborted) {break;}
+                        continue;
+
+                    } else {
+                        if (!(ToAttr & FILE_ATTRIBUTE_DIRECTORY)) {
+                            FIXME(__FUNCTION__" FO_COPY only with %s -> %t ? ,stub\n",pNextFrom,pTo);
+                            nlpFileOp.fAnyOperationsAborted=TRUE;
+                            retCode=0x77;
+                            break;
+                        }
+                        if (strlen(pToFile)==0) {
+                            nlpFileOp.fAnyOperationsAborted=TRUE;
+                            retCode=0x78;
+                            break;
+                        } else {
+                            nlpFileOp.fAnyOperationsAborted=TRUE;
+                            retCode=0x80;
+                            break;
+                        } /* endif */
+
+                    }
+
+                }
+
+                if (!(ToAttr == -1) && (ToAttr & FILE_ATTRIBUTE_DIRECTORY)) {
+                    nlpFileOp.fAnyOperationsAborted=TRUE;
+                    break;
+                }
 // first try to copy
-					copyOk = CopyFileA(pFrom, pTempTo, not_overwrite);
-
-					if (!copyOk && not_overwrite) {
-						if (SHELL_ConfirmDialog (ASK_OVERWRITE_FILE, pTempTo))
+                if (CopyFileA(pNextFrom, pTempTo, not_overwrite)) continue;
+
+                if (not_overwrite) {
+                    if (SHELL_ConfirmDialog (ASK_OVERWRITE_FILE, pTempTo))
 // second try to copy after confirm
-							copyOk = CopyFileA(pFrom, pTempTo, FALSE);
-					} /* endif */
-					if (!copyOk) lpFileOp->fAnyOperationsAborted=TRUE;
-// fix for mor then one source for one target 
-					pToFile[0] = '\0';
-
-                                        if (!withFileName && Multi && (pTo[strlen(pTo)+1]=='\0')) {
-// Win Bug ?
-                                                Multi = FALSE;
-                                        } /* endif */
-					if (Multi) HeapFree(GetProcessHeap(), 0, pTempTo);
-				}				
-
-				pFrom += strlen(pFrom) + 1;
-                                
-                        	if (Multi) pTo += strlen(pTo) + 1;
-
-			}
-		} /* endif */
-		if (!Multi && pTempTo) HeapFree(GetProcessHeap(), 0, pTempTo);
-
-		if (lpFileOp->fAnyOperationsAborted==TRUE) {
-			TRACE(__FUNCTION__" Setting AnyOpsAborted=TRUE\n");
-			return 0x75l;
-		} else {
-		      TRACE(__FUNCTION__" Setting AnyOpsAborted=FALSE\n");
+                        if (CopyFileA(pNextFrom, pTempTo, FALSE)) continue;
                 } /* endif */
-		return 0;
+
+                nlpFileOp.fAnyOperationsAborted=TRUE;
+            }
+
+            if (pTempTo) HeapFree(GetProcessHeap(), 0, pTempTo);
+
+            if (nlpFileOp.fAnyOperationsAborted) {
+                lpFileOp->fAnyOperationsAborted=TRUE;
+                if (TempretCode > retCode) {
+                    retCode = TempretCode;
+                } /* endif */
+            }
+            if (lpFileOp->fAnyOperationsAborted==TRUE) {
+                TRACE(__FUNCTION__" Setting AnyOpsAborted=TRUE\n");
+                return retCode;
+            } /* endif */
+
+            TRACE(__FUNCTION__" Setting AnyOpsAborted=FALSE\n");
+            return 0;
 #else
 		while(1) {
