DDK示例中的代码。
NTSTATUS
FltReadSectors(
IN PDEVICE_OBJECT DeviceObject,
OUT PVOID Buffer,
IN ULONG Length,
IN LONGLONG ByteOffset,
IN BOOLEAN Wait
)
/*++
Routine Description:
This routine tries to read the data from the disk.
Arguments:
DeviceObject - the lower device in the stack
Buffer - the buffer which hold the data
Length - the data length want to read
ByteOffset - the data offset on the disk
Return Value:
NT Status is returned.
--*/
{
PIRP irp;
IO_STATUS_BLOCK iosb;
KEVENT event;
NTSTATUS status;
irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, DeviceObject,
Buffer, Length, (PLARGE_INTEGER) &ByteOffset, &iosb);
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Wait) {
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
&event, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject, irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = iosb.Status;
}
} else {
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
NULL, TRUE, TRUE, TRUE);
irp->UserIosb = NULL;
status = IoCallDriver(DeviceObject, irp);
}
return status;
}
NTSTATUS
FltWriteSectors(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Buffer,
IN ULONG Length,
IN LONGLONG ByteOffset,
IN BOOLEAN Wait
)
/*++
Routine Description:
This routine tries to write the data to the disk.
Arguments:
DeviceObject - the lower device in the stack
Buffer - the buffer which hold the data
Length - the data length want to read
ByteOffset - the data offset on the disk
Return Value:
NT Status is returned.
--*/
{
PIRP irp;
IO_STATUS_BLOCK iosb;
KEVENT event;
NTSTATUS status;
irp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE, DeviceObject,
Buffer, Length, (PLARGE_INTEGER) &ByteOffset, &iosb);
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Wait) {
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
&event, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject, irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = iosb.Status;
}
} else {
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
NULL, TRUE, TRUE, TRUE);
irp->UserIosb = NULL;
status = IoCallDriver(DeviceObject, irp);
}
return status;
}
NTSTATUS
FltReadWriteSectorsCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
A completion routine for use when calling the lower device objects to
which our filter deviceobject is attached.
Arguments:
DeviceObject - Pointer to deviceobject
Irp - Pointer to a PnP Irp.
Context - NULL or PKEVENT
Return Value:
NT Status is returned.
--*/
{
PMDL mdl;
UNREFERENCED_PARAMETER(DeviceObject);
//
// Free resources
//
if (Irp->AssociatedIrp.SystemBuffer && (Irp->Flags & IRP_DEALLOCATE_BUFFER)) {
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
}
while (Irp->MdlAddress) {
mdl = Irp->MdlAddress;
Irp->MdlAddress = mdl->Next;
MmUnlockPages(mdl);
IoFreeMdl(mdl);
}
if (Irp->PendingReturned && (Context != NULL)) {
*Irp->UserIosb = Irp->IoStatus;
KeSetEvent((PKEVENT) Context, IO_DISK_INCREMENT, FALSE);
}
IoFreeIrp(Irp);
//
// Don't touch irp any more
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
FltReadSectors(
IN PDEVICE_OBJECT DeviceObject,
OUT PVOID Buffer,
IN ULONG Length,
IN LONGLONG ByteOffset,
IN BOOLEAN Wait
)
/*++
Routine Description:
This routine tries to read the data from the disk.
Arguments:
DeviceObject - the lower device in the stack
Buffer - the buffer which hold the data
Length - the data length want to read
ByteOffset - the data offset on the disk
Return Value:
NT Status is returned.
--*/
{
PIRP irp;
IO_STATUS_BLOCK iosb;
KEVENT event;
NTSTATUS status;
irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, DeviceObject,
Buffer, Length, (PLARGE_INTEGER) &ByteOffset, &iosb);
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Wait) {
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
&event, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject, irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = iosb.Status;
}
} else {
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
NULL, TRUE, TRUE, TRUE);
irp->UserIosb = NULL;
status = IoCallDriver(DeviceObject, irp);
}
return status;
}
NTSTATUS
FltWriteSectors(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Buffer,
IN ULONG Length,
IN LONGLONG ByteOffset,
IN BOOLEAN Wait
)
/*++
Routine Description:
This routine tries to write the data to the disk.
Arguments:
DeviceObject - the lower device in the stack
Buffer - the buffer which hold the data
Length - the data length want to read
ByteOffset - the data offset on the disk
Return Value:
NT Status is returned.
--*/
{
PIRP irp;
IO_STATUS_BLOCK iosb;
KEVENT event;
NTSTATUS status;
irp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE, DeviceObject,
Buffer, Length, (PLARGE_INTEGER) &ByteOffset, &iosb);
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Wait) {
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
&event, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject, irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = iosb.Status;
}
} else {
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
NULL, TRUE, TRUE, TRUE);
irp->UserIosb = NULL;
status = IoCallDriver(DeviceObject, irp);
}
return status;
}
NTSTATUS
FltReadWriteSectorsCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
A completion routine for use when calling the lower device objects to
which our filter deviceobject is attached.
Arguments:
DeviceObject - Pointer to deviceobject
Irp - Pointer to a PnP Irp.
Context - NULL or PKEVENT
Return Value:
NT Status is returned.
--*/
{
PMDL mdl;
UNREFERENCED_PARAMETER(DeviceObject);
//
// Free resources
//
if (Irp->AssociatedIrp.SystemBuffer && (Irp->Flags & IRP_DEALLOCATE_BUFFER)) {
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
}
while (Irp->MdlAddress) {
mdl = Irp->MdlAddress;
Irp->MdlAddress = mdl->Next;
MmUnlockPages(mdl);
IoFreeMdl(mdl);
}
if (Irp->PendingReturned && (Context != NULL)) {
*Irp->UserIosb = Irp->IoStatus;
KeSetEvent((PKEVENT) Context, IO_DISK_INCREMENT, FALSE);
}
IoFreeIrp(Irp);
//
// Don't touch irp any more
//
return STATUS_MORE_PROCESSING_REQUIRED;
}