Hello,
My minifilter does a file copy in its pre-read routine. When a MJ_READ
request comes for fileA whose content is empty, the filter copies data from
fileB to fileA and let the request continues. The problem is that if I read
fileA by DOS command type “c:\>type fileA”, it only shows the beginning part
content of the file. If I open it by Notepad.exe, it shows the whole content
of the file. Below is my file copy code. Please advise me what I can do
else. - Thanks.
BOOLEAN
MfCopyFile(
IN PFLT_CALLBACK_DATA Data,
IN PWSTR SrcFilePath
)
{
OBJECT_ATTRIBUTES objectAttr;
IO_STATUS_BLOCK ioStatusZW;
HANDLE hSrcFile;
PFILE_OBJECT ObSrcFile;
NTSTATUS status;
UNICODE_STRING fileName;
PFILTER_INSTANCE_CONTEXT instContext;
USHORT SectorSize;
// Get the context.
status = FltGetInstanceContext( Data->Iopb->SrcInstance,
&instContext );
if (!NT_SUCCESS(status))
{
return FALSE;
}
SectorSize = instContext->SectorSize;
// Release our reference on the context
FltReleaseContext( instContext );
// open the source file for copying its content
RtlInitUnicodeString(&fileName, SrcFilePath);
InitializeObjectAttributes(&objectAttr,
&fileName,
OBJ_KERNEL_HANDLE,
NULL,
NULL);
status = ZwOpenFile(&hSrcFile,
DELETE | SYNCHRONIZE | GENERIC_READ,
&objectAttr,
&ioStatusZW,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_COMPLETE_IF_OPLOCKED);
if (STATUS_SUCCESS != status)
{
return FALSE;
}
// get file’s handle
status = ObReferenceObjectByHandle(hSrcFile,
FILE_READ_ACCESS,
*IoFileObjectType,
KernelMode,
&ObSrcFile, 0);
if (STATUS_SUCCESS == status)
{
// copy file data
status = MfCopyData( Data->Iopb->SrcInstance, ObSrcFile,
Data->Iopb->SrcFileObject, 10 * SectorSize);
ObDereferenceObject(ObSrcFile);
// delete the source file if copy successful
if (STATUS_SUCCESS == status)
{
FILE_DISPOSITION_INFORMATION delInfo;
delInfo.DeleteFile = TRUE;
status = ZwSetInformationFile(hSrcFile,
&ioStatusZW, &delInfo, sizeof(delInfo),
FileDispositionInformation);
}
}
ZwClose(hSrcFile);
if (STATUS_SUCCESS != status)
return FALSE;
return TRUE;
}
NTSTATUS MfCopyData(
IN PFLT_INSTANCE Instance,
IN PFILE_OBJECT SrcFile,
IN PFILE_OBJECT DestFile,
IN USHORT BufferSize
)
{
PVOID buffer;
NTSTATUS status;
FILE_POSITION_INFORMATION posInfo;
// allocate copy buffer
buffer = FltAllocatePoolAlignedWithTag( Instance, NonPagedPool,
BufferSize, POOL_TAG );
if (NULL == buffer)
{
return STATUS_INSUFFICIENT_RESOURCES; // Allocation must have failed.
}
while (TRUE)
{
ULONG bytesRead = 0;
ULONG bytesWritten = 0;
status = FltReadFile( Instance, SrcFile, NULL,
BufferSize, buffer,
FLTFL_IO_OPERATION_NON_CACHED, &bytesRead, NULL, NULL );
if (!NT_SUCCESS(status) || 0 == bytesRead)
break;
// write data to destination file
status = FltWriteFile( Instance, DestFile, NULL,
bytesRead, buffer,
FLTFL_IO_OPERATION_NON_CACHED,
&bytesWritten, NULL, NULL );
if (!NT_SUCCESS(status) || bytesWritten != bytesRead)
break;
}
FltFreePoolAlignedWithTag( Instance, buffer, POOL_TAG );
// reset file pointer of destination file
posInfo.CurrentByteOffset.QuadPart = 0;
status = FltSetInformationFile( Instance, DestFile, &posInfo,
sizeof(posInfo), FilePositionInformation);
return status;
}