diff options
Diffstat (limited to 'private/eventlog/server/copy.c')
-rw-r--r-- | private/eventlog/server/copy.c | 196 |
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 + |