Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. copyfile.c
  5. Abstract:
  6. InternalCopyFile - Copies a file retaining time and attributes
  7. Author:
  8. Matthew A Felton
  9. Revision History:
  10. Matthew Felton (mattfe) 27 March 1995
  11. --*/
  12. #include <precomp.h>
  13. #define FILE_SHARE_EXCLUSIVE 0
  14. #define BUFFER_SIZE 4096
  15. BOOL
  16. InternalCopyFile(
  17. HANDLE hSourceFile,
  18. PWIN32_FIND_DATA pSourceFileData,
  19. LPWSTR lpNewFileName,
  20. BOOL bFailIfExists
  21. )
  22. /*++
  23. Routine Description:
  24. Arguments:
  25. hSourceFile - SourceFile Handle
  26. pSourceFileData - Pointer to WIN32_FIND_DATA for the source file
  27. lpNewFileName - Supplies the name where a copy of the existing
  28. files data and attributes are to be stored.
  29. bFailIfExists - Supplies a flag that indicates how this operation is
  30. to proceed if the specified new file already exists. A value of
  31. TRUE specifies that this call is to fail. A value of FALSE
  32. causes the call to the function to succeed whether or not the
  33. specified new file exists.
  34. Return Value:
  35. TRUE - The operation was successful.
  36. FALSE/NULL - The operation failed. Extended error status is available
  37. using GetLastError.
  38. --*/
  39. {
  40. DWORD dwSourceFileAttributes;
  41. BOOL bReturnValue = FALSE;
  42. HANDLE hTargetFile = INVALID_HANDLE_VALUE;
  43. DWORD dwLowFileSize, dwHighFileSize;
  44. LPVOID pBuffer;
  45. DWORD cbBufferSize = BUFFER_SIZE;
  46. DWORD cbBytesRead;
  47. DWORD cbBytesWritten;
  48. DWORD dwSourceFilePointer;
  49. DWORD dwTargetFileAttributes;
  50. SPLASSERT( hSourceFile != NULL &&
  51. hSourceFile != INVALID_HANDLE_VALUE &&
  52. pSourceFileData != NULL &&
  53. lpNewFileName != NULL );
  54. #if DBG
  55. // <<<<< DEBUG ONLY >>>>>>
  56. //
  57. // ASSERTION Check Source File Pointer is Zero.
  58. //
  59. dwSourceFilePointer = SetFilePointer( hSourceFile, 0, NULL, FILE_CURRENT );
  60. if ( dwSourceFilePointer != 0xffffffff ) {
  61. SPLASSERT( dwSourceFilePointer == 0 );
  62. }
  63. #endif // DBG
  64. //
  65. // Alloc I/O Buffer
  66. //
  67. pBuffer = AllocSplMem( BUFFER_SIZE );
  68. if ( pBuffer == NULL )
  69. goto InternalCopyFileExit;
  70. //
  71. // Create TagetFile with same File Attributes except for READ ONLY attribute
  72. // which must be cleared.
  73. //
  74. dwTargetFileAttributes = pSourceFileData->dwFileAttributes & ~FILE_ATTRIBUTE_READONLY;
  75. if (pSourceFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY)
  76. {
  77. //
  78. // Clear the READ ONLY attribute if the corresponding source file attribute
  79. // is set. In fact at that point we don't know if the target file exists and
  80. // that is the reason to ignore the value returned by SetFileAttributes.
  81. // The file shouldn't exist on Whistler because of the dwTargetFileAttributes
  82. // value where the READ ONLY flag is cleared. There are slim chances to be there
  83. // if the machine was upgraded from W2K ( where the bug still exists) if on that
  84. // machine the driver was ever installed.
  85. //
  86. SetFileAttributes( lpNewFileName, dwTargetFileAttributes );
  87. }
  88. hTargetFile = CreateFile( lpNewFileName,
  89. GENERIC_WRITE,
  90. FILE_SHARE_EXCLUSIVE,
  91. NULL,
  92. bFailIfExists ? CREATE_NEW : CREATE_ALWAYS,
  93. dwTargetFileAttributes | FILE_FLAG_SEQUENTIAL_SCAN,
  94. NULL );
  95. if ( hTargetFile != INVALID_HANDLE_VALUE ) {
  96. //
  97. // Copy The Data
  98. //
  99. while (( bReturnValue = ReadFile( hSourceFile, pBuffer, cbBufferSize, &cbBytesRead, NULL )) &&
  100. cbBytesRead != 0 ) {
  101. //
  102. // Add Code to Build CheckSum Here
  103. //
  104. bReturnValue = WriteFile( hTargetFile, pBuffer, cbBytesRead, &cbBytesWritten, NULL );
  105. if ( bReturnValue == FALSE ||
  106. cbBytesWritten != cbBytesRead ) {
  107. bReturnValue = FALSE;
  108. break;
  109. }
  110. }
  111. if ( bReturnValue ) {
  112. //
  113. // Set TargetFile Times to be the same as the Source File
  114. //
  115. bReturnValue = SetFileTime( hTargetFile,
  116. &pSourceFileData->ftCreationTime,
  117. &pSourceFileData->ftLastAccessTime,
  118. &pSourceFileData->ftLastWriteTime );
  119. //
  120. // Verify that the file size is correct.
  121. //
  122. if ( bReturnValue ) {
  123. dwLowFileSize = GetFileSize( hTargetFile, &dwHighFileSize );
  124. if ( dwLowFileSize != pSourceFileData->nFileSizeLow ||
  125. dwHighFileSize != pSourceFileData->nFileSizeHigh ) {
  126. DBGMSG(DBG_ERROR,
  127. ("InternalCopyFile: sizes do not match for %ws: (%d %d) and (%d %d)",
  128. lpNewFileName,
  129. pSourceFileData->nFileSizeHigh,
  130. pSourceFileData->nFileSizeLow,
  131. dwHighFileSize,
  132. dwLowFileSize));
  133. bReturnValue = FALSE;
  134. SetLastError(ERROR_FILE_INVALID);
  135. }
  136. }
  137. //
  138. // Add Code here to Verify the CheckSum is correct.
  139. //
  140. }
  141. CloseHandle( hTargetFile );
  142. }
  143. FreeSplMem( pBuffer );
  144. InternalCopyFileExit:
  145. if ( !bReturnValue ) {
  146. DBGMSG( DBG_WARN, ("InternalCopyFile hSourceFile %x %ws error %d\n", hSourceFile, lpNewFileName, GetLastError() ));
  147. SPLASSERT( GetLastError() != ERROR_SUCCESS );
  148. }
  149. return bReturnValue;
  150. }