/*++ Copyright (c) 1995 Microsoft Corporation Module Name: initunlo.c Abstract: This module contains the code that is very specific to initialization and unload operations in the irenum driver Author: Brian Lieuallen, 7-13-2000 Environment: Kernel mode Revision History : --*/ #include "internal.h" #pragma alloc_text(PAGE,IrEnumAddDevice) #pragma alloc_text(PAGE,IrEnumPnP) #pragma alloc_text(PAGE,IrEnumPower) #pragma alloc_text(PAGE,IrEnumWmi) NTSTATUS IrEnumAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo ) { NTSTATUS Status; PDEVICE_OBJECT Fdo = NULL; PDEVICE_OBJECT LowerDevice=NULL; // // Pointer to the device extension created for this // device // PFDO_DEVICE_EXTENSION DeviceExtension = NULL; D_PNP(DbgPrint("IRENUM: AddDevice\n");) // // Create the device object for this device. // Status = IoCreateDevice( DriverObject, sizeof(FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_NULL, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &Fdo ); if (!NT_SUCCESS(Status)) { goto CleanUp; } LowerDevice=IoAttachDeviceToDeviceStack( Fdo, Pdo ); if (LowerDevice == NULL) { D_ERROR(DbgPrint("IRENUM: Could not attach to PDO\n");) Status=STATUS_INSUFFICIENT_RESOURCES; goto CleanUp; } Fdo->Flags |= LowerDevice->Flags; Fdo->Flags &= ~DO_DEVICE_INITIALIZING; Fdo->StackSize=LowerDevice->StackSize+1; DeviceExtension=Fdo->DeviceExtension; DeviceExtension->DoType=DO_TYPE_FDO; DeviceExtension->DeviceObject = Fdo; DeviceExtension->Pdo=Pdo; DeviceExtension->LowerDevice=LowerDevice; DeviceExtension->CreateStaticDevice= (EnumStaticDevice != 0) ; CreateEnumObject(Fdo,&DeviceExtension->EnumHandle,DeviceExtension->CreateStaticDevice); return STATUS_SUCCESS; CleanUp: IoDeleteDevice(Fdo); return Status; } NTSTATUS IrEnumPnP( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status; ULONG i; if ((DeviceExtension->DoType==DO_TYPE_PDO) || (DeviceExtension->DoType==DO_TYPE_DEL_PDO)) { // // this one is for the child // return IrEnumPdoPnp( DeviceObject, Irp ); } if (DeviceExtension->DoType != DO_TYPE_FDO) { DbgPrint("IRENUM: IrEnumPnp: Bad DevObj\n"); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; } switch (irpSp->MinorFunction) { case IRP_MN_START_DEVICE: Irp->IoStatus.Status = STATUS_SUCCESS; return ForwardIrp(DeviceExtension->LowerDevice, Irp); case IRP_MN_QUERY_STOP_DEVICE: D_PNP(DbgPrint("IRENUM: IRP_MN_QUERY_STOP_DEVICE\n");) Irp->IoStatus.Status = STATUS_SUCCESS; return ForwardIrp(DeviceExtension->LowerDevice, Irp); case IRP_MN_CANCEL_STOP_DEVICE: D_PNP(DbgPrint("IRENUM: IRP_MN_CANCEL_STOP_DEVICE\n");) Irp->IoStatus.Status = STATUS_SUCCESS; return ForwardIrp(DeviceExtension->LowerDevice, Irp); case IRP_MN_STOP_DEVICE: D_PNP(DbgPrint("IRENUM: IRP_MN_STOP_DEVICE\n");) Irp->IoStatus.Status = STATUS_SUCCESS; return ForwardIrp(DeviceExtension->LowerDevice, Irp); case IRP_MN_QUERY_DEVICE_RELATIONS: { PDEVICE_RELATIONS CurrentRelations=(PDEVICE_RELATIONS)Irp->IoStatus.Information; PDEVICE_RELATIONS NewRelations=NULL; D_PNP(DbgPrint("IRENUM: IRP_MN_QUERY_DEVICE_RELATIONS type=%d\n",irpSp->Parameters.QueryDeviceRelations.Type);) D_PNP(DbgPrint(" Information=%p\n",Irp->IoStatus.Information);) switch (irpSp->Parameters.QueryDeviceRelations.Type ) { case BusRelations: { if (DeviceExtension->EnumHandle != NULL) { status=GetDeviceList( DeviceExtension->EnumHandle, Irp ); Irp->IoStatus.Status = status; if (!NT_SUCCESS(status)) { IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } } return ForwardIrp(DeviceExtension->LowerDevice, Irp); } case TargetDeviceRelation: default: { return ForwardIrp(DeviceExtension->LowerDevice, Irp); } } break; } case IRP_MN_QUERY_REMOVE_DEVICE: D_PNP(DbgPrint("IRENUM: IRP_MN_QUERY_REMOVE_DEVICE\n");) Irp->IoStatus.Status = STATUS_SUCCESS; return ForwardIrp(DeviceExtension->LowerDevice, Irp); case IRP_MN_CANCEL_REMOVE_DEVICE: D_PNP(DbgPrint("IRENUM: IRP_MN_CANCEL_REMOVE_DEVICE\n");) Irp->IoStatus.Status = STATUS_SUCCESS; return ForwardIrp(DeviceExtension->LowerDevice, Irp); case IRP_MN_SURPRISE_REMOVAL: { D_PNP(DbgPrint("IRENUM: IRP_MN_SURPRISE_REMOVAL\n");) Irp->IoStatus.Status = STATUS_SUCCESS; return ForwardIrp(DeviceExtension->LowerDevice, Irp); } break; case IRP_MN_REMOVE_DEVICE: { ULONG NewReferenceCount; D_PNP(DbgPrint("IRENUM: IRP_MN_REMOVE_DEVICE\n");) // // removing now for sure // DeviceExtension->Removing=TRUE; DeviceExtension->Removed=TRUE; IoCopyCurrentIrpStackLocationToNext(Irp); status=IoCallDriver(DeviceExtension->LowerDevice, Irp); // // detach from the driver below // IoDetachDevice(DeviceExtension->LowerDevice); DeviceExtension->DoType=DO_TYPE_DEL_FDO; if (DeviceExtension->EnumHandle != NULL) { CloseEnumObject(DeviceExtension->EnumHandle); } // // delete our device object // IoDeleteDevice(DeviceObject); D_PNP(DbgPrint("IRENUM: IRP_MN_REMOVE_DEVICE exit, %08lx\n",status);) return status; } default: D_PNP(DbgPrint("IRENUM: Sending to PDO PnP IRP, MN func=%d\n",irpSp->MinorFunction);) return ForwardIrp(DeviceExtension->LowerDevice, Irp); } IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS IrEnumPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; if ((DeviceExtension->DoType==DO_TYPE_PDO) || (DeviceExtension->DoType==DO_TYPE_DEL_PDO)) { // // this one is for the child // return IrEnumPdoPower( DeviceObject, Irp ); } PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); return PoCallDriver(DeviceExtension->LowerDevice, Irp); } NTSTATUS IrEnumWmi( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; PIO_STACK_LOCATION irpSp=IoGetCurrentIrpStackLocation(Irp); NTSTATUS Status; if ((DeviceExtension->DoType==DO_TYPE_PDO) || (DeviceExtension->DoType==DO_TYPE_DEL_PDO)) { return IrEnumPdoWmi( DeviceObject, Irp ); } if (irpSp->Parameters.WMI.ProviderId == (ULONG_PTR)DeviceObject) { // // The irp was targeted at this device, but we don't support wmi // Status = Irp->IoStatus.Status; IoCompleteRequest(Irp,IO_NO_INCREMENT); } else { // // the irp is targeted at another device object in the stack // Status=ForwardIrp(DeviceExtension->LowerDevice, Irp); } return Status; }