//extern "C"
//{
#include "usbio.h"

#define USE_CHAR_STR 

USB_DEVICE_INFO usb_device_info[MAX_USB_PORT_NUMBER];	
static HANDLE hDev_USB = NULL;
static HANDLE hInter = NULL;
static HANDLE hWBulk = NULL;
static HANDLE hRBulk = NULL;
static HANDLE hWIso = NULL;
static HANDLE hRIso = NULL;
#define EVENT_MAX_LEN    256
static unsigned char DeviceControl_Event[EVENT_MAX_LEN];
static unsigned int  DeviceControl_Event_length=0; 

int
RTK_Usb_Open(
	BASE_INTERFACE_MODULE *pBaseInterface
	)
{
 
	hDev_USB = OpenUsbDevice((LPGUID)&GUID_REALTEK_USB_DVBT, pBaseInterface->PortNo);

	//vic, open device success
	if(hDev_USB != INVALID_HANDLE_VALUE)
	{
		//open  interrupt in pipe
#ifndef USE_CHAR_STR
		hInter = OpenPipe(pBaseInterface->PortNo, L"I0P0");
#else
		hInter = OpenPipe(pBaseInterface->PortNo,"I0P0");
#endif
		if(hInter == INVALID_HANDLE_VALUE)
		{
			goto error;
		}

		//open Write Bulk in pipe
#ifndef USE_CHAR_STR
		hWBulk = OpenPipe(pBaseInterface->PortNo, L"I0P1");
#else
		hWBulk = OpenPipe(pBaseInterface->PortNo, "I0P1");
#endif
		if(hWBulk == INVALID_HANDLE_VALUE)
		{
			goto error;
		}

		//Open Read Bulk in pipe
#ifndef USE_CHAR_STR		
		hRBulk = OpenPipe(pBaseInterface->PortNo, L"I0P2");
#else
		hRBulk = OpenPipe(pBaseInterface->PortNo, "I0P2");
#endif
		if(hRBulk == INVALID_HANDLE_VALUE)
		{
			goto error;
		}

		//Open Write Iso in pipe
#ifndef USE_CHAR_STR
		hWIso= OpenPipe(pBaseInterface->PortNo, L"I1P0");
#else
	    hWIso= OpenPipe(pBaseInterface->PortNo, "I1P0");
#endif
		if(hWIso == INVALID_HANDLE_VALUE)
		{
			goto error;
		}

		 //Open Read Iso in pipe
#ifndef USE_CHAR_STR
		hRIso= OpenPipe(pBaseInterface->PortNo, L"I1P1");
#else
		hRIso= OpenPipe(pBaseInterface->PortNo, "I1P1");
#endif
		if(hRIso == INVALID_HANDLE_VALUE)
		{
			goto error;
		}

		if (Set_Interface1_Alternative_Number(pBaseInterface->PortNo, 1, 1) == 0)
		{
			goto error;
		}

		//ghHciEvent= CreateEvent( NULL, FALSE, TRUE, TEXT("HCI"));
		//if (ghHciEvent == NULL)
		//{
		//	goto error;
		//}
	
	}
	else 
	{
			goto error;
	}

	memset(DeviceControl_Event,0,EVENT_MAX_LEN);
	return BT_FUNCTION_SUCCESS;

error:
	
	return FUNCTION_ERROR;   
}



int
RTKL_Usb_SendHCICommand(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char *pWritingBuf,
	unsigned long Len
	)
{
	unsigned char Buf[HCI_CMD_LEN_MAX+32];
	unsigned long RetnLen;
	unsigned long length;
	int Status;
	UNREFERENCED_PARAMETER(Len);
	UNREFERENCED_PARAMETER(pBaseInterface);
	
	memset(Buf, 0, sizeof(Buf));
	memset(DeviceControl_Event,0,EVENT_MAX_LEN);
	DeviceControl_Event_length=0;
    if (hDev_USB == INVALID_HANDLE_VALUE)
		goto error;

	*(Buf) = 0x20;					//bmRequestType = class device
	*(Buf+1) = 0x00;					//bRequest = GET_STATUS
	*((UINT16*)(Buf+2)) = 0;			//wValue : 0
	*((UINT16*)(Buf+4)) = 0;			//wIndex :0

	length = *(pWritingBuf+2) + 3;	
						
	*((UINT16*)(Buf+6)) = (UINT16)length;		//length of HCI cmd to send
	memcpy(Buf+8, pWritingBuf, length);

	 Status = DeviceIoControl(hDev_USB,							
				IOCTL_REGISTER_WRITE,
				Buf,
				(8+length),
				Buf,
				(8+length),
				&RetnLen,//vic, [out]byteReturned
				NULL);

	if(Status == 0)
	{
		goto error;
	}
	if (RetnLen>0) 
	{
		memcpy(DeviceControl_Event,Buf,RetnLen);
		DeviceControl_Event_length=RetnLen;
	}
	return BT_FUNCTION_SUCCESS;

error:
	
	return FUNCTION_ERROR;   
}





int
RTKL_Usb_WaitHCIEvent(
	BASE_INTERFACE_MODULE *pBaseInterface,
	unsigned char *pReadingBuf,
	unsigned long  Len,
	unsigned long *pRetLen
	)
{
	int Status = 0;
	DWORD WaitResult;
	OVERLAPPED ovInternal;
	LPOVERLAPPED lpOverLapped;
	unsigned char *pBuf;
	unsigned long EventLen;
	unsigned char timeout;
	UNREFERENCED_PARAMETER(Len);

    if (hInter == INVALID_HANDLE_VALUE)
		goto error;

	memset(&ovInternal,0,sizeof(OVERLAPPED));
	ovInternal.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL);	          	
	lpOverLapped = &ovInternal;
	EventLen = 0;
	timeout = 0;
	pBuf = pReadingBuf;


re_read:
	
	Status = ReadFile(hInter, pBuf, LEN_16_BYTE, NULL, lpOverLapped);
	
	if (Status)
	{
			Status = BT_FUNCTION_SUCCESS;
	}
	else if (!Status && GetLastError() == ERROR_IO_PENDING)
 	{			
		WaitResult = WaitForSingleObject(ovInternal.hEvent, 100);

		switch(WaitResult)
	    	{
			case WAIT_TIMEOUT:
				CancelIo(hInter);
				goto error;
			case WAIT_FAILED:
			case WAIT_ABANDONED:
			default:
				CancelIo(hInter);			  
				goto error;

			case WAIT_OBJECT_0:
				 Status = BT_FUNCTION_SUCCESS;						
				break;              
                	
   	    	}
	}
	else
	{
		goto error;
	}

	if( (pBuf[0]==0x00) &&(pBuf[1]==0x00) )
	{
		timeout++;
		if(timeout > 3)
		{
			goto error;
		}
		else
		{
			pBaseInterface->WaitMs(pBaseInterface, 50);
			goto re_read;
		}		
	}
	
	EventLen = pBuf[1];
	
	if(EventLen > LEN_14_BYTE)
	{
		Status = ReadFile(hInter, pBuf+LEN_16_BYTE, EventLen-LEN_14_BYTE, NULL, lpOverLapped);
		
		if (Status)
		{
				Status = BT_FUNCTION_SUCCESS;
		}
		else if (!Status && GetLastError() == ERROR_IO_PENDING) 
	 	{			
			WaitResult = WaitForSingleObject(ovInternal.hEvent, 300);

			switch(WaitResult)
		    	{
				case WAIT_TIMEOUT:
					CancelIo(hInter);			  
					goto error;

				case WAIT_FAILED:
				case WAIT_ABANDONED:
				default:
					CancelIo(hInter);			  
					goto error;

				case WAIT_OBJECT_0:
					 Status = BT_FUNCTION_SUCCESS;						
					break;              
	                	
	   	    	}
		}
		else
		{
			goto error;
		}

	}

	CloseHandle(ovInternal.hEvent);

	*pRetLen = EventLen + LEN_2_BYTE;

	return Status;

error:	

	CloseHandle(ovInternal.hEvent);
	
	return FUNCTION_ERROR;
}



int
RTK_Usb_Close(
	BASE_INTERFACE_MODULE *pBaseInterface
	)
{

	UNREFERENCED_PARAMETER(pBaseInterface);
	if(hWBulk!=NULL)
	{
		CloseHandle(hWBulk);
		hWBulk=NULL;
	}

	if(hRBulk!=NULL)
	{
		CloseHandle(hRBulk);
		hRBulk=NULL;
	}

	if(hWIso!=NULL)
	{
		CloseHandle(hWIso);
		hWIso=NULL;
	}

	//if(ghHciEvent!=NULL)
	//{
	//	CloseHandle(ghHciEvent);
	//}

	if(hRIso!=NULL)
	{
		CloseHandle(hRIso);
		hRIso=NULL;
	}
	if(hDev_USB!=NULL)
	{
		CloseHandle(hDev_USB);
		hDev_USB=NULL;
	}

	return BT_FUNCTION_SUCCESS;

}



HANDLE
OpenOneDevice (
    IN HDEVINFO                     HardwareDeviceInfo,
    IN PSP_DEVICE_INTERFACE_DATA    DeviceInfoData,
#ifndef USE_CHAR_STR    
    IN wchar_t                    *devName
#else
    IN char			    *devName
#endif
)
/*++
   Routine Description:

   Given the HardwareDeviceInfo, representing a handle to the plug and
   play information, and deviceInfoData, representing a specific usb device,
   open that device and fill in all the relevant information in the given
   USB_DEVICE_DESCRIPTOR structure.

   Arguments:

   HardwareDeviceInfo:  handle to info obtained from Pnp mgr via SetupDiGetClassDevs()
   DeviceInfoData:      ptr to info obtained via SetupDiEnumDeviceInterfaces()

   Return Value:

   return HANDLE if the open and initialization was successfull,
   else INVLAID_HANDLE_VALUE.

--*/
{
    PSP_DEVICE_INTERFACE_DETAIL_DATA    functionClassDeviceData = NULL;
    ULONG                               predictedLength = 0;
    ULONG                               requiredLength = 0;
    HANDLE                              hOut = INVALID_HANDLE_VALUE;
    SP_DEVINFO_DATA   dd   =   {sizeof(SP_DEVINFO_DATA)};
    ULONG tmprequiredLength=0;

    //
    // allocate a function class device data structure to receive the
    // goods about this particular device.
    //
    if (SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo,
                                        DeviceInfoData,
                                        NULL,   // probing so no output buffer yet
                                        0,      // probing so output buffer length of zero
                                        &requiredLength,
                                        NULL))  // not interested in the specific dev-node
    {
        return INVALID_HANDLE_VALUE;
    }

    if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
    {
        return INVALID_HANDLE_VALUE;
    }

    predictedLength = requiredLength;
    // sizeof (SP_FNCLASS_DEVICE_DATA) + 512;

    functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(predictedLength);

    if (NULL == functionClassDeviceData)
    {
        return INVALID_HANDLE_VALUE;
    }

    functionClassDeviceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    //Dean Add 	

    SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo, DeviceInfoData, NULL, 0, &tmprequiredLength, NULL);

    if(!SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo,DeviceInfoData,   functionClassDeviceData,   predictedLength,   NULL,   &dd))
    {
                  return hOut;
    }    
    
    
    //
    // Retrieve the information from Plug and Play.
    //
    if (!SetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo,
                                         DeviceInfoData,
                                         functionClassDeviceData,
                                         predictedLength,
                                         &requiredLength,
                                         NULL))
    {
        free(functionClassDeviceData);

        return INVALID_HANDLE_VALUE;
    }
#ifndef USE_CHAR_STR  	
    	wcscpy(devName, functionClassDeviceData->DevicePath);
#else
	strcpy(devName, functionClassDeviceData->DevicePath);
#endif	
    //printf("Attempting to open %s\n", devName);

    hOut = CreateFile(functionClassDeviceData->DevicePath,
                      GENERIC_READ | GENERIC_WRITE,
                      FILE_SHARE_READ | FILE_SHARE_WRITE,
                      NULL,         // No SECURITY_ATTRIBUTES structure
                      OPEN_EXISTING,// No special create flags
                      0,            // No special attributes
                      NULL);        // No template file

    if (INVALID_HANDLE_VALUE == hOut)
    {
        ;//printf("FAILED to open %s\n", devName);
    }

    free(functionClassDeviceData);

    return hOut;
}

/*
HANDLE OpenUsbDevice (
    LPGUID  pGuid,
    char   *outNameBuf
)

   Routine Description:

   Do the required PnP things in order to find
   the next available proper device in the system at this time.

   Arguments:

   pGuid:      ptr to GUID registered by the driver itself
   outNameBuf: the generated name for this device

   Return Value:

   return HANDLE if the open and initialization was successful,
   else INVLAID_HANDLE_VALUE.

{
    ULONG NumberDevices;
    HANDLE hOut = INVALID_HANDLE_VALUE;
    HDEVINFO                 hardwareDeviceInfo;
    SP_DEVICE_INTERFACE_DATA deviceInfoData;
    ULONG                    i;
    BOOLEAN                  done;
    PUSB_DEVICE_DESCRIPTOR   usbDeviceInst;
    PUSB_DEVICE_DESCRIPTOR  *UsbDevices = &usbDeviceInst;
    PUSB_DEVICE_DESCRIPTOR   tempDevDesc;

    *UsbDevices = NULL;
    tempDevDesc = NULL;
    NumberDevices = 0;

    //
    // Open a handle to the plug and play dev node.
    // SetupDiGetClassDevs() returns a device information set that contains info on all
    // installed devices of a specified class.
    //
    hardwareDeviceInfo = SetupDiGetClassDevs(pGuid,
                                             NULL, // Define no enumerator (global)
                                             NULL, // Define no
                                             (DIGCF_PRESENT | // Only Devices present
                                              DIGCF_DEVICEINTERFACE)); // Function class devices.

    if (hardwareDeviceInfo == INVALID_HANDLE_VALUE)
    {
        return INVALID_HANDLE_VALUE;
    }

    //
    // Take a wild guess at the number of devices we have;
    // Be prepared to realloc and retry if there are more than we guessed
    //
    NumberDevices = 4;
    done = FALSE;
    deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);

    i=0;

    while (!done)
    {
        NumberDevices *= 2;

        if (*UsbDevices)
        {
            tempDevDesc = (PUSB_DEVICE_DESCRIPTOR)realloc(*UsbDevices,
                                  (NumberDevices * sizeof (USB_DEVICE_DESCRIPTOR)));
            if(tempDevDesc)
            {
                *UsbDevices = tempDevDesc;
                tempDevDesc = NULL;
            }
            else
            {
                free(*UsbDevices);
                *UsbDevices = NULL;
            }
        }
        else
        {
            *UsbDevices = (PUSB_DEVICE_DESCRIPTOR)calloc(NumberDevices, sizeof(USB_DEVICE_DESCRIPTOR));
        }

        if (NULL == *UsbDevices)
        {
            // SetupDiDestroyDeviceInfoList destroys a device information set
            // and frees all associated memory.

            SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);

            return INVALID_HANDLE_VALUE;
        }

        usbDeviceInst = *UsbDevices + i;

        for (; i < NumberDevices; i++)
        {
            // SetupDiEnumDeviceInterfaces() returns information about device interfaces
            // exposed by one or more devices. Each call returns information about one interface;
            // the routine can be called repeatedly to get information about several interfaces
            // exposed by one or more devices.

            if (SetupDiEnumDeviceInterfaces(hardwareDeviceInfo,
                                            0, // We don't care about specific PDOs
                                            pGuid,
                                            i,
                                            &deviceInfoData))
            {
                hOut = OpenOneDevice(hardwareDeviceInfo,
                                     &deviceInfoData,
                                     outNameBuf);

                if (hOut != INVALID_HANDLE_VALUE)
                {
                    done = TRUE;
                    break;
                }
            }
            else
            {
                if (ERROR_NO_MORE_ITEMS == GetLastError())
                {
                    done = TRUE;
                    break;
                }
            }
        }
    }

    NumberDevices = i;

    // SetupDiDestroyDeviceInfoList() destroys a device information set
    // and frees all associated memory.

    SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);

    free(*UsbDevices);

    return hOut;
}

*/

HANDLE  OpenUsbDevice(
	LPGUID pGuid,
	int USBPortNumber
	)
{
	ULONG NumberDevices;
	HANDLE hOut = INVALID_HANDLE_VALUE;
	HDEVINFO                 hardwareDeviceInfo;
	SP_DEVICE_INTERFACE_DATA deviceInfoData;
	ULONG                    i;
	int                            num_of_usb_port;
	BOOLEAN                  done;
	PUSB_DEVICE_DESCRIPTOR   usbDeviceInst;
	PUSB_DEVICE_DESCRIPTOR   *UsbDevices = &usbDeviceInst;
	PUSB_DEVICE_DESCRIPTOR   tempDevDesc;
     //	int bsuccess = 1;
		
       //HCI_CMD_ACL_PACKETS_INFO hci_pkt_info[MAX_USB_PORT_NUMBER];

      
	for(i=0;i<MAX_USB_PORT_NUMBER;i++)
	{
		usb_device_info[i].hDevice = INVALID_HANDLE_VALUE;
		usb_device_info[i].hI0P0_Read_Intr = INVALID_HANDLE_VALUE; 
		usb_device_info[i].hI0P1_Write_Bulk = INVALID_HANDLE_VALUE;
		usb_device_info[i].hI0P2_Read_Bulk = INVALID_HANDLE_VALUE;
		usb_device_info[i].hI1P0_Write_ISO = INVALID_HANDLE_VALUE;
		usb_device_info[i].hI1P1_Read_ISO = INVALID_HANDLE_VALUE;
     	       memset(usb_device_info[i].CompleteDeviceName, 0, 256);
	}
	   

	*UsbDevices = NULL;
	tempDevDesc = NULL;
	NumberDevices = 0;
	
	// Open a handle to the plug and play dev node.
	// SetupDiGetClassDevs() returns a device information set that contains info on all
	// installed devices of a specified class.
	hardwareDeviceInfo = SetupDiGetClassDevs (pGuid,					//class guid, defined same with in .sys	file
											  NULL,						//Define no enumerator (global)
											  NULL,						//Define no(handle to the top-level window )
											  (DIGCF_PRESENT |			// Only Devices present
											  DIGCF_DEVICEINTERFACE));  // Function class devices.

	
	// Take a wild guess at the number of devices we have;
	// Be prepared to realloc and retry if there are more than we guessed
	NumberDevices = 4;
	done = FALSE;
	deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);

	//vic, used as usb port index
	i=0;
	num_of_usb_port = 0;
	
	while (!done) 
	{
		NumberDevices *= 2;
		
		if (*UsbDevices) 
		{
			tempDevDesc = (PUSB_DEVICE_DESCRIPTOR)realloc (*UsbDevices, (NumberDevices * sizeof (USB_DEVICE_DESCRIPTOR)));
			if(tempDevDesc) 
			{
				*UsbDevices = tempDevDesc;
				tempDevDesc = NULL;
			}
			else 
			{
				free(*UsbDevices);
				*UsbDevices = NULL;
			}
		} 
		else 
		{
			*UsbDevices = (PUSB_DEVICE_DESCRIPTOR)calloc(NumberDevices, sizeof(USB_DEVICE_DESCRIPTOR));
		}
		
		if (NULL == *UsbDevices) 
		{
			// SetupDiDestroyDeviceInfoList destroys a device information set
			// and frees all associated memory.
			SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
			//return INVALID_HANDLE_VALUE;
			return FALSE;
		}
		
		usbDeviceInst = *UsbDevices + i;
		
		for (; i <NumberDevices; i++) 
		{
			// SetupDiEnumDeviceInterfaces() returns information about device interfaces
			// exposed by one or more devices. Each call returns information about one interface;
			// the routine can be called repeatedly to get information about several interfaces
			// exposed by one or more devices.
			if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
				0, // We don't care about specific PDOs
				pGuid,
				i,
				&deviceInfoData))
			{
				
				//vic, get device path (outNameBuf)
				hOut = OpenOneDevice (hardwareDeviceInfo, &deviceInfoData, usb_device_info[i].CompleteDeviceName);

				if ( hOut != INVALID_HANDLE_VALUE ) 
				{					
					//done = TRUE;
					//break;

					usb_device_info[i].hDevice = hOut;
                                   //     bsuccess = 1;
				}
				else
				{
				     //	bsuccess = 0;
					break;
				}
			} 
			else 
			{		
				//no usb port to open, 'not' indicate port open failed
				if (ERROR_NO_MORE_ITEMS == GetLastError()) 
				{
					//done = TRUE;
					//break;
					break;
				}
			    //	else
			    //	{
					//other reason..?
				     //	bsuccess = 0;
			     //	}
			}
		}//end for

		//vic
		done = TRUE;
	}

   num_of_usb_port = NumberDevices = i;

    // SetupDiDestroyDeviceInfoList() destroys a device information set
   // and frees all associated memory.
   SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
   free ( *UsbDevices );
   //return hOut;


   if (USBPortNumber > num_of_usb_port)
    return  (INVALID_HANDLE_VALUE);
   else
    return (usb_device_info[USBPortNumber-1].hDevice) ;	

}




HANDLE
OpenPipe(
	int usb_port_idx,
#ifndef USE_CHAR_STR   	
	wchar_t *pipename
#else
	char *pipename
#endif
	)
{
	HANDLE h;
	
	DWORD dwFlagsAndAttributes;
#ifndef USE_CHAR_STR
    wchar_t FullPipeName[256];
	wcscpy(FullPipeName, usb_device_info[usb_port_idx-1].CompleteDeviceName);

	wcscat (FullPipeName,L"\\");                      
//	if((strlen(FullPipeName) + strlen(pipename)) > 255) 
//	{
		//printf("Failed to open handle - possibly long filename\n");
//			return INVALID_HANDLE_VALUE;
//	}

	wcscat (FullPipeName, pipename);                                      
//	UsbPrintf(RED, "%s", *FullPipeName);
#else
		char FullPipeName[256];
        strcpy(FullPipeName,usb_device_info[usb_port_idx-1].CompleteDeviceName);
        strcat(FullPipeName,"\\");
        strcat(FullPipeName,pipename);
#endif
      /*
       if ( (stricmp(pipename, "I1P0") == 0) || (stricmp(pipename, "I1P1") == 0) )  //synchronous
        	dwFlagsAndAttributes = 0;
	else */ 
             dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED;  //asynchronous

	h = CreateFile( (LPCTSTR)FullPipeName,
			GENERIC_WRITE | GENERIC_READ,
			FILE_SHARE_WRITE | FILE_SHARE_READ,
			NULL,
			OPEN_EXISTING,
			dwFlagsAndAttributes,//0,
			NULL);

	if (h == INVALID_HANDLE_VALUE)
	{
		//UsbPrintf(RED, 0, "Failed to open (%s) = %d", FullPipeName, GetLastError());		
	} 

	return h;
}



BOOL
Set_Interface1_Alternative_Number(
	int usb_port_idx,
	UINT8 alter_num,
	UINT8 inter_num
	)
{
	UINT8 *buf;
	BOOL success;
	DWORD tmp_bytelength;

	if(alter_num>5)
	{
		//UsbPrintf(RED, 0, "set_interface1_alternative_number() interface1 alternative number should be [0,5]!");
		return FALSE;
	}

	//marked by vic, 2010.08.18
	//if(alter_num == current_IF1_alternative_number[usb_port_idx])
	//	return TRUE;

	//=======================================
	//bmRequestType :		1 byte
	//bRequest:				1 byte
	//wValue:				2 byte
	//wIndex:				2 byte
	//wLength:				2 byte
	//=======================================
	buf=(unsigned char*)malloc(3);
	if(!buf){
		//UsbPrintf(RED, 0, "set_interface1_alternative_number() malloc fail!");
		return FALSE;
	}

	*(buf) = 0;//INTERFACE_SET;										//bmRequestType
	*(buf+1) = inter_num;												//bRequest
	*(buf+2) = alter_num;												//bRequest

	//success = DeviceIoControl(hDevice,							
	success = DeviceIoControl(usb_device_info[usb_port_idx-1].hDevice,
		IOCTL_RTUSB_INTERFACE,
		buf,
		3,
		buf,
		3,
		&tmp_bytelength,
		NULL);
	if(!success){
		//UsbPrintf(RED, 0, "set_interface1_alternative_number() DeviceIoControl fail");
		return FALSE;
	}

	//current_IF1_alternative_number[usb_port_idx-1] = alter_num;
	free(buf);
	return TRUE;
}







