?? usblspnp.c
字號:
NTSTATUS
USBLS120_IrpCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
Used as a general purpose completion routine so it can signal an event,
passed as the Context, when the next lower driver is done with the input Irp.
This routine is used by both PnP and Power Management logic.
Even though this routine does nothing but set an event, it must be defined and
prototyped as a completetion routine for use as such
Arguments:
DeviceObject - Pointer to the device object for the class device.
Irp - Irp completed.
Context - Driver defined context, in this case a pointer to an event.
Return Value:
The function value is the final status from the operation.
--*/
{
PKEVENT event = Context;
// Set the input event
KeSetEvent(
event,
1, // Priority increment for waiting thread.
FALSE); // Flag this call is not immediately followed by wait.
// This routine must return STATUS_MORE_PROCESSING_REQUIRED because we have not yet called
// IoFreeIrp() on this IRP.
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
USBLS120_FdoDeviceQuery(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp)
/*++
Routine Description:
Handler for IRP_MN_QUERY_DEVICE_RELATIONS.
Enumerates our child PDO.
Arguments:
DeviceObject - pointer to our child PDO
Irp - pointer to an I/O Request Packet
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus;
PIO_STACK_LOCATION irpStack;
PDEVICE_RELATIONS DeviceRelations;
PDEVICE_EXTENSION DeviceExtension;
PDEVICE_EXTENSION PdoExtension;
UNICODE_STRING PdoUniName;
static UCHAR PdoCount=0;
//NOTE: This name be unique to each hardware vendor
// to avoid name collision between different
// drivers based on this code
WCHAR PdoName[] = CHILD_PDO_NAME;
irpStack = IoGetCurrentIrpStackLocation(pIrp);
DeviceExtension = pDeviceObject->DeviceExtension;
switch (irpStack->Parameters.QueryDeviceRelations.Type)
{
case BusRelations:
// Allocate space for 1 child PDO
DeviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
// If we can't allocate DeviceRelations structure, bail
if (!DeviceRelations) {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
else {
DeviceRelations->Count = 0;
if ((!DeviceExtension->ChildPdo) && (PdoCount<9)) {
RtlInitUnicodeString (&PdoUniName, PdoName);
PdoName [((sizeof(PdoName)/sizeof(WCHAR)) - 2)] = L'0' + PdoCount++;
ntStatus = IoCreateDevice(
USBLS120DriverObject,
sizeof(DEVICE_EXTENSION),
&PdoUniName,
FILE_DEVICE_MASS_STORAGE,
0,
FALSE,
&DeviceExtension->ChildPdo
);
if(NT_SUCCESS(ntStatus))
{
PdoExtension = DeviceExtension->ChildPdo->DeviceExtension;
// Mark the device object as our child PDO
PdoExtension->DeviceObjectType = DO_PDO;
DeviceExtension->ChildPdo->Flags &= ~DO_DEVICE_INITIALIZING;
DeviceRelations->Objects[DeviceRelations->Count++] = DeviceExtension->ChildPdo;
ObReferenceObject(DeviceExtension->ChildPdo);
}
}
else {
// Child PDO already exists, just return it
DeviceRelations->Objects[DeviceRelations->Count++] = DeviceExtension->ChildPdo;
ObReferenceObject(DeviceExtension->ChildPdo);
}
pIrp->IoStatus.Information = (ULONG)DeviceRelations;
ntStatus = pIrp->IoStatus.Status = STATUS_SUCCESS;
}
break;
default:
// We pass on any non-BusRelations IRP
IoSkipCurrentIrpStackLocation (pIrp);
ntStatus = IoCallDriver (DeviceExtension->TopOfStackDeviceObject, pIrp);
}
return ntStatus;
}
NTSTATUS
USBLS120_PdoProcessPnPIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Dispatch table routine for IRP_MJ_PNP.
Process the Plug and Play IRPs sent to our PDO.
Arguments:
DeviceObject - pointer to our child PDO
Irp - pointer to an I/O Request Packet
Return Value:
NT status code
--*/
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT stackDeviceObject;
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
USBLS120_KdPrint( DBGLVL_MEDIUM, ( "enter USBLS120_PdoProcessPnPIrp()\n"));
irpStack = IoGetCurrentIrpStackLocation (Irp);
//
// Get a pointer to the device extension
//
deviceExtension = DeviceObject->DeviceExtension;
stackDeviceObject = deviceExtension->TopOfStackDeviceObject;
USBLS120_KdPrint( DBGLVL_MEDIUM, ( "enter USBLS120_ProcessPnPIrp() IRP_MJ_PNP, minor %s\n",
USBLS120_StringForPnpMnFunc( irpStack->MinorFunction ) ));
// inc the FDO device extension's pending IO count for this Irp
//USBLS120_IncrementIoCount(DeviceObject);
USBLS120_ASSERT( IRP_MJ_PNP == irpStack->MajorFunction );
switch (irpStack->MinorFunction)
{
case IRP_MN_QUERY_DEVICE_RELATIONS:
ntStatus = USBLS120_PdoDeviceQuery(DeviceObject, Irp);
break;
case IRP_MN_QUERY_ID:
ntStatus = USBLS120_PdoQueryID(DeviceObject, Irp);
break;
case IRP_MN_REMOVE_DEVICE:
IoDeleteDevice(DeviceObject);
break;
case IRP_MN_QUERY_BUS_INFORMATION:
ntStatus = USBLS120_QueryBusInfo(DeviceObject, Irp);
break;
}
return (ntStatus);
}
NTSTATUS
USBLS120_QueryBusInfo(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
NTSTATUS ntStatus;
PIO_STACK_LOCATION irpStack;
PPNP_BUS_INFORMATION BusInfo;
USBLS120_KdPrint( DBGLVL_MEDIUM, ( "enter USBLS120_QueryBusInfo()\n"));
irpStack = IoGetCurrentIrpStackLocation(pIrp);
BusInfo = ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
// If we can't allocate BusInfo structure, bail
if (!BusInfo) {
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
else {
BusInfo->BusTypeGuid = GUID_BUS_USBLS120;
BusInfo->LegacyBusType = PNPBus;
BusInfo->BusNumber = 0;
pIrp->IoStatus.Information = (ULONG)BusInfo;
ntStatus = pIrp->IoStatus.Status = STATUS_SUCCESS;
}
return ntStatus;
}
NTSTATUS
USBLS120_PdoDeviceQuery(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
NTSTATUS ntStatus;
PIO_STACK_LOCATION irpStack;
PDEVICE_RELATIONS DeviceRelations;
PDEVICE_EXTENSION DeviceExtension;
USBLS120_KdPrint( DBGLVL_DEFAULT, ( "enter USBLS120_PdoDeviceQuery()\n"));
irpStack = IoGetCurrentIrpStackLocation(pIrp);
DeviceExtension = pDeviceObject->DeviceExtension;
switch (irpStack->Parameters.QueryDeviceRelations.Type)
{
case TargetDeviceRelation:
// Allocate space for 1 child device
DeviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
// If we can't allocate DeviceRelations structure, bail
if (!DeviceRelations) {
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
else {
ObReferenceObject(pDeviceObject);
DeviceRelations->Count = 1;
DeviceRelations->Objects[0] = pDeviceObject;
pIrp->IoStatus.Information = (ULONG)DeviceRelations;
ntStatus = pIrp->IoStatus.Status = STATUS_SUCCESS;
}
break;
default:
ntStatus = pIrp->IoStatus.Status;
}
return ntStatus;
}
NTSTATUS
USBLS120_PdoQueryID(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp)
{
PIO_STACK_LOCATION ioStack;
PWCHAR buffer;
WCHAR IDString[] = CHILD_DEVICE_ID;
WCHAR InstanceIDString[] = L"0000";
ULONG length;
USBLS120_KdPrint( DBGLVL_MEDIUM, ( "enter USBLS120_PdoQueryID()\n"));
ioStack = IoGetCurrentIrpStackLocation(pIrp);
switch (ioStack->Parameters.QueryId.IdType)
{
case BusQueryHardwareIDs:
// return a multi WCHAR (null terminated) string (null terminated)
// array for use in matching hardare ids in inf files;
case BusQueryDeviceID:
// return a WCHAR (null terminated) string describing the device
// For symplicity we make it exactly the same as the Hardware ID.
length = sizeof (IDString) * sizeof(WCHAR);
buffer = ExAllocatePool (PagedPool, length);
if (buffer) {
RtlCopyMemory (buffer, IDString, length);
}
pIrp->IoStatus.Information = (ULONG) buffer;
break;
case BusQueryInstanceID:
length = sizeof (InstanceIDString) * sizeof(WCHAR);
buffer = ExAllocatePool (PagedPool, length);
if (buffer) {
RtlCopyMemory (buffer, InstanceIDString, length);
}
pIrp->IoStatus.Information = (ULONG) buffer;
break;
}
return STATUS_SUCCESS;
}
NTSTATUS
USBLS120_AbortPipes(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Called as part of sudden device removal handling.
Cancels any pending transfers for all open pipes.
If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
Also marks the pipe 'closed' in our saved configuration info.
Arguments:
Ptrs to our FDO
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb;
PDEVICE_EXTENSION deviceExtension;
ULONG i;
PUSBD_INTERFACE_INFORMATION interface;
PUSBD_PIPE_INFORMATION PipeInfo;
deviceExtension = DeviceObject->DeviceExtension;
interface = deviceExtension->UsbInterface;
for (i=0; i<interface->NumberOfPipes; i++) {
PipeInfo = &interface->Pipes[i]; // PUSBD_PIPE_INFORMATION PipeInfo;
if ( PipeInfo->PipeFlags ) {
USBLS120_KdPrint( DBGLVL_HIGH,("USBLS120_AbortPipes() Aborting open Pipe %d\n", i));
urb = USBLS120_ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
if (urb) {
urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
urb->UrbPipeRequest.PipeHandle = PipeInfo->PipeHandle;
ntStatus = USBLS120_CallUSBD(DeviceObject, urb);
USBLS120_ExFreePool(urb);
}
else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
USBLS120_KdPrint( DBGLVL_HIGH,("USBLS120_AbortPipes() FAILED urb alloc\n" ));
break;
}
if (!(NT_SUCCESS(ntStatus))) {
// if we failed, dump out
#if DBG
if ( gpDbg )
gpDbg->PipeErrorCount++;
#endif
break;
}
else {
PipeInfo->PipeFlags = FALSE; // mark the pipe 'closed'
deviceExtension->OpenPipeCount--;
#if DBG
if ( gpDbg )
gpDbg->AbortPipeCount++;
#endif
}
} // end, if pipe open
} // end, for all pipes
return ntStatus;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -