?? isopnp.c
字號:
ntStatus = IoCallDriver (deviceExtension->TopOfStackDeviceObject, Irp);
IsoUsb_DecrementIoCount(DeviceObject);
return ntStatus;
}
// Reset this flag so new IOCTL and IO Irp processing will be re-enabled
deviceExtension->RemoveDeviceRequested = FALSE;
break; // end, case IRP_MN_CANCEL_REMOVE_DEVICE
case IRP_MN_REMOVE_DEVICE:
// The PnP Manager uses this IRP to direct drivers to remove a device.
// For a "polite" device removal, the PnP Manager sends an
// IRP_MN_QUERY_REMOVE_DEVICE prior to the remove IRP. In this case,
// the device is in the remove-pending state when the remove IRP arrives.
// For a surprise-style device removal ( i.e. sudden cord yank ),
// the physical device has already been removed so the PnP Manager sends
// the remove IRP without a prior query-remove. A device can be in any state
// when it receives a remove IRP as a result of a surprise-style removal.
// match the inc at the begining of the dispatch routine
IsoUsb_DecrementIoCount(DeviceObject);
//
// Once DeviceRemoved is set no new IOCTL or read/write irps will be passed
// down the stack to lower drivers; all will be quickly failed
//
deviceExtension->DeviceRemoved = TRUE;
// If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
// This call will also close the pipes; if any user close calls get through,
// they will be noops
IsoUsb_AbortPipes( DeviceObject );
// We don't explicitly wait for the below driver to complete, but just make
// the call and go on, finishing cleanup
IoCopyCurrentIrpStackLocationToNext(Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
//
// The final decrement to device extension PendingIoCount == 0
// will set deviceExtension->RemoveEvent, enabling device removal.
// If there is no pending IO at this point, the below decrement will be it.
//
IsoUsb_DecrementIoCount(DeviceObject);
// wait for any io request pending in our driver to
// complete for finishing the remove
KeWaitForSingleObject(
&deviceExtension->RemoveEvent,
Suspended,
KernelMode,
FALSE,
NULL);
//
// Delete the link and FDO we created
//
IsoUsb_RemoveDevice(DeviceObject);
ISOUSB_KdPrint( DBGLVL_DEFAULT,("IsoUsb_ProcessPnPIrp() Detaching from %08X\n",
deviceExtension->TopOfStackDeviceObject));
IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
ISOUSB_KdPrint( DBGLVL_DEFAULT,("IsoUsb_ProcessPnPIrp() Deleting %08X\n",
DeviceObject));
IoDeleteDevice (DeviceObject);
return ntStatus; // end, case IRP_MN_REMOVE_DEVICE
default:
ISOUSB_KdPrint( DBGLVL_MAXIMUM,("IsoUsb_ProcessPnPIrp() Minor PnP IOCTL not handled\n"));
} /* case MinorFunction */
if (!NT_SUCCESS(ntStatus)) {
// if anything went wrong, return failure without passing Irp down
Irp->IoStatus.Status = ntStatus;
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
IsoUsb_DecrementIoCount(DeviceObject);
ISOUSB_KdPrint( DBGLVL_MAXIMUM,("IsoUsb_ProcessPnPIrp() Exit IsoUsb_ProcessPnPIrp FAILURE %x\n", ntStatus));
return ntStatus;
}
IoCopyCurrentIrpStackLocationToNext(Irp);
//
// All PNP_POWER messages get passed to the TopOfStackDeviceObject
// we were given in PnPAddDevice
//
ISOUSB_KdPrint( DBGLVL_MAXIMUM,("IsoUsb_ProcessPnPIrp() Passing PnP Irp down, status = %x\n", ntStatus));
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
IsoUsb_DecrementIoCount(DeviceObject);
ISOUSB_KdPrint( DBGLVL_MAXIMUM,("IsoUsb_ProcessPnPIrp() Exit IsoUsb_ProcessPnPIrp %x\n", ntStatus));
return ntStatus;
}
NTSTATUS
IsoUsb_PnPAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
/*++
Routine Description:
This routine is called to create and initialize our Functional Device Object (FDO).
For monolithic drivers, this is done in DriverEntry(), but Plug and Play devices
wait for a PnP event
Arguments:
DriverObject - pointer to the driver object for this instance of IsoUsb
PhysicalDeviceObject - pointer to a device object created by the bus
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject = NULL;
PDEVICE_EXTENSION deviceExtension;
USBD_VERSION_INFORMATION versionInformation;
ULONG i;
ISOUSB_KdPrint( DBGLVL_DEFAULT,("enter IsoUsb_PnPAddDevice()\n"));
//
// create our funtional device object (FDO)
//
ntStatus =
IsoUsb_CreateDeviceObject(DriverObject, PhysicalDeviceObject, &deviceObject);
if (NT_SUCCESS(ntStatus)) {
deviceExtension = deviceObject->DeviceExtension;
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
//
// we support direct io for read/write
//
deviceObject->Flags |= DO_DIRECT_IO;
//Set this flag causes the driver to not receive a IRP_MN_STOP_DEVICE
//during suspend and also not get an IRP_MN_START_DEVICE during resume.
//This is neccesary because during the start device call,
// the GetDescriptors() call will be failed by the USB stack.
deviceObject->Flags |= DO_POWER_PAGABLE;
// initialize our device extension
//
// remember the Physical device Object
//
deviceExtension->PhysicalDeviceObject=PhysicalDeviceObject;
//
// Attach to the PDO
//
deviceExtension->TopOfStackDeviceObject =
IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);
// Get a copy of the physical device's capabilities into a
// DEVICE_CAPABILITIES struct in our device extension;
// We are most interested in learning which system power states
// are to be mapped to which device power states for handling
// IRP_MJ_SET_POWER Irps.
IsoUsb_QueryCapabilities(PhysicalDeviceObject,
&deviceExtension->DeviceCapabilities);
// We want to determine what level to auto-powerdown to; This is the lowest
// sleeping level that is LESS than D3;
// If all are set to D3, auto powerdown/powerup will be disabled.
deviceExtension->PowerDownLevel = PowerDeviceUnspecified; // init to disabled
for (i=PowerSystemSleeping1; i<= PowerSystemSleeping3; i++) {
if ( deviceExtension->DeviceCapabilities.DeviceState[i] < PowerDeviceD3 )
deviceExtension->PowerDownLevel = deviceExtension->DeviceCapabilities.DeviceState[i];
}
#if DBG
// May want override auto power-down level from registry;
// ( CurrentControlSet\Services\IsoUsb\Parameters )
// Setting to 0 or 1 in registry disables auto power-down
IsoUsb_GetRegistryDword( ISOUSB_REGISTRY_PARAMETERS_PATH,
L"PowerDownLevel",
&(deviceExtension->PowerDownLevel) );
//
// display the device caps
//
ISOUSB_KdPrint( DBGLVL_MEDIUM,(" >>>>>> DeviceCaps\n"));
ISOUSB_KdPrint( DBGLVL_MEDIUM,(" SystemWake = %s\n",
ISOUSB_StringForSysState( deviceExtension->DeviceCapabilities.SystemWake ) ));
ISOUSB_KdPrint( DBGLVL_MEDIUM,(" DeviceWake = %s\n",
ISOUSB_StringForDevState( deviceExtension->DeviceCapabilities.DeviceWake) ));
for (i=PowerSystemUnspecified; i< PowerSystemMaximum; i++) {
ISOUSB_KdPrint( DBGLVL_MEDIUM,(" Device State Map: sysstate %s = devstate %s\n",
ISOUSB_StringForSysState( i ),
ISOUSB_StringForDevState( deviceExtension->DeviceCapabilities.DeviceState[i] ) ));
}
ISOUSB_KdPrint( DBGLVL_MEDIUM,(" <<<<<<<<DeviceCaps\n"));
#endif
// We keep a pending IO count ( extension->PendingIoCount ) in the device extension.
// The first increment of this count is done on adding the device.
// Subsequently, the count is incremented for each new IRP received and
// decremented when each IRP is completed or passed on.
// Transition to 'one' therefore indicates no IO is pending and signals
// deviceExtension->NoPendingIoEvent. This is needed for processing
// IRP_MN_QUERY_REMOVE_DEVICE
// Transition to 'zero' signals an event ( deviceExtension->RemoveEvent )
// to enable device removal. This is used in processing for IRP_MN_REMOVE_DEVICE
//
IsoUsb_IncrementIoCount(deviceObject);
}
USBD_GetUSBDIVersion(&versionInformation);
if( NT_SUCCESS( ntStatus ) )
{
NTSTATUS actStat;
// try to power down device until IO actually requested
actStat = IsoUsb_SelfSuspendOrActivate( deviceObject, TRUE );
}
ISOUSB_KdPrint( DBGLVL_DEFAULT,("exit IsoUsb_PnPAddDevice() (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
IsoUsb_StartDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Called from IsoUsb_ProcessPnPIrp(), the dispatch routine for IRP_MJ_PNP.
Initializes a given instance of the device on the USB.
USB client drivers such as us set up URBs (USB Request Packets) to send requests
to the host controller driver (HCD). The URB structure defines a format for all
possible commands that can be sent to a USB device.
Here, we request the device descriptor and store it, and configure the device.
Arguments:
DeviceObject - pointer to the FDO (Functional Device Object)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -