⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umss.c

📁 usb海量存储的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
        {
            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 (&paramTable[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,
                               &paramTable[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 + -