?? fpfilter.c
字號(hào):
//
// if removing last paging device, need to set DO_POWER_PAGABLE
// bit here, and possible re-set it below on failure.
//
setPagable = FALSE;
if (!irpStack->Parameters.UsageNotification.InPath &&
deviceExtension->PagingPathCount == 1 ) {
//
// removing the last paging file
// must have DO_POWER_PAGABLE bits set
//
if (TEST_FLAG(DeviceObject->Flags, DO_POWER_INRUSH)) {
DebugPrint((3, "FPFilterDispatchPnp: last paging file "
"removed but DO_POWER_INRUSH set, so not "
"setting PAGABLE bit "
"for DO %p\n", DeviceObject));
} else {
DebugPrint((2, "FPFilterDispatchPnp: Setting PAGABLE "
"bit for DO %p\n", DeviceObject));
SET_FLAG(DeviceObject->Flags, DO_POWER_PAGABLE);
setPagable = TRUE;
}
}
//
// send the irp synchronously
//
status = FPFilterForwardIrpSynchronous(DeviceObject, Irp);
//
// now deal with the failure and success cases.
// note that we are not allowed to fail the irp
// once it is sent to the lower drivers.
//
if (NT_SUCCESS(status)) {
IoAdjustPagingPathCount(
&deviceExtension->PagingPathCount,
irpStack->Parameters.UsageNotification.InPath);
if (irpStack->Parameters.UsageNotification.InPath) {
if (deviceExtension->PagingPathCount == 1) {
//
// first paging file addition
//
DebugPrint((3, "FPFilterDispatchPnp: Clearing PAGABLE bit "
"for DO %p\n", DeviceObject));
CLEAR_FLAG(DeviceObject->Flags, DO_POWER_PAGABLE);
}
}
} else {
//
// cleanup the changes done above
//
if (setPagable == TRUE) {
CLEAR_FLAG(DeviceObject->Flags, DO_POWER_PAGABLE);
setPagable = FALSE;
}
}
//
// set the event so the next one can occur.
//
KeSetEvent(&deviceExtension->PagingPathCountEvent,
IO_NO_INCREMENT, FALSE);
}
default:
{
DebugPrint((3,
"FPFilterDispatchPnp: Forwarding irp"));
//
// Simply forward all other Irps
//
IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);
lockHeld = FALSE;
status = FPFilterSendToNextDriver(DeviceObject, Irp);
irpCompleted = TRUE;
}
}
if (! irpCompleted)
{
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
if (lockHeld)
{
IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);
}
return status;
} // end FPFilterDispatchPnp()
NTSTATUS
FPFilterIrpCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
Forwarded IRP completion routine. Set an event and return
STATUS_MORE_PROCESSING_REQUIRED. Irp forwarder will wait on this
event and then re-complete the irp after cleaning up.
Arguments:
DeviceObject is the device object of the WMI driver
Irp is the WMI irp that was just completed
Context is a PKEVENT that forwarder will wait on
Return Value:
STATUS_MORE_PORCESSING_REQUIRED
--*/
{
PKEVENT Event = (PKEVENT) Context;
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(Irp);
KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
return(STATUS_MORE_PROCESSING_REQUIRED);
} // end FPFilterIrpCompletion()
NTSTATUS
FPFilterStartDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called when a Pnp Start Irp is received.
It will schedule a completion routine to initialize and register with WMI.
Arguments:
DeviceObject - a pointer to the device object
Irp - a pointer to the irp
Return Value:
Status of processing the Start Irp
--*/
{
PDEVICE_EXTENSION deviceExtension;
KEVENT event;
NTSTATUS status;
PAGED_CODE();
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
status = FPFilterForwardIrpSynchronous(DeviceObject, Irp);
FPFilterSyncFilterWithTarget(DeviceObject,
deviceExtension->TargetDeviceObject);
return status;
}
NTSTATUS
FPFilterRemoveDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called when the device is to be removed.
It will de-register itself from WMI first, detach itself from the
stack before deleting itself.
Arguments:
DeviceObject - a pointer to the device object
Irp - a pointer to the irp
Return Value:
Status of removing the device
--*/
{
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
PAGED_CODE();
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
status = FPFilterForwardIrpSynchronous(DeviceObject, Irp);
IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock, Irp);
IoDetachDevice(deviceExtension->TargetDeviceObject);
IoDeleteDevice(DeviceObject);
return status;
}
NTSTATUS
FPFilterSendToNextDriver(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine sends the Irp to the next driver in line
when the Irp is not processed by this driver.
Arguments:
DeviceObject
Irp
Return Value:
NTSTATUS
--*/
{
PDEVICE_EXTENSION deviceExtension;
IoSkipCurrentIrpStackLocation(Irp);
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
return IoCallDriver(deviceExtension->TargetDeviceObject, Irp);
} // end FPFilterSendToNextDriver()
NTSTATUS
FPFilterDispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension;
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
return PoCallDriver(deviceExtension->TargetDeviceObject, Irp);
} // end FPFilterDispatchPower
NTSTATUS
FPFilterForwardIrpSynchronous(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine sends the Irp to the next driver in line
when the Irp needs to be processed by the lower drivers
prior to being processed by this one.
Arguments:
DeviceObject
Irp
Return Value:
NTSTATUS
--*/
{
PDEVICE_EXTENSION deviceExtension;
KEVENT event;
NTSTATUS status;
KeInitializeEvent(&event, NotificationEvent, FALSE);
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//
// copy the irpstack for the next device
//
IoCopyCurrentIrpStackLocationToNext(Irp);
//
// set a completion routine
//
IoSetCompletionRoutine(Irp, FPFilterIrpCompletion,
&event, TRUE, TRUE, TRUE);
//
// call the next lower device
//
status = IoCallDriver(deviceExtension->TargetDeviceObject, Irp);
//
// wait for the actual completion
//
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = Irp->IoStatus.Status;
}
return status;
} // end FPFilterForwardIrpSynchronous()
NTSTATUS
FPFilterDeviceControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
/*++
Routine Description:
This device control dispatcher handles only the failure prediction
device control. All others are passed down to the disk drivers.
Arguments:
DeviceObject - Context for the activity.
Irp - The device control argument block.
Return Value:
Status is returned.
--*/
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
PSTORAGE_PREDICT_FAILURE checkFailure;
NTSTATUS status;
DebugPrint((2, "FPFilterDeviceControl: DeviceObject %X Irp %X\n",
DeviceObject, Irp));
//
// Acquire the remove lock so that device will not be removed while
// processing this irp.
//
status = IoAcquireRemoveLock(&deviceExtension->RemoveLock, Irp);
if (!NT_SUCCESS(status))
{
DebugPrint((3, "FpFilterDeviceControl: Remove lock failed IOCTL Irp type [%x]\n",
currentIrpStack->Parameters.DeviceIoControl.IoControlCode));
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
if (currentIrpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_STORAGE_PREDICT_FAILURE)
{
//
// Verify user buffer is large enough for the failure prediction data
//
if (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(STORAGE_PREDICT_FAILURE))
{
//
// Indicate unsuccessful status and no data transferred.
//
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = sizeof(STORAGE_PREDICT_FAILURE);
} else {
//
// If underlying device stack supports failure prediction then
// most likely there is another filter driver and/or support for
// SMART in the disk stack. We'll call down to get its opinion
// first before making our own decision as to if the device
// is predicting failure.
status = FPFilterForwardIrpSynchronous(DeviceObject, Irp);
//
// Here we decide if we want to predict whether the device
// will fail or not. We can do many interesting things such
// as sending a hardware request to the physical device,
// doing some statistical analysis, whatever makes sense for
// the device in question.
//
checkFailure = Irp->AssociatedIrp.SystemBuffer;
if (NT_SUCCESS(status))
{
//
// Since a driver lower on the stack has an opinion then we
// abide by it. We could also do more sophisticated analysis
} else {
RtlZeroMemory(checkFailure, sizeof(STORAGE_PREDICT_FAILURE));
checkFailure->PredictFailure = (deviceExtension->PredictFailure) ?
1 : 0;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(STORAGE_PREDICT_FAILURE);
}
}
//
// Complete request.
//
Irp->IoStatus.Status = status;
IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
} else {
//
// Pass unrecognized device control requests
// down to next driver layer.
//
IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp);
status = FPFilterSendToNextDriver(DeviceObject, Irp);
}
return(status);
} // end FPFilterDeviceControl()
VOID
FPFilterUnload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Free all the allocated resources, etc.
Arguments:
DriverObject - pointer to a driver object.
Return Value:
VOID.
--*/
{
PAGED_CODE();
return;
}
#if DBG
VOID
FPFilterDebugPrint(
ULONG DebugPrintLevel,
PCCHAR DebugMessage,
...
)
/*++
Routine Description:
Debug print for all FPFilter
Arguments:
Debug print level between 0 and 3, with 3 being the most verbose.
Return Value:
None
--*/
{
va_list ap;
va_start(ap, DebugMessage);
if ((DebugPrintLevel <= (FPFilterDebug & 0x0000ffff)) ||
((1 << (DebugPrintLevel + 15)) & FPFilterDebug)) {
_vsnprintf(FPFilterDebugBuffer, DEBUG_BUFFER_LENGTH, DebugMessage, ap);
DbgPrint(FPFilterDebugBuffer);
}
va_end(ap);
}
#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -