Example #1
0
// Set usb device to unconfiguration state.
NTSTATUS UsbDev::SetToUnconfigure()
{
	NTSTATUS	ntStatus;
    PURB		pUrb;
    ULONG		siz;

	DBGU_TRACE(">>>UsbDev::Unconfigure !\n");
	siz = sizeof(struct _URB_SELECT_CONFIGURATION);
	pUrb = (PURB) ExAllocatePoolWithTag(NonPagedPool, siz, USBDEV_POOLTAG);
	
	if (pUrb) {
		UsbBuildSelectConfigurationRequest(pUrb, (USHORT) siz,	NULL);				
		ntStatus = SendAwaitUrb(pUrb);
	} 
	else 
	{	
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
	}
	
	if(!NT_SUCCESS(ntStatus)) 
		DBGU_TRACE("Fail to Unconfigure ! (Error : %x)\n",ntStatus);
	
	if(pUrb)
		ExFreePoolWithTag(pUrb,USBDEV_POOLTAG);
	
	return ntStatus;
}
Example #2
0
// Abort or Reset pipe
NTSTATUS UsbDev::PipeAbortOrReset(UCHAR InterfaceNo,UCHAR PipeNo,BOOLEAN Abort)
{
    NTSTATUS	ntStatus;
	PURB		pUrb;

	if (m_pInterface[InterfaceNo]) {//if (m_pInterfaceListEntry) {
		pUrb = (PURB) ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST), USBDEV_POOLTAG);
		
		if (pUrb) 
		{
			pUrb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
    		pUrb->UrbHeader.Function = (USHORT) (Abort ? URB_FUNCTION_ABORT_PIPE : URB_FUNCTION_RESET_PIPE);
			pUrb->UrbPipeRequest.PipeHandle = m_pInterface[InterfaceNo]->Pipes[PipeNo].PipeHandle;
			ntStatus = SendAwaitUrb(pUrb);
			ExFreePoolWithTag(pUrb,USBDEV_POOLTAG);
		} 
		else 
		{
			ntStatus = STATUS_INSUFFICIENT_RESOURCES;		
		}	
	}
	else {
		ntStatus = STATUS_UNSUCCESSFUL;
	}

	//2010/11/18 02:51下午
	if(Abort)
	{
		m_StopIsoThread[PipeNo] = TRUE;
		
		if(InterfaceNo == SELECTED_DATA_INTERFACE_INDEX)
		{
			if(&m_DataReadyEvent)
			{
				KeSetEvent(&m_DataReadyEvent, 0, FALSE);
				DBGU_TRACE("PipeAbort KeSetEvent(&m_DataReadyEvent, 0, FALSE)\n");
			}
		}
		else if(InterfaceNo == SELECTED_MPEG2_INTERFACE_INDEX)
		{
			if(&m_MEPG2DataReadyEvent)
			{
				KeSetEvent(&m_MEPG2DataReadyEvent, 0, FALSE);
				DBGU_TRACE("PipeAbort KeSetEvent(&m_MEPG2DataReadyEvent, 0, FALSE)\n");
			}
		}
	}

#if DBG
	if(Abort)
		DBGU_TRACE("UsbDev::PipeAbortOrReset ! Num = %d, (ABORT PIPE), Status : %x\n",InterfaceNo, ntStatus);
	else
		DBGU_TRACE("UsbDev::PipeAbortOrReset ! Num = %d, (RESET PIPE), Status : %x\n",InterfaceNo, ntStatus);
#endif
    
	return ntStatus;
}
VOID StopDevice(IN PDEVICE_OBJECT fdo, BOOLEAN oktouch /* = FALSE */)
{
    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
    
    // Stop polling
    StopPolling(pdx);

    // Disable the operational interface
    IoSetDeviceInterfaceState(&pdx->operationsInterfaceName, FALSE);

    // Disable the inquiry interface
    IoSetDeviceInterfaceState(&pdx->inquiriesInterfaceName, FALSE);
    
    // wait for polling thread to exit 
    if(pdx->RecoveryThread)
    { 
        // stop recovery thread
        pdx->RecoveryExit = TRUE;
        KeSetEvent(&pdx->RecoveryEvent, 0, FALSE);
        
        KeWaitForSingleObject(pdx->RecoveryThread, Executive, KernelMode, FALSE, NULL);    

        ObDereferenceObject(pdx->RecoveryThread);

        pdx->RecoveryThread = NULL;
    }

    // If it's okay to touch our hardware (i.e., we're processing an IRP_MN_STOP_DEVICE),
    // deconfigure the device.
    if(oktouch) 
    {
        URB urb;
        
        UsbBuildSelectConfigurationRequest(&urb, sizeof(_URB_SELECT_CONFIGURATION), NULL);

        NTSTATUS status = SendAwaitUrb(fdo, &urb);

        if(!NT_SUCCESS(status))
        {
            KdPrint((DRIVERNAME " - Error %X trying to deconfigure device\n", status));
        }
    }

    if(pdx->pcd)
    {
        ExFreePool(pdx->pcd);
        
        pdx->pcd = NULL;
    }
}
Example #4
0
// Send vendor specific command to usb device by control pipe.
NTSTATUS UsbDev::UsbControlVendorTransfer(
	USHORT Functions,
	BOOL  Rw,
	UCHAR Request,
	USHORT Value,
	USHORT Index,
	PVOID TransferBuffer,
	ULONG TransferBufferLength
	)
{
	NTSTATUS	ntStatus = STATUS_SUCCESS;
    PURB		Urb;

	Urb = (PURB) ExAllocatePoolWithTag(NonPagedPool,
			sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), USBDEV_POOLTAG);

    if (Urb) 
	{// if Urb != NULL
		RtlZeroMemory((void *) Urb, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
		UsbBuildVendorRequest(
					Urb,																// Urb
					Functions,															// Functions
					(USHORT)sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),		// Length 
					(Rw ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT),	// TransferFlags
					0,																	// ReservedBits 
					Request,															// Request
					Value,														// Value 
					Index,														// Index
					TransferBuffer,												// TransferBuffer
					NULL,														// TransferBufferMDL
					TransferBufferLength,										// TransferBufferLength 
					NULL);														// Link 
        ntStatus = SendAwaitUrb(Urb);
	    ExFreePoolWithTag(Urb,USBDEV_POOLTAG);
//		if (!NT_SUCCESS(ntStatus)) 
//		{
//			DBGU_TRACE("Cannot WriteCommandToASIC %X!!\n",ntStatus);
//		}
    }// if Urb != NULL
	else 
	{// if Urb == NULL	
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }// if Urb == NULL

    return ntStatus;
}
Example #5
0
// Set the configuration of the usb device.
NTSTATUS UsbDev::SetConfiguration()
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
    PUSBD_INTERFACE_LIST_ENTRY	pTempInterfaceList = NULL, pTempInterfaceList_First = NULL;
	PUSB_CONFIGURATION_DESCRIPTOR pTemp_pConfigDesc = m_pConfigDesc[m_UsbConfigurationNo];
	int i,j,NoOfInterface;
	PUSB_INTERFACE_DESCRIPTOR pTempInterfaceDesc = NULL;
	PURB pUrb = NULL;
	//2010/8/17 03:49下午
	KIRQL oldIrql;
	PUSBD_INTERFACE_INFORMATION interface_temp;
	
	//2010/8/16 06:17下午
	NoOfInterface = pTemp_pConfigDesc->bNumInterfaces;
	DBGU_TRACE(">>>UsbDev::SetConfiguration ! NoOfInterface = %d\n",NoOfInterface);
	pTempInterfaceList_First = pTempInterfaceList = (PUSBD_INTERFACE_LIST_ENTRY) ExAllocatePoolWithTag( NonPagedPool,	sizeof(USBD_INTERFACE_LIST_ENTRY) * (NoOfInterface + 1), USBDEV_POOLTAG);
	
	//2010/8/23 11:51上午
	m_NumberOfInterfaces = NoOfInterface;
	
	if(pTempInterfaceList)
	{// pTempInterfaceList != NULL
		RtlZeroMemory(pTempInterfaceList, sizeof(USBD_INTERFACE_LIST_ENTRY) * (NoOfInterface + 1));

		for(i=0;i<NoOfInterface;i++) 
		{// for loop i
			pTempInterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseConfigurationDescriptorEx( 
														m_pConfigDesc[0],		// Pointer to configuration descriptor
														m_pConfigDesc[0],		// Start position
														i,					// Interface number
														-1,//0,					// Alternate setting
														-1,
														-1,
														-1);

			if(!pTempInterfaceDesc)
				break;

			pTempInterfaceList->InterfaceDescriptor = pTempInterfaceDesc;
			pTempInterfaceList++;
		}// for loop i

	    pTempInterfaceList->InterfaceDescriptor = NULL;	// Mark the end of the list
		//pTempInterfaceList = pTempInterfaceList_First; // Pointer to the first entry of the interface list.
		pUrb = USBD_CreateConfigurationRequestEx(pTemp_pConfigDesc, pTempInterfaceList_First);

		if(pUrb) 
		{// pUrb != NULL
			for(i=0;i<NoOfInterface;i++) 
			{// for loop i
				// Set to interface i, alternater 0
				pTempInterfaceList_First[i].Interface->InterfaceNumber	= i;
				pTempInterfaceList_First[i].Interface->AlternateSetting	= 0;	
				DBGU_TRACE("No of endpoints : %d\n", pTempInterfaceList_First[i].InterfaceDescriptor->bNumEndpoints);
				
				for(j=0;j<pTempInterfaceList_First[i].InterfaceDescriptor->bNumEndpoints;j++) 
					pTempInterfaceList_First[i].Interface->Pipes[j].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
			}// for loop i
			
			//2010/8/24 05:51下午
			interface_temp = &pUrb->UrbSelectConfiguration.Interface;
			
			ntStatus = SendAwaitUrb(pUrb);
			
			if(!NT_SUCCESS(ntStatus)) 
			{// ntStatus != STATUS_SUCCESS
				ntStatus = STATUS_IO_DEVICE_ERROR;
				DBGU_TRACE("Fail to configure usb device !\n");
			}// ntStatus != STATUS_SUCCESS
			else
			{// ntStatus == STATUS_SUCCESS
				m_hConfigureation = pUrb->UrbSelectConfiguration.ConfigurationHandle;
				//Release memory
				//if(m_pInterfaceListEntry)
				{ // m_pInterfaceListEntry != NULL
					for(i=0;i<m_NumberOfInterfaces;i++)
						if(m_pInterface[i])
						{
							ExFreePoolWithTag(m_pInterface[i],USBDEV_POOLTAG);
							m_pInterface[i] = NULL;
							DBGU_TRACE("ExFreePoolWithTag m_pInterface[%d]\n",i);
						}
				//	ExFreePoolWithTag(m_pInterfaceListEntry,USBDEV_POOLTAG);
				//	m_pInterfaceListEntry = NULL;
				} // m_pInterfaceListEntry != NULL
				//2010/8/23 11:51上午
				//m_NumberOfInterfaces = NoOfInterface;
				//Copy interface list
				//m_pInterfaceListEntry = (PUSBD_INTERFACE_LIST_ENTRY) ExAllocatePoolWithTag(NonPagedPool,(m_NumberOfInterfaces * sizeof(USBD_INTERFACE_LIST_ENTRY)), USBDEV_POOLTAG);

				//if(m_pInterfaceListEntry)
				{// m_pInterfaceListEntry != NULL
					
					for(i=0;i<m_NumberOfInterfaces;i++) 
					{//for loop i
						//m_pInterfaceListEntry[i].InterfaceDescriptor = pTempInterfaceList_First[i].InterfaceDescriptor;
#ifdef __VIDEO_CLASS__
						// For Video Class Device
						if (pTempInterfaceList_First[i].Interface->InterfaceNumber==1) // UVC has 2 interfaces
						{
							//2011/5/12 02:22下午
							if(BeST5R286)
								pTempInterfaceList_First[i].Interface->NumberOfPipes = 2;
							else
								pTempInterfaceList_First[i].Interface->NumberOfPipes = 1;
							
							pTempInterfaceList_First[i].Interface->Length = sizeof(USBD_INTERFACE_INFORMATION);
						}

						// james try M2TS.
						if (pTempInterfaceList_First[i].Interface->InterfaceNumber==2)
						{
							pTempInterfaceList_First[i].Interface->NumberOfPipes = 1;
							pTempInterfaceList_First[i].Interface->Length = sizeof(USBD_INTERFACE_INFORMATION);
						}
#endif
						//2010/8/24 05:53下午
//						m_pInterface[i] = (PUSBD_INTERFACE_INFORMATION) ExAllocatePoolWithTag(NonPagedPool, pTempInterfaceList_First[i].Interface->Length, USBDEV_POOLTAG);
						if(BeST5R286)
							m_pInterface[i] = (PUSBD_INTERFACE_INFORMATION) ExAllocatePoolWithTag(NonPagedPool, GET_USBD_INTERFACE_SIZE(2), USBDEV_POOLTAG);
						else
							m_pInterface[i] = (PUSBD_INTERFACE_INFORMATION) ExAllocatePoolWithTag(NonPagedPool, interface_temp->Length, USBDEV_POOLTAG);
						
						//2010/8/17 05:42下午
						//KeAcquireSpinLock(&SetConfigSpinLock, &oldIrql);

						//2010/8/13 05:20下午
						if (m_pInterface[i] && pTempInterfaceList_First[i].Interface && pTempInterfaceList_First[i].Interface->Length >0)
						//if (m_pInterfaceListEntry[i].Interface)
						{
							//2010/8/25 10:52上午
							//DBGU_TRACE("RtlCopyMemory Interface[%d] len = %d\n",i,pTempInterfaceList_First[i].Interface->Length);
							//RtlCopyMemory(m_pInterface[i], pTempInterfaceList_First[i].Interface, pTempInterfaceList_First[i].Interface->Length);
							DBGU_TRACE("MJ RtlCopyMemory Interface[%d] len = %d\n",i,interface_temp->Length);
							RtlCopyMemory(m_pInterface[i], interface_temp, interface_temp->Length);
							m_pInterface[i]->InterfaceNumber	= i;
							m_pInterface[i]->AlternateSetting	= 0;	
							
							if(i==0)
								m_pInterface[i]->Pipes[0].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
							else
							{
								if(BeST5R286)
									m_pInterface[i]->NumberOfPipes = 2;
								else	
									m_pInterface[i]->NumberOfPipes = 1;
							}

						}
						else
						{
							DBGU_TRACE("RtlCopyMemory Interface[%d] STATUS_INSUFFICIENT_RESOURCES\n",i);
							ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						}	
						//2010/8/17 03:42下午
						//KeReleaseSpinLock(&SetConfigSpinLock, oldIrql);
					}//for loop i
					

				}// m_pInterfaceListEntry != NULL
				/*else
				{// m_pInterfaceListEntry == NULL
					ntStatus = STATUS_INSUFFICIENT_RESOURCES;
				}*/// m_pInterfaceListEntry == NULL
			}// ntStatus == STATUS_SUCCESS
		}// pUrb != NULL
		else
		{// pUrb == NULL
			ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		}// pUrb == NULL
	}// pTempInterfaceList != NULL
	else
	{// pTempInterfaceList == NULL
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
	}// pTempInterfaceList == NULL

	if(pUrb) 
		ExFreePool(pUrb);

	if(pTempInterfaceList_First)
	{
		ExFreePoolWithTag(pTempInterfaceList_First,USBDEV_POOLTAG);
		//2010/8/16 07:00下午
		pTempInterfaceList_First = NULL;
	}

	return ntStatus;
}
Example #6
0
// Set the alternate setting of the interface.
NTSTATUS UsbDev::SetAlternate(UCHAR AlternateNo, UCHAR InterfaceNo)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
	PURB pUrb = NULL;
	PUSBD_INTERFACE_INFORMATION pInterfaceInfo = NULL;
	int i;

	DBGU_TRACE(">>>UsbDev::SetAlternate !\n");

	if (m_pInterface[InterfaceNo])
		pInterfaceInfo = m_pInterface[InterfaceNo];

	if(pInterfaceInfo)
	{//pInterfaceInfo != NULL
#ifdef __VIDEO_CLASS__
		// For Video Class Device
		DBGU_TRACE("Change information for ISO Interface\n");
		/*
		if (InterfaceNo == 1)
			pInterfaceInfo->NumberOfPipes = 1;

		if ((InterfaceNo == 1)&&(AlternateNo > 0))
			pInterfaceInfo->Length = sizeof(USBD_INTERFACE_INFORMATION);
		*/
		// james try M2TS.
		if (InterfaceNo == 1 || InterfaceNo == 2)
		{
			//if(TwoPipeEnable)
			if(BeST5R286)
			{
				pInterfaceInfo->NumberOfPipes = 2;

				if (AlternateNo > 0)
				{
					//2010/10/28 06:45下午 test
					pInterfaceInfo->Length = GET_USBD_INTERFACE_SIZE(2);//sizeof(USBD_INTERFACE_INFORMATION);
					
					//2010/11/18 03:17下午
					if(TwoPipeEnable)
					{
						m_StopIsoThread[0] = FALSE;
						m_StopIsoThread[1] = FALSE;
					}
					else
						m_StopIsoThread[0] = FALSE;
				}				
			}
			else
			{
					pInterfaceInfo->NumberOfPipes = 1;
					if (AlternateNo > 0)
						pInterfaceInfo->Length = sizeof(USBD_INTERFACE_INFORMATION);
					m_StopIsoThread[0] = FALSE;			
			}
		}
#endif
		pUrb = (PURB) ExAllocatePoolWithTag(NonPagedPool, GET_SELECT_INTERFACE_REQUEST_SIZE(pInterfaceInfo->NumberOfPipes), USBDEV_POOLTAG);

		if(pUrb) 
		{//pUrb != NULL
			pInterfaceInfo->AlternateSetting = AlternateNo;

			for(i=0;i<pInterfaceInfo->NumberOfPipes;i++)
			{
				if (m_fUSBHighSpeed)
					pInterfaceInfo->Pipes[i].MaximumTransferSize = MAX_TRANSFER_SIZE_2;
				else
					pInterfaceInfo->Pipes[i].MaximumTransferSize = MAX_TRANSFER_SIZE;

				pInterfaceInfo->Pipes[i].PipeFlags = 0;
			}

			RtlCopyMemory(&pUrb->UrbSelectInterface.Interface, pInterfaceInfo, pInterfaceInfo->Length);
			pUrb->UrbHeader.Length   = GET_SELECT_INTERFACE_REQUEST_SIZE(pInterfaceInfo->NumberOfPipes);
			pUrb->UrbHeader.Function = URB_FUNCTION_SELECT_INTERFACE;
			pUrb->UrbSelectInterface.ConfigurationHandle = m_hConfigureation;
			ntStatus = SendAwaitUrb(pUrb);

			if(!NT_SUCCESS(ntStatus))
			{//ntStatus != STATUS_SUCCESS
				DBGU_TRACE("ERR: Fail to set alternate setting !!\n");
				ntStatus = STATUS_UNSUCCESSFUL;
			}//ntStatus != STATUS_SUCCESS
			else
			{//ntStatus == STATUS_SUCCESS
				if(pInterfaceInfo->Length > pUrb->UrbSelectInterface.Interface.Length) 
					pInterfaceInfo->Length = pUrb->UrbSelectInterface.Interface.Length;

				RtlCopyMemory(pInterfaceInfo, &pUrb->UrbSelectInterface.Interface, pUrb->UrbSelectInterface.Interface.Length);
				//Display interface information
#if DBG
				DBGU_TRACE(" Interface Information\n");
				DBGU_TRACE(" -----------------------------------\n");
				DBGU_TRACE(" Length: %x\n",pUrb->UrbSelectInterface.Interface.Length);
				DBGU_TRACE(" InterfaceNumber: %x\n",pUrb->UrbSelectInterface.Interface.InterfaceNumber);
				DBGU_TRACE(" AlternateSetting: %x\n", pUrb->UrbSelectInterface.Interface.AlternateSetting);
				DBGU_TRACE(" NumberOfPipes: %x\n",pUrb->UrbSelectInterface.Interface.NumberOfPipes);
				DBGU_TRACE(" Class: %x\n",pUrb->UrbSelectInterface.Interface.Class);
				DBGU_TRACE(" SubClass: %x\n",	pUrb->UrbSelectInterface.Interface.SubClass);
				DBGU_TRACE(" Protocol: %x\n",pUrb->UrbSelectInterface.Interface.Protocol);
				DBGU_TRACE(" InterfaceHandle: %x\n",pUrb->UrbSelectInterface.Interface.InterfaceHandle);
				DBGU_TRACE(" -----------------------------------\n");

				for(i=0;i<pInterfaceInfo->NumberOfPipes;i++) 
				{// for loop i
					DBGU_TRACE(" Pipes (%x) Information\n",i);
					DBGU_TRACE(" -----------------------------------\n");	
					DBGU_TRACE(" EndpointAddress: %x\n",pUrb->UrbSelectInterface.Interface.Pipes[i].EndpointAddress);     
					DBGU_TRACE(" PipeType: %x\n",pUrb->UrbSelectInterface.Interface.Pipes[i].PipeType);
					DBGU_TRACE(" PipeHandle: %x\n",pUrb->UrbSelectInterface.Interface.Pipes[i].PipeHandle);
					DBGU_TRACE(" MaximumPacketSize: %x\n",pUrb->UrbSelectInterface.Interface.Pipes[i].MaximumPacketSize);
				}// for loop i

				DBGU_TRACE(" -----------------------------------\n");	
#endif
			}//ntStatus == STATUS_SUCCESS
		}//pUrb != NULL
		else
		{//pUrb == NULL
			ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		}//pUrb == NULL
	}//pInterfaceInfo != NULL
	else
	{//pInterfaceInfo == NULL
		DBGU_TRACE("pInterfaceInfo == NULL !\n");
		ntStatus = STATUS_UNSUCCESSFUL;
	}//pInterfaceInfo == NULL

	if(pUrb)
		ExFreePoolWithTag(pUrb,USBDEV_POOLTAG);
	
	return ntStatus;
}
Example #7
0
// Get Usb Configuration Descriptor
NTSTATUS UsbDev::GetConfigurationDescriptor()
{
	NTSTATUS						ntStatus = STATUS_SUCCESS;
    PURB							pUrb;
    ULONG							siz;
	UCHAR							index;
	PUSB_CONFIGURATION_DESCRIPTOR	pTemp_pConfigDesc = NULL;

	DBGU_TRACE(">>>UsbDev::GetConfigurationDescriptor !\n");
	pUrb = (PURB) ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), USBDEV_POOLTAG);

	if(pUrb)
	{//pUrb != NULL	
		RtlZeroMemory(pUrb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

		for(index=0;index<m_DevDesc.bNumConfigurations;index++)
		{//travel all configurations
			siz = 64;
get_config_descriptor_retry:
			if(pTemp_pConfigDesc) ExFreePoolWithTag(pTemp_pConfigDesc,USBDEV_POOLTAG);

			if ((pTemp_pConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, siz, USBDEV_POOLTAG)))
			{//pTemp_pConfigDesc != NULL
				RtlZeroMemory(pTemp_pConfigDesc,siz);
				UsbBuildGetDescriptorRequest(
					pUrb,
					(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
					USB_CONFIGURATION_DESCRIPTOR_TYPE,
					index,
					0,
					pTemp_pConfigDesc,
					NULL,
					siz,
					NULL);
				ntStatus = SendAwaitUrb(pUrb);

				if(!NT_SUCCESS(ntStatus))
				{//ntStatus != STATUS_SUCCESS
					DBGU_TRACE("ERR: Fail to get configuration descriptor !!\n");
					ExFreePoolWithTag(pTemp_pConfigDesc,USBDEV_POOLTAG);
					ntStatus = STATUS_INSUFFICIENT_RESOURCES;
					break;
				}//ntStatus != STATUS_SUCCESS

				if ((pUrb->UrbControlDescriptorRequest.TransferBufferLength>0) && \
					(pTemp_pConfigDesc->wTotalLength>siz)) 
				{
					siz = pTemp_pConfigDesc->wTotalLength;
					goto get_config_descriptor_retry;
				}

				m_pConfigDesc[index] = pTemp_pConfigDesc;
				pTemp_pConfigDesc = NULL;
				// Print configuration descriptor
				DBGU_TRACE("  Configuration Descriptor: %x\n",index);
				DBGU_TRACE("  -------------------------\n");
				DBGU_TRACE("  bLength %x\n",m_pConfigDesc[index]->bLength);
				DBGU_TRACE("  bDescriptorType %x\n",m_pConfigDesc[index]->bDescriptorType);
				DBGU_TRACE("  wTotalLength %x\n",m_pConfigDesc[index]->wTotalLength);
				DBGU_TRACE("  bNumInterfaces %x\n",m_pConfigDesc[index]->bNumInterfaces);
				DBGU_TRACE("  bConfigurationValue %x\n",m_pConfigDesc[index]->bConfigurationValue);
				DBGU_TRACE("  iConfiguration %x\n",m_pConfigDesc[index]->iConfiguration);
				DBGU_TRACE("  MaxPower %x\n",m_pConfigDesc[index]->MaxPower);
				DBGU_TRACE("  -------------------------\n");
			}//pTemp_pConfigDesc != NULL
			else
			{//pTemp_pConfigDesc == NULL
				DBGU_TRACE("ERR: Fail to allocate memory for m_pConfigDesc !!\n");
				ntStatus = STATUS_INSUFFICIENT_RESOURCES;
				break;
			}//pTemp_pConfigDesc == NULL
		}//travel all configurations
	}//pUrb != NULL	
	else 
	{//pUrb == NULL	
		DBGU_TRACE("ERR: Fail to allocate memory for pUrb !!\n");
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
	}//pUrb == NULL

	if(pUrb) ExFreePoolWithTag(pUrb,USBDEV_POOLTAG);

    return ntStatus;
}
Example #8
0
// Get Usb Device Descriptor
NTSTATUS UsbDev::GetDeviceDescriptor()
{
	NTSTATUS	ntStatus;
    PURB		pUrb;

	DBGU_TRACE(">>>UsbDev::GetDeviceDescriptor !\n");
    pUrb = (PURB) ExAllocatePoolWithTag(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST), USBDEV_POOLTAG);

    if (pUrb) 
	{//pUrb != NULL
		RtlZeroMemory((void *) pUrb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
        UsbBuildGetDescriptorRequest(
			pUrb,
			(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
			USB_DEVICE_DESCRIPTOR_TYPE,
			0,
			0,
			&m_DevDesc,
			NULL,
			sizeof(USB_DEVICE_DESCRIPTOR),
			NULL);
        ntStatus = SendAwaitUrb(pUrb);
	    ExFreePoolWithTag(pUrb,USBDEV_POOLTAG);

#if DBG
        if (NT_SUCCESS(ntStatus)) {

			//Print the infomation of device descriptor
            DBGU_TRACE("  Device Descriptor:\n");
            DBGU_TRACE("  -------------------------\n");
            DBGU_TRACE("  bLength %x\n", m_DevDesc.bLength);
            DBGU_TRACE("  bDescriptorType 0x%x\n", m_DevDesc.bDescriptorType);
            DBGU_TRACE("  bcdUSB 0x%x\n", m_DevDesc.bcdUSB);
            DBGU_TRACE("  bDeviceClass 0x%x\n", m_DevDesc.bDeviceClass);
            DBGU_TRACE("  bDeviceSubClass 0x%x\n", m_DevDesc.bDeviceSubClass);
            DBGU_TRACE("  bDeviceProtocol 0x%x\n", m_DevDesc.bDeviceProtocol);
            DBGU_TRACE("  bMaxPacketSize0 0x%x\n", m_DevDesc.bMaxPacketSize0);
            DBGU_TRACE("  idVendor 0x%x\n", m_DevDesc.idVendor);
            DBGU_TRACE("  idProduct 0x%x\n", m_DevDesc.idProduct);
            DBGU_TRACE("  bcdDevice 0x%x\n", m_DevDesc.bcdDevice);
            DBGU_TRACE("  iManufacturer 0x%x\n", m_DevDesc.iManufacturer);
            DBGU_TRACE("  iProduct 0x%x\n", m_DevDesc.iProduct);
            DBGU_TRACE("  iSerialNumber 0x%x\n", m_DevDesc.iSerialNumber);
            DBGU_TRACE("  bNumConfigurations 0x%x\n", m_DevDesc.bNumConfigurations);
            DBGU_TRACE("  -------------------------\n");
			
        } 
		else 
		{
			DBGU_TRACE("ERR: Cannot get device descriptor !!\n");
		}
#endif
    }//pUrb != NULL 
	else 
	{//pUrb == NULL	
		DBGU_TRACE("ERR: Fail to allocate memory for pUrb !!\n");
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }//pUrb == NULL

    return ntStatus;
}
NTSTATUS StartDevice( PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated )
{
    USB_CONFIGURATION_DESCRIPTOR  tcd;
    PUSB_CONFIGURATION_DESCRIPTOR pcd;
    PUSB_STRING_DESCRIPTOR        desc;            
    HANDLE                        RecoveryHandle;
    PURB                          selurb;
    URB                           urb;     
    NTSTATUS                      status;

    status = STATUS_SUCCESS; 
    
    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

    selurb = NULL;
    pcd    = NULL;

    // Read our device descriptor. The only real purpose to this would be to find out how many
    // configurations there are so we can read their descriptors. In this simplest of examples,
    // there's only one configuration.
    
    KdPrint((DRIVERNAME " - Start device\n"));

    UsbBuildGetDescriptorRequest(
                                  &urb, 
                                  sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                  USB_DEVICE_DESCRIPTOR_TYPE,
                                  0, 
                                  LangId, 
                                  &pdx->dd, 
                                  NULL, 
                                  sizeof(pdx->dd), 
                                  NULL
                                );
 
    status = SendAwaitUrb( fdo, &urb );
    
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to retrieve device descriptor\n", status));
        goto cleanup;
    }

    // allocate the buffer for the descriptor; take extra space to null terminate the bString member
    desc = (PUSB_STRING_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, SPOT_TAG );

    if(!desc)
    {
        KdPrint((DRIVERNAME " - Unable to allocate %X bytes for string descriptor\n", sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }
    
    pdx->devHash = desc;

    UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_STRING_DESCRIPTOR_TYPE,
                                 DeviceId, 
                                 LangId, 
                                 desc, 
                                 NULL, 
                                 sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes,
                                 NULL);
    
    status = SendAwaitUrb(fdo, &urb);
    
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to retrieve string descriptor for DeviceId\n", status));
        goto cleanup;
    }
        
    // null terminate the buffer; we allocated one more wchar_t for the purpose 
    desc->bString[ (desc->bLength / 2) - 1 ] = L'\0';

    UpdateDeviceInformation( fdo );

    // Read the descriptor of the first configuration. This requires two steps. The first step
    // reads the fixed-size configuration descriptor alone. The second step reads the
    // configuration descriptor plus all imbedded interface and endpoint descriptors.

    UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                 0, 
                                 LangId, 
                                 &tcd, 
                                 NULL, 
                                 sizeof(tcd), 
                                 NULL);

    status = SendAwaitUrb(fdo, &urb);
    
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status));
        goto cleanup;
    }

    ULONG size = tcd.wTotalLength;
    
    pcd = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size, SPOT_TAG);
    
    if(!pcd)
    {
        KdPrint((DRIVERNAME " - Unable to allocate %X bytes for configuration descriptor\n", size));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                 0, 
                                 LangId, 
                                 pcd, 
                                 NULL, 
                                 size, 
                                 NULL);

    status = SendAwaitUrb(fdo, &urb);
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status));
        goto cleanup;
    }
                           
    // Locate the descriptor for the one and only interface we expect to find

    PUSB_INTERFACE_DESCRIPTOR pid = USBD_ParseConfigurationDescriptorEx(pcd, 
                                                                        pcd,
                                                                        -1, 
                                                                        -1, 
                                                                        -1, 
                                                                        -1, 
                                                                        -1);

    ASSERT(pid);
                           
    // Create a URB to use in selecting a configuration.

    USBD_INTERFACE_LIST_ENTRY interfaces[2] = {
        {pid, NULL},
        {NULL, NULL},        // fence to terminate the array
    };

    selurb = USBD_CreateConfigurationRequestEx(pcd, interfaces);
    if(!selurb)
    {
        KdPrint((DRIVERNAME " - Unable to create configuration request\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    // Verify that the interface describes exactly the endpoints we expect
    if(pid->bNumEndpoints != 2)
    {
        KdPrint((DRIVERNAME " - %d is the wrong number of endpoints\n", pid->bNumEndpoints));
        status = STATUS_DEVICE_CONFIGURATION_ERROR;
        goto cleanup;
    }

    PUSB_ENDPOINT_DESCRIPTOR ped = (PUSB_ENDPOINT_DESCRIPTOR) pid;
    ped = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(pcd, tcd.wTotalLength, ped, USB_ENDPOINT_DESCRIPTOR_TYPE);
    if(!ped || 0 == (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64)
    {
        KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n"));
        status = STATUS_DEVICE_CONFIGURATION_ERROR;
        goto cleanup;
    }
    ++ped;
    if(!ped || 0 != (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64)
    {
        KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n"));
        status = STATUS_DEVICE_CONFIGURATION_ERROR;
        goto cleanup;
    }
    ++ped;

    PUSBD_INTERFACE_INFORMATION pii = interfaces[0].Interface;
    ASSERT(pii->NumberOfPipes == pid->bNumEndpoints);

    // Initialize the maximum transfer size for each of the endpoints. The
    // default would be PAGE_SIZE. The firmware itself only has a 4096-byte
    // ring buffer, though. We need to restrict the test applet to that many
    // bytes. In order to exercise the multi-segment aspect of the transfer code,
    // therefore, reduce the maximum transfer size to 1024 bytes.

    pii->Pipes[0].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
    pii->Pipes[1].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
    pdx->maxtransfer = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;

    // Submit the set-configuration request

    status = SendAwaitUrb(fdo, selurb);
    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - Error %X trying to select configuration\n", status));
        goto cleanup;
    }

    // Save the configuration and pipe handles
    pdx->hconfig = selurb->UrbSelectConfiguration.ConfigurationHandle;
    pdx->hinpipe = pii->Pipes[0].PipeHandle;
    pdx->houtpipe = pii->Pipes[1].PipeHandle;

    // Transfer ownership of the configuration descriptor to the device extension

    pdx->pcd = pcd;
    pcd = NULL;

    // Enable the interface
    IoSetDeviceInterfaceState(&pdx->operationsInterfaceName, TRUE);        

    // Enable the interface
    IoSetDeviceInterfaceState(&pdx->inquiriesInterfaceName, TRUE);                    

    // create recovery thread                     
    status = PsCreateSystemThread(&RecoveryHandle, 0, NULL, NULL, NULL, RecoveryThread, (PVOID)pdx);

    if(!NT_SUCCESS(status))
    {
        KdPrint((DRIVERNAME " - PsCreateSystemThread failed with error %08x\n", status));
        goto cleanup;
    }
    
    status = ObReferenceObjectByHandle( RecoveryHandle,
                                        SYNCHRONIZE,
                                        NULL,
                                        KernelMode,
                                        (PVOID*)&pdx->RecoveryThread,
                                        NULL );

    ASSERT(NT_SUCCESS(status));

    ZwClose(RecoveryHandle);
    
    // Start polling
    status = StartPolling(pdx);
    
    if(!NT_SUCCESS(status))
    {   
        KdPrint((DRIVERNAME " - StartPolling failed 0x%08x\n", status));

        if(pdx->RecoveryThread)
        {
            // shutdown recovery thread
            pdx->RecoveryExit = TRUE; 
            KeSetEvent(&pdx->RecoveryEvent, 0, FALSE);    
            // wait for polling thread to exit 
            KeWaitForSingleObject(pdx->RecoveryThread, Executive, KernelMode, FALSE, NULL);     
            ObDereferenceObject(pdx->RecoveryThread);
            pdx->RecoveryThread = NULL;
        }
        
        goto cleanup;
    }
    
cleanup:
    if(selurb) ExFreePool(selurb);
    if(pcd   ) ExFreePool(pcd   );

    // get rid of return codes like STATUS_PENDING
    if(NT_SUCCESS(status)) 
    {
        return STATUS_SUCCESS;
    }
    
    return status;
}
NTSTATUS UpdateDeviceInformation( PDEVICE_OBJECT fdo )
{
    PUSB_STRING_DESCRIPTOR desc;
    UNICODE_STRING         dummy;
    URB                    urb;    
    int                    id;      
    NTSTATUS               status;
    
    KdPrint((DRIVERNAME " - UpdateDeviceInformation\n"));

    status = STATUS_SUCCESS;

    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

    // initialize buffers
    pdx->manufacturer.Buffer = NULL;
    pdx->product     .Buffer = NULL;
    pdx->serialNumber.Buffer = NULL;
    pdx->displayName .Buffer = NULL;
    desc                     = NULL;
    
    // allocate buffers for all strings
    pdx->manufacturer.Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG );
    pdx->product     .Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG );
    pdx->serialNumber.Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG );
    pdx->displayName .Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG );

    if( 
        (pdx->manufacturer.Buffer == NULL) ||
        (pdx->product     .Buffer == NULL) ||
        (pdx->serialNumber.Buffer == NULL) ||
        (pdx->displayName .Buffer == NULL)   
      )
    {
        KdPrint((DRIVERNAME " - Unable to allocate memory for device info\n"));        
        status =  STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }
    
    pdx->manufacturer.Length        = 0;
    pdx->manufacturer.MaximumLength = StringDescriptorBytes;    
    pdx->product     .Length        = 0;
    pdx->product     .MaximumLength = StringDescriptorBytes;    
    pdx->serialNumber.Length        = 0;
    pdx->serialNumber.MaximumLength = StringDescriptorBytes;    
    pdx->displayName .Length        = 0;
    pdx->displayName .MaximumLength = StringDescriptorBytes;
    
    // allocate buffer for device string descriptor requests
    desc = (PUSB_STRING_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, SPOT_TAG );
    
    if(!desc)
    {
        KdPrint((DRIVERNAME " - Unable to allocate %X bytes for string descriptor\n", sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes));
        status =  STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    
    if(0 != pdx->dd.iManufacturer)
    {
        // Manufacturer
        UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_STRING_DESCRIPTOR_TYPE,
                                 pdx->dd.iManufacturer,
                                 LangId, 
                                 desc, 
                                 NULL, 
                                 sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes,
                                 NULL);
        
        status = SendAwaitUrb(fdo, &urb);

        if(NT_SUCCESS(status))
        {            
            desc->bString[ (desc->bLength / 2) - 1 ] = L'\0';

            RtlInitUnicodeString( &dummy            , desc->bString );
            RtlCopyUnicodeString( &pdx->manufacturer, &dummy        );
        }
        else
        {
            RtlInitUnicodeString( &dummy            , EmptyString );
            RtlCopyUnicodeString( &pdx->manufacturer, &dummy      );
            KdPrint(( DRIVERNAME " - could not retrieve manufacturer %08x\n", status ));                
        }
    }

    if(0 != pdx->dd.iProduct)
    {
        // Product
        UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_STRING_DESCRIPTOR_TYPE,
                                 pdx->dd.iProduct,
                                 LangId, 
                                 desc, 
                                 NULL, 
                                 sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes,
                                 NULL);
        
        status = SendAwaitUrb(fdo, &urb);

        if(NT_SUCCESS(status))
        {            
            desc->bString[ (desc->bLength / 2) - 1 ] = L'\0';

            RtlInitUnicodeString( &dummy       , desc->bString );
            RtlCopyUnicodeString( &pdx->product, &dummy        );
            
        }
        else
        {
            RtlInitUnicodeString( &dummy       , EmptyString );
            RtlCopyUnicodeString( &pdx->product, &dummy      );       
            KdPrint(( DRIVERNAME " - could not retrieve product %08x\n", status ));          
        }
    }

    if(0 != pdx->dd.iSerialNumber)
    {
        // Serial Number
        UsbBuildGetDescriptorRequest(&urb, 
                                 sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_STRING_DESCRIPTOR_TYPE,
                                 pdx->dd.iSerialNumber,
                                 LangId, 
                                 desc, 
                                 NULL, 
                                 sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes,
                                 NULL);
        
        status = SendAwaitUrb(fdo, &urb);

        if(NT_SUCCESS(status))
        {            
            desc->bString[ (desc->bLength / 2) - 1 ] = L'\0';
            
            RtlInitUnicodeString( &dummy            , desc->bString );
            RtlCopyUnicodeString( &pdx->serialNumber, &dummy        );
            
        }
        else
        {          
            RtlInitUnicodeString( &dummy            , EmptyString );
            RtlCopyUnicodeString( &pdx->serialNumber, &dummy      );
            KdPrint(( DRIVERNAME " - could not retrieve serial number %08x\n", status ));            
        }
    }
    
    // DisplayName
    UsbBuildGetDescriptorRequest(&urb, 
                             sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), 
                             USB_STRING_DESCRIPTOR_TYPE,
                             DisplayNameId,
                             LangId, 
                             desc, 
                             NULL, 
                             sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes,
                             NULL);
    
    status = SendAwaitUrb(fdo, &urb);

    if(NT_SUCCESS(status))
    {            
        desc->bString[ (desc->bLength / 2) - 1 ] = L'\0';
        

        RtlInitUnicodeString( &dummy           , desc->bString );
        RtlCopyUnicodeString( &pdx->displayName, &dummy        );
        
    }
    else
    {
        RtlInitUnicodeString( &dummy            , EmptyString );
        RtlCopyUnicodeString( &pdx->displayName, &dummy      );
        KdPrint(( DRIVERNAME " - could not retrieve display name %08x\n", status ));    
    }

cleanup:
    
    if(desc) ExFreePool( desc );
    
    if(!NT_SUCCESS(status))
    {
        if(pdx->manufacturer.Buffer) ExFreePool( pdx->manufacturer.Buffer );
        if(pdx->product     .Buffer) ExFreePool( pdx->product     .Buffer );
        if(pdx->serialNumber.Buffer) ExFreePool( pdx->serialNumber.Buffer );
        if(pdx->displayName .Buffer) ExFreePool( pdx->displayName .Buffer );

        pdx->manufacturer.Buffer = NULL;
        pdx->product     .Buffer = NULL;
        pdx->serialNumber.Buffer = NULL;
        pdx->displayName .Buffer = NULL;       
    }
    
    return status;
}