[KERNEL32]
[reactos.git] / reactos / dll / win32 / kernel32 / client / file / copy.c
index 2af2cdf..3eb763d 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * FILE:            lib/kernel32/file/copy.c
@@ -25,287 +24,330 @@ DEBUG_CHANNEL(kernel32file);
 
 static NTSTATUS
 CopyLoop (
-       HANDLE                  FileHandleSource,
-       HANDLE                  FileHandleDest,
-       LARGE_INTEGER           SourceFileSize,
-       LPPROGRESS_ROUTINE      lpProgressRoutine,
-       LPVOID                  lpData,
-       BOOL                    *pbCancel,
-       BOOL                 *KeepDest
-       )
+    HANDLE                     FileHandleSource,
+    HANDLE                     FileHandleDest,
+    LARGE_INTEGER              SourceFileSize,
+    LPPROGRESS_ROUTINE lpProgressRoutine,
+    LPVOID                     lpData,
+    BOOL                       *pbCancel,
+    BOOL                 *KeepDest
+)
 {
-   NTSTATUS errCode;
-   IO_STATUS_BLOCK IoStatusBlock;
-   UCHAR *lpBuffer = NULL;
-   SIZE_T RegionSize = 0x10000;
-   LARGE_INTEGER BytesCopied;
-   DWORD CallbackReason;
-   DWORD ProgressResult;
-   BOOL EndOfFileFound;
-
-   *KeepDest = FALSE;
-   errCode = NtAllocateVirtualMemory(NtCurrentProcess(),
-                                    (PVOID *)&lpBuffer,
-                                    2,
-                                    &RegionSize,
-                                    MEM_RESERVE | MEM_COMMIT,
-                                    PAGE_READWRITE);
-
-   if (NT_SUCCESS(errCode))
-     {
-       BytesCopied.QuadPart = 0;
-       EndOfFileFound = FALSE;
-       CallbackReason = CALLBACK_STREAM_SWITCH;
-       while (! EndOfFileFound &&
-              NT_SUCCESS(errCode) &&
-              (NULL == pbCancel || ! *pbCancel))
-         {
-            if (NULL != lpProgressRoutine)
-              {
-                  ProgressResult = (*lpProgressRoutine)(SourceFileSize,
-                                                        BytesCopied,
-                                                        SourceFileSize,
-                                                        BytesCopied,
-                                                        0,
-                                                        CallbackReason,
-                                                        FileHandleSource,
-                                                        FileHandleDest,
-                                                        lpData);
-                  switch (ProgressResult)
-                    {
-                    case PROGRESS_CANCEL:
-                       TRACE("Progress callback requested cancel\n");
-                       errCode = STATUS_REQUEST_ABORTED;
-                       break;
-                    case PROGRESS_STOP:
-                       TRACE("Progress callback requested stop\n");
-                       errCode = STATUS_REQUEST_ABORTED;
-                       *KeepDest = TRUE;
-                       break;
-                    case PROGRESS_QUIET:
-                       lpProgressRoutine = NULL;
-                       break;
-                    case PROGRESS_CONTINUE:
-                    default:
-                       break;
-                    }
-                  CallbackReason = CALLBACK_CHUNK_FINISHED;
-              }
-            if (NT_SUCCESS(errCode))
-              {
-                 errCode = NtReadFile(FileHandleSource,
-                                      NULL,
-                                      NULL,
-                                      NULL,
-                                      (PIO_STATUS_BLOCK)&IoStatusBlock,
-                                      lpBuffer,
-                                      RegionSize,
-                                      NULL,
-                                      NULL);
-                 if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel))
-                   {
-                      errCode = NtWriteFile(FileHandleDest,
-                                            NULL,
-                                            NULL,
-                                            NULL,
-                                            (PIO_STATUS_BLOCK)&IoStatusBlock,
-                                            lpBuffer,
-                                            IoStatusBlock.Information,
-                                            NULL,
-                                            NULL);
-                      if (NT_SUCCESS(errCode))
-                        {
-                           BytesCopied.QuadPart += IoStatusBlock.Information;
-                        }
-                      else
-                        {
-                           WARN("Error 0x%08x reading writing to dest\n", errCode);
-                        }
-                   }
-                 else if (!NT_SUCCESS(errCode))
-                   {
-                      if (STATUS_END_OF_FILE == errCode)
-                        {
-                           EndOfFileFound = TRUE;
-                           errCode = STATUS_SUCCESS;
-                        }
-                      else
-                        {
-                           WARN("Error 0x%08x reading from source\n", errCode);
-                        }
-                   }
-              }
-         }
-
-       if (! EndOfFileFound && (NULL != pbCancel && *pbCancel))
-         {
-         TRACE("User requested cancel\n");
-         errCode = STATUS_REQUEST_ABORTED;
-         }
-
-       NtFreeVirtualMemory(NtCurrentProcess(),
-                           (PVOID *)&lpBuffer,
-                           &RegionSize,
-                           MEM_RELEASE);
-     }
-   else
-     {
-       TRACE("Error 0x%08x allocating buffer of %d bytes\n", errCode, RegionSize);
-     }
-
-   return errCode;
+    NTSTATUS errCode;
+    IO_STATUS_BLOCK IoStatusBlock;
+    UCHAR *lpBuffer = NULL;
+    SIZE_T RegionSize = 0x10000;
+    LARGE_INTEGER BytesCopied;
+    DWORD CallbackReason;
+    DWORD ProgressResult;
+    BOOL EndOfFileFound;
+
+    *KeepDest = FALSE;
+    errCode = NtAllocateVirtualMemory(NtCurrentProcess(),
+                                      (PVOID *)&lpBuffer,
+                                      0,
+                                      &RegionSize,
+                                      MEM_RESERVE | MEM_COMMIT,
+                                      PAGE_READWRITE);
+
+    if (NT_SUCCESS(errCode))
+    {
+        BytesCopied.QuadPart = 0;
+        EndOfFileFound = FALSE;
+        CallbackReason = CALLBACK_STREAM_SWITCH;
+        while (! EndOfFileFound &&
+                NT_SUCCESS(errCode) &&
+                (NULL == pbCancel || ! *pbCancel))
+        {
+            if (NULL != lpProgressRoutine)
+            {
+                ProgressResult = (*lpProgressRoutine)(SourceFileSize,
+                                                      BytesCopied,
+                                                      SourceFileSize,
+                                                      BytesCopied,
+                                                      0,
+                                                      CallbackReason,
+                                                      FileHandleSource,
+                                                      FileHandleDest,
+                                                      lpData);
+                switch (ProgressResult)
+                {
+                case PROGRESS_CANCEL:
+                    TRACE("Progress callback requested cancel\n");
+                    errCode = STATUS_REQUEST_ABORTED;
+                    break;
+                case PROGRESS_STOP:
+                    TRACE("Progress callback requested stop\n");
+                    errCode = STATUS_REQUEST_ABORTED;
+                    *KeepDest = TRUE;
+                    break;
+                case PROGRESS_QUIET:
+                    lpProgressRoutine = NULL;
+                    break;
+                case PROGRESS_CONTINUE:
+                default:
+                    break;
+                }
+                CallbackReason = CALLBACK_CHUNK_FINISHED;
+            }
+            if (NT_SUCCESS(errCode))
+            {
+                errCode = NtReadFile(FileHandleSource,
+                                     NULL,
+                                     NULL,
+                                     NULL,
+                                     (PIO_STATUS_BLOCK)&IoStatusBlock,
+                                     lpBuffer,
+                                     RegionSize,
+                                     NULL,
+                                     NULL);
+                if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel))
+                {
+                    errCode = NtWriteFile(FileHandleDest,
+                                          NULL,
+                                          NULL,
+                                          NULL,
+                                          (PIO_STATUS_BLOCK)&IoStatusBlock,
+                                          lpBuffer,
+                                          IoStatusBlock.Information,
+                                          NULL,
+                                          NULL);
+                    if (NT_SUCCESS(errCode))
+                    {
+                        BytesCopied.QuadPart += IoStatusBlock.Information;
+                    }
+                    else
+                    {
+                        WARN("Error 0x%08x reading writing to dest\n", errCode);
+                    }
+                }
+                else if (!NT_SUCCESS(errCode))
+                {
+                    if (STATUS_END_OF_FILE == errCode)
+                    {
+                        EndOfFileFound = TRUE;
+                        errCode = STATUS_SUCCESS;
+                    }
+                    else
+                    {
+                        WARN("Error 0x%08x reading from source\n", errCode);
+                    }
+                }
+            }
+        }
+
+        if (! EndOfFileFound && (NULL != pbCancel && *pbCancel))
+        {
+            TRACE("User requested cancel\n");
+            errCode = STATUS_REQUEST_ABORTED;
+        }
+
+        NtFreeVirtualMemory(NtCurrentProcess(),
+                            (PVOID *)&lpBuffer,
+                            &RegionSize,
+                            MEM_RELEASE);
+    }
+    else
+    {
+        TRACE("Error 0x%08x allocating buffer of %lu bytes\n", errCode, RegionSize);
+    }
+
+    return errCode;
 }
 
 static NTSTATUS
 SetLastWriteTime(
-       HANDLE FileHandle,
-       LARGE_INTEGER LastWriteTime
-       )
+    HANDLE FileHandle,
+    LARGE_INTEGER LastWriteTime
+)
 {
-   NTSTATUS errCode = STATUS_SUCCESS;
-   IO_STATUS_BLOCK IoStatusBlock;
-   FILE_BASIC_INFORMATION FileBasic;
-
-   errCode = NtQueryInformationFile (FileHandle,
-                                    &IoStatusBlock,
-                                    &FileBasic,
-                                    sizeof(FILE_BASIC_INFORMATION),
-                                    FileBasicInformation);
-   if (!NT_SUCCESS(errCode))
-     {
-       WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode);
-     }
-   else
-     {
-       FileBasic.LastWriteTime.QuadPart = LastWriteTime.QuadPart;
-       errCode = NtSetInformationFile (FileHandle,
-                                       &IoStatusBlock,
-                                       &FileBasic,
-                                       sizeof(FILE_BASIC_INFORMATION),
-                                       FileBasicInformation);
-       if (!NT_SUCCESS(errCode))
-         {
-            WARN("Error 0x%0x setting LastWriteTime\n", errCode);
-         }
-     }
-
-   return errCode;
+    NTSTATUS errCode = STATUS_SUCCESS;
+    IO_STATUS_BLOCK IoStatusBlock;
+    FILE_BASIC_INFORMATION FileBasic;
+
+    errCode = NtQueryInformationFile (FileHandle,
+                                      &IoStatusBlock,
+                                      &FileBasic,
+                                      sizeof(FILE_BASIC_INFORMATION),
+                                      FileBasicInformation);
+    if (!NT_SUCCESS(errCode))
+    {
+        WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode);
+    }
+    else
+    {
+        FileBasic.LastWriteTime.QuadPart = LastWriteTime.QuadPart;
+        errCode = NtSetInformationFile (FileHandle,
+                                        &IoStatusBlock,
+                                        &FileBasic,
+                                        sizeof(FILE_BASIC_INFORMATION),
+                                        FileBasicInformation);
+        if (!NT_SUCCESS(errCode))
+        {
+            WARN("Error 0x%0x setting LastWriteTime\n", errCode);
+        }
+    }
+
+    return errCode;
 }
 
+BOOL
+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;
+    IO_STATUS_BLOCK IoStatusBlock;
+    FILE_STANDARD_INFORMATION FileStandard;
+    FILE_BASIC_INFORMATION FileBasic;
+    BOOL RC = FALSE;
+    BOOL KeepDestOnError = FALSE;
+    DWORD SystemError;
+
+    FileHandleSource = CreateFileW(lpExistingFileName,
+                                   GENERIC_READ,
+                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                   NULL,
+                                   OPEN_EXISTING,
+                                   FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
+                                   NULL);
+    if (INVALID_HANDLE_VALUE != FileHandleSource)
+    {
+        errCode = NtQueryInformationFile(FileHandleSource,
+                                         &IoStatusBlock,
+                                         &FileStandard,
+                                         sizeof(FILE_STANDARD_INFORMATION),
+                                         FileStandardInformation);
+        if (!NT_SUCCESS(errCode))
+        {
+            TRACE("Status 0x%08x obtaining FileStandardInformation for source\n", errCode);
+            BaseSetLastNTError(errCode);
+        }
+        else
+        {
+            errCode = NtQueryInformationFile(FileHandleSource,
+                                             &IoStatusBlock,&FileBasic,
+                                             sizeof(FILE_BASIC_INFORMATION),
+                                             FileBasicInformation);
+            if (!NT_SUCCESS(errCode))
+            {
+                TRACE("Status 0x%08x obtaining FileBasicInformation for source\n", errCode);
+                BaseSetLastNTError(errCode);
+            }
+            else
+            {
+                FileHandleDest = CreateFileW(lpNewFileName,
+                                             GENERIC_WRITE,
+                                             FILE_SHARE_WRITE,
+                                             NULL,
+                                             dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS,
+                                             FileBasic.FileAttributes,
+                                             NULL);
+                if (INVALID_HANDLE_VALUE != FileHandleDest)
+                {
+                    errCode = CopyLoop(FileHandleSource,
+                                       FileHandleDest,
+                                       FileStandard.EndOfFile,
+                                       lpProgressRoutine,
+                                       lpData,
+                                       pbCancel,
+                                       &KeepDestOnError);
+                    if (!NT_SUCCESS(errCode))
+                    {
+                        BaseSetLastNTError(errCode);
+                    }
+                    else
+                    {
+                        LARGE_INTEGER t;
+
+                        t.QuadPart = FileBasic.LastWriteTime.QuadPart;
+                        errCode = SetLastWriteTime(FileHandleDest, t);
+                        if (!NT_SUCCESS(errCode))
+                        {
+                            BaseSetLastNTError(errCode);
+                        }
+                        else
+                        {
+                            RC = TRUE;
+                        }
+                    }
+                    NtClose(FileHandleDest);
+                    if (! RC && ! KeepDestOnError)
+                    {
+                        SystemError = GetLastError();
+                        SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL);
+                        DeleteFileW(lpNewFileName);
+                        SetLastError(SystemError);
+                    }
+                }
+                else
+                {
+                    WARN("Error %lu during opening of dest file\n", GetLastError());
+                }
+            }
+        }
+        NtClose(FileHandleSource);
+    }
+    else
+    {
+        WARN("Error %lu during opening of source file\n", GetLastError());
+    }
+
+    return RC;
+}
 
 /*
  * @implemented
  */
 BOOL
 WINAPI
-CopyFileExW (
-       LPCWSTR                 lpExistingFileName,
-       LPCWSTR                 lpNewFileName,
-       LPPROGRESS_ROUTINE      lpProgressRoutine,
-       LPVOID                  lpData,
-       BOOL                    *pbCancel,
-       DWORD                   dwCopyFlags
-       )
+CopyFileExW(IN LPCWSTR lpExistingFileName,
+            IN LPCWSTR lpNewFileName,
+            IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
+            IN LPVOID lpData OPTIONAL,
+            IN LPBOOL pbCancel OPTIONAL,
+            IN DWORD dwCopyFlags)
 {
-   NTSTATUS errCode;
-   HANDLE FileHandleSource, FileHandleDest;
-   IO_STATUS_BLOCK IoStatusBlock;
-   FILE_STANDARD_INFORMATION FileStandard;
-   FILE_BASIC_INFORMATION FileBasic;
-   BOOL RC = FALSE;
-   BOOL KeepDestOnError = FALSE;
-   DWORD SystemError;
-
-   FileHandleSource = CreateFileW(lpExistingFileName,
-                                 GENERIC_READ,
-                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
-                                 NULL,
-                                 OPEN_EXISTING,
-                                 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
-                                 NULL);
-   if (INVALID_HANDLE_VALUE != FileHandleSource)
-     {
-       errCode = NtQueryInformationFile(FileHandleSource,
-                                        &IoStatusBlock,
-                                        &FileStandard,
-                                        sizeof(FILE_STANDARD_INFORMATION),
-                                        FileStandardInformation);
-       if (!NT_SUCCESS(errCode))
-         {
-            TRACE("Status 0x%08x obtaining FileStandardInformation for source\n", errCode);
-            BaseSetLastNTError(errCode);
-         }
-       else
-         {
-            errCode = NtQueryInformationFile(FileHandleSource,
-                                             &IoStatusBlock,&FileBasic,
-                                             sizeof(FILE_BASIC_INFORMATION),
-                                             FileBasicInformation);
-            if (!NT_SUCCESS(errCode))
-              {
-                 TRACE("Status 0x%08x obtaining FileBasicInformation for source\n", errCode);
-                 BaseSetLastNTError(errCode);
-              }
-            else
-              {
-                 FileHandleDest = CreateFileW(lpNewFileName,
-                                              GENERIC_WRITE,
-                                              FILE_SHARE_WRITE,
-                                              NULL,
-                                              dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS,
-                                               FileBasic.FileAttributes,
-                                              NULL);
-                 if (INVALID_HANDLE_VALUE != FileHandleDest)
-                   {
-                      errCode = CopyLoop(FileHandleSource,
-                                         FileHandleDest,
-                                         FileStandard.EndOfFile,
-                                         lpProgressRoutine,
-                                         lpData,
-                                         pbCancel,
-                                         &KeepDestOnError);
-                      if (!NT_SUCCESS(errCode))
-                        {
-                           BaseSetLastNTError(errCode);
-                        }
-                      else
-                        {
-                LARGE_INTEGER t;
-
-                           t.QuadPart = FileBasic.LastWriteTime.QuadPart;
-                           errCode = SetLastWriteTime(FileHandleDest, t);
-                           if (!NT_SUCCESS(errCode))
-                             {
-                                BaseSetLastNTError(errCode);
-                             }
-                           else
-                             {
-                                RC = TRUE;
-                             }
-                        }
-                      NtClose(FileHandleDest);
-                      if (! RC && ! KeepDestOnError)
-                        {
-                           SystemError = GetLastError();
-                           SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL);
-                           DeleteFileW(lpNewFileName);
-                           SetLastError(SystemError);
-                        }
-                   }
-                 else
-                   {
-                   WARN("Error %d during opening of dest file\n", GetLastError());
-                   }
-              }
-         }
-       NtClose(FileHandleSource);
-     }
-   else
-     {
-     WARN("Error %d during opening of source file\n", GetLastError());
-     }
-
-   return RC;
+    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;
 }
 
 
@@ -326,7 +368,7 @@ CopyFileExA(IN LPCSTR lpExistingFileName,
     PUNICODE_STRING lpExistingFileNameW;
 
     lpExistingFileNameW = Basep8BitStringToStaticUnicodeString(lpExistingFileName);
-    if (!lpExistingFileName)
+    if (!lpExistingFileNameW)
     {
         return FALSE;
     }
@@ -352,18 +394,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;
 }
 
 
@@ -372,18 +429,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));
 }
 
 
@@ -392,17 +447,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 */