ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

copy.c
Go to the documentation of this file.
00001 /* $Id: copy.c 55885 2012-02-27 17:10:44Z sir_richard $
00002  *
00003  * COPYRIGHT:       See COPYING in the top level directory
00004  * PROJECT:         ReactOS system libraries
00005  * FILE:            lib/kernel32/file/copy.c
00006  * PURPOSE:         Copying files
00007  * PROGRAMMER:      Ariadne (ariadne@xs4all.nl)
00008  * UPDATE HISTORY:
00009  *                  01/11/98 Created
00010  *                  07/02/99 Moved to seperate file
00011  */
00012 
00013 /* INCLUDES ****************************************************************/
00014 
00015 #include <k32.h>
00016 #define NDEBUG
00017 #include <debug.h>
00018 
00019 #if DBG
00020 DEBUG_CHANNEL(kernel32file);
00021 #endif
00022 
00023 /* FUNCTIONS ****************************************************************/
00024 
00025 
00026 static NTSTATUS
00027 CopyLoop (
00028     HANDLE          FileHandleSource,
00029     HANDLE          FileHandleDest,
00030     LARGE_INTEGER       SourceFileSize,
00031     LPPROGRESS_ROUTINE  lpProgressRoutine,
00032     LPVOID          lpData,
00033     BOOL            *pbCancel,
00034     BOOL                 *KeepDest
00035     )
00036 {
00037    NTSTATUS errCode;
00038    IO_STATUS_BLOCK IoStatusBlock;
00039    UCHAR *lpBuffer = NULL;
00040    SIZE_T RegionSize = 0x10000;
00041    LARGE_INTEGER BytesCopied;
00042    DWORD CallbackReason;
00043    DWORD ProgressResult;
00044    BOOL EndOfFileFound;
00045 
00046    *KeepDest = FALSE;
00047    errCode = NtAllocateVirtualMemory(NtCurrentProcess(),
00048                      (PVOID *)&lpBuffer,
00049                      0,
00050                      &RegionSize,
00051                      MEM_RESERVE | MEM_COMMIT,
00052                      PAGE_READWRITE);
00053 
00054    if (NT_SUCCESS(errCode))
00055      {
00056     BytesCopied.QuadPart = 0;
00057     EndOfFileFound = FALSE;
00058     CallbackReason = CALLBACK_STREAM_SWITCH;
00059     while (! EndOfFileFound &&
00060            NT_SUCCESS(errCode) &&
00061            (NULL == pbCancel || ! *pbCancel))
00062       {
00063          if (NULL != lpProgressRoutine)
00064            {
00065            ProgressResult = (*lpProgressRoutine)(SourceFileSize,
00066                              BytesCopied,
00067                              SourceFileSize,
00068                              BytesCopied,
00069                              0,
00070                              CallbackReason,
00071                              FileHandleSource,
00072                              FileHandleDest,
00073                              lpData);
00074            switch (ProgressResult)
00075              {
00076              case PROGRESS_CANCEL:
00077             TRACE("Progress callback requested cancel\n");
00078             errCode = STATUS_REQUEST_ABORTED;
00079             break;
00080              case PROGRESS_STOP:
00081             TRACE("Progress callback requested stop\n");
00082             errCode = STATUS_REQUEST_ABORTED;
00083             *KeepDest = TRUE;
00084             break;
00085              case PROGRESS_QUIET:
00086             lpProgressRoutine = NULL;
00087             break;
00088              case PROGRESS_CONTINUE:
00089              default:
00090             break;
00091              }
00092            CallbackReason = CALLBACK_CHUNK_FINISHED;
00093            }
00094          if (NT_SUCCESS(errCode))
00095            {
00096           errCode = NtReadFile(FileHandleSource,
00097                        NULL,
00098                        NULL,
00099                        NULL,
00100                        (PIO_STATUS_BLOCK)&IoStatusBlock,
00101                        lpBuffer,
00102                        RegionSize,
00103                        NULL,
00104                        NULL);
00105           if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel))
00106             {
00107                errCode = NtWriteFile(FileHandleDest,
00108                          NULL,
00109                          NULL,
00110                          NULL,
00111                          (PIO_STATUS_BLOCK)&IoStatusBlock,
00112                          lpBuffer,
00113                          IoStatusBlock.Information,
00114                          NULL,
00115                          NULL);
00116                if (NT_SUCCESS(errCode))
00117              {
00118                 BytesCopied.QuadPart += IoStatusBlock.Information;
00119              }
00120                else
00121              {
00122                 WARN("Error 0x%08x reading writing to dest\n", errCode);
00123              }
00124             }
00125           else if (!NT_SUCCESS(errCode))
00126             {
00127                if (STATUS_END_OF_FILE == errCode)
00128              {
00129                 EndOfFileFound = TRUE;
00130                 errCode = STATUS_SUCCESS;
00131              }
00132                else
00133              {
00134                 WARN("Error 0x%08x reading from source\n", errCode);
00135              }
00136             }
00137            }
00138       }
00139 
00140     if (! EndOfFileFound && (NULL != pbCancel && *pbCancel))
00141       {
00142       TRACE("User requested cancel\n");
00143       errCode = STATUS_REQUEST_ABORTED;
00144       }
00145 
00146     NtFreeVirtualMemory(NtCurrentProcess(),
00147                 (PVOID *)&lpBuffer,
00148                 &RegionSize,
00149                 MEM_RELEASE);
00150      }
00151    else
00152      {
00153     TRACE("Error 0x%08x allocating buffer of %d bytes\n", errCode, RegionSize);
00154      }
00155 
00156    return errCode;
00157 }
00158 
00159 static NTSTATUS
00160 SetLastWriteTime(
00161     HANDLE FileHandle,
00162     LARGE_INTEGER LastWriteTime
00163     )
00164 {
00165    NTSTATUS errCode = STATUS_SUCCESS;
00166    IO_STATUS_BLOCK IoStatusBlock;
00167    FILE_BASIC_INFORMATION FileBasic;
00168 
00169    errCode = NtQueryInformationFile (FileHandle,
00170                      &IoStatusBlock,
00171                      &FileBasic,
00172                      sizeof(FILE_BASIC_INFORMATION),
00173                      FileBasicInformation);
00174    if (!NT_SUCCESS(errCode))
00175      {
00176     WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode);
00177      }
00178    else
00179      {
00180     FileBasic.LastWriteTime.QuadPart = LastWriteTime.QuadPart;
00181     errCode = NtSetInformationFile (FileHandle,
00182                     &IoStatusBlock,
00183                     &FileBasic,
00184                     sizeof(FILE_BASIC_INFORMATION),
00185                     FileBasicInformation);
00186     if (!NT_SUCCESS(errCode))
00187       {
00188          WARN("Error 0x%0x setting LastWriteTime\n", errCode);
00189       }
00190      }
00191 
00192    return errCode;
00193 }
00194 
00195 
00196 /*
00197  * @implemented
00198  */
00199 BOOL
00200 WINAPI
00201 CopyFileExW (
00202     LPCWSTR         lpExistingFileName,
00203     LPCWSTR         lpNewFileName,
00204     LPPROGRESS_ROUTINE  lpProgressRoutine,
00205     LPVOID          lpData,
00206     BOOL            *pbCancel,
00207     DWORD           dwCopyFlags
00208     )
00209 {
00210    NTSTATUS errCode;
00211    HANDLE FileHandleSource, FileHandleDest;
00212    IO_STATUS_BLOCK IoStatusBlock;
00213    FILE_STANDARD_INFORMATION FileStandard;
00214    FILE_BASIC_INFORMATION FileBasic;
00215    BOOL RC = FALSE;
00216    BOOL KeepDestOnError = FALSE;
00217    DWORD SystemError;
00218 
00219    FileHandleSource = CreateFileW(lpExistingFileName,
00220                   GENERIC_READ,
00221                   FILE_SHARE_READ | FILE_SHARE_WRITE,
00222                   NULL,
00223                   OPEN_EXISTING,
00224                   FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
00225                   NULL);
00226    if (INVALID_HANDLE_VALUE != FileHandleSource)
00227      {
00228     errCode = NtQueryInformationFile(FileHandleSource,
00229                      &IoStatusBlock,
00230                      &FileStandard,
00231                      sizeof(FILE_STANDARD_INFORMATION),
00232                      FileStandardInformation);
00233     if (!NT_SUCCESS(errCode))
00234       {
00235          TRACE("Status 0x%08x obtaining FileStandardInformation for source\n", errCode);
00236          BaseSetLastNTError(errCode);
00237       }
00238     else
00239       {
00240          errCode = NtQueryInformationFile(FileHandleSource,
00241                           &IoStatusBlock,&FileBasic,
00242                           sizeof(FILE_BASIC_INFORMATION),
00243                           FileBasicInformation);
00244          if (!NT_SUCCESS(errCode))
00245            {
00246           TRACE("Status 0x%08x obtaining FileBasicInformation for source\n", errCode);
00247           BaseSetLastNTError(errCode);
00248            }
00249          else
00250            {
00251           FileHandleDest = CreateFileW(lpNewFileName,
00252                            GENERIC_WRITE,
00253                            FILE_SHARE_WRITE,
00254                            NULL,
00255                            dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS,
00256                                                FileBasic.FileAttributes,
00257                            NULL);
00258           if (INVALID_HANDLE_VALUE != FileHandleDest)
00259             {
00260                errCode = CopyLoop(FileHandleSource,
00261                       FileHandleDest,
00262                       FileStandard.EndOfFile,
00263                       lpProgressRoutine,
00264                       lpData,
00265                       pbCancel,
00266                       &KeepDestOnError);
00267                if (!NT_SUCCESS(errCode))
00268              {
00269                 BaseSetLastNTError(errCode);
00270              }
00271                else
00272              {
00273                 LARGE_INTEGER t;
00274 
00275                 t.QuadPart = FileBasic.LastWriteTime.QuadPart;
00276                 errCode = SetLastWriteTime(FileHandleDest, t);
00277                 if (!NT_SUCCESS(errCode))
00278                   {
00279                  BaseSetLastNTError(errCode);
00280                   }
00281                 else
00282                   {
00283                  RC = TRUE;
00284                   }
00285              }
00286                NtClose(FileHandleDest);
00287                if (! RC && ! KeepDestOnError)
00288              {
00289                 SystemError = GetLastError();
00290                 SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL);
00291                 DeleteFileW(lpNewFileName);
00292                 SetLastError(SystemError);
00293              }
00294             }
00295           else
00296             {
00297             WARN("Error %d during opening of dest file\n", GetLastError());
00298             }
00299            }
00300       }
00301     NtClose(FileHandleSource);
00302      }
00303    else
00304      {
00305      WARN("Error %d during opening of source file\n", GetLastError());
00306      }
00307 
00308    return RC;
00309 }
00310 
00311 
00312 /*
00313  * @implemented
00314  */
00315 BOOL
00316 WINAPI
00317 CopyFileExA(IN LPCSTR lpExistingFileName,
00318             IN LPCSTR lpNewFileName,
00319             IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
00320             IN LPVOID lpData OPTIONAL,
00321             IN LPBOOL pbCancel OPTIONAL,
00322             IN DWORD dwCopyFlags)
00323 {
00324     BOOL Result = FALSE;
00325     UNICODE_STRING lpNewFileNameW;
00326     PUNICODE_STRING lpExistingFileNameW;
00327 
00328     lpExistingFileNameW = Basep8BitStringToStaticUnicodeString(lpExistingFileName);
00329     if (!lpExistingFileName)
00330     {
00331         return FALSE;
00332     }
00333 
00334     if (Basep8BitStringToDynamicUnicodeString(&lpNewFileNameW, lpNewFileName))
00335     {
00336         Result = CopyFileExW(lpExistingFileNameW->Buffer,
00337                              lpNewFileNameW.Buffer,
00338                              lpProgressRoutine,
00339                              lpData,
00340                              pbCancel,
00341                              dwCopyFlags);
00342 
00343         RtlFreeUnicodeString(&lpNewFileNameW);
00344     }
00345 
00346     return Result;
00347 }
00348 
00349 
00350 /*
00351  * @implemented
00352  */
00353 BOOL
00354 WINAPI
00355 CopyFileA (
00356     LPCSTR  lpExistingFileName,
00357     LPCSTR  lpNewFileName,
00358     BOOL    bFailIfExists
00359     )
00360 {
00361     return CopyFileExA (lpExistingFileName,
00362                         lpNewFileName,
00363                         NULL,
00364                         NULL,
00365                         NULL,
00366                         bFailIfExists);
00367 }
00368 
00369 
00370 /*
00371  * @implemented
00372  */
00373 BOOL
00374 WINAPI
00375 CopyFileW (
00376     LPCWSTR lpExistingFileName,
00377     LPCWSTR lpNewFileName,
00378     BOOL    bFailIfExists
00379     )
00380 {
00381     return CopyFileExW (lpExistingFileName,
00382                         lpNewFileName,
00383                         NULL,
00384                         NULL,
00385                         NULL,
00386                         bFailIfExists);
00387 }
00388 
00389 
00390 /*
00391  * @implemented
00392  */
00393 BOOL
00394 WINAPI
00395 PrivCopyFileExW (
00396     LPCWSTR         lpExistingFileName,
00397     LPCWSTR         lpNewFileName,
00398     LPPROGRESS_ROUTINE  lpProgressRoutine,
00399     LPVOID          lpData,
00400     BOOL            *pbCancel,
00401     DWORD           dwCopyFlags
00402     )
00403 {
00404     UNIMPLEMENTED;
00405     return FALSE;
00406 }
00407 
00408 /* EOF */

Generated on Wed May 23 2012 04:16:17 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.