All good morning! The task is to write at zero-size file preliminary 4-bytes signature and to set endoffile in 4, then to skip irp further. Thus in a cache signature should not be, only on a disk. So, at first i receive IRP with flags 0xa00 - I skip it, marking for myself that with given FCB I will work. If I have correctly understood all, it is writing in a cache. Afterwards behind it there is a IRP with flags 0x43 - (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO). It, obviously, writing directly on a disk. In it I also insert the signature. So, I create IRP_MJ_WRITE with the signature, and after it send IRP_MJ_SET_INFORMATION, to shift end of a file on 4 units forwards. After all it I shift in parametres initial irp on 4 offset on which record will be carried out and easy I transfer control further. What problems - record like passes normally (status_success, and information=4) while precisely has not checked up since the data from a cache which in any case skips the signature further is permanently read. And here with shifting the end of a file of a problem - in IoStatus all on zero, i.e. no information is written. It also confirms the subsequent interception IRP_MJ_SET_INFORMATION which the system sends after original record. Here a code from DispatchWrite:
KeInitializeEvent(&event2, SynchronizationEvent, FALSE);
MyIrp = IoAllocateIrp(DeviceObject->StackSize,FALSE);
if(!MyIrp)
{
return ERROR_CREATE_IRP;
}
MyBuffer=(PVOID)ExAllocatePool(NonPagedPool,BUFFER_SIZE);
MyIrp->AssociatedIrp.SystemBuffer=MyBuffer;
if(pDiskDeviceExtension->DiskDeviceObject->Flags & DO_DIRECT_IO)
{
MyMDL=IoAllocateMdl(
MyBuffer,
4,
FALSE,
FALSE, // TRUE for highest level driver
MyIrp
);
if(MyMDL==NULL)
{
return ERROR_CREATE_IRP;
}
// MmBuildMdlForNonPagedPool(MyMDL);
// MmProbeAndLockPages(MyMDL, KernelMode,IoReadAccess);
}
MyIrp->UserEvent = &event2;
MyIrp->UserBuffer=MyBuffer;
MyIrp->Cancel=FALSE;
MyIrp->UserIosb = &IoStatusBlock;
MyIrp->Tail.Overlay.Thread = PsGetCurrentThread();
MyIrp->Tail.Overlay.OriginalFileObject = p_IO_STK->FileObject;
MyIrp->RequestorMode = KernelMode; // changed
MyIrp->Flags |= (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO);
RtlCopyMemory(MyBuffer,“ABCD”,4);
if(MyMDL!=NULL)
{
MmBuildMdlForNonPagedPool(MyMDL);
}
IoSetNextIrpStackLocation(MyIrp);
p_IO_NextSTK = IoGetCurrentIrpStackLocation(MyIrp);
p_IO_NextSTK->DeviceObject = DeviceObject;
p_IO_NextSTK->FileObject=p_IO_STK->FileObject;
p_IO_NextSTK =IoGetNextIrpStackLocation(MyIrp);
p_IO_NextSTK->MajorFunction=IRP_MJ_WRITE;
p_IO_NextSTK->MinorFunction = 0;
p_IO_NextSTK->DeviceObject = DeviceObject;
p_IO_NextSTK->FileObject=p_IO_STK->FileObject;
p_IO_NextSTK->Parameters.Write.Length = 4;
p_IO_NextSTK->Parameters.Write.ByteOffset.QuadPart = 0;
IoSetCompletionRoutine(MyIrp,
OnCreateWriteCompletion,
&DeviceObject,
TRUE,
TRUE,
TRUE);
IoCallDriver(((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject,MyIrp);
KeWaitForSingleObject(&event2, Executive, KernelMode, TRUE, 0);
KeClearEvent(&event2);
// ??? ??? ??? ???
KeInitializeEvent(&event2, SynchronizationEvent, FALSE);
MyIrp = IoAllocateIrp(DeviceObject->StackSize,FALSE);
if(!MyIrp)
{
return ERROR_CREATE_IRP;
}
MyBuffer=(PVOID)ExAllocatePool(NonPagedPool,sizeof(FILE_END_OF_FILE_INFORMATION));
((PFILE_END_OF_FILE_INFORMATION)MyBuffer)->EndOfFile.QuadPart=4;
MyIrp->AssociatedIrp.SystemBuffer=MyBuffer;
MyIrp->UserEvent = &event2;
MyIrp->UserBuffer=MyBuffer;
MyIrp->Cancel=FALSE;
MyIrp->UserIosb = &IoStatusBlock;
MyIrp->Tail.Overlay.Thread = PsGetCurrentThread();
MyIrp->Tail.Overlay.OriginalFileObject = p_IO_STK->FileObject;
MyIrp->RequestorMode = KernelMode;
// MyIrp->Flags = 0;
MyIrp->Flags |= (IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO);
IoSetNextIrpStackLocation(MyIrp);
p_IO_NextSTK =IoGetNextIrpStackLocation(MyIrp);
p_IO_NextSTK->MajorFunction=IRP_MJ_SET_INFORMATION;
p_IO_NextSTK->MinorFunction = 0;
p_IO_NextSTK->DeviceObject = DeviceObject;
p_IO_NextSTK->FileObject=p_IO_STK->FileObject;
p_IO_NextSTK->Parameters.SetFile.FileObject=0;
p_IO_NextSTK->Parameters.SetFile.Length=sizeof(FILE_END_OF_FILE_INFORMATION);
p_IO_NextSTK->Parameters.SetFile.ReplaceIfExists=FALSE;
p_IO_NextSTK->Parameters.SetFile.AdvanceOnly=TRUE;
p_IO_NextSTK->Parameters.SetFile.FileInformationClass=FileEndOfFileInformation;
IoSetCompletionRoutine(MyIrp,
OnSetCompletion,
&DeviceObject,
TRUE,
TRUE,
TRUE);
IoCallDriver(((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject,MyIrp);
KeWaitForSingleObject(&event2, Executive, KernelMode, TRUE, 0);
KeClearEvent(&event2);
if(p_IO_STK->Parameters.Write.ByteOffset.HighPart != -1)
{
p_IO_STK->Parameters.Write.ByteOffset.QuadPart+=4;
p_IO_STK->FileObject->CurrentByteOffset.QuadPart+=4;
}