📄 class.c
字号:
IoAdjustPagingPathCount(
&commonExtension->HibernationPathCount,
irpStack->Parameters.UsageNotification.InPath
);
status = ClassForwardIrpSynchronous(commonExtension, Irp);
if (!NT_SUCCESS(status)) {
IoAdjustPagingPathCount(
&commonExtension->HibernationPathCount,
!irpStack->Parameters.UsageNotification.InPath
);
}
break;
}
case DeviceUsageTypeDumpFile: {
IoAdjustPagingPathCount(
&commonExtension->DumpPathCount,
irpStack->Parameters.UsageNotification.InPath
);
status = ClassForwardIrpSynchronous(commonExtension, Irp);
if (!NT_SUCCESS(status)) {
IoAdjustPagingPathCount(
&commonExtension->DumpPathCount,
!irpStack->Parameters.UsageNotification.InPath
);
}
break;
}
default: {
status = STATUS_INVALID_PARAMETER;
break;
}
}
break;
}
case IRP_MN_QUERY_CAPABILITIES: {
DebugPrint((2, "ClassDispatchPnp (%p,%p): QueryCapabilities\n",
DeviceObject, Irp));
if(!isFdo) {
status = ClassQueryPnpCapabilities(
DeviceObject,
irpStack->Parameters.DeviceCapabilities.Capabilities
);
break;
} else {
PDEVICE_CAPABILITIES deviceCapabilities;
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
PCLASS_PRIVATE_FDO_DATA fdoData;
fdoExtension = DeviceObject->DeviceExtension;
fdoData = fdoExtension->PrivateFdoData;
deviceCapabilities =
irpStack->Parameters.DeviceCapabilities.Capabilities;
//
// forward the irp before handling the special cases
//
status = ClassForwardIrpSynchronous(commonExtension, Irp);
if (!NT_SUCCESS(status)) {
break;
}
//
// we generally want to remove the device from the hotplug
// applet, which requires the SR-OK bit to be set.
// only when the user specifies that they are capable of
// safely removing things do we want to clear this bit
// (saved in WriteCacheEnableOverride)
//
// setting of this bit is done either above, or by the
// lower driver.
//
// note: may not be started, so check we have FDO data first.
//
if (fdoData &&
fdoData->HotplugInfo.WriteCacheEnableOverride) {
if (deviceCapabilities->SurpriseRemovalOK) {
DebugPrint((1, "Classpnp: Clearing SR-OK bit in "
"device capabilities due to hotplug "
"device or media\n"));
}
deviceCapabilities->SurpriseRemovalOK = FALSE;
}
break;
} // end QUERY_CAPABILITIES for FDOs
ASSERT(FALSE);
break;
} // end QUERY_CAPABILITIES
default: {
if (isFdo){
IoCopyCurrentIrpStackLocationToNext(Irp);
ClassReleaseRemoveLock(DeviceObject, Irp);
status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
completeRequest = FALSE;
}
break;
}
}
}
else {
ASSERT(driverExtension);
status = STATUS_INTERNAL_ERROR;
}
if (completeRequest){
Irp->IoStatus.Status = status;
if (!lockReleased){
ClassReleaseRemoveLock(DeviceObject, Irp);
}
ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);
DBGTRACE(ClassDebugTrace, ("ClassDispatchPnp (%p,%p): leaving with previous %#x, current %#x.", DeviceObject, Irp, commonExtension->PreviousState, commonExtension->CurrentState));
}
else {
/*
* The irp is already completed so don't touch it.
* This may be a remove so don't touch the device extension.
*/
DBGTRACE(ClassDebugTrace, ("ClassDispatchPnp (%p,%p): leaving.", DeviceObject, Irp));
}
return status;
} // end ClassDispatchPnp()
/*++////////////////////////////////////////////////////////////////////////////
ClassPnpStartDevice()
Routine Description:
Storage class driver routine for IRP_MN_START_DEVICE requests.
This routine kicks off any device specific initialization
Arguments:
DeviceObject - a pointer to the device object
Irp - a pointer to the io request packet
Return Value:
none
--*/
NTSTATUS ClassPnpStartDevice(IN PDEVICE_OBJECT DeviceObject)
{
PCLASS_DRIVER_EXTENSION driverExtension;
PCLASS_INIT_DATA initData;
PCLASS_DEV_INFO devInfo;
PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
BOOLEAN isFdo = commonExtension->IsFdo;
BOOLEAN isMountedDevice = TRUE;
UNICODE_STRING interfaceName;
BOOLEAN timerStarted = FALSE;
NTSTATUS status = STATUS_SUCCESS;
PAGED_CODE();
driverExtension = IoGetDriverObjectExtension(DeviceObject->DriverObject,
CLASS_DRIVER_EXTENSION_KEY);
initData = &(driverExtension->InitData);
if(isFdo) {
devInfo = &(initData->FdoData);
} else {
devInfo = &(initData->PdoData);
}
ASSERT(devInfo->ClassInitDevice != NULL);
ASSERT(devInfo->ClassStartDevice != NULL);
if (!commonExtension->IsInitialized){
//
// perform FDO/PDO specific initialization
//
if (isFdo){
STORAGE_PROPERTY_ID propertyId;
//
// allocate a private extension for class data
//
if (fdoExtension->PrivateFdoData == NULL) {
fdoExtension->PrivateFdoData =
ExAllocatePoolWithTag(NonPagedPool,
sizeof(CLASS_PRIVATE_FDO_DATA),
CLASS_TAG_PRIVATE_DATA
);
}
if (fdoExtension->PrivateFdoData == NULL) {
DebugPrint((0, "ClassPnpStartDevice: Cannot allocate for "
"private fdo data\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// initialize the struct's various fields.
//
RtlZeroMemory(fdoExtension->PrivateFdoData, sizeof(CLASS_PRIVATE_FDO_DATA));
KeInitializeTimer(&fdoExtension->PrivateFdoData->Retry.Timer);
KeInitializeDpc(&fdoExtension->PrivateFdoData->Retry.Dpc,
ClasspRetryRequestDpc,
DeviceObject);
KeInitializeSpinLock(&fdoExtension->PrivateFdoData->Retry.Lock);
fdoExtension->PrivateFdoData->Retry.Granularity = KeQueryTimeIncrement();
commonExtension->Reserved4 = (ULONG_PTR)(' GPH'); // debug aid
InitializeListHead(&fdoExtension->PrivateFdoData->DeferredClientIrpList);
/*
* Anchor the FDO in our static list.
* Pnp is synchronized, so we shouldn't need any synchronization here.
*/
InsertTailList(&AllFdosList, &fdoExtension->PrivateFdoData->AllFdosListEntry);
//
// NOTE: the old interface allowed the class driver to allocate
// this. this was unsafe for low-memory conditions. allocate one
// unconditionally now, and modify our internal functions to use
// our own exclusively as it is the only safe way to do this.
//
status = ClasspAllocateReleaseQueueIrp(fdoExtension);
if (!NT_SUCCESS(status)) {
DebugPrint((0, "ClassPnpStartDevice: Cannot allocate the private release queue irp\n"));
return status;
}
//
// Call port driver to get adapter capabilities.
//
propertyId = StorageAdapterProperty;
status = ClassGetDescriptor(
commonExtension->LowerDeviceObject,
&propertyId,
&fdoExtension->AdapterDescriptor);
if (!NT_SUCCESS(status)) {
DebugPrint((0, "ClassPnpStartDevice: ClassGetDescriptor [ADAPTER] failed %lx\n", status));
return status;
}
//
// Call port driver to get device descriptor.
//
propertyId = StorageDeviceProperty;
status = ClassGetDescriptor(
commonExtension->LowerDeviceObject,
&propertyId,
&fdoExtension->DeviceDescriptor);
if (NT_SUCCESS(status)){
ClasspScanForSpecialInRegistry(fdoExtension);
ClassScanForSpecial(fdoExtension, ClassBadItems, ClasspScanForClassHacks);
//
// allow perf to be re-enabled after a given number of failed IOs
// require this number to be at least CLASS_PERF_RESTORE_MINIMUM
//
{
ULONG t = CLASS_PERF_RESTORE_MINIMUM;
ClassGetDeviceParameter(fdoExtension,
CLASSP_REG_SUBKEY_NAME,
CLASSP_REG_PERF_RESTORE_VALUE_NAME,
&t);
if (t >= CLASS_PERF_RESTORE_MINIMUM) {
fdoExtension->PrivateFdoData->Perf.ReEnableThreshhold = t;
}
}
//
// compatibility comes first. writable cd media will not
// get a SYNCH_CACHE on power down.
//
if (fdoExtension->DeviceObject->DeviceType != FILE_DEVICE_DISK) {
SET_FLAG(fdoExtension->PrivateFdoData->HackFlags, FDO_HACK_NO_SYNC_CACHE);
}
//
// initialize the hotplug information only after the ScanForSpecial
// routines, as it relies upon the hack flags.
//
status = ClasspInitializeHotplugInfo(fdoExtension);
if (NT_SUCCESS(status)){
/*
* Allocate/initialize TRANSFER_PACKETs and related resources.
*/
status = InitializeTransferPackets(DeviceObject);
}
else {
DebugPrint((1, "ClassPnpStartDevice: Could not initialize hotplug information %lx\n", status));
}
}
else {
DebugPrint((0, "ClassPnpStartDevice: ClassGetDescriptor [DEVICE] failed %lx\n", status));
}
}
//
// ISSUE - drivers need to disable write caching on the media
// if hotplug and !useroverride. perhaps we should
// allow registration of a callback to enable/disable
// write cache instead.
//
if (NT_SUCCESS(status)){
status = devInfo->ClassInitDevice(DeviceObject);
}
}
if (!NT_SUCCESS(status)){
//
// Just bail out - the remove that comes down will clean up the
// initialized scraps.
//
return status;
} else {
commonExtension->IsInitialized = TRUE;
if (commonExtension->IsFdo) {
fdoExtension->PrivateFdoData->Perf.OriginalSrbFlags = fdoExtension->SrbFlags;
}
}
//
// If device requests autorun functionality or a once a second callback
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -