Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

389 lines
8.5 KiB

/*++
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;
}