summaryrefslogtreecommitdiffstats
path: root/private/eventlog/server/copy.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/eventlog/server/copy.c')
-rw-r--r--private/eventlog/server/copy.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/private/eventlog/server/copy.c b/private/eventlog/server/copy.c
new file mode 100644
index 000000000..3344bc3e4
--- /dev/null
+++ b/private/eventlog/server/copy.c
@@ -0,0 +1,196 @@
+/*++
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ copy.c
+
+Abstract:
+
+ This module contains the routine to copy a file.
+
+Author:
+
+ Dan Hinsley (DanHi) 24-Feb-1991
+
+Revision History:
+
+ 02-Feb-1994 Danl
+ Fixed memory leak where ioBuffer wasn't getting free'd when doing
+ an error exit from ElfpCopyFile.
+
+--*/
+
+//
+// INCLUDES
+//
+
+#include <eventp.h>
+
+
+NTSTATUS
+ElfpCopyFile (
+ IN HANDLE SourceHandle,
+ IN PUNICODE_STRING TargetFileName
+ )
+
+/*++
+
+Routine Description:
+
+ This routine copies or appends from the source file to the target file.
+ If the target file already exists, the copy fails.
+
+Arguments:
+
+ SourceHandle - An open handle to the source file.
+
+ TargetFileName - The name of the file to copy to.
+
+
+Return Value:
+
+ NTSTATUS - STATUS_SUCCESS or error.
+
+--*/
+
+{
+
+ NTSTATUS Status;
+
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_STANDARD_INFORMATION sourceStandardInfo;
+
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE TargetHandle;
+
+ PCHAR ioBuffer;
+ ULONG ioBufferSize;
+ ULONG bytesRead;
+
+ //
+ // Get the size of the file so we can set the attributes of the target
+ // file.
+ //
+
+ Status = NtQueryInformationFile(
+ SourceHandle,
+ &IoStatusBlock,
+ &sourceStandardInfo,
+ sizeof(sourceStandardInfo),
+ FileStandardInformation
+ );
+
+ if ( !NT_SUCCESS(Status) ) {
+
+ return(Status);
+ }
+
+ //
+ // Open the target file, fail if the file already exists.
+ //
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ TargetFileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL
+ );
+
+ Status = NtCreateFile(&TargetHandle,
+ GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ &(sourceStandardInfo.EndOfFile),
+ FILE_ATTRIBUTE_NORMAL,
+ 0, // Share access
+ FILE_CREATE,
+ FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
+ NULL, // EA buffer
+ 0 // EA length
+ );
+
+ if (!NT_SUCCESS(Status)) {
+ return(Status);
+ }
+
+ //
+ // Allocate a buffer to use for the data copy.
+ //
+
+ ioBufferSize = 4096;
+
+ ioBuffer = ElfpAllocateBuffer ( ioBufferSize);
+
+ if ( ioBuffer == NULL ) {
+
+ return (STATUS_NO_MEMORY);
+ }
+
+ //
+ // Copy data--read from source, write to target. Do this until
+ // all the data is written or an error occurs.
+ //
+
+ while ( TRUE ) {
+
+ Status = NtReadFile(
+ SourceHandle,
+ NULL, // Event
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &IoStatusBlock,
+ ioBuffer,
+ ioBufferSize,
+ NULL, // ByteOffset
+ NULL // Key
+ );
+
+ if ( !NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE ) {
+
+ ElfDbgPrint(("[ELF] Copy failed reading source file - %X\n",
+ Status));
+ ElfpFreeBuffer(ioBuffer);
+ return (Status);
+
+ }
+
+ if ( IoStatusBlock.Information == 0 ||
+ Status == STATUS_END_OF_FILE ) {
+ break;
+ }
+
+ bytesRead = IoStatusBlock.Information;
+
+ Status = NtWriteFile(
+ TargetHandle,
+ NULL, // Event
+ NULL, // ApcRoutine
+ NULL, // ApcContext
+ &IoStatusBlock,
+ ioBuffer,
+ bytesRead,
+ NULL, // ByteOffset
+ NULL // Key
+ );
+
+ if ( !NT_SUCCESS(Status) ) {
+ ElfDbgPrint(("[ELF] Copy failed writing target file - %X\n",
+ Status));
+ ElfpFreeBuffer(ioBuffer);
+ return (Status);
+ }
+ }
+
+ ElfpFreeBuffer ( ioBuffer );
+
+ Status = NtClose(TargetHandle);
+
+ ASSERT(NT_SUCCESS(Status));
+
+ return STATUS_SUCCESS;
+
+} // ElfpCopyFile
+