📄 kfc.c
字号:
// This function retrieves the "standard" information for the underlying file system.
//
// Inputs:
// FileObject - the file to retrieve information about
//
// Outputs:
// StandardInformation - the buffer where the data should be stored
// IoStatusBlock - information about what actually happened.
//
// Returns:
// None.
//
// Notes:
// This is equivalent to ZwQueryInformationFile, for FILE_STANDARD_INFORMATION
//
static VOID KfcGetFileStandardInformation(PFILE_OBJECT FileObject,
PFILE_STANDARD_INFORMATION StandardInformation,
PIO_STATUS_BLOCK IoStatusBlock)
{
PIRP irp;
PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
//
// Start off on the right foot - zero the information block.
//
RtlZeroMemory(StandardInformation, sizeof(FILE_STANDARD_INFORMATION));
//
// Allocate an irp for this request. This could also come from a
// private pool, for instance.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp) {
//
// Failure!
//
return;
}
irp->AssociatedIrp.SystemBuffer = StandardInformation;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->RequestorMode = KernelMode;
//
// Initialize the event
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Set up the I/O stack location.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
ioStackLocation->Parameters.QueryFile.Length = sizeof(FILE_STANDARD_INFORMATION);
ioStackLocation->Parameters.QueryFile.FileInformationClass = FileStandardInformation;
//
// Set the completion routine.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
//
// Send it to the FSD
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done!
//
return;
}
//
// KfcIoCompletion
//
// This routine is used to handle I/O (read OR write) completion
//
// Inputs:
// DeviceObject - not used
// Irp - the I/O operation being completed
// Context - not used
//
// Outputs:
// None.
//
// Returns:
// STATUS_MORE_PROCESSING_REQUIRED
//
// Notes:
// The purpose of this routine is to do "cleanup" on I/O operations
// so we don't constantly throw away perfectly good MDLs as part of
// completion processing.
//
static NTSTATUS KfcIoCompletion(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
//
// Copy the status information back into the "user" IOSB.
//
*Irp->UserIosb = Irp->IoStatus;
//
// Set the user event - wakes up the mainline code doing this.
//
KeSetEvent(Irp->UserEvent, 0, FALSE);
//
// Free the IRP now that we are done with it.
//
IoFreeIrp(Irp);
//
// We return STATUS_MORE_PROCESSING_REQUIRED because this "magic" return value
// tells the I/O Manager that additional processing will be done by this driver
// to the IRP - in fact, it might (as it is in this case) already BE done - and
// the IRP cannot be completed.
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
static VOID KfcRead(PFILE_OBJECT FileObject,
PLARGE_INTEGER Offset,
ULONG Length,
PMDL Mdl,
PIO_STATUS_BLOCK IoStatusBlock)
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);
//
// Set up the event we'll use.
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Allocate and build the IRP we'll be sending to the FSD.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp) {
//
// Allocation failed, presumably due to memory allocation failure.
//
IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = 0;
}
irp->MdlAddress = Mdl;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject= FileObject;
irp->RequestorMode = KernelMode;
//
// Indicate that this is a READ operation.
//
irp->Flags = IRP_READ_OPERATION;
//
// Set up the next I/O stack location. These are the parameters
// that will be passed to the underlying driver.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_READ;
ioStackLocation->MinorFunction = 0;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
//
// We use a completion routine to keep the I/O Manager from doing
// "cleanup" on our IRP - like freeing our MDL.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
ioStackLocation->Parameters.Read.Length = Length;
ioStackLocation->Parameters.Read.ByteOffset = *Offset;
//
// Send it on. Ignore the return code.
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O to complete.
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done. Return results are in the io status block.
//
return;
}
//
// KfcSetFileAllocation
//
// This routine sets a file's ALLOCATION size to the specified value.
// Note that this DOES NOT extend the file's EOF.
//
// Inputs:
// FileObject - the file on which to set the allocation size
// AllocationSize - the new allocation size
//
// Ouputs:
// IoStatusBlock - the results of this operation
//
// Returns:
// None.
//
// Notes:
// None.
static VOID KfcSetFileAllocation(PFILE_OBJECT FileObject,
PLARGE_INTEGER AllocationSize,
PIO_STATUS_BLOCK IoStatusBlock)
{
PIRP irp;
PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
//
// Allocate an irp for this request. This could also come from a
// private pool, for instance.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp) {
//
// Failure!
//
return;
}
irp->AssociatedIrp.SystemBuffer = AllocationSize;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->RequestorMode = KernelMode;
//
// Initialize the event
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Set up the I/O stack location.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_SET_INFORMATION;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
ioStackLocation->Parameters.SetFile.Length = sizeof(LARGE_INTEGER);
ioStackLocation->Parameters.SetFile.FileInformationClass = FileAllocationInformation;
ioStackLocation->Parameters.SetFile.FileObject = 0; // not used for allocation
ioStackLocation->Parameters.SetFile.AdvanceOnly = FALSE;
//
// Set the completion routine.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
//
// Send it to the FSD
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done!
//
return;
}
static VOID KfcWrite(PFILE_OBJECT FileObject,
PLARGE_INTEGER Offset,
ULONG Length,
PMDL Mdl,
PIO_STATUS_BLOCK IoStatusBlock)
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);
//
// Set up the event we'll use.
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Allocate and build the IRP we'll be sending to the FSD.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp) {
//
// Allocation failed, presumably due to memory allocation failure.
//
IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = 0;
}
irp->MdlAddress = Mdl;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject= FileObject;
irp->RequestorMode = KernelMode;
//
// Indicate that this is a WRITE operation.
//
irp->Flags = IRP_WRITE_OPERATION;
//
// Set up the next I/O stack location. These are the parameters
// that will be passed to the underlying driver.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_WRITE;
ioStackLocation->MinorFunction = 0;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
//
// We use a completion routine to keep the I/O Manager from doing
// "cleanup" on our IRP - like freeing our MDL.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
ioStackLocation->Parameters.Write.Length = Length;
ioStackLocation->Parameters.Write.ByteOffset = *Offset;
//
// Send it on. Ignore the return code.
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O to complete.
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done. Return results are in the io status block.
//
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -