📄 umsspnp.c
字号:
UMSS_KdPrint( DBGLVL_MEDIUM,("USB Mass Storage Device Descriptor:\n"));
UMSS_KdPrint( DBGLVL_MEDIUM,("-----------------------------------\n"));
UMSS_KdPrint( DBGLVL_MEDIUM,("bLength %d\n", deviceDescriptor->bLength));
UMSS_KdPrint( DBGLVL_MEDIUM,("bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType));
UMSS_KdPrint( DBGLVL_MEDIUM,("bcdUSB 0x%x\n", deviceDescriptor->bcdUSB));
UMSS_KdPrint( DBGLVL_MEDIUM,("bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass));
UMSS_KdPrint( DBGLVL_MEDIUM,("bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass));
UMSS_KdPrint( DBGLVL_MEDIUM,("bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol));
UMSS_KdPrint( DBGLVL_MEDIUM,("bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0));
UMSS_KdPrint( DBGLVL_MEDIUM,("idVendor 0x%x\n", deviceDescriptor->idVendor));
UMSS_KdPrint( DBGLVL_MEDIUM,("idProduct 0x%x\n", deviceDescriptor->idProduct));
UMSS_KdPrint( DBGLVL_MEDIUM,("bcdDevice 0x%x\n", deviceDescriptor->bcdDevice));
UMSS_KdPrint( DBGLVL_MEDIUM,("iManufacturer 0x%x\n", deviceDescriptor->iManufacturer));
UMSS_KdPrint( DBGLVL_MEDIUM,("iProduct 0x%x\n", deviceDescriptor->iProduct));
UMSS_KdPrint( DBGLVL_MEDIUM,("iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber));
UMSS_KdPrint( DBGLVL_MEDIUM,("bNumConfigurations 0x%x\n", deviceDescriptor->bNumConfigurations));
}
}
else
{
// if we got here we failed to allocate deviceDescriptor
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus))
{
deviceExtension->UsbDeviceDescriptor = deviceDescriptor;
}
else if (deviceDescriptor)
{
UMSS_ExFreePool(deviceDescriptor);
}
UMSS_ExFreePool(urb);
}
else
{
// if we got here we failed to allocate the urb
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus))
{
ntStatus = UMSS_ConfigureDevice(DeviceObject);
UMSS_KdPrintCond( DBGLVL_MEDIUM,!NT_SUCCESS(ntStatus),("UMSS_StartDevice UMSS_ConfigureDevice() FAILURE (%x)\n", ntStatus));
}
if (NT_SUCCESS(ntStatus))
{
deviceExtension->DeviceStarted = TRUE;
}
RETURN(ntStatus, UMSS_StartDevice);
}
NTSTATUS
UMSS_RemoveDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Called from UMSS_ProcessPnPIrp() to
clean up our device instance's allocated buffers; free symbolic links
Arguments:
DeviceObject - pointer to the FDO
Return Value:
NT status code from free symbolic link operation
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING deviceLinkUnicodeString;
ENTER(UMSS_RemoveDevice);
deviceExtension = DeviceObject->DeviceExtension;
//
// Free device descriptor structure
//
if (deviceExtension->UsbDeviceDescriptor)
{
UMSS_ExFreePool(deviceExtension->UsbDeviceDescriptor);
}
//
// Free up the UsbInterface structure
//
if (deviceExtension->UsbInterface)
{
UMSS_ExFreePool(deviceExtension->UsbInterface);
}
// free up the USB config discriptor
if (deviceExtension->UsbConfigurationDescriptor)
{
UMSS_ExFreePool(deviceExtension->UsbConfigurationDescriptor);
}
// free the data transfer DPC
if (deviceExtension->CbiTransferDataDpc)
{
UMSS_ExFreePool(deviceExtension->CbiTransferDataDpc);
}
UMSS_ASSERT( gExAllocCount == 0 );
RETURN(ntStatus, UMSS_RemoveDevice);
}
NTSTATUS
UMSS_StopDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Stops a given instance of a USB mass storage device on the USB.
We basically just tell USB this device is now 'unconfigured'
Arguments:
DeviceObject - pointer to the device object for this instance of a USB storage device
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb;
ULONG siz;
ENTER(UMSS_StopDevice);
deviceExtension = DeviceObject->DeviceExtension;
//
// Send the select configuration urb with a NULL pointer for the configuration
// handle. This closes the configuration and puts the device in the 'unconfigured'
// state.
//
siz = sizeof(struct _URB_SELECT_CONFIGURATION);
urb = UMSS_ExAllocatePool(NonPagedPool, siz);
if (urb)
{
UsbBuildSelectConfigurationRequest(
urb,
(USHORT) siz,
NULL
);
ntStatus = UMSS_CallUSBD(DeviceObject, urb);
UMSS_KdPrintCond( DBGLVL_DEFAULT,!NT_SUCCESS(ntStatus),("UMSS_StopDevice() FAILURE Configuration Closed status = %x usb status = %x.\n", ntStatus, urb->UrbHeader.Status));
UMSS_ExFreePool(urb);
}
else
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus))
{
deviceExtension->DeviceStarted = FALSE;
}
deviceExtension->StopDeviceRequested = FALSE;
RETURN(ntStatus, UMSS_StopDevice);
}
NTSTATUS
UMSS_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;
ENTER(UMSS_IrpCompletionRoutine);
// 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, UMSS_IrpCompletionRoutine);
}
NTSTATUS
UMSS_FdoDeviceQuery(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
/*++
Routine Description:
Handler for IRP_MN_QUERY_DEVICE_RELATIONS.
Enumerates our virtual 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 needs to be unique to each hardware vendor
// to avoid name collision between different
// drivers based on this code
WCHAR PdoName[] = CHILD_PDO_NAME;
ENTER(UMSS_FdoDeviceQuery);
irpStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = DeviceObject->DeviceExtension;
switch (irpStack->Parameters.QueryDeviceRelations.Type)
{
case BusRelations:
// Allocate space for 1 child PDO
// Don't use UMSS_ExAllocatePool, since DeviceRelations structure
// will be freed by the OS rather than this driver.
DeviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
// If we can't allocate DeviceRelations structure, bail
if (!DeviceRelations)
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
Irp->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(
UMSSDriverObject,
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);
}
Irp->IoStatus.Information = (ULONG)DeviceRelations;
ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
default:
// We pass on any non-BusRelations IRP
IoSkipCurrentIrpStackLocation (Irp);
ntStatus = IoCallDriver (DeviceExtension->TopOfStackDeviceObject, Irp);
}
RETURN(ntStatus, UMSS_FdoDeviceQuery);
}
NTSTATUS
UMSS_PdoProcessPnPIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -