📄 umss.c
字号:
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
UMSS_KdPrint( DBGLVL_MEDIUM,("---------\n"));
if (NT_SUCCESS(ntStatus))
{
deviceExtension->DeviceProtocol = PROTOCOL_UNDEFINED;
if (!UMSS_GetDeviceProtocolFromRegistry(DeviceObject))
{
if (!UMSS_GetDeviceProtocolFromDescriptor(DeviceObject))
{
// Can't determine device protocol
ntStatus = STATUS_DEVICE_CONFIGURATION_ERROR;
}
}
}
}
if (PROTOCOL_BULKONLY == deviceExtension->DeviceProtocol)
{
// Query device for max LUN number
deviceExtension->MaxLun = UMSS_BulkOnlyGetMaxLun(deviceExtension);
}
else
{
// CBI protocol doesn't implement LUNs, so set to 0
deviceExtension->MaxLun = 0;
}
if (urb)
{
// don't call the UMSS_ExFreePool since the buffer was
// alloced by USBD_CreateConfigurationRequest, not UMSS_ExAllocatePool()
ExFreePool(urb);
}
RETURN(ntStatus, UMSS_SelectInterface);
}
NTSTATUS
UMSS_ResetPipe(
IN PDEVICE_OBJECT DeviceObject,
USBD_PIPE_HANDLE PipeHandle
)
/*++
Routine Description:
Reset a given USB pipe.
NOTES:
This will reset the host to Data0 and should also reset the device to Data0
Arguments:
Ptrs to our FDO and a USBD_PIPE_INFORMATION struct
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus;
PURB urb;
PDEVICE_EXTENSION deviceExtension;
deviceExtension = DeviceObject->DeviceExtension;
ENTER(UMSS_ResetPipe);
UMSS_KdPrint( DBGLVL_DEFAULT,("UMSS_ResetPipe() Reset Pipe %x\n", PipeHandle));
urb = UMSS_ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
if (urb)
{
urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
urb->UrbPipeRequest.PipeHandle = PipeHandle;
ntStatus = UMSS_CallUSBD(DeviceObject, urb);
UMSS_ExFreePool(urb);
}
else
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (!(NT_SUCCESS(ntStatus)))
{
#if DBG
if ( gpDbg )
gpDbg->PipeErrorCount++;
#endif
UMSS_KdPrint( DBGLVL_DEFAULT,("UMSS_ResetPipe() FAILED, ntStatus =0x%x\n", ntStatus ));
}
else
{
#if DBG
if ( gpDbg )
gpDbg->ResetPipeCount++;
#endif
UMSS_KdPrint( DBGLVL_DEFAULT,("UMSS_ResetPipe() SUCCESS, ntStatus =0x%x\n", ntStatus ));
}
RETURN(ntStatus, UMSS_ResetPipe);
}
LONG
UMSS_DecrementIoCount(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
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
Arguments:
DeviceObject -- ptr to our FDO
Return Value:
deviceExtension->PendingIoCount
--*/
{
PDEVICE_EXTENSION deviceExtension;
LONG ioCount;
KIRQL oldIrql;
deviceExtension = DeviceObject->DeviceExtension;
KeAcquireSpinLock (&deviceExtension->IoCountSpinLock, &oldIrql);
ioCount = InterlockedDecrement(&deviceExtension->PendingIoCount);
#if DBG
InterlockedDecrement(&gpDbg->PendingIoCount);
#endif
UMSS_TrapCond( DBGLVL_HIGH,( 0 > ioCount ) );
if (ioCount==1)
{
// trigger no pending io
KeSetEvent(
&deviceExtension->NoPendingIoEvent,
1,
FALSE
);
}
if (ioCount==0)
{
// trigger remove-device event
KeSetEvent(
&deviceExtension->RemoveEvent,
1,
FALSE
);
}
KeReleaseSpinLock (&deviceExtension->IoCountSpinLock, oldIrql);
UMSS_KdPrint( DBGLVL_HIGH,("Exit UMSS_DecrementIoCount() Pending io count = %x\n", ioCount));
return ioCount;
}
VOID
UMSS_IncrementIoCount(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
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.
Arguments:
DeviceObject -- ptr to our FDO
Return Value:
NONE
--*/
{
PDEVICE_EXTENSION deviceExtension;
KIRQL oldIrql;
deviceExtension = DeviceObject->DeviceExtension;
UMSS_KdPrint( DBGLVL_HIGH,("Enter UMSS_IncrementIoCount() Pending io count = %x\n", deviceExtension->PendingIoCount));
KeAcquireSpinLock (&deviceExtension->IoCountSpinLock, &oldIrql);
InterlockedIncrement(&deviceExtension->PendingIoCount);
#if DBG
InterlockedIncrement(&gpDbg->PendingIoCount);
#endif
KeReleaseSpinLock (&deviceExtension->IoCountSpinLock, oldIrql);
UMSS_KdPrint( DBGLVL_HIGH,("Exit UMSS_IncrementIoCount() Pending io count = %x\n", deviceExtension->PendingIoCount));
}
BOOLEAN UMSS_GetDeviceProtocolFromRegistry(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Retrieves the device protocol to be used for the USB mass storage
device from the device's registry section.
Arguments:
DeviceObject - Device object for USB mass storage device.
Return Value:
TRUE if device protocol found in registry.
FALSE if device protocol not found in registry.
--*/
{
HANDLE RegistryHandle;
UCHAR DeviceProtocol;
RTL_QUERY_REGISTRY_TABLE paramTable[2];
PDEVICE_EXTENSION DeviceExtension;
ENTER(UMSS_GetDeviceProtocolFromRegistry);
DeviceExtension = DeviceObject->DeviceExtension;
if (NT_SUCCESS(IoOpenDeviceRegistryKey(
DeviceExtension->PhysicalDeviceObject,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_ALL,
&RegistryHandle) ) )
{
RtlZeroMemory (¶mTable[0], sizeof(paramTable));
paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[0].Name = L"DeviceProtocol";
paramTable[0].EntryContext = &DeviceProtocol;
paramTable[0].DefaultType = REG_BINARY;
paramTable[0].DefaultData = &DeviceProtocol;
paramTable[0].DefaultLength = sizeof(DeviceProtocol);
RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
(PCWSTR)RegistryHandle,
¶mTable[0],
NULL, // Context
NULL); // Environment
ZwClose(RegistryHandle);
DeviceExtension->DeviceProtocol = DeviceProtocol;
switch (DeviceProtocol)
{
case PROTOCOL_BULKONLY:
UMSS_KdPrint( DBGLVL_DEFAULT,("Protocol from registry - BULK ONLY\n"));
return TRUE;
case PROTOCOL_CBI:
UMSS_KdPrint( DBGLVL_DEFAULT,("Protocol from registry - CONTROL/BULK/INTERRUPT\n"));
return TRUE;
case PROTOCOL_CB:
UMSS_KdPrint( DBGLVL_DEFAULT,("Protocol from registry - CONTROL/BULK\n"));
return TRUE;
}
}
DeviceExtension->DeviceProtocol = PROTOCOL_UNDEFINED;
RETURN(FALSE, UMSS_GetDeviceProtocolFromRegistry);
}
BOOLEAN
UMSS_GetDeviceProtocolFromDescriptor(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Retrieves the device protocol to be used for the USB mass storage
device from the device's interface descriptor.
Arguments:
DeviceObject - Device object for USB mass storage device.
Return Value:
TRUE if valid device protocol found in descriptor.
FALSE if valid device protocol not found in descriptor.
--*/
{
ULONG DeviceProtocol;
PDEVICE_EXTENSION DeviceExtension;
ENTER(UMSS_GetDeviceProtocolFromDescriptor);
DeviceExtension = DeviceObject->DeviceExtension;
if (DeviceExtension->UsbInterface->Class == CLASS_MASS_STORAGE)
{
DeviceExtension->DeviceProtocol = DeviceExtension->UsbInterface->Protocol;
switch (DeviceExtension->DeviceProtocol)
{
case PROTOCOL_BULKONLY:
UMSS_KdPrint( DBGLVL_DEFAULT,("Protocol from descriptor - BULK ONLY\n"));
return TRUE;
case PROTOCOL_CBI:
UMSS_KdPrint( DBGLVL_DEFAULT,("Protocol from descriptor - CONTROL/BULK/INTERRUPT\n"));
return TRUE;
case PROTOCOL_CB:
UMSS_KdPrint( DBGLVL_DEFAULT,("Protocol from descriptor - CONTROL/BULK\n"));
return TRUE;
}
}
UMSS_KdPrint( DBGLVL_DEFAULT,("No protocol found in descriptor!\n"));
DeviceExtension->DeviceProtocol = PROTOCOL_UNDEFINED;
RETURN(FALSE, UMSS_GetDeviceProtocolFromDescriptor);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -