Commit in reactos/lib/kernel32/file on MAIN
move.c+94-401.14 -> 1.15
- Split up the handling if the fsd returns STATUS_NOT_IMPLEMENTED in MoveFileWithProgressW. 
- Converted the destination name before calling NtSetInformationFile in MoveFileWithProgressW.

reactos/lib/kernel32/file
move.c 1.14 -> 1.15
diff -u -r1.14 -r1.15
--- move.c	13 Jun 2004 20:04:55 -0000	1.14
+++ move.c	4 Dec 2004 15:38:22 -0000	1.15
@@ -1,4 +1,4 @@
-/* $Id: move.c,v 1.14 2004/06/13 20:04:55 navaraf Exp $
+/* $Id: move.c,v 1.15 2004/12/04 15:38:22 hbirr Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -16,9 +16,15 @@
 #define NDEBUG
 #include "../include/debug.h"
 
+/* GLOBALS *****************************************************************/
 
-#define FILE_RENAME_SIZE  MAX_PATH +sizeof(FILE_RENAME_INFORMATION)
-
+#if defined(__GNUC__)
+void * alloca(size_t size);
+#elif defined(_MSC_VER)
+void* _alloca(size_t size);
+#else
+#error Unknown compiler for alloca intrinsic stack allocation "function"
+#endif
 
 /* FUNCTIONS ****************************************************************/
 
@@ -164,11 +170,12 @@
 {
 	HANDLE hFile = NULL;
 	IO_STATUS_BLOCK IoStatusBlock;
-	FILE_RENAME_INFORMATION *FileRename;
-	USHORT Buffer[FILE_RENAME_SIZE];
+	PFILE_RENAME_INFORMATION FileRename;
 	NTSTATUS errCode;
-	DWORD err;
 	BOOL Result;
+	UNICODE_STRING DstPathU;
+
+	DPRINT("MoveFileWithProgressW()\n");
 
 	hFile = CreateFileW (lpExistingFileName,
 	                     GENERIC_ALL,
@@ -178,71 +185,118 @@
 	                     FILE_ATTRIBUTE_NORMAL,
 	                     NULL);
 
-	FileRename = (FILE_RENAME_INFORMATION *)Buffer;
+	if (hFile == INVALID_HANDLE_VALUE)
+	{
+           return FALSE;
+	}
+
+        /* validate & translate the filename */
+        if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpNewFileName,
+				           &DstPathU,
+				           NULL,
+				           NULL))
+        {
+           DPRINT("Invalid destination path\n");
+	   CloseHandle(hFile);
+           SetLastError(ERROR_PATH_NOT_FOUND);
+           return FALSE;
+        }
+
+	FileRename = alloca(sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length);
 	if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == MOVEFILE_REPLACE_EXISTING)
 		FileRename->ReplaceIfExists = TRUE;
 	else
 		FileRename->ReplaceIfExists = FALSE;
-	FileRename->FileNameLength = wcslen (lpNewFileName);
-	memcpy (FileRename->FileName,
-	        lpNewFileName,
-	        min(FileRename->FileNameLength, MAX_PATH));
 
+	memcpy(FileRename->FileName, DstPathU.Buffer, DstPathU.Length);
+        RtlFreeHeap (RtlGetProcessHeap (),
+		     0,
+		     DstPathU.Buffer);
+	/* 
+	 * FIXME:
+	 *   Is the length the count of characters or the length of the buffer?
+	 */
+	FileRename->FileNameLength = DstPathU.Length / sizeof(WCHAR);
 	errCode = NtSetInformationFile (hFile,
 	                                &IoStatusBlock,
 	                                FileRename,
-	                                FILE_RENAME_SIZE,
+	                                sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length,
 	                                FileRenameInformation);
 	CloseHandle(hFile);
 	if (NT_SUCCESS(errCode))
 	{
 		Result = TRUE;
 	}
+	else if (STATUS_NOT_SAME_DEVICE == errCode &&
+		 MOVEFILE_COPY_ALLOWED == (dwFlags & MOVEFILE_COPY_ALLOWED))
+	{
+		Result = CopyFileExW (lpExistingFileName,
+		                      lpNewFileName,
+		                      lpProgressRoutine,
+		                      lpData,
+		                      NULL,
+		                      FileRename->ReplaceIfExists ? 0 : COPY_FILE_FAIL_IF_EXISTS);
+		if (Result)
+		{
+			/* Cleanup the source file */
+			AdjustFileAttributes(lpExistingFileName, lpNewFileName);
+	                Result = DeleteFileW (lpExistingFileName);
+		}
+	}
+#if 1
 	/* FIXME file rename not yet implemented in all FSDs so it will always
 	 * fail, even when the move is to the same device
 	 */
-#if 0
-	else if (STATUS_NOT_SAME_DEVICE == errCode &&
-		 MOVEFILE_COPY_ALLOWED == (dwFlags & MOVEFILE_COPY_ALLOWED))
-#else
-	else
-#endif
+	else if (STATUS_NOT_IMPLEMENTED == errCode)
 	{
+
+		UNICODE_STRING SrcPathU;
+
+		SrcPathU.Buffer = alloca(sizeof(WCHAR) * MAX_PATH);
+		SrcPathU.MaximumLength = MAX_PATH * sizeof(WCHAR);
+		SrcPathU.Length = GetFullPathNameW(lpExistingFileName, MAX_PATH, SrcPathU.Buffer, NULL);
+		if (SrcPathU.Length >= MAX_PATH)
+		{
+		    SetLastError(ERROR_FILENAME_EXCED_RANGE);
+		    return FALSE;
+		}
+		SrcPathU.Length *= sizeof(WCHAR);
+
+		DstPathU.Buffer = alloca(sizeof(WCHAR) * MAX_PATH);
+		DstPathU.MaximumLength = MAX_PATH * sizeof(WCHAR);
+		DstPathU.Length = GetFullPathNameW(lpNewFileName, MAX_PATH, DstPathU.Buffer, NULL);
+		if (DstPathU.Length >= MAX_PATH)
+		{
+		    SetLastError(ERROR_FILENAME_EXCED_RANGE);
+		    return FALSE;
+		}
+		DstPathU.Length *= sizeof(WCHAR);
+
+		if (0 == RtlCompareUnicodeString(&SrcPathU, &DstPathU, TRUE))
+		{
+		   /* Source and destination file are the same, nothing to do */
+		   return TRUE;
+		}
+
 		Result = CopyFileExW (lpExistingFileName,
 		                      lpNewFileName,
 		                      lpProgressRoutine,
 		                      lpData,
 		                      NULL,
-		                      FileRename->ReplaceIfExists ? 0 : COPY_FILE_FAIL_IF_EXISTS) &&
-		         AdjustFileAttributes(lpExistingFileName, lpNewFileName) &&
-		         DeleteFileW (lpExistingFileName);
-		if (! Result)
+		                      FileRename->ReplaceIfExists ? 0 : COPY_FILE_FAIL_IF_EXISTS);
+		if (Result)
 		{
-			/* Delete of the existing file failed so the
-			 * existing file is still there. Clean up the
-			 * new file (if possible)
-			 */
-			err = GetLastError();
-			if (! SetFileAttributesW (lpNewFileName, FILE_ATTRIBUTE_NORMAL))
-			{
-				DPRINT("Removing possible READONLY attrib from new file failed with code %d\n", GetLastError());
-			}
-			if (! DeleteFileW (lpNewFileName))
-			{
-				DPRINT("Deleting new file during cleanup failed with code %d\n", GetLastError());
-			}
-			SetLastError (err);
+		    /* Cleanup the source file */
+                    AdjustFileAttributes(lpExistingFileName, lpNewFileName); 
+		    Result = DeleteFileW (lpExistingFileName);
 		}
 	}
-	/* See FIXME above */
-#if 0
+#endif
 	else
 	{
 		SetLastErrorByStatus (errCode);
 		Result = FALSE;
 	}
-#endif
-
 	return Result;
 }
 
CVSspam 0.2.8