Source code of Windows XP (NT5)
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.

210 lines
5.1 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. copy.c
  5. Abstract:
  6. This module contains the routine to copy a file.
  7. Author:
  8. Dan Hinsley (DanHi) 24-Feb-1991
  9. Revision History:
  10. 02-Feb-1994 Danl
  11. Fixed memory leak where ioBuffer wasn't getting free'd when doing
  12. an error exit from ElfpCopyFile.
  13. --*/
  14. //
  15. // INCLUDES
  16. //
  17. #include <eventp.h>
  18. NTSTATUS
  19. ElfpCopyFile (
  20. IN HANDLE SourceHandle,
  21. IN PUNICODE_STRING TargetFileName
  22. )
  23. /*++
  24. Routine Description:
  25. This routine copies or appends from the source file to the target file.
  26. If the target file already exists, the copy fails.
  27. Arguments:
  28. SourceHandle - An open handle to the source file.
  29. TargetFileName - The name of the file to copy to.
  30. Return Value:
  31. NTSTATUS - STATUS_SUCCESS or error.
  32. --*/
  33. {
  34. NTSTATUS Status;
  35. IO_STATUS_BLOCK IoStatusBlock;
  36. FILE_STANDARD_INFORMATION sourceStandardInfo;
  37. OBJECT_ATTRIBUTES ObjectAttributes;
  38. HANDLE TargetHandle;
  39. PCHAR ioBuffer;
  40. ULONG ioBufferSize;
  41. ULONG bytesRead;
  42. //
  43. // Get the size of the file so we can set the attributes of the target
  44. // file.
  45. //
  46. Status = NtQueryInformationFile(
  47. SourceHandle,
  48. &IoStatusBlock,
  49. &sourceStandardInfo,
  50. sizeof(sourceStandardInfo),
  51. FileStandardInformation
  52. );
  53. if (!NT_SUCCESS(Status))
  54. {
  55. ELF_LOG1(ERROR,
  56. "ElfpCopyFile: Unable to query size of source file %#x\n",
  57. Status);
  58. return Status;
  59. }
  60. //
  61. // Open the target file, fail if the file already exists.
  62. //
  63. InitializeObjectAttributes(
  64. &ObjectAttributes,
  65. TargetFileName,
  66. OBJ_CASE_INSENSITIVE,
  67. NULL,
  68. NULL
  69. );
  70. Status = NtCreateFile(&TargetHandle,
  71. GENERIC_WRITE | SYNCHRONIZE,
  72. &ObjectAttributes,
  73. &IoStatusBlock,
  74. &(sourceStandardInfo.EndOfFile),
  75. FILE_ATTRIBUTE_NORMAL,
  76. 0, // Share access
  77. FILE_CREATE,
  78. FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
  79. NULL, // EA buffer
  80. 0); // EA length
  81. if (!NT_SUCCESS(Status))
  82. {
  83. ELF_LOG2(ERROR,
  84. "ElfpCopyFile: NtCreateFile of file %ws failed %#x\n",
  85. TargetFileName->Buffer,
  86. Status);
  87. return Status;
  88. }
  89. //
  90. // Allocate a buffer to use for the data copy.
  91. //
  92. ioBufferSize = 4096;
  93. ioBuffer = ElfpAllocateBuffer (ioBufferSize);
  94. if (ioBuffer == NULL)
  95. {
  96. ELF_LOG1(ERROR,
  97. "ElfpCopyFile: Unable to allocate I/O buffer to copy file %ws\n",
  98. TargetFileName->Buffer);
  99. NtClose(TargetHandle);
  100. return STATUS_NO_MEMORY;
  101. }
  102. //
  103. // Copy data--read from source, write to target. Do this until
  104. // all the data is written or an error occurs.
  105. //
  106. while ( TRUE )
  107. {
  108. Status = NtReadFile(
  109. SourceHandle,
  110. NULL, // Event
  111. NULL, // ApcRoutine
  112. NULL, // ApcContext
  113. &IoStatusBlock,
  114. ioBuffer,
  115. ioBufferSize,
  116. NULL, // ByteOffset
  117. NULL); // Key
  118. if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
  119. {
  120. ELF_LOG1(ERROR,
  121. "ElfpCopyFile: NtReadFile of source file failed %#x\n",
  122. Status);
  123. ElfpFreeBuffer(ioBuffer);
  124. NtClose(TargetHandle);
  125. return Status;
  126. }
  127. if (IoStatusBlock.Information == 0 || Status == STATUS_END_OF_FILE)
  128. {
  129. break;
  130. }
  131. bytesRead = (ULONG)IoStatusBlock.Information;
  132. Status = NtWriteFile(
  133. TargetHandle,
  134. NULL, // Event
  135. NULL, // ApcRoutine
  136. NULL, // ApcContext
  137. &IoStatusBlock,
  138. ioBuffer,
  139. bytesRead,
  140. NULL, // ByteOffset
  141. NULL); // Key
  142. if (!NT_SUCCESS(Status))
  143. {
  144. ELF_LOG2(ERROR,
  145. "ElfpCopyFile: NtWriteFile to file %ws failed %#x\n",
  146. TargetFileName->Buffer,
  147. Status);
  148. ElfpFreeBuffer(ioBuffer);
  149. NtClose(TargetHandle);
  150. return Status;
  151. }
  152. }
  153. ElfpFreeBuffer (ioBuffer);
  154. Status = NtClose(TargetHandle);
  155. ASSERT(NT_SUCCESS(Status));
  156. return STATUS_SUCCESS;
  157. } // ElfpCopyFile