[KERNEL32]
[reactos.git] / reactos / dll / win32 / kernel32 / client / file / copy.c
index 9601e10..92c4555 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
- * FILE:            lib/kernel32/file/copy.c
+ * FILE:            dll/win32/kernel32/client/file/copy.c
  * PURPOSE:         Copying files
  * PROGRAMMER:      Ariadne (ariadne@xs4all.nl)
  * UPDATE HISTORY:
  *                  01/11/98 Created
- *                  07/02/99 Moved to seperate file
+ *                  07/02/99 Moved to separate file
  */
 
 /* INCLUDES ****************************************************************/
@@ -101,6 +101,13 @@ CopyLoop (
                                      RegionSize,
                                      NULL,
                                      NULL);
+                /* With sync read, 0 length + status success mean EOF:
+                 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx
+                 */
+                if (NT_SUCCESS(errCode) && IoStatusBlock.Information == 0)
+                {
+                    errCode = STATUS_END_OF_FILE;
+                }
                 if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel))
                 {
                     errCode = NtWriteFile(FileHandleDest,
@@ -191,20 +198,16 @@ SetLastWriteTime(
     return errCode;
 }
 
-
-/*
- * @implemented
- */
 BOOL
-WINAPI
-CopyFileExW (
-    LPCWSTR                    lpExistingFileName,
-    LPCWSTR                    lpNewFileName,
-    LPPROGRESS_ROUTINE lpProgressRoutine,
-    LPVOID                     lpData,
-    BOOL                       *pbCancel,
-    DWORD                      dwCopyFlags
-)
+BasepCopyFileExW(IN LPCWSTR lpExistingFileName,
+                 IN LPCWSTR lpNewFileName,
+                 IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
+                 IN LPVOID lpData OPTIONAL,
+                 IN LPBOOL pbCancel OPTIONAL,
+                 IN DWORD dwCopyFlags,
+                 IN DWORD dwBasepFlags,
+                 OUT LPHANDLE lpExistingHandle,
+                 OUT LPHANDLE lpNewHandle)
 {
     NTSTATUS errCode;
     HANDLE FileHandleSource, FileHandleDest;
@@ -307,6 +310,53 @@ CopyFileExW (
     return RC;
 }
 
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+CopyFileExW(IN LPCWSTR lpExistingFileName,
+            IN LPCWSTR lpNewFileName,
+            IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
+            IN LPVOID lpData OPTIONAL,
+            IN LPBOOL pbCancel OPTIONAL,
+            IN DWORD dwCopyFlags)
+{
+    BOOL Ret;
+    HANDLE ExistingHandle, NewHandle;
+
+    ExistingHandle = INVALID_HANDLE_VALUE;
+    NewHandle = INVALID_HANDLE_VALUE;
+
+    _SEH2_TRY
+    {
+        Ret = BasepCopyFileExW(lpExistingFileName,
+                               lpNewFileName,
+                               lpProgressRoutine,
+                               lpData,
+                               pbCancel,
+                               dwCopyFlags,
+                               0,
+                               &ExistingHandle,
+                               &NewHandle);
+    }
+    _SEH2_FINALLY
+    {
+        if (ExistingHandle != INVALID_HANDLE_VALUE)
+        {
+            CloseHandle(ExistingHandle);
+        }
+
+        if (NewHandle != INVALID_HANDLE_VALUE)
+        {
+            CloseHandle(NewHandle);
+        }
+    }
+    _SEH2_END;
+
+    return Ret;
+}
+
 
 /*
  * @implemented
@@ -351,18 +401,33 @@ CopyFileExA(IN LPCSTR lpExistingFileName,
  */
 BOOL
 WINAPI
-CopyFileA (
-    LPCSTR     lpExistingFileName,
-    LPCSTR     lpNewFileName,
-    BOOL       bFailIfExists
-)
+CopyFileA(IN LPCSTR lpExistingFileName,
+          IN LPCSTR lpNewFileName,
+          IN BOOL bFailIfExists)
 {
-    return CopyFileExA (lpExistingFileName,
-                        lpNewFileName,
-                        NULL,
-                        NULL,
-                        NULL,
-                        bFailIfExists);
+    BOOL Result = FALSE;
+    UNICODE_STRING lpNewFileNameW;
+    PUNICODE_STRING lpExistingFileNameW;
+
+    lpExistingFileNameW = Basep8BitStringToStaticUnicodeString(lpExistingFileName);
+    if (!lpExistingFileNameW)
+    {
+        return FALSE;
+    }
+
+    if (Basep8BitStringToDynamicUnicodeString(&lpNewFileNameW, lpNewFileName))
+    {
+        Result = CopyFileExW(lpExistingFileNameW->Buffer,
+                             lpNewFileNameW.Buffer,
+                             NULL,
+                             NULL,
+                             NULL,
+                             (bFailIfExists ? COPY_FILE_FAIL_IF_EXISTS : 0));
+
+        RtlFreeUnicodeString(&lpNewFileNameW);
+    }
+
+    return Result;
 }
 
 
@@ -371,18 +436,16 @@ CopyFileA (
  */
 BOOL
 WINAPI
-CopyFileW (
-    LPCWSTR    lpExistingFileName,
-    LPCWSTR    lpNewFileName,
-    BOOL       bFailIfExists
-)
+CopyFileW(IN LPCWSTR lpExistingFileName,
+          IN LPCWSTR lpNewFileName,
+          IN BOOL bFailIfExists)
 {
-    return CopyFileExW (lpExistingFileName,
-                        lpNewFileName,
-                        NULL,
-                        NULL,
-                        NULL,
-                        bFailIfExists);
+    return CopyFileExW(lpExistingFileName,
+                       lpNewFileName,
+                       NULL,
+                       NULL,
+                       NULL,
+                       (bFailIfExists ? COPY_FILE_FAIL_IF_EXISTS : 0));
 }
 
 
@@ -391,17 +454,53 @@ CopyFileW (
  */
 BOOL
 WINAPI
-PrivCopyFileExW (
-    LPCWSTR                    lpExistingFileName,
-    LPCWSTR                    lpNewFileName,
-    LPPROGRESS_ROUTINE lpProgressRoutine,
-    LPVOID                     lpData,
-    BOOL                       *pbCancel,
-    DWORD                      dwCopyFlags
-)
+PrivCopyFileExW(IN LPCWSTR lpExistingFileName,
+                IN LPCWSTR lpNewFileName,
+                IN LPPROGRESS_ROUTINE lpProgressRoutine,
+                IN LPVOID lpData,
+                IN LPBOOL pbCancel,
+                IN DWORD dwCopyFlags)
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    BOOL Ret;
+    HANDLE ExistingHandle, NewHandle;
+
+    ExistingHandle = INVALID_HANDLE_VALUE;
+    NewHandle = INVALID_HANDLE_VALUE;
+
+    /* Check for incompatible flags */
+    if (dwCopyFlags & COPY_FILE_FAIL_IF_EXISTS && dwCopyFlags & BASEP_COPY_REPLACE)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    _SEH2_TRY
+    {
+        Ret = BasepCopyFileExW(lpExistingFileName,
+                               lpNewFileName,
+                               lpProgressRoutine,
+                               lpData,
+                               pbCancel,
+                               dwCopyFlags & BASEP_COPY_PUBLIC_MASK,
+                               dwCopyFlags & BASEP_COPY_BASEP_MASK,
+                               &ExistingHandle,
+                               &NewHandle);
+    }
+    _SEH2_FINALLY
+    {
+        if (ExistingHandle != INVALID_HANDLE_VALUE)
+        {
+            CloseHandle(ExistingHandle);
+        }
+
+        if (NewHandle != INVALID_HANDLE_VALUE)
+        {
+            CloseHandle(NewHandle);
+        }
+    }
+    _SEH2_END;
+
+    return Ret;
 }
 
 /* EOF */