📄 class.c
字号:
)
{
PCLASS_DRIVER_EXTENSION driverExtension;
NTSTATUS status;
PAGED_CODE();
driverExtension = IoGetDriverObjectExtension( DriverObject,
CLASS_DRIVER_EXTENSION_KEY
);
if (IsEqualGUID(Guid, &ClassGuidQueryRegInfoEx))
{
PCLASS_QUERY_WMI_REGINFO_EX_LIST List;
//
// Indicate the device supports PCLASS_QUERY_REGINFO_EX
// callback instead of PCLASS_QUERY_REGINFO callback.
//
List = (PCLASS_QUERY_WMI_REGINFO_EX_LIST)Data;
if (List->Size == sizeof(CLASS_QUERY_WMI_REGINFO_EX_LIST))
{
driverExtension->ClassFdoQueryWmiRegInfoEx = List->ClassFdoQueryWmiRegInfoEx;
driverExtension->ClassPdoQueryWmiRegInfoEx = List->ClassPdoQueryWmiRegInfoEx;
status = STATUS_SUCCESS;
} else {
status = STATUS_INVALID_PARAMETER;
}
} else {
status = STATUS_NOT_SUPPORTED;
}
return(status);
} // end ClassInitializeEx()
/*++////////////////////////////////////////////////////////////////////////////
ClassUnload()
Routine Description:
called when there are no more references to the driver. this allows
drivers to be updated without rebooting.
Arguments:
DriverObject - a pointer to the driver object that is being unloaded
Status:
--*/
VOID
ClassUnload(
IN PDRIVER_OBJECT DriverObject
)
{
PCLASS_DRIVER_EXTENSION driverExtension;
NTSTATUS status;
PAGED_CODE();
ASSERT( DriverObject->DeviceObject == NULL );
driverExtension = IoGetDriverObjectExtension( DriverObject,
CLASS_DRIVER_EXTENSION_KEY
);
ASSERT(driverExtension != NULL);
ASSERT(driverExtension->RegistryPath.Buffer != NULL);
ASSERT(driverExtension->InitData.ClassUnload != NULL);
DebugPrint((1, "ClassUnload: driver unloading %wZ\n",
&driverExtension->RegistryPath));
//
// attempt to process the driver's unload routine first.
//
driverExtension->InitData.ClassUnload(DriverObject);
//
// free own allocated resources and return
//
ExFreePool( driverExtension->RegistryPath.Buffer );
driverExtension->RegistryPath.Buffer = NULL;
driverExtension->RegistryPath.Length = 0;
driverExtension->RegistryPath.MaximumLength = 0;
return;
} // end ClassUnload()
/*++////////////////////////////////////////////////////////////////////////////
ClassAddDevice()
Routine Description:
SCSI class driver add device routine. This is called by pnp when a new
physical device come into being.
This routine will call out to the class driver to verify that it should
own this device then will create and attach a device object and then hand
it to the driver to initialize and create symbolic links
Arguments:
DriverObject - a pointer to the driver object that this is being created for
PhysicalDeviceObject - a pointer to the physical device object
Status: STATUS_NO_SUCH_DEVICE if the class driver did not want this device
STATUS_SUCCESS if the creation and attachment was successful
status of device creation and initialization
--*/
NTSTATUS
ClassAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
PCLASS_DRIVER_EXTENSION driverExtension =
IoGetDriverObjectExtension(DriverObject,
CLASS_DRIVER_EXTENSION_KEY);
NTSTATUS status;
PAGED_CODE();
status = driverExtension->InitData.ClassAddDevice(DriverObject,
PhysicalDeviceObject);
return status;
} // end ClassAddDevice()
/*++////////////////////////////////////////////////////////////////////////////
ClassDispatchPnp()
Routine Description:
Storage class driver pnp routine. This is called by the io system when
a PNP request is sent to the device.
Arguments:
DeviceObject - pointer to the device object
Irp - pointer to the io request packet
Return Value:
status
--*/
NTSTATUS
ClassDispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
BOOLEAN isFdo = commonExtension->IsFdo;
PCLASS_DRIVER_EXTENSION driverExtension;
PCLASS_INIT_DATA initData;
PCLASS_DEV_INFO devInfo;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
NTSTATUS status = Irp->IoStatus.Status;
BOOLEAN completeRequest = TRUE;
BOOLEAN lockReleased = FALSE;
ULONG isRemoved;
PAGED_CODE();
//
// Extract all the useful information out of the driver object
// extension
//
driverExtension = IoGetDriverObjectExtension(DeviceObject->DriverObject,
CLASS_DRIVER_EXTENSION_KEY);
if (driverExtension){
initData = &(driverExtension->InitData);
if(isFdo) {
devInfo = &(initData->FdoData);
} else {
devInfo = &(initData->PdoData);
}
isRemoved = ClassAcquireRemoveLock(DeviceObject, Irp);
DebugPrint((2, "ClassDispatchPnp (%p,%p): minor code %#x for %s %p\n",
DeviceObject, Irp,
irpStack->MinorFunction,
isFdo ? "fdo" : "pdo",
DeviceObject));
DebugPrint((2, "ClassDispatchPnp (%p,%p): previous %#x, current %#x\n",
DeviceObject, Irp,
commonExtension->PreviousState,
commonExtension->CurrentState));
switch(irpStack->MinorFunction) {
case IRP_MN_START_DEVICE: {
//
// if this is sent to the FDO we should forward it down the
// attachment chain before we start the FDO.
//
if (isFdo) {
status = ClassForwardIrpSynchronous(commonExtension, Irp);
}
else {
status = STATUS_SUCCESS;
}
if (NT_SUCCESS(status)){
status = Irp->IoStatus.Status = ClassPnpStartDevice(DeviceObject);
}
break;
}
case IRP_MN_QUERY_DEVICE_RELATIONS: {
DEVICE_RELATION_TYPE type =
irpStack->Parameters.QueryDeviceRelations.Type;
PDEVICE_RELATIONS deviceRelations = NULL;
if(!isFdo) {
if(type == TargetDeviceRelation) {
//
// Device relations has one entry built in to it's size.
//
status = STATUS_INSUFFICIENT_RESOURCES;
deviceRelations = ExAllocatePoolWithTag(PagedPool,
sizeof(DEVICE_RELATIONS),
'2CcS');
if(deviceRelations != NULL) {
RtlZeroMemory(deviceRelations,
sizeof(DEVICE_RELATIONS));
Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;
deviceRelations->Count = 1;
deviceRelations->Objects[0] = DeviceObject;
ObReferenceObject(deviceRelations->Objects[0]);
status = STATUS_SUCCESS;
}
} else {
//
// PDO's just complete enumeration requests without altering
// the status.
//
status = Irp->IoStatus.Status;
}
break;
} else if (type == BusRelations) {
ASSERT(commonExtension->IsInitialized);
//
// Make sure we support enumeration
//
if(initData->ClassEnumerateDevice == NULL) {
//
// Just send the request down to the lower driver. Perhaps
// It can enumerate children.
//
} else {
//
// Re-enumerate the device
//
status = ClassPnpQueryFdoRelations(DeviceObject, Irp);
if(!NT_SUCCESS(status)) {
completeRequest = TRUE;
break;
}
}
}
IoCopyCurrentIrpStackLocationToNext(Irp);
ClassReleaseRemoveLock(DeviceObject, Irp);
status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
completeRequest = FALSE;
break;
}
case IRP_MN_QUERY_ID: {
BUS_QUERY_ID_TYPE idType = irpStack->Parameters.QueryId.IdType;
UNICODE_STRING unicodeString;
if(isFdo) {
//
// FDO's should just forward the query down to the lower
// device objects
//
IoCopyCurrentIrpStackLocationToNext(Irp);
ClassReleaseRemoveLock(DeviceObject, Irp);
status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
completeRequest = FALSE;
break;
}
//
// PDO's need to give an answer - this is easy for now
//
RtlInitUnicodeString(&unicodeString, NULL);
status = ClassGetPdoId(DeviceObject,
idType,
&unicodeString);
if(status == STATUS_NOT_IMPLEMENTED) {
//
// The driver doesn't implement this ID (whatever it is).
// Use the status out of the IRP so that we don't mangle a
// response from someone else.
//
status = Irp->IoStatus.Status;
} else if(NT_SUCCESS(status)) {
Irp->IoStatus.Information = (ULONG_PTR) unicodeString.Buffer;
} else {
Irp->IoStatus.Information = (ULONG_PTR) NULL;
}
break;
}
case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_QUERY_REMOVE_DEVICE: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -