Hey, as I have seen many posts concerning copying files i have took some time to write a file copy function for legacy drivers that can be used with very few changes (the DeviceObject part has to be adjusted)…
The good thing, its not gonna reenter your create file dispatch routines.
Anyway, I hope I could help you a little bit:
VOID CagaraCopyFile(PUNICODE_STRING source, PUNICODE_STRING destination, PDEVICE_OBJECT devExt)
{
/* STATUS BLOCKS NEEDED FOR FILECOPY */
IO_STATUS_BLOCK iosbWrite;
IO_STATUS_BLOCK iosbRead;
IO_STATUS_BLOCK iosbOpenWrite;
IO_STATUS_BLOCK iosbOpenRead;
/* OBJATTR’s NEEDED FOR FILECOPY */
OBJECT_ATTRIBUTES objAttrOpen;
OBJECT_ATTRIBUTES objAttrWrite;
/* STATUS CODES FOR FILECOPY */
NTSTATUS statusWrite;
NTSTATUS statusRead;
/* HANDLE FOR FILE COPY */
HANDLE handleRead=NULL;
HANDLE handleWrite=NULL;
/* LARGE INTEGER TO SAVE CURRENT POINTER POSITION */
LARGE_INTEGER byteOffset;
/* READ BUFFER */
PCHAR pBuffer = (PCHAR)ExAllocatePool(NonPagedPool,128); // 64 chars buffer, 128 bytes shouldnt fill the Stack and still work fast
/* Device Object */
PSFILTER_DEVICE_EXTENSION devExtMy = (PSFILTER_DEVICE_EXTENSION)(devExt->DeviceExtension);
/* INIT THE FILECOPY OBJATTR’s */
InitializeObjectAttributes(&objAttrOpen, source,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, NULL);
InitializeObjectAttributes(&objAttrWrite, destination,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, NULL);
// Open Handles to both, original file and new file
statusWrite = IoCreateFileSpecifyDeviceObjectHint(&handleWrite,
GENERIC_WRITE,
&objAttrWrite, &iosbOpenWrite, NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OVERWRITE_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL, 0, /* FROM NOW ON ADDITIONAL PARAMETERS*/ CreateFileTypeNone, NULL, 0, devExtMy->NLExtHeader.AttachedToDeviceObject);
statusRead = IoCreateFileSpecifyDeviceObjectHint(&handleRead,
GENERIC_READ,
&objAttrOpen, &iosbOpenRead,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL, 0, /* FROM NOW ON ADDITIONAL PARAMETERS*/ CreateFileTypeNone, NULL, 0, devExtMy->NLExtHeader.AttachedToDeviceObject);
/* HERE COMES THE ACTUAL COPY LOOK */
if(NT_SUCCESS(statusRead) && NT_SUCCESS(statusWrite))
{
byteOffset.LowPart = byteOffset.HighPart = 0;
do
{
RtlZeroMemory(pBuffer,128);
statusRead = ZwReadFile(handleRead, NULL, NULL, NULL, &iosbRead,
pBuffer, 128, &byteOffset, NULL);
byteOffset.LowPart+=128;
statusWrite = ZwWriteFile(handleWrite, NULL, NULL, NULL, &iosbWrite,
pBuffer, safeWrite, NULL, NULL);
}
while(NT_SUCCESS(statusRead));
}
/* DONT FORGET TO CLOSE BOTH HANDLES */
ZwClose(handleWrite);
ZwClose(handleRead);
// FREE THE BUFFER
ExFreePool(pBuffer); // Important so we dont fill up the Stack
/* FILE COPY DONE */
}