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

📄 usb.c

📁 usb2.0 驱动; 包括SYS目录
💻 C
📖 第 1 页 / 共 5 页
字号:
                         sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
	if ( !urb )
	{
		USB_KdPrint( DBGLVL_DEFAULT,("ERROR USB_ExAllocatePool return !urb\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}

    siz = sizeof(USB_CONFIGURATION_DESCRIPTOR) + 100;  
	
	USB_KdPrint( DBGLVL_DEFAULT,("sizeof(USB_CONFIGURATION_DESCRIPTOR) + 512 = (%x)\n",
						siz));
	// We will break out of this 'retry loop' when UsbBuildGetDescriptorRequest()
	// has a big enough deviceExtension->UsbConfigurationDescriptor buffer not to truncate
	while( 1 ) {

		deviceExtension->UsbConfigurationDescriptor = USB_ExAllocatePool(NonPagedPool, siz);

		if ( !deviceExtension->UsbConfigurationDescriptor ) {
			USB_KdPrint( DBGLVL_DEFAULT,("ERROR USB_ExAllocatePool return !UsbConfigurationDescriptor\n"));
		    USB_ExFreePool(urb);
			return STATUS_INSUFFICIENT_RESOURCES;
		}

		UsbBuildGetDescriptorRequest(urb,
									 (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
									 USB_CONFIGURATION_DESCRIPTOR_TYPE,
									 0,
									 0,
									 deviceExtension->UsbConfigurationDescriptor,
									 NULL,
									 siz,
									 NULL);

		ntStatus = USB_CallUSBD(DeviceObject, urb);

		USB_KdPrint( DBGLVL_DEFAULT,("USB_CallUSBD() Configuration Descriptor = %x, len %x , ntStatus %x\n",
						deviceExtension->UsbConfigurationDescriptor,
						urb->UrbControlDescriptorRequest.TransferBufferLength,ntStatus));
		//
		// if we got some data see if it was enough.
		// NOTE: we may get an error in URB because of buffer overrun
		if (urb->UrbControlDescriptorRequest.TransferBufferLength>0 &&
				deviceExtension->UsbConfigurationDescriptor->wTotalLength > siz) {

			siz = deviceExtension->UsbConfigurationDescriptor->wTotalLength;
			USB_ExFreePool(deviceExtension->UsbConfigurationDescriptor);
			deviceExtension->UsbConfigurationDescriptor = NULL;
		} else {
			break;  // we got it on the first try
		}

	} // end, while (retry loop )
	
	USB_KdPrint( DBGLVL_DEFAULT,("UsbConfigurationDescriptor->wTotalLength = (%x)\n",
						deviceExtension->UsbConfigurationDescriptor->wTotalLength));
    USB_ExFreePool(urb);
	USB_ASSERT( deviceExtension->UsbConfigurationDescriptor );

    //
    // We have the configuration descriptor for the configuration we want.
    // Now we issue the select configuration command to get
    // the  pipes associated with this configuration.
    //

    ntStatus = USB_SelectInterface(DeviceObject,
        deviceExtension->UsbConfigurationDescriptor);


    USB_KdPrint( DBGLVL_HIGH,("exit USB_ConfigureDevice (%x)\n", ntStatus));

    return ntStatus;
} 


NTSTATUS
USB_SelectInterface(
    IN PDEVICE_OBJECT DeviceObject,
    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
    )

{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus;
    PURB urb = NULL;
    ULONG i;
    PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL;
	PUSBD_INTERFACE_INFORMATION Interface = NULL;
    USHORT siz;
    PUCHAR pInf;

    USB_KdPrint( DBGLVL_MEDIUM,("enter USB_SelectInterface\n"));

    deviceExtension = DeviceObject->DeviceExtension;


    USB_KdPrint( DBGLVL_DEFAULT,("USB_SelectInterface() called with NULL Interface\n"));


    urb = USBD_CreateConfigurationRequest(ConfigurationDescriptor, &siz);

    if (urb) {

		//
		// USBD_ParseConfigurationDescriptorEx searches a given configuration
		// descriptor and returns a pointer to an interface that matches the 
		//  given search criteria. We only support one interface on this device
		//
        interfaceDescriptor =
            USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,
								  ConfigurationDescriptor, //search from start of config  descriptror
								  -1,	// interface number not a criteria; we only support one interface
								  -1,   // not interested in alternate setting here either
								  -1,   // interface class not a criteria
								  -1,   // interface subclass not a criteria
								  -1    // interface protocol not a criteria
								  );

		if ( !interfaceDescriptor ) {

			USB_KdPrint( DBGLVL_DEFAULT,("USB_SelectInterface() ParseConfigurationDescriptorEx() failed\n  returning STATUS_INSUFFICIENT_RESOURCES\n"));
			USB_ExFreePool(urb);
			return STATUS_INSUFFICIENT_RESOURCES;
		}

        Interface = &urb->UrbSelectConfiguration.Interface;


        // allocate space for an array of pipe information structs;
        //  in this basic sample, just used to track if opened/closed
        deviceExtension->PipeInfo = USB_ExAllocatePool(
            NonPagedPool, 
            Interface->NumberOfPipes * sizeof ( USB_PIPEINFO ) );
    
        if ( !deviceExtension->PipeInfo ) {
		    return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlZeroMemory(deviceExtension->PipeInfo,
            Interface->NumberOfPipes * sizeof ( USB_PIPEINFO ) );

        pInf = (PUCHAR ) deviceExtension->PipeInfo;

        for (i=0; i< Interface->NumberOfPipes; i++) {
            //
            // Perform any pipe initialization here;
			// We set the max transfer size and any Pipe flags we use; USBD sets the rest
			// of the Interface struct members
            //
            Interface->Pipes[i].MaximumTransferSize = deviceExtension->MaximumTransferSize;
            ( (PUSB_PIPEINFO) pInf)->fPipeOpened = FALSE;
            pInf += sizeof ( USB_PIPEINFO );
        }

        UsbBuildSelectConfigurationRequest(urb,
                                          (USHORT) siz,
                                          ConfigurationDescriptor);


        ntStatus = USB_CallUSBD(DeviceObject, urb);

        deviceExtension->UsbConfigurationHandle =
            urb->UrbSelectConfiguration.ConfigurationHandle;

    } else {
        USB_KdPrint( DBGLVL_DEFAULT,("USB_SelectInterface() USBD_CreateConfigurationRequest() failed\n  returning STATUS_INSUFFICIENT_RESOURCES\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }


    if (NT_SUCCESS(ntStatus)) {

        //
        // Save the configuration handle for this device
        //

        deviceExtension->UsbConfigurationHandle =
            urb->UrbSelectConfiguration.ConfigurationHandle;

        deviceExtension->UsbInterface = USB_ExAllocatePool(NonPagedPool,
                                                    Interface->Length);

        if (deviceExtension->UsbInterface) {
            ULONG j;

            //
            // save a copy of the interface information returned
            //
            RtlCopyMemory(deviceExtension->UsbInterface, Interface, Interface->Length);

            //
            // Dump the interface to the debugger
            //
            USB_KdPrint( DBGLVL_DEFAULT,("---------\n"));
            USB_KdPrint( DBGLVL_DEFAULT,("NumberOfPipes 0x%x\n", deviceExtension->UsbInterface->NumberOfPipes));
            USB_KdPrint( DBGLVL_DEFAULT,("Length 0x%x\n", deviceExtension->UsbInterface->Length));
            USB_KdPrint( DBGLVL_DEFAULT,("Alt Setting 0x%x\n", deviceExtension->UsbInterface->AlternateSetting));
            USB_KdPrint( DBGLVL_DEFAULT,("Interface Number 0x%x\n", deviceExtension->UsbInterface->InterfaceNumber));
            USB_KdPrint( DBGLVL_DEFAULT,("Class, subclass, protocol 0x%x 0x%x 0x%x\n",
                deviceExtension->UsbInterface->Class,
                deviceExtension->UsbInterface->SubClass,
                deviceExtension->UsbInterface->Protocol));

            // Dump the pipe info

            for (j=0; j<Interface->NumberOfPipes; j++) {
                PUSBD_PIPE_INFORMATION pipeInformation;

                pipeInformation = &deviceExtension->UsbInterface->Pipes[j];

                USB_KdPrint( DBGLVL_DEFAULT,("---------\n"));
                USB_KdPrint( DBGLVL_DEFAULT,("PipeType 0x%x\n", pipeInformation->PipeType));
                USB_KdPrint( DBGLVL_DEFAULT,("EndpointAddress 0x%x\n", pipeInformation->EndpointAddress));
                USB_KdPrint( DBGLVL_DEFAULT,("MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize));
                USB_KdPrint( DBGLVL_DEFAULT,("Interval 0x%x\n", pipeInformation->Interval));
                USB_KdPrint( DBGLVL_DEFAULT,("Handle 0x%x\n", pipeInformation->PipeHandle));
                USB_KdPrint( DBGLVL_DEFAULT,("MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize));
            }

            USB_KdPrint( DBGLVL_DEFAULT,("---------\n"));
        }
    }

    if (urb) {
		// don't call the USB_ExFreePool since the buffer was 
		//  alloced by USBD_CreateConfigurationRequest, not USB_ExAllocatePool()
        ExFreePool(urb);
    }
    USB_KdPrint( DBGLVL_DEFAULT,("exit USB_SelectInterface (%x)\n", ntStatus));

    return ntStatus; 
}



NTSTATUS
USB_ResetPipe(
    IN PDEVICE_OBJECT DeviceObject,
    IN PUSBD_PIPE_INFORMATION PipeInfo
    )

{
    NTSTATUS ntStatus;
    PURB urb;
    PDEVICE_EXTENSION deviceExtension;

    deviceExtension = DeviceObject->DeviceExtension;

    USB_KdPrint( DBGLVL_DEFAULT,("USB_ResetPipe() Reset Pipe %x\n", PipeInfo));

    urb = USB_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 =
            PipeInfo->PipeHandle;

        ntStatus = USB_CallUSBD(DeviceObject, urb);

        USB_ExFreePool(urb);

    } else {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    if (!(NT_SUCCESS(ntStatus))) {
#if DBG
		if ( gpDbg )
			gpDbg->PipeErrorCount++;
#endif

        USB_KdPrint( DBGLVL_DEFAULT,("USB_ResetPipe() FAILED, ntStatus =0x%x\n", ntStatus ));
    }
    else {
#if DBG
		if ( gpDbg )
			gpDbg->ResetPipeCount++;
#endif

        USB_KdPrint( DBGLVL_DEFAULT,("USB_ResetPipe() SUCCESS, ntStatus =0x%x\n", ntStatus ));
    }

    return ntStatus;
}




LONG
USB_DecrementIoCount(
    IN PDEVICE_OBJECT DeviceObject
    )


{
    PDEVICE_EXTENSION deviceExtension;
    LONG ioCount;
    KIRQL             oldIrql;

    deviceExtension = DeviceObject->DeviceExtension;
	KeAcquireSpinLock (&deviceExtension->IoCountSpinLock, &oldIrql);

    ioCount = InterlockedDecrement(&deviceExtension->PendingIoCount);
#if DBG
    InterlockedDecrement(&gpDbg->PendingIoCount);
#endif


    USB_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);

    USB_KdPrint( DBGLVL_HIGH,("Exit USB_DecrementIoCount() Pending io count = %x\n", ioCount));
    return ioCount;
}


VOID
USB_IncrementIoCount(
    IN PDEVICE_OBJECT DeviceObject
    )

{
    PDEVICE_EXTENSION deviceExtension;
    KIRQL             oldIrql;

    deviceExtension = DeviceObject->DeviceExtension;

    USB_KdPrint( DBGLVL_MAXIMUM,("Enter USB_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);

    USB_KdPrint( DBGLVL_HIGH,("Exit USB_IncrementIoCount() Pending io count = %x\n", deviceExtension->PendingIoCount));
}

////////////////////////////////////////
NTSTATUS
USB_ProcessPnPIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )

{

    PIO_STACK_LOCATION irpStack;
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    NTSTATUS waitStatus;
    PDEVICE_OBJECT stackDeviceObject;
    KEVENT startDeviceEvent;

    irpStack = IoGetCurrentIrpStackLocation (Irp);


    deviceExtension = DeviceObject->DeviceExtension;
    stackDeviceObject = deviceExtension->TopOfStackDeviceObject;
	USB_KdPrint( DBGLVL_DEFAULT,("USB_ProcessPnPIrp()\n"));
    USB_KdPrint( DBGLVL_MEDIUM, ( "enter USB_ProcessPnPIrp() IRP_MJ_PNP, minor %s\n",
        USB_StringForPnpMnFunc( irpStack->MinorFunction ) ));

        // inc the FDO device extension's pending IO count for this Irp
    USB_IncrementIoCount(DeviceObject);

    USB_ASSERT( IRP_MJ_PNP == irpStack->MajorFunction );

    switch (irpStack->MinorFunction) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -