Exemplo n.º 1
0
bool USBDeviceWin32::Open(int VID, int PID, int blocksize, int num)
{
    DWORD index = 0;

    CString path;
    while ((path = GetUSBDevicePath (index++)) != "")
    {
		HANDLE h = CreateFile (path, GENERIC_READ,
			FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

		if(h == INVALID_HANDLE_VALUE)
			continue;

		HIDD_ATTRIBUTES attr;
		if (!HidD_GetAttributes (h, &attr))
		{
			CloseHandle(h);
			continue;
		}
		CloseHandle(h);

        if ((VID != -1 && attr.VendorID != VID) &&
            (PID != -1 && attr.ProductID != PID))
			continue; /* This isn't it. */

		/* The VID and PID match. */
		if(num-- > 0)
			continue;

		io.Open(path, blocksize);
        return true;
    }

    return false;
}
Exemplo n.º 2
0
int open_path(const char * path, int print) {

  int device = async_open_path(path, print);
  if(device >= 0) {
    HIDD_ATTRIBUTES attributes = { .Size = sizeof(HIDD_ATTRIBUTES) };
    if(HidD_GetAttributes(devices[device].handle, &attributes) == TRUE) {
        PHIDP_PREPARSED_DATA preparsedData;
        HIDP_CAPS hidCapabilities;
        if(HidD_GetPreparsedData(devices[device].handle, &preparsedData) == TRUE) {
            if(HidP_GetCaps(preparsedData, &hidCapabilities) == HIDP_STATUS_SUCCESS ) {
                devices[device].write.size = hidCapabilities.OutputReportByteLength;
                async_set_read_size(device, hidCapabilities.InputReportByteLength);
                devices[device].hidInfo.vendor_id = attributes.VendorID;
                devices[device].hidInfo.product_id = attributes.ProductID;
                devices[device].hidInfo.bcdDevice = attributes.VersionNumber;
            }
            else {
                if (print) {
                    ASYNC_PRINT_ERROR("HidP_GetCaps")
                }
                async_close(device);
                device = -1;
            }
            HidD_FreePreparsedData(preparsedData);
        }
        else {
            if (print) {
                ASYNC_PRINT_ERROR("HidD_GetPreparsedData")
            }
            async_close(device);
            device = -1;
        }
    }
Exemplo n.º 3
0
bool CUSBDevice::Connect(const DWORD *vendorID, const DWORD *productID, const DWORD *versionNumber)
{
	Disconnect();
    handle = INVALID_HANDLE_VALUE;
    DWORD index = 0;
    HIDD_ATTRIBUTES deviceAttributes;
    BOOL matched = FALSE;
//	LPCWSTR dummy ( L"" );
	
//    while (!matched && (handle = ConnectToIthDevice (index)) != INVALID_HANDLE_VALUE)
    while (!matched)
    {
        if (!HidD_GetAttributes (handle, &deviceAttributes))
            return INVALID_HANDLE_VALUE;
		
        if ((vendorID == 0 || deviceAttributes.VendorID == *vendorID) &&
            (productID == 0 || deviceAttributes.ProductID == *productID) &&
            (versionNumber == 0 || deviceAttributes.VersionNumber == *versionNumber)) {
				EventObject = CreateEvent(NULL, TRUE, TRUE, NULL);
				//Set the members of the overlapped structure.
				HIDOverlapped.Offset = 0;
				HIDOverlapped.OffsetHigh = 0;
				HIDOverlapped.hEvent = EventObject;
			
				return true; /* matched */
		}
        
        CloseHandle (handle); /* not a match - close and try again */
		
        index++;
    }
	
    return false;
}
Exemplo n.º 4
0
bool HIDDeviceManager::initVendorProductVersion(HANDLE hidDev, HIDDeviceDesc* desc) const
{
    HIDD_ATTRIBUTES attr;
    attr.Size = sizeof(attr);
    if (!HidD_GetAttributes(hidDev, &attr))
        return false;
    desc->VendorId      = attr.VendorID;
    desc->ProductId     = attr.ProductID;
    desc->VersionNumber = attr.VersionNumber;
    return true;
}
Exemplo n.º 5
0
int _ykusb_get_vid_pid(void *yk, int *vid, int *pid) {
	HIDD_ATTRIBUTES devInfo;
	int rc = HidD_GetAttributes(yk, &devInfo);
	if (rc) {
		*vid = devInfo.VendorID;
		*pid = devInfo.ProductID;
		return 1;
	}
	yk_errno = YK_EUSBERR;
	return 0;
}
Exemplo n.º 6
0
BOOL CUSBDrive::CheckHandle()
{
	m_HidHandle=FindHandle();

	_HIDD_ATTRIBUTES hidAttributes;
	if(!HidD_GetAttributes(m_HidHandle, &hidAttributes))
		{
		CloseHandle(m_HidHandle);
		return false;
		}
	return true;
}
Exemplo n.º 7
0
static HANDLE open_usb_device(int vid, int pid)
{
	GUID guid;
	HDEVINFO info;
	DWORD index, required_size;
	SP_DEVICE_INTERFACE_DATA iface;
	SP_DEVICE_INTERFACE_DETAIL_DATA *details;
	HIDD_ATTRIBUTES attrib;
	HANDLE h;
	BOOL ret;

	HidD_GetHidGuid(&guid);
	info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (info == INVALID_HANDLE_VALUE) return NULL;
	for (index=0; 1 ;index++) {
		iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
		ret = SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface);
		if (!ret) {
			SetupDiDestroyDeviceInfoList(info);
			break;
		}
		SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &required_size, NULL);
		details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(required_size);
		if (details == NULL) continue;
		memset(details, 0, required_size);
		details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		ret = SetupDiGetDeviceInterfaceDetail(info, &iface, details,
			required_size, NULL, NULL);
		if (!ret) {
			free(details);
			continue;
		}
		h = CreateFile(details->DevicePath, GENERIC_READ|GENERIC_WRITE,
			FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
			FILE_FLAG_OVERLAPPED, NULL);
		free(details);
		if (h == INVALID_HANDLE_VALUE) continue;
		attrib.Size = sizeof(HIDD_ATTRIBUTES);
		ret = HidD_GetAttributes(h, &attrib);
		if (!ret) {
			CloseHandle(h);
			continue;
		}
		if (attrib.VendorID != vid || attrib.ProductID != pid) {
			CloseHandle(h);
			continue;
		}
		SetupDiDestroyDeviceInfoList(info);
		return h;
	}
	return NULL;
}
Exemplo n.º 8
0
BOOLEAN
CheckIfOurDevice(
    HANDLE file,
    USAGE myUsagePage,
    USAGE myUsage)
{
    PHIDP_PREPARSED_DATA Ppd = NULL; // The opaque parser info describing this device
    HIDD_ATTRIBUTES                 Attributes; // The Attributes of this hid device.
    HIDP_CAPS                       Caps; // The Capabilities of this hid device.
    BOOLEAN                         result = FALSE;

    if (!HidD_GetPreparsedData (file, &Ppd))
    {
        printf("Error: HidD_GetPreparsedData failed \n");
        goto cleanup;
    }

    if (!HidD_GetAttributes(file, &Attributes))
    {
        printf("Error: HidD_GetAttributes failed \n");
        goto cleanup;
    }

    if (Attributes.VendorID == vmultib_VID && Attributes.ProductID == vmultib_PID)
    {
        if (!HidP_GetCaps (Ppd, &Caps))
        {
            printf("Error: HidP_GetCaps failed \n");
            goto cleanup;
        }

        if ((Caps.UsagePage == myUsagePage) && (Caps.Usage == myUsage))
        {
            printf("Success: Found my device.. \n");
            result = TRUE;
        }
    }

cleanup:

    if (Ppd != NULL)
    {
        HidD_FreePreparsedData (Ppd);
    }

    return result;
}
Exemplo n.º 9
0
int RawInputPad::Open()
{
	PHIDP_PREPARSED_DATA pPreparsedData = NULL;

	//TODO Better place?
	LoadMappings(mapVector);

	memset(&this->ovl, 0, sizeof(OVERLAPPED));
	memset(&this->ovlW, 0, sizeof(OVERLAPPED));

	//this->padState.initStage = 0;
	this->doPassthrough = !!conf.DFPPass;//TODO per player
	this->usbHandle = INVALID_HANDLE_VALUE;
	std::wstring path;
	{
		CONFIGVARIANT var(N_JOYSTICK, CONFIG_TYPE_WCHAR);
		if (LoadSetting(mPort, APINAME, var))
			path = var.wstrValue;
		else
			return 1;
	}

	this->usbHandle = CreateFileW(path.c_str(), GENERIC_READ|GENERIC_WRITE,
		FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

	if(this->usbHandle != INVALID_HANDLE_VALUE)
	{
		this->ovl.hEvent = CreateEvent(0, 0, 0, 0);
		this->ovlW.hEvent = CreateEvent(0, 0, 0, 0);

		HidD_GetAttributes(this->usbHandle, &(this->attr));
		HidD_GetPreparsedData(this->usbHandle, &pPreparsedData);
		HidP_GetCaps(pPreparsedData, &(this->caps));
		HidD_FreePreparsedData(pPreparsedData);
		return 0;
	}
	else
		fwprintf(stderr, L"Could not open device '%s'.\nPassthrough and FFB will not work.\n", path.c_str());

	return 1;
}
Exemplo n.º 10
0
// 获取设备一些能力信息
USBHIDDLL_API void __stdcall USBHIDGetDeviceCapabilities(USBHANDLE handle, PHIDD_ATTRIBUTES attributes, PHIDP_CAPS caps)
{
    if (handle != INVALID_HANDLE_VALUE)
    {
        HidD_GetAttributes(handle, attributes);

        //Get the Capabilities structure for the device.

        PHIDP_PREPARSED_DATA	PreparsedData;

        /*
        API function: HidD_GetPreparsedData
        Returns: a pointer to a buffer containing the information about the device's capabilities.
        Requires: A handle returned by CreateFile.
        There's no need to access the buffer directly,
        but HidP_GetCaps and other API functions require a pointer to the buffer.
        */

        HidD_GetPreparsedData (handle, &PreparsedData);
        //DisplayLastError("HidD_GetPreparsedData: ");

        /*
        API function: HidP_GetCaps
        Learn the device's capabilities.
        For standard devices such as joysticks, you can find out the specific
        capabilities of the device.
        For a custom device, the software will probably know what the device is capable of,
        and the call only verifies the information.
        Requires: the pointer to the buffer returned by HidD_GetPreparsedData.
        Returns: a Capabilities structure containing the information.
        */

        HidP_GetCaps (PreparsedData, caps);

        //No need for PreparsedData any more, so free the memory it's using.
        HidD_FreePreparsedData(PreparsedData);
        //DisplayLastError("HidD_FreePreparsedData: ") ;
    }
}
Exemplo n.º 11
0
void parse_info_from_path(hid_event* event, char* device_path) {
	auto write_handle = open_device(device_path, TRUE);

	/* Check validity of write_handle. */
	if (write_handle == INVALID_HANDLE_VALUE) {
		/* Unable to open the device. */
		//register_error(dev, "CreateFile");
		//goto cont_close;
		return;
	}

	//TODO: clean this shit up

	HIDD_ATTRIBUTES attrib;
	attrib.Size = sizeof(HIDD_ATTRIBUTES);

	HidD_GetAttributes(write_handle, &attrib);

	event->device_info->product_id = attrib.ProductID;
	event->device_info->vendor_id = attrib.VendorID;
	event->device_info->release_number = attrib.VersionNumber;

	PHIDP_PREPARSED_DATA pp_data = NULL;
	auto res = HidD_GetPreparsedData(write_handle, &pp_data);
	if (res) {
		HIDP_CAPS caps;
		auto nt_res = HidP_GetCaps(pp_data, &caps);
		if (nt_res == HIDP_STATUS_SUCCESS) {
			event->device_info->usage_page = caps.UsagePage;
			event->device_info->usage = caps.Usage;
		}

		HidD_FreePreparsedData(pp_data);
	}

	CloseHandle(write_handle);
}
Exemplo n.º 12
0
BOOLEAN TryToSwitch( LPTSTR devPath, BOOL toHID )
{
	HANDLE hHidDevice = CreateFile(devPath, 0, 
		FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 );

	if ( hHidDevice == INVALID_HANDLE_VALUE )
		return FALSE;

	HIDD_ATTRIBUTES HidAttributes;
	HidAttributes.Size = sizeof(HIDD_ATTRIBUTES);

	if ( !HidD_GetAttributes( hHidDevice, &HidAttributes) )
	{
		CloseHandle( hHidDevice );
		return FALSE;
	}

	ConversionFunction conversionFunction;
	if (LPTSTR lptstrDongleName = IsBTHidDevice(HidAttributes.VendorID, HidAttributes.ProductID, &conversionFunction))
		(*conversionFunction)(lptstrDongleName, hHidDevice, toHID);

	CloseHandle( hHidDevice );
	return TRUE;
}
Exemplo n.º 13
0
//
// Make sure specified USB device has corrent vendor/product ID's...
//
bool PicBootloader::isValidDevice(char *DevicePath)
{
  HANDLE hHidDevice = CreateFile(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 (hHidDevice == INVALID_HANDLE_VALUE)
    return NULL;

  HIDD_ATTRIBUTES Attr;
  memset (&Attr, 0, sizeof(Attr));

  BOOL result = HidD_GetAttributes (hHidDevice, &Attr);
  CloseHandle(hHidDevice);

  //printf ("%s\n",DevicePath);
  //printf ("device: vid=%x, pid=%x\n", Attr.VendorID, Attr.ProductID);

  return (result && (Attr.VendorID == m_vid) && (Attr.ProductID == m_pid));
}
Exemplo n.º 14
0
	BOOL OpenDevice(USHORT usVID, USHORT usPID)
	{
		//CString MyDevPathName="";
		TCHAR MyDevPathName[MAX_PATH];

		//定義一個GUID的結構體HidGuid來保存HID設備的接口類GUID。
		GUID HidGuid;
		//定義一個DEVINFO的句柄hDevInfoSet來保存獲取到的設備信息集合句柄。
		HDEVINFO hDevInfoSet;
		//定義MemberIndex,表示當前搜索到第幾個設備,0表示第一個設備。
		DWORD MemberIndex;
		//DevInterfaceData,用來保存設備的驅動接口信息
		SP_DEVICE_INTERFACE_DATA DevInterfaceData;
		//定義一個BOOL變量,保存函數調用是否返回成功
		BOOL Result;
		//定義一個RequiredSize的變量,用來接收需要保存詳細信息的緩衝長度。
		DWORD RequiredSize;
		//定義一個指向設備詳細信息的結構體指針。
		PSP_DEVICE_INTERFACE_DETAIL_DATA	pDevDetailData;
		//定義一個用來保存打開設備的句柄。
		HANDLE hDevHandle;
		//定義一個HIDD_ATTRIBUTES的結構體變量,保存設備的屬性。
		HIDD_ATTRIBUTES DevAttributes;
		
		//初始化設備未找到
		BOOL MyDevFound=FALSE;
		
		//初始化讀、寫句柄為無效句柄。
		m_hReadHandle=INVALID_HANDLE_VALUE;
		m_hWriteHandle=INVALID_HANDLE_VALUE;
		
		//對DevInterfaceData結構體的cbSize初始化為結構體大小
		DevInterfaceData.cbSize=sizeof(DevInterfaceData);
		//對DevAttributes結構體的Size初始化為結構體大小
		DevAttributes.Size=sizeof(DevAttributes);
		
		//調用HidD_GetHidGuid函數獲取HID設備的GUID,並保存在HidGuid中。
		HidD_GetHidGuid(&HidGuid);
		
		//根據HidGuid來獲取設備信息集合。其中Flags參數設置為
		//DIGCF_DEVICEINTERFACE|DIGCF_PRESENT,前者表示使用的GUID為
		//接口類GUID,後者表示只列舉正在使用的設備,因為我們這裡只
		//查找已經連接上的設備。返回的句柄保存在hDevinfo中。注意設備
		//信息集合在使用完畢後,要使用函數SetupDiDestroyDeviceInfoList
		//銷毀,不然會造成內存洩漏。
		hDevInfoSet=SetupDiGetClassDevs(&HidGuid,
			NULL,
			NULL,
			DIGCF_DEVICEINTERFACE|DIGCF_PRESENT);
		
		//AddToInfOut("開始查找設備");
		//然後對設備集合中每個設備進行列舉,檢查是否是我們要找的設備
		//當找到我們指定的設備,或者設備已經查找完畢時,就退出查找。
		//首先指向第一個設備,即將MemberIndex置為0。
		MemberIndex=0;
		while(1)
		{
			//調用SetupDiEnumDeviceInterfaces在設備信息集合中獲取編號為
			//MemberIndex的設備信息。
			Result=SetupDiEnumDeviceInterfaces(hDevInfoSet,
				NULL,
				&HidGuid,
				MemberIndex,
				&DevInterfaceData);
			
			//如果獲取信息失敗,則說明設備已經查找完畢,退出循環。
			if(Result==FALSE) break;
			
			//將MemberIndex指向下一個設備
			MemberIndex++;
			
			//如果獲取信息成功,則繼續獲取該設備的詳細信息。在獲取設備
			//詳細信息時,需要先知道保存詳細信息需要多大的緩衝區,這通過
			//第一次調用函數SetupDiGetDeviceInterfaceDetail來獲取。這時
			//提供緩衝區和長度都為NULL的參數,並提供一個用來保存需要多大
			//緩衝區的變量RequiredSize。
			Result=SetupDiGetDeviceInterfaceDetail(hDevInfoSet,
				&DevInterfaceData,
				NULL,
				NULL,
				&RequiredSize,
				NULL);
			
			//然後,分配一個大小為RequiredSize緩衝區,用來保存設備詳細信息。
			pDevDetailData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize);
			if(pDevDetailData==NULL) //如果內存不足,則直接返回。
			{
				//MessageBox("內存不足!");
				SetupDiDestroyDeviceInfoList(hDevInfoSet);
				return FALSE;
			}
			
			//並設置pDevDetailData的cbSize為結構體的大小(注意只是結構體大小,
			//不包括後面緩衝區)。
			pDevDetailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
			
			//然後再次調用SetupDiGetDeviceInterfaceDetail函數來獲取設備的
			//詳細信息。這次調用設置使用的緩衝區以及緩衝區大小。
			Result=SetupDiGetDeviceInterfaceDetail(hDevInfoSet,
				&DevInterfaceData,
				pDevDetailData,
				RequiredSize,
				NULL,
				NULL);
			
			//將設備路徑複製出來,然後銷毀剛剛申請的內存。
			//MyDevPathName=pDevDetailData->DevicePath;
			//_tcscpy(MyDevPathName, pDevDetailData->DevicePath);
			wcscpy_s(MyDevPathName, pDevDetailData->DevicePath);
            free(pDevDetailData);
			
			//如果調用失敗,則查找下一個設備。
			if(Result==FALSE) continue;
			
			//如果調用成功,則使用不帶讀寫訪問的CreateFile函數
			//來獲取設備的屬性,包括VID、PID、版本號等。
			//對於一些獨佔設備(例如USB鍵盤),使用讀訪問方式是無法打開的,
			//而使用不帶讀寫訪問的格式才可以打開這些設備,從而獲取設備的屬性。
			hDevHandle=CreateFile(MyDevPathName, 
				NULL,
				FILE_SHARE_READ|FILE_SHARE_WRITE, 
				NULL,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL,
				NULL);
			
			//如果打開成功,則獲取設備屬性。
			if(hDevHandle!=INVALID_HANDLE_VALUE)
			{
				//獲取設備的屬性並保存在DevAttributes結構體中
				Result=HidD_GetAttributes(hDevHandle,
					&DevAttributes);
				
				//關閉剛剛打開的設備
				CloseHandle(hDevHandle);
				
				//獲取失敗,查找下一個
				if(Result==FALSE) continue;
				
				//如果獲取成功,則將屬性中的VID、PID以及設備版本號與我們需要的
				//進行比較,如果都一致的話,則說明它就是我們要找的設備。
				if(DevAttributes.VendorID == usVID
					&& DevAttributes.ProductID == usPID){
							MyDevFound=TRUE; //設置設備已經找到
							//AddToInfOut("設備已經找到");
							
							//那麼就是我們要找的設備,分別使用讀寫方式打開之,並保存其句柄
							//並且選擇為異步訪問方式。
							
							//讀方式打開設備
							m_hReadHandle=CreateFile(MyDevPathName, 
								GENERIC_READ,
								FILE_SHARE_READ|FILE_SHARE_WRITE, 
								NULL,
								OPEN_EXISTING,
								//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
								FILE_ATTRIBUTE_NORMAL,
								NULL);
								//if(hReadHandle!=INVALID_HANDLE_VALUE)AddToInfOut("讀訪問打開設備成功");
								//else AddToInfOut("讀訪問打開設備失敗");
							
							//寫方式打開設備
							m_hWriteHandle=CreateFile(MyDevPathName, 
								GENERIC_WRITE,
								FILE_SHARE_READ|FILE_SHARE_WRITE, 
								NULL,
								OPEN_EXISTING,
								//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
								FILE_ATTRIBUTE_NORMAL,
								NULL);
								//if(hWriteHandle!=INVALID_HANDLE_VALUE)AddToInfOut("寫訪問打開設備成功");
								//else AddToInfOut("寫訪問打開設備失敗");
							
						
							//手動觸發事件,讓讀報告線程恢復運行。因為在這之前並沒有調用
							//讀數據的函數,也就不會引起事件的產生,所以需要先手動觸發一
							//次事件,讓讀報告線程恢復運行。
							//SetEvent(ReadOverlapped.hEvent);
							
							//顯示設備的狀態。
							//SetDlgItemText(IDC_DS,"設備已打開");
							
							//找到設備,退出循環。本程序只檢測一個目標設備,查找到後就退出
							//查找了。如果你需要將所有的目標設備都列出來的話,可以設置一個
							//數組,找到後就保存在數組中,直到所有設備都查找完畢才退出查找
							break;
						}
			}
			//如果打開失敗,則查找下一個設備
			else continue;
		}
		
		//調用SetupDiDestroyDeviceInfoList函數銷毀設備信息集合
		SetupDiDestroyDeviceInfoList(hDevInfoSet);
		
		//如果設備已經找到,那麼應該使能各操作按鈕,並同時禁止打開設備按鈕
		return MyDevFound;
	}
Exemplo n.º 15
0
//  open - open 1 or more devices
//
//    Inputs:
//      max = maximum number of devices to open
//      vid = Vendor ID, or -1 if any
//      pid = Product ID, or -1 if any
//      usage_page = top level usage page, or -1 if any
//      usage = top level usage number, or -1 if any
//    Output:
//      actual number of devices opened
//
int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
{
        GUID guid;
        HDEVINFO info;
        DWORD index=0, reqd_size;
        SP_DEVICE_INTERFACE_DATA iface;
        SP_DEVICE_INTERFACE_DETAIL_DATA *details;
        HIDD_ATTRIBUTES attrib;
        PHIDP_PREPARSED_DATA hid_data;
        HIDP_CAPS capabilities;
        HANDLE h;
        BOOL ret;
        hid_t *hid;

        int count=0;

        if (first_hid) free_all_hid();

        if (max < 1) return 0;

        if (!rx_event)
        {
                rx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
                tx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
                InitializeCriticalSection(&rx_mutex);
                InitializeCriticalSection(&tx_mutex);
    }

        HidD_GetHidGuid(&guid);

        info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
        if (info == INVALID_HANDLE_VALUE) return 0;

        for (index=0; 1 ;index++)
        {
                iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
                ret = SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface);
                if (!ret) return count;

                SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &reqd_size, NULL);
                details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(reqd_size);
                if (details == NULL) continue;

                memset(details, 0, reqd_size);
                details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
                ret = SetupDiGetDeviceInterfaceDetail(info, &iface, details, reqd_size, NULL, NULL);
                if (!ret)
                {
                        free(details);
                        continue;
                }

                h = CreateFile(details->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
                if (h == INVALID_HANDLE_VALUE)
                {
                        DWORD err = GetLastError();

                        // I get ERROR_ACCESS_DENIED with most/all my input devices (mice/trackballs/tablet).
                        // Let's not log it :)
                        if (err == ERROR_ACCESS_DENIED)
                        {
                                free(details);
                                continue;
                        }

                        // qDebug wipes the GetLastError() it seems, so do that after print_win32_err().
                        print_win32_err(err);
                        qDebug() << "Problem opening handle, path: " << QString().fromWCharArray(details->DevicePath);

                        free(details);
                        continue;
                }

                free(details);

                attrib.Size = sizeof(HIDD_ATTRIBUTES);
                ret = HidD_GetAttributes(h, &attrib);
                //printf("vid: %4x\n", attrib.VendorID);
                if (!ret || (vid > 0 && attrib.VendorID != vid) ||
              (pid > 0 && attrib.ProductID != pid) ||
                          !HidD_GetPreparsedData(h, &hid_data))
                {
                        CloseHandle(h);
                        continue;
                }

                if (!HidP_GetCaps(hid_data, &capabilities) ||
              (usage_page > 0 && capabilities.UsagePage != usage_page) ||
                          (usage > 0 && capabilities.Usage != usage))
                {
                        HidD_FreePreparsedData(hid_data);
                        CloseHandle(h);
                        continue;
                }

                HidD_FreePreparsedData(hid_data);

                hid = (struct hid_struct *)malloc(sizeof(struct hid_struct));
                if (!hid)
                {
                        CloseHandle(h);
                        continue;
                }

//              COMMTIMEOUTS CommTimeouts;
//              CommTimeouts.ReadIntervalTimeout = 100;                 // 100ms
//              CommTimeouts.ReadTotalTimeoutConstant = 5;              // ms
//              CommTimeouts.ReadTotalTimeoutMultiplier = 1;    //
//              CommTimeouts.WriteTotalTimeoutConstant = 5;             // ms
//              CommTimeouts.WriteTotalTimeoutMultiplier = 1;   //
//              if (!SetCommTimeouts(h, &CommTimeouts))
//              {
////                    DWORD err = GetLastError();
//
//              }

                qDebug("Open: Handle address: %li for num: %i", (long int) h, count);

                hid->handle = h;
                add_hid(hid);

                count++;
                if (count >= max) return count;
        }

        return count;
}
Exemplo n.º 16
0
	BOOLEAN Hid::GetAttributes(HANDLE HidDeviceObject, ATTRIBUTES *Attributes)
	{
		return HidD_GetAttributes(HidDeviceObject, Attributes);
	}
Exemplo n.º 17
0
Arquivo: USBHID.c Projeto: agb861/ddd
/*********************************************************************
*
*       _AddConnection
*
*  Function description
*    Checks the information about the queried device, if complying with
*    out vendor page information, add the device to the connection list.
*
*     
*  Return value:
*   1    - O.K., HID device added.
*   0    - HID device not compatible.
*    
*/
static int _AddConnection(HANDLE hDevList, SP_DEVICE_INTERFACE_DATA * pDevData, CONN_INFO * pConnInfo) {
  SP_INTERFACE_DEVICE_DETAIL_DATA * pDevDetail;
  DWORD                             ReqLen;
  BOOL                              succ;
  HANDLE                            hDevice;
  int                               r;

  r          = 0;
  ReqLen     = 0;
  pDevDetail = NULL;
  // Get length of INTERFACE_DEVICE_DETAIL_DATA, allocate buffer
  // This function call returns the system error "buffer too small" (code 122).
  // We ignore this return code.
  SetupDiGetDeviceInterfaceDetail(hDevList, pDevData, NULL, ReqLen, &ReqLen, NULL);
  pDevDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA*)malloc(ReqLen);
  if (pDevDetail == NULL ) {
    // Memory allocation failed
    return 0;
  }
  // Now get the INTERFACE_DEVICE_DETAIL_DATA struct
  ZeroMemory(pDevDetail,ReqLen);
  pDevDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
  succ = SetupDiGetDeviceInterfaceDetail(hDevList, pDevData, pDevDetail, ReqLen, &ReqLen, NULL);
  if (succ == FALSE) {
    //
    // Could not retrieve information about the device
    //
    free(pDevDetail);
    return 0;
  }
  //
  //  Open a device handle to the HID device and retriece HID information
  //
  hDevice = CreateFile(pDevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
  if (hDevice != INVALID_HANDLE_VALUE) {
    PHIDP_PREPARSED_DATA  pPreparsedData;
    HIDP_CAPS             Capabilities;

    //
    //  Parse the information from HID device
    //
    HidD_GetPreparsedData(hDevice, &pPreparsedData);
    HidP_GetCaps(pPreparsedData, &Capabilities);
    //
    //  Does the device match the Vendor specific page implementation?
    //
    if (Capabilities.UsagePage == _VendorPage) {
      HIDD_ATTRIBUTES  Attributes;

      memset(&Attributes, 0, sizeof(Attributes));
      Attributes.Size = sizeof(Attributes);
      HidD_GetAttributes(hDevice, &Attributes); 
      strcpy(pConnInfo->acDevicePath, pDevDetail->DevicePath);
      pConnInfo->InputReportByteLength  = Capabilities.InputReportByteLength;
      pConnInfo->OutputReportByteLength = Capabilities.OutputReportByteLength;
      pConnInfo->ProductId              = Attributes.ProductID;
      pConnInfo->VendorId               = Attributes.VendorID;
      r = 1;
    }
    CloseHandle(hDevice);
  }
  free(pDevDetail);
  return r;
}
Exemplo n.º 18
0
int thirdspacevest_open_win32(thirdspacevest_device* dev, unsigned int device_index, int get_count)
{
	//Use a series of API calls to find a HID with a specified Vendor IF and Product ID.

	HIDD_ATTRIBUTES						Attributes;
	SP_DEVICE_INTERFACE_DATA			devInfoData;
	BOOL								LastDevice = FALSE;
	int									MemberIndex = 0;
	LONG								Result;
	int									device_count = 0;

	Length = 0;
	detailData = NULL;
	dev->_dev = NULL;

	/*
	  API function: HidD_GetHidGuid
	  Get the GUID for all system HIDs.
	  Returns: the GUID in HidGuid.
	*/

	HidD_GetHidGuid(&HidGuid);

	/*
	  API function: SetupDiGetClassDevs
	  Returns: a handle to a device information set for all installed devices.
	  Requires: the GUID returned by GetHidGuid.
	*/

	hDevInfo=SetupDiGetClassDevs
		(&HidGuid,
		 NULL,
		 NULL,
		 DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);

	devInfoData.cbSize = sizeof(devInfoData);

	//Step through the available devices looking for the one we want.
	//Quit on detecting the desired device or checking all available devices without success.

	MemberIndex = 0;
	LastDevice = FALSE;

	do
	{
		/*
		  API function: SetupDiEnumDeviceInterfaces
		  On return, MyDeviceInterfaceData contains the handle to a
		  SP_DEVICE_INTERFACE_DATA structure for a detected 
		  Requires:
		  The DeviceInfoSet returned in SetupDiGetClassDevs.
		  The HidGuid returned in GetHidGuid.
		  An index to specify a 
		*/

		Result=SetupDiEnumDeviceInterfaces
			(hDevInfo,
			 0,
			 &HidGuid,
			 MemberIndex,
			 &devInfoData);

		if (Result != 0)
		{
			//A device has been detected, so get more information about it.

			/*
			  API function: SetupDiGetDeviceInterfaceDetail
			  Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
			  containing information about a 
			  To retrieve the information, call this function twice.
			  The first time returns the size of the structure in Length.
			  The second time returns a pointer to the data in DeviceInfoSet.
			  Requires:
			  A DeviceInfoSet returned by SetupDiGetClassDevs
			  The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.

			  The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
			  This application doesn't retrieve or use the structure.
			  If retrieving the structure, set
			  MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
			  and pass the structure's address.
			*/

			//Get the Length value.
			//The call will return with a "buffer too small" error which can be ignored.

			Result = SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				 &devInfoData,
				 NULL,
				 0,
				 &Length,
				 NULL);

			//Allocate memory for the hDevInfo structure, using the returned Length.

 			detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);

			//Set cbSize in the detailData structure.

			detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

			//Call the function again, this time passing it the returned buffer size.

			Result = SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				 &devInfoData,
				 detailData,
				 Length,
				 &Required,
				 NULL);

			// Open a handle to the 
			// To enable retrieving information about a system mouse or keyboard,
			// don't request Read or Write access for this handle.

			/*
			  API function: CreateFile
			  Returns: a handle that enables reading and writing to the 
			  Requires:
			  The DevicePath in the detailData structure
			  returned by SetupDiGetDeviceInterfaceDetail.
			*/

			
			dev->_dev =CreateFile
				(detailData->DevicePath,
				 GENERIC_READ | GENERIC_WRITE,
				 FILE_SHARE_READ|FILE_SHARE_WRITE,
				 (LPSECURITY_ATTRIBUTES)NULL,
				 OPEN_EXISTING,
				 0,
				 NULL);

			/*
			  API function: HidD_GetAttributes
			  Requests information from the 
			  Requires: the handle returned by CreateFile.
			  Returns: a HIDD_ATTRIBUTES structure containing
			  the Vendor ID, Product ID, and Product Version Number.
			  Use this information to decide if the detected device is
			  the one we're looking for.
			*/

			//Set the Size to the number of bytes in the structure.

			Attributes.Size = sizeof(Attributes);

			Result = HidD_GetAttributes
				(dev->_dev,
				 &Attributes);

			//Is it the desired device?

			MyDeviceDetected = FALSE;

			if ((Attributes.VendorID == THIRDSPACEVEST_VID && Attributes.ProductID == THIRDSPACEVEST_PID))
			{
				if(get_count)
				{
					++device_count;
					CloseHandle(dev->_dev);
				}
				else
				{
					MyDeviceDetected = TRUE;
					MyDevicePathName = detailData->DevicePath;
					GetDeviceCapabilities(dev->_dev);
					break;
				}
			}
			else
			{
				CloseHandle(dev->_dev);
			}
			free(detailData);
		}  //if (Result != 0)

		else
		{
			LastDevice=TRUE;
		}
		//If we haven't found the device yet, and haven't tried every available device,
		//try the next one.
		MemberIndex = MemberIndex + 1;
	}
	while (!LastDevice);
	SetupDiDestroyDeviceInfoList(hDevInfo);
	if(get_count) return device_count;
	if(MyDeviceDetected) return 0;
	return -1;
}
bool AIOTestAdapter::open()
{
	GUID HidGuid;
	SP_DEVICE_INTERFACE_DATA devInfoData;
	int index = 0;
	BOOL result;
	bool done = false;
	MemoryBlock detailDataBlock(1024);

	HidD_GetHidGuid(&HidGuid);

	HANDLE hDevInfo = SetupDiGetClassDevs
		(&HidGuid,
		NULL,
		NULL,
		DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);

	devInfoData.cbSize = sizeof(devInfoData);

	do
	{
		result = SetupDiEnumDeviceInterfaces
			(hDevInfo,
			0,
			&HidGuid,
			index,
			&devInfoData);
		if (result)
		{ 
			PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
			ULONG bytesNeeded;

			SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				&devInfoData,
				NULL,
				0,
				&bytesNeeded,
				NULL);

			if (bytesNeeded > detailDataBlock.getSize())
			{
				detailDataBlock.setSize(bytesNeeded);
			}
			
			detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)detailDataBlock.getData();
			detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
			SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				&devInfoData,
				detailData,
				detailDataBlock.getSize(),
				&bytesNeeded,
				NULL);

			deviceHandle = CreateFile
				(detailData->DevicePath,
				0,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				(LPSECURITY_ATTRIBUTES)NULL,
				OPEN_EXISTING,
				0,
				NULL);
			if (deviceHandle != INVALID_HANDLE_VALUE)
			{
				HIDD_ATTRIBUTES attributes;

				zerostruct(attributes);
				attributes.Size = sizeof(attributes);
				BOOL attributes_result = HidD_GetAttributes(deviceHandle,&attributes);
				if (attributes_result && ECHO_VENDOR_ID == attributes.VendorID)
				{
					bool match = false;

					switch (attributes.ProductID)
					{
#if SUPPORT_TEST_ADAPTER_V200
					case ECHO_HID_TESTER_PRODUCT_ID_V100:
					case ECHO_HID_TESTER_PRODUCT_ID_V200:
#endif
					case ECHO_HID_TESTER_PRODUCT_ID_V210:
						DBG("Test adapter found");
						match = true;
						productIDs.add(attributes.ProductID);
						break;
					}

					if (match)
					{
						readHandle = CreateFile
							(detailData->DevicePath,
							GENERIC_READ,
							FILE_SHARE_READ | FILE_SHARE_WRITE,
							(LPSECURITY_ATTRIBUTES)NULL,
							OPEN_EXISTING,
							FILE_FLAG_OVERLAPPED,
							NULL);

						writeHandle = CreateFile
							(detailData->DevicePath,
							GENERIC_WRITE,
							FILE_SHARE_READ | FILE_SHARE_WRITE,
							(LPSECURITY_ATTRIBUTES)NULL,
							OPEN_EXISTING,
							FILE_FLAG_OVERLAPPED,
							NULL);
						break;
					}
				}

				CloseHandle(deviceHandle);
				deviceHandle = INVALID_HANDLE_VALUE;
			}
		}
		else
		{
			done = true;
		}

		index++;
	} while (false == done);

	SetupDiDestroyDeviceInfoList(hDevInfo);

	return deviceHandle != INVALID_HANDLE_VALUE && readHandle != INVALID_HANDLE_VALUE && writeHandle != INVALID_HANDLE_VALUE;
}
Exemplo n.º 20
0
struct ols_boot_t *BOOT_Init(uint16_t vid, uint16_t pid)
{
#if IS_WIN32
	GUID HidGuid;
	HDEVINFO hDevInfo;
	SP_DEVICE_INTERFACE_DATA DevInterfaceData;
	unsigned long DevIndex = 0;
	unsigned long DetailsSize;
	PSP_INTERFACE_DEVICE_DETAIL_DATA pDetails;
	HANDLE hHidDevice;
	HIDD_ATTRIBUTES Attr;
#endif

	struct ols_boot_t *ob;
	int ret;

	ob = malloc(sizeof(struct ols_boot_t));
	if (ob == NULL) {
		fprintf(stderr, "Not enough memory \n");
		return NULL;
	}
	memset(ob, 0, sizeof(struct ols_boot_t));

#if IS_WIN32
	HidD_GetHidGuid( &HidGuid);
	hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
	if (hDevInfo == INVALID_HANDLE_VALUE)
	{
		fprintf(stderr, "INVALID_HANDLE_VALUE\n");
		return NULL;
	}
	DevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

	// iterate thgough all HID devices
	// this part is inspirated by Diolan's fw_update
	while(1)
	{
		int bad = 0;

		if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &HidGuid, DevIndex, &DevInterfaceData)) {
			fprintf(stderr, "Device does not exist\n");
			return NULL;
		}

		SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevInterfaceData, NULL, 0, &DetailsSize, NULL);
		pDetails = malloc(DetailsSize);
		if (pDetails == NULL)
		{
			SetupDiDestroyDeviceInfoList(hDevInfo);
			fprintf(stderr, "Not enough memory \n");
			return NULL;
		}

		pDetails->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
		if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevInterfaceData, pDetails, DetailsSize, NULL, NULL))
		{
			free(pDetails);
			SetupDiDestroyDeviceInfoList(hDevInfo);
			fprintf(stderr, "SetupDiGetDeviceInterfaceDetail failed\n");
			return NULL;
		}

		hHidDevice = CreateFile(pDetails->DevicePath,	GENERIC_READ | GENERIC_WRITE,	FILE_SHARE_READ | FILE_SHARE_WRITE,
			NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

		if (hHidDevice == INVALID_HANDLE_VALUE) {
			bad = 1;
		}

		if ((bad == 0) && (!HidD_GetAttributes (hHidDevice, &Attr))) {
			bad = 2;
		}

		if ((bad == 0) && (Attr.VendorID == vid) && (Attr.ProductID == pid)) {
			ob->hDevice = hHidDevice;
			free(pDetails);
			break;
		}

		if (bad > 1) {
			CloseHandle(hHidDevice);
		}

		free(pDetails);
		DevIndex++;
	}
	SetupDiDestroyDeviceInfoList(hDevInfo);
#else
	ret = libusb_init(&ob->ctx);
	if (ret != 0) {
		fprintf(stderr, "libusb_init proobem\n");
	}

	libusb_set_debug(ob->ctx, 4);
	ob->dev = libusb_open_device_with_vid_pid(ob->ctx, vid, pid);
	if (ob->dev == NULL) {
		fprintf(stderr, "USB Device (%04x:%04x) not found, is OLS in bootloader mode ?\n", vid, pid);
		free(ob);
		return NULL;
	}

	if (libusb_kernel_driver_active(ob->dev, 0)) {
		// reattach later
		ob->attach = 1;
		if (libusb_detach_kernel_driver(ob->dev, 0)) {
			fprintf(stderr, "Error detaching kernel driver \n");
			free(ob);
			return NULL;
		}
	}

	ret = libusb_claim_interface(ob->dev, 0);
	if (ret != 0) {
		fprintf(stderr, "Cannot claim USB device\n");
	}

	ret = libusb_set_interface_alt_setting(ob->dev, 0, 0);
	if (ret != 0) {
		fprintf(stderr, "Unable to set alternative interface \n");
	}
#endif

	return ob;
}
Exemplo n.º 21
0
/*
    Func: open_hid()
    Desc: finds & opens device having specified VID & PID.
    Retn: Handle of open device or INVALID_HANDLE_VALUE on fail

    Note this routine is a modified function from:
        usbhidiocDlg.cpp : implementation file
        Project: usbhidioc.cpp
        Version: 3.0
        Date: 7/18/05
        by Jan Axelson ([email protected])
*/
static HANDLE open_hid(unsigned short vid, unsigned short pid)
{
    //Use a series of API calls to find a HID with a specified Vendor IF and Product ID.
    HANDLE                              returnHandle = INVALID_HANDLE_VALUE;
    HIDD_ATTRIBUTES                     Attributes;
//    DWORD                               DeviceUsage;
    SP_DEVICE_INTERFACE_DATA            devInfoData;
    BOOL                                LastDevice = FALSE;
    int                                 MemberIndex = 0;
    LONG                                Result;

    // were global, now just local scrap
    DWORD                               Length = 0;
    PSP_DEVICE_INTERFACE_DETAIL_DATA    detailData = NULL;
    HANDLE                              DeviceHandle=NULL;
    GUID                                HidGuid;
    HANDLE                              hDevInfo;
    ULONG                               Required;
    BOOL                                MyDeviceDetected = 0;

    /*
    API function: HidD_GetHidGuid
    Get the GUID for all system HIDs.
    Returns: the GUID in HidGuid.
    */

    HidD_GetHidGuid(&HidGuid);
    DEBUG("\nHidD_GetHidGuid returned.\n");

    /*
    API function: SetupDiGetClassDevs
    Returns: a handle to a device information set for all installed devices.
    Requires: the GUID returned by GetHidGuid.
    */

    hDevInfo=SetupDiGetClassDevs
             (&HidGuid,
              NULL,
              NULL,
              DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);

    DEBUG("\nSetupDiGetClassDevs returned 0x%x\n", hDevInfo);
    devInfoData.cbSize = sizeof(devInfoData);

    //Step through the available devices looking for the one we want.
    //Quit on detecting the desired device or checking all available devices without success.

    MemberIndex = 0;
    LastDevice = FALSE;

    do
    {
        /*
        API function: SetupDiEnumDeviceInterfaces
        On return, MyDeviceInterfaceData contains the handle to a
        SP_DEVICE_INTERFACE_DATA structure for a detected device.
        Requires:
        The DeviceInfoSet returned in SetupDiGetClassDevs.
        The HidGuid returned in GetHidGuid.
        An index to specify a device.
        */


        Result=SetupDiEnumDeviceInterfaces
               (hDevInfo,
                0,
                &HidGuid,
                MemberIndex,
                &devInfoData);

        DEBUG("\nSetupDiEnumDeviceInterfaces returned 0x%x\n", Result);

        if (Result != 0)
        {
            //A device has been detected, so get more information about it.

            /*
            API function: SetupDiGetDeviceInterfaceDetail
            Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
            containing information about a device.
            To retrieve the information, call this function twice.
            The first time returns the size of the structure in Length.
            The second time returns a pointer to the data in DeviceInfoSet.
            Requires:
            A DeviceInfoSet returned by SetupDiGetClassDevs
            The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.

            The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
            This application doesn't retrieve or use the structure.
            If retrieving the structure, set
            MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
            and pass the structure's address.
            */

            //Get the Length value.
            //The call will return with a "buffer too small" error which can be ignored.
            Result = SetupDiGetDeviceInterfaceDetail
                     (hDevInfo,
                      &devInfoData,
                      NULL,
                      0,
                      &Length,
                      NULL);

            DEBUG("\nSetupDiGetDeviceInterfaceDetail returned 0x%x\n", Result);

            //Allocate memory for the hDevInfo structure, using the returned Length.

            detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);

            //Set cbSize in the detailData structure.

            detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

            //Call the function again, this time passing it the returned buffer size.

            Result = SetupDiGetDeviceInterfaceDetail
                     (hDevInfo,
                      &devInfoData,
                      detailData,
                      Length,
                      &Required,
                      NULL);

            // Open a handle to the device.
            // To enable retrieving information about a system mouse or keyboard,
            // don't request Read or Write access for this handle.

            /*
            API function: CreateFile
            Returns: a handle that enables reading and writing to the device.
            Requires:
            The DevicePath in the detailData structure
            returned by SetupDiGetDeviceInterfaceDetail.
            */

            DeviceHandle=CreateFile
                         (detailData->DevicePath,
                          0,
                          FILE_SHARE_READ|FILE_SHARE_WRITE,
                          (LPSECURITY_ATTRIBUTES)NULL,
                          OPEN_EXISTING,
                          0,
                          NULL);

            DEBUG("CreateFile(): %s\n", detailData->DevicePath);
            /*
            API function: HidD_GetAttributes
            Requests information from the device.
            Requires: the handle returned by CreateFile.
            Returns: a HIDD_ATTRIBUTES structure containing
            the Vendor ID, Product ID, and Product Version Number.
            Use this information to decide if the detected device is
            the one we're looking for.
            */

            //Set the Size to the number of bytes in the structure.

            Attributes.Size = sizeof(Attributes);

            Result = HidD_GetAttributes
                     (DeviceHandle,
                      &Attributes);

            DEBUG("HidD_GetAttributes returned 0x%x\n", Result);
            DEBUG("VID: %.4X PID: %.4X\n", Attributes.VendorID, Attributes.ProductID);

            //Is it the desired device?
            MyDeviceDetected = FALSE;
            if (Attributes.VendorID == vid)
            {
                if (Attributes.ProductID == pid)
                {
                    //Both the Vendor ID and Product ID match.

                    MyDeviceDetected = TRUE;

                    // Get a handle for us to use.

                    returnHandle = CreateFile
                                   (detailData->DevicePath,
                                    GENERIC_WRITE | GENERIC_READ,
                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                                    (LPSECURITY_ATTRIBUTES)NULL,
                                    OPEN_EXISTING,
                                    FILE_FLAG_OVERLAPPED,
                                    NULL);

                } //if (Attributes.ProductID == ProductID)

                else
                    //The Product ID doesn't match.

                    CloseHandle(DeviceHandle);

            } //if (Attributes.VendorID == VendorID)

            else
                //The Vendor ID doesn't match.

                CloseHandle(DeviceHandle);

            //Free the memory used by the detailData structure (no longer needed).

            free(detailData);

        }  //if (Result != 0)

        else
            //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.

            LastDevice=TRUE;

        //If we haven't found the device yet, and haven't tried every available device,
        //try the next one.

        MemberIndex = MemberIndex + 1;

    } //do

    while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));

    if (MyDeviceDetected == FALSE)
        DEBUG("Device not detected\n");
    else
        DEBUG("Device detected\n");

    //Free the memory reserved for hDevInfo by SetupDiClassDevs.

    DEBUG("Calling SetupDiDestroyDeviceInfoList\n");
    SetupDiDestroyDeviceInfoList(hDevInfo);

    return returnHandle;
}
Exemplo n.º 22
0
std::vector<device> find_devices(size_t max_wiimotes)
{
	// VID = Nintendo, PID = Wiimote
	// must be sorted!
	static std::pair<USHORT, USHORT> const vid_pids[] =
	{
		std::make_pair(0x0001, 0x0002),
		std::make_pair(0x0002, 0x00f7),
		std::make_pair(0x057e, 0x0306),
	};

	auto const vid_pids_end = vid_pids + 3;	// TODO: s/3/sizeof...

	std::vector<device> found_wiimotes;
	
	// Get the device id
	GUID device_id;
	HidD_GetHidGuid(&device_id);

	// Get all hid devices connected
	HDEVINFO const device_info = SetupDiGetClassDevs(&device_id, nullptr, nullptr, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);

	DWORD index = 0;
	while (found_wiimotes.size() != max_wiimotes)
	{
		// Query the next hid device info
		SP_DEVICE_INTERFACE_DATA device_data;
		device_data.cbSize = sizeof(device_data);

		if (!SetupDiEnumDeviceInterfaces(device_info, nullptr, &device_id, index++, &device_data))
			break;

		// Get the size of the data block required
		DWORD len = 0;
		SetupDiGetDeviceInterfaceDetail(device_info, &device_data, nullptr, 0, &len, nullptr);

		std::unique_ptr<u8> const detail_array(new u8[len]);

		PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)detail_array.get();
		detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

		// Query the data for this device
		if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, nullptr, nullptr))
			continue;

		// Open new device
		HANDLE const dev = CreateFile(detail_data->DevicePath,
			GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
			OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
		
		if (INVALID_HANDLE_VALUE == dev)
			continue;

		// Get device attributes
		HIDD_ATTRIBUTES attr;
		attr.Size = sizeof(attr);

		HidD_GetAttributes(dev, &attr);
		if (std::binary_search(vid_pids, vid_pids_end, std::make_pair(attr.VendorID, attr.ProductID)))
		{
			// This is a wiimote
			found_wiimotes.push_back(device(dev));
		}
		else
			CloseHandle(dev);
	}

	SetupDiDestroyDeviceInfoList(device_info);

	return found_wiimotes;
}
Exemplo n.º 23
0
BOOLEAN
OpenHidDevice (
    IN       PCHAR          DevicePath,
    IN       BOOL           HasReadAccess,
    IN       BOOL           HasWriteAccess,
    IN       BOOL           IsOverlapped,
    IN       BOOL           IsExclusive,
    IN OUT   PHID_DEVICE    HidDevice
)
/*++
RoutineDescription:
    Given the HardwareDeviceInfo, representing a handle to the plug and
    play information, and deviceInfoData, representing a specific hid device,
    open that device and fill in all the relivant information in the given
    HID_DEVICE structure.

    return if the open and initialization was successfull or not.

--*/
{
    DWORD   accessFlags = 0;
    DWORD   sharingFlags = 0;
    BOOLEAN bSuccess;
    INT     iDevicePathSize;
	HRESULT stringReturn;

    iDevicePathSize = strlen(DevicePath) + 1;
    
    HidDevice -> DevicePath = malloc(iDevicePathSize);

    if (NULL == HidDevice -> DevicePath) 
    {
        return (FALSE);
    }

    stringReturn = StringCbCopy(HidDevice -> DevicePath, iDevicePathSize, DevicePath);
    
    if (HasReadAccess)
    {
        accessFlags |= GENERIC_READ;
    }

    if (HasWriteAccess)
    {
        accessFlags |= GENERIC_WRITE;
    }

    if (!IsExclusive)
    {
        sharingFlags = FILE_SHARE_READ | FILE_SHARE_WRITE;
    }
    
    //
	//  The hid.dll api's do not pass the overlapped structure into deviceiocontrol
	//  so to use them we must have a non overlapped device.  If the request is for
	//  an overlapped device we will close the device below and get a handle to an
	//  overlapped device
	//
	
	HidDevice->HidDevice = CreateFile (DevicePath,
                                       accessFlags,
                                       sharingFlags,
                                       NULL,        // no SECURITY_ATTRIBUTES structure
                                       OPEN_EXISTING, // No special create flags
                                       0,   // Open device as non-overlapped so we can get data
                                       NULL);       // No template file

    if (INVALID_HANDLE_VALUE == HidDevice->HidDevice) 
    {
        free(HidDevice -> DevicePath);
		HidDevice -> DevicePath = INVALID_HANDLE_VALUE ;
        return FALSE;
    }

    HidDevice -> OpenedForRead = HasReadAccess;
    HidDevice -> OpenedForWrite = HasWriteAccess;
    HidDevice -> OpenedOverlapped = IsOverlapped;
    HidDevice -> OpenedExclusive = IsExclusive;
    
    //
    // If the device was not opened as overlapped, then fill in the rest of the
    //  HidDevice structure.  However, if opened as overlapped, this handle cannot
    //  be used in the calls to the HidD_ exported functions since each of these
    //  functions does synchronous I/O.
    //

	if (!HidD_GetPreparsedData (HidDevice->HidDevice, &HidDevice->Ppd)) 
	{
		free(HidDevice -> DevicePath);
		HidDevice -> DevicePath = NULL ;
		CloseHandle(HidDevice -> HidDevice);
		HidDevice -> HidDevice = INVALID_HANDLE_VALUE ;
		return FALSE;
	}

	if (!HidD_GetAttributes (HidDevice->HidDevice, &HidDevice->Attributes)) 
	{
		free(HidDevice -> DevicePath);
		HidDevice -> DevicePath = NULL;
		CloseHandle(HidDevice -> HidDevice);
		HidDevice -> HidDevice = INVALID_HANDLE_VALUE;
		HidD_FreePreparsedData (HidDevice->Ppd);
		HidDevice->Ppd = NULL;

		return FALSE;
	}

	if (!HidP_GetCaps (HidDevice->Ppd, &HidDevice->Caps))
	{
		free(HidDevice -> DevicePath);
		HidDevice -> DevicePath = NULL;
		CloseHandle(HidDevice -> HidDevice);
		HidDevice -> HidDevice = INVALID_HANDLE_VALUE;
		HidD_FreePreparsedData (HidDevice->Ppd);
		HidDevice->Ppd = NULL;

		return FALSE;
	}

	//
	// At this point the client has a choice.  It may chose to look at the
	// Usage and Page of the top level collection found in the HIDP_CAPS
	// structure.  In this way it could just use the usages it knows about.
	// If either HidP_GetUsages or HidP_GetUsageValue return an error then
	// that particular usage does not exist in the report.
	// This is most likely the preferred method as the application can only
	// use usages of which it already knows.
	// In this case the app need not even call GetButtonCaps or GetValueCaps.
	//
	// In this example, however, we will call FillDeviceInfo to look for all
	//    of the usages in the device.
	//

	bSuccess = FillDeviceInfo(HidDevice);

	if (FALSE == bSuccess)
	{
		CloseHidDevice(HidDevice);
		return (FALSE);
	}
    
	if (IsOverlapped)
	{
		CloseHandle(HidDevice->HidDevice);

	    HidDevice->HidDevice = CreateFile (DevicePath,
                                       accessFlags,
                                       sharingFlags,
                                       NULL,        // no SECURITY_ATTRIBUTES structure
                                       OPEN_EXISTING, // No special create flags
                                       FILE_FLAG_OVERLAPPED, // Now we open the device as overlapped
                                       NULL);       // No template file
	
	    if (INVALID_HANDLE_VALUE == HidDevice->HidDevice) 
		{
			CloseHidDevice(HidDevice);
			return FALSE;
		}
	}

    return (TRUE);
}
Exemplo n.º 24
0
bool CUsbhidioc::FindTheHID(int unitNumber)
{
	//Use a series of API calls to find a HID with a matching Vendor and Product ID.

	HIDD_ATTRIBUTES			Attributes;
	SP_DEVICE_INTERFACE_DATA	   devInfoData;
	bool					LastDevice = FALSE;
	int						MemberIndex;
	LONG					Result;
	int						unitIndex;
	char					unitIDSerial[64];

	//These are the vendor and product IDs to look for.
	const unsigned int VendorID = 0x04d8;    // Uses Microchip's Vendor ID.
	const unsigned int ProductID = 0x0033;   // PICkit 2 Flash Starter Kit

	Length = 0;
	detailData = NULL;
	DeviceHandle=NULL;

	/*
	API function: HidD_GetHidGuid
	Get the GUID for all system HIDs.
	Returns: the GUID in HidGuid.
	*/

	HidD_GetHidGuid(&HidGuid);
	
	/*
	API function: SetupDiGetClassDevs
	Returns: a handle to a device information set for all installed devices.
	Requires: the GUID returned by GetHidGuid.
	*/
	
	hDevInfo=SetupDiGetClassDevs
		(&HidGuid,
		NULL, 
		NULL,
		DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
		
	devInfoData.cbSize = sizeof(devInfoData);

	//Step through the available devices looking for the one we want. 
	//Quit on detecting the desired device or checking all available devices without success.
	MemberIndex = 0;
	unitIndex = 0;
	LastDevice = FALSE;

	do
	{
		DeviceDetected=false;

		/*
		API function: SetupDiEnumDeviceInterfaces
		On return, MyDeviceInterfaceData contains the handle to a
		SP_DEVICE_INTERFACE_DATA structure for a detected device.
		Requires:
		The DeviceInfoSet returned in SetupDiGetClassDevs.
		The HidGuid returned in GetHidGuid.
		An index to specify a device.
		*/

		Result=SetupDiEnumDeviceInterfaces
			(hDevInfo,
			0,
			&HidGuid,
			MemberIndex,
			&devInfoData);

		if (Result != 0)
		{
			//A device has been detected, so get more information about it.

			/*
			API function: SetupDiGetDeviceInterfaceDetail
			Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
			containing information about a device.
			To retrieve the information, call this function twice.
			The first time returns the size of the structure in Length.
			The second time returns a pointer to the data in DeviceInfoSet.
			Requires:
			A DeviceInfoSet returned by SetupDiGetClassDevs
			The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.

			The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
			This application doesn't retrieve or use the structure.
			If retrieving the structure, set
			MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
			and pass the structure's address.
			*/

			//Get the Length value.
			//The call will return with a "buffer too small" error which can be ignored.
			Result = SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				&devInfoData,
				NULL,
				0,
				&Length,
				NULL);

			//Allocate memory for the hDevInfo structure, using the returned Length.
			detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);

			//Set cbSize in the detailData structure.
			detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        // **** IMPORTANT ****
        // sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) should equal 5.
        // In C++ Builder, go to Project/Options/Advanced Compiler/Data Alignment
        // and select "byte" align.

			//Call the function again, this time passing it the returned buffer size.
			Result = SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				&devInfoData,
				detailData,
				Length,
				&Required,
				NULL);

                        Result = GetLastError ();
			//Open a handle to the device.

			/*
			API function: CreateFile
			Returns: a handle that enables reading and writing to the device.
			Requires:
			The DevicePath in the detailData structure
			returned by SetupDiGetDeviceInterfaceDetail.
			*/

			DeviceHandle=CreateFile
				(detailData->DevicePath,
				GENERIC_READ|GENERIC_WRITE,
				FILE_SHARE_READ|FILE_SHARE_WRITE,
				(LPSECURITY_ATTRIBUTES)NULL,
				OPEN_EXISTING,
				0,
				NULL);

			if ((int)DeviceHandle != -1)
			{
				/*
				API function: HidD_GetAttributes
				Requests information from the device.
				Requires: the handle returned by CreateFile.
				Returns: a HIDD_ATTRIBUTES structure containing
				the Vendor ID, Product ID, and Product Version Number.
				Use this information to decide if the detected device is
				the one we're looking for.
				*/

				//Set the Size to the number of bytes in the structure.
				Attributes.Size = sizeof(Attributes);

				Result = HidD_GetAttributes
					(DeviceHandle,
					&Attributes);

				if (Result != 0)
				{
					//Is it the desired device?
					DeviceDetected = false;

					if (Attributes.VendorID == VendorID)
					{
						if (Attributes.ProductID == ProductID)
						{
							//Both the Product and Vendor IDs match.
							if (unitNumber == unitIndex)
							{
								// Get Unit ID serial string
								HidD_GetSerialNumberString(DeviceHandle, unitIDSerial, 64);
								int x = 2;
								if ((unitIDSerial[0] == 0x09) || (unitIDSerial[0] == 0x00))
								{
									m_UnitID[0] = '-';
									m_UnitID[1] = 0;
								}
								else
								{
									m_UnitID[0] = unitIDSerial[0];
									for (; x < 28; x+=2)
									{
										m_UnitID[x/2] = unitIDSerial[x];
									    if ((unitIDSerial[x] == 0) || (unitIDSerial[x] == 0xE0))
										   break;
									    m_UnitID[x] = 0;
									    m_UnitID[x+1] = 0;
									}
								}
								DeviceDetected = true;
								PrepareForOverlappedTransfer();
							}
							else
							{
								CloseHandle(DeviceHandle);
								unitIndex++;
							}
						} //if (Attributes.ProductID == ProductID)

						else
							//The Product ID doesn't match.
							CloseHandle(DeviceHandle);
					} //if (Attributes.VendorID == VendorID)

					else
						//The Vendor ID doesn't match.
						CloseHandle(DeviceHandle);

				//Free the memory used by the detailData structure (no longer needed).
				free(detailData);
				}  //if (Result != 0)

				else
					//SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
					LastDevice=TRUE;
			}
		}

		//If we haven't found the device yet, and haven't tried every available device,
		//try the next one.
		MemberIndex = MemberIndex + 1;

	} //do
	while ((LastDevice == FALSE) && (DeviceDetected == false) && (MemberIndex < 24)); // check 24 devices max

	//Free the memory reserved for hDevInfo by SetupDiClassDevs.
	SetupDiDestroyDeviceInfoList(hDevInfo);

	return DeviceDetected;
}
Exemplo n.º 25
0
bool CLCDConnectionLogitech::HIDInit()
{
	if (GetConnectionState() != CONNECTED ||
		m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //LGLCD_DEVICE_FAMILY_KEYBOARD_G15)
		return false;

	// Logitech G15 
	int VendorID = 0x046d;
	int ProductID = 0xc222;

	//Use a series of API calls to find a HID with a specified Vendor IF and Product ID.

	HIDD_ATTRIBUTES						Attributes;
	SP_DEVICE_INTERFACE_DATA			devInfoData;
	bool								LastDevice = FALSE;
	int									MemberIndex = 0;
	LONG								Result;

	DWORD Length = 0;
	PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
	HANDLE hDevInfo = NULL;
	GUID HidGuid;
	ULONG Required = 0;

	bool MyDeviceDetected = false;

	/*
	API function: HidD_GetHidGuid
	Get the GUID for all system HIDs.
	Returns: the GUID in HidGuid.
	*/

	HidD_GetHidGuid(&HidGuid);

	/*
	API function: SetupDiGetClassDevs
	Returns: a handle to a device information set for all installed devices.
	Requires: the GUID returned by GetHidGuid.
	*/

	hDevInfo = SetupDiGetClassDevs
		(&HidGuid,
		NULL,
		NULL,
		DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);

	devInfoData.cbSize = sizeof(devInfoData);

	//Step through the available devices looking for the one we want. 
	//Quit on detecting the desired device or checking all available devices without success.

	MemberIndex = 0;
	LastDevice = FALSE;

	do
	{
		/*
		API function: SetupDiEnumDeviceInterfaces
		On return, MyDeviceInterfaceData contains the handle to a
		SP_DEVICE_INTERFACE_DATA structure for a detected device.
		Requires:
		The DeviceInfoSet returned in SetupDiGetClassDevs.
		The HidGuid returned in GetHidGuid.
		An index to specify a device.
		*/

		Result = SetupDiEnumDeviceInterfaces
			(hDevInfo,
			0,
			&HidGuid,
			MemberIndex,
			&devInfoData);

		if (Result != 0)
		{
			//A device has been detected, so get more information about it.

			/*
			API function: SetupDiGetDeviceInterfaceDetail
			Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
			containing information about a device.
			To retrieve the information, call this function twice.
			The first time returns the size of the structure in Length.
			The second time returns a pointer to the data in DeviceInfoSet.
			Requires:
			A DeviceInfoSet returned by SetupDiGetClassDevs
			The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.

			The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
			This application doesn't retrieve or use the structure.
			If retrieving the structure, set
			MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
			and pass the structure's address.
			*/

			//Get the Length value.
			//The call will return with a "buffer too small" error which can be ignored.

			Result = SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				&devInfoData,
				NULL,
				0,
				&Length,
				NULL);

			//Allocate memory for the hDevInfo structure, using the returned Length.

			detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);

			//Set cbSize in the detailData structure.

			detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

			//Call the function again, this time passing it the returned buffer size.

			Result = SetupDiGetDeviceInterfaceDetail
				(hDevInfo,
				&devInfoData,
				detailData,
				Length,
				&Required,
				NULL);

			// Open a handle to the device.
			// To enable retrieving information about a system mouse or keyboard,
			// don't request Read or Write access for this handle.

			/*
			API function: CreateFile
			Returns: a handle that enables reading and writing to the device.
			Requires:
			The DevicePath in the detailData structure
			returned by SetupDiGetDeviceInterfaceDetail.
			*/

			m_hHIDDeviceHandle = CreateFile
				(detailData->DevicePath,
				FILE_GENERIC_READ | FILE_GENERIC_WRITE,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				(LPSECURITY_ATTRIBUTES)NULL,
				OPEN_EXISTING,
				FILE_FLAG_OVERLAPPED,
				NULL);

			/*
			API function: HidD_GetAttributes
			Requests information from the device.
			Requires: the handle returned by CreateFile.
			Returns: a HIDD_ATTRIBUTES structure containing
			the Vendor ID, Product ID, and Product Version Number.
			Use this information to decide if the detected device is
			the one we're looking for.
			*/

			//Set the Size to the number of bytes in the structure.

			Attributes.Size = sizeof(Attributes);

			Result = HidD_GetAttributes
				(m_hHIDDeviceHandle,
				&Attributes);

			//Is it the desired device?
			MyDeviceDetected = FALSE;

			if (Attributes.VendorID == VendorID)
			{
				if (Attributes.ProductID == ProductID)
				{
					//Both the Vendor ID and Product ID match.
					MyDeviceDetected = TRUE;
				}
				else
					CloseHandle(m_hHIDDeviceHandle);

			}
			else
				CloseHandle(m_hHIDDeviceHandle);

			//Free the memory used by the detailData structure (no longer needed).
			free(detailData);
		}

		else
			LastDevice = TRUE;

		MemberIndex = MemberIndex + 1;
	} //do
	while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));

	if (MyDeviceDetected)
	{
		PHIDP_PREPARSED_DATA	PreparsedData;

		HidD_GetPreparsedData
			(m_hHIDDeviceHandle,
			&PreparsedData);

		HidP_GetCaps
			(PreparsedData,
			&m_HIDCapabilities);

		HidD_FreePreparsedData(PreparsedData);
	}
	//Free the memory reserved for hDevInfo by SetupDiClassDevs.

	SetupDiDestroyDeviceInfoList(hDevInfo);

	return MyDeviceDetected;
}
Exemplo n.º 26
0
BOOL CUSBDrive::WriteData(LPVOID lpBuffer)
{
	if(m_HidHandle == INVALID_HANDLE_VALUE)
		{
   /*     //MessageBox("设备未连接");
        return false;
		}

	 char	reportbuf[9];

	::memcpy( &reportbuf[1],lpBuffer,8);
	reportbuf[0]=0;

	OVERLAPPED op={0};
	HANDLE hEvent=CreateEvent(NULL,false,false,NULL);
	op.hEvent=hEvent;

	ULONG	nWritten;
	    
	if(!WriteFile(m_HidHandle, &reportbuf[0],9,&nWritten,  &op))//0))
	{
			DWORD dwErr=::GetLastError();
			//AfxMessageBox("发送erase command失败!");
			if(dwErr != ERROR_IO_PENDING )
			{
				CloseHandle(hEvent);
			    return false;
			}
		    else
			{
		    	DWORD dwObj=WaitForSingleObject(op.hEvent,50);
		    	if(dwObj==WAIT_OBJECT_0)
				{
					CloseHandle(hEvent);
				   return true;
				}
		    	else if(dwObj==WAIT_TIMEOUT)
				{
					CancelIo(m_HidHandle);
				CloseHandle(hEvent);
				return false;
				}
			}
//			return false;
	}
   	//AfxMessageBox("发送erase command ok! 3s后可以写flash");
	CloseHandle(hEvent);
	return true;*/
}

BOOL CUSBDrive::ReadData(LPVOID lpBuffer)
{
	if(m_HidHandle == INVALID_HANDLE_VALUE)
		{
        //MessageBox("设备未连接");
        return false;
		}

	char	reportbuf[9];
	memset(reportbuf,0,9);
//	reportbuf[0]=2;	
	OVERLAPPED op={0};
	HANDLE hEvent=CreateEvent(NULL,false,false,NULL);
	op.hEvent=hEvent;

	ULONG	nWritten;
	    
		 if(!ReadFile(m_HidHandle, &reportbuf[0],9,&nWritten,  &op))//0))
		{
			DWORD dwErr=::GetLastError();
			//AfxMessageBox("发送erase command失败!");
			if(dwErr != ERROR_IO_PENDING )
			{
				CloseHandle(hEvent);
			    return false;
			}
		    else
			{
		    	DWORD dwObj=WaitForSingleObject(op.hEvent,1200);
		    	if(dwObj==WAIT_OBJECT_0)
				{
					
					::memcpy(lpBuffer,&reportbuf[1],8);
					CloseHandle(hEvent);
				   return true;
				}
		    	else if(dwObj==WAIT_TIMEOUT)
				{
					CancelIo(m_HidHandle);
					CloseHandle(hEvent);
				return false;
				}
			}
//			return false;
		}

   	::memcpy(lpBuffer,&reportbuf[1],8);
	
	//AfxMessageBox("发送erase command ok! 3s后可以写flash");
	CloseHandle(hEvent);
	return true;
}

HANDLE CUSBDrive::FindHandle()
{
	HANDLE hidHandle=INVALID_HANDLE_VALUE;

	//查找本系统中HID类的GUID标识
    GUID hidGuid;

    HidD_GetHidGuid(&hidGuid);           

	//准备查找符合HID规范的USB设备,获取HID类设备信息集
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&hidGuid,
                                            NULL,
                                            NULL,
                                            (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); 
    if(hDevInfo==INVALID_HANDLE_VALUE)
    {
        //m_Status.SetWindowText("获取HID设备信息失败!");
		hidHandle=INVALID_HANDLE_VALUE;
        return  hidHandle;
    }

    SP_DEVICE_INTERFACE_DATA devInfoData;
    devInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
    int deviceNo = 0;
	BOOL bSuccess=false;

 //   SetLastError(NO_ERROR);

 //   while(GetLastError() != ERROR_NO_MORE_ITEMS)
	
	do
    {
		// 枚举设备接口信息
		bSuccess=SetupDiEnumDeviceInterfaces (hDevInfo,
											  0, 
											  &hidGuid,
										      deviceNo,
											  &devInfoData);
		//找到了可用的USB设备
        if(bSuccess&&(GetLastError()!=ERROR_NO_MORE_ITEMS)) 
        {
			//若找到了一个USB设备,则获取该设备的细节信息
            ULONG  requiredLength = 0;

			PSP_INTERFACE_DEVICE_DETAIL_DATA devDetail;
            SetupDiGetDeviceInterfaceDetail(hDevInfo,
                                            &devInfoData,
                                            NULL, 
                                            0, 
                                            &requiredLength,
                                            NULL);

            devDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc (requiredLength);
            devDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

            if(! SetupDiGetDeviceInterfaceDetail(hDevInfo,
                                                 &devInfoData,
                                                 devDetail,
                                                 requiredLength,
                                                 NULL,
                                                 NULL)) 
				{
                //AfxMessageBox("获取HID设备细节信息失败!");
                free(devDetail);
				hidHandle=INVALID_HANDLE_VALUE;
                return hidHandle;
				}
			
            hidHandle = CreateFile(devDetail->DevicePath,
                                   GENERIC_READ | GENERIC_WRITE,
                                   FILE_SHARE_READ|FILE_SHARE_WRITE,
                                   NULL, 
								   OPEN_EXISTING,         
                                   FILE_FLAG_OVERLAPPED|FILE_ATTRIBUTE_NORMAL,
			   					  //NULL,
                                  NULL);
		
			DWORD err;
			err=GetLastError();
            free(devDetail);

            if(hidHandle==INVALID_HANDLE_VALUE)
				{
             //   AfxMessageBox("获取HID设备句柄失败!");
				++deviceNo;
                continue;
				}

            HIDD_ATTRIBUTES hidAttributes;
            if(!HidD_GetAttributes(hidHandle, &hidAttributes))
				{
            //    AfxMessageBox("获取HID设备属性失败!");
                CloseHandle(hidHandle);
				hidHandle=INVALID_HANDLE_VALUE;
                return	hidHandle;
				}

            if(USB_VID == hidAttributes.VendorID &&			//USB_VID
               USB_PID  == hidAttributes.ProductID &&			//USB_PID
               USBRS232_VERSION == hidAttributes.VersionNumber)

				{
				SetupDiDestroyDeviceInfoList(hDevInfo);
			    return	hidHandle;
				}
            else
				{
                CloseHandle(hidHandle);
                ++deviceNo;
				}
        }
	else break;//没有找到可用的设备或者没找到更多的可用设备
	}while(bSuccess);

	SetupDiDestroyDeviceInfoList(hDevInfo);
	hidHandle=INVALID_HANDLE_VALUE;
	return hidHandle;
}

BOOL CUSBDrive::WriteData(int Address, unsigned char Data)
{
	unsigned char buf[8];
	buf[0]=(char)WriteCommandWord;
	buf[3]=(char)EndMark;
	buf[4]=(char)WriteCommandWord;
	buf[5]=Data;
	buf[6]=(char)0x00;
	buf[7]=(char)EndMark;
	unsigned char ADDR_H = Address/256;
	unsigned char ADDR_L = Address%256;
	buf[1]=ADDR_H;
	buf[2]=ADDR_L;
	
	if(!WriteData(buf))
		return FALSE;
	if(!ReadData(buf))
		return FALSE;
	for (int i = 0; i < 8; i++){
		if(buf[i] != 0xA5)
			return FALSE;
	}
	return TRUE;
}
Exemplo n.º 27
0
int usbOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs)
{
GUID                                hidGuid;        /* GUID for HID driver */
HDEVINFO                            deviceInfoList;
SP_DEVICE_INTERFACE_DATA            deviceInfo;
SP_DEVICE_INTERFACE_DETAIL_DATA     *deviceDetails = NULL;
DWORD                               size;
int                                 i, openFlag = 0;  /* may be FILE_FLAG_OVERLAPPED */
int                                 errorCode = USB_ERROR_NOTFOUND;
HANDLE                              handle = INVALID_HANDLE_VALUE;
HIDD_ATTRIBUTES                     deviceAttributes;
				
    HidD_GetHidGuid(&hidGuid);
    deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
    deviceInfo.cbSize = sizeof(deviceInfo);
    for(i=0;;i++){
        if(handle != INVALID_HANDLE_VALUE){
            CloseHandle(handle);
            handle = INVALID_HANDLE_VALUE;
        }
        if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
            break;  /* no more entries */
        /* first do a dummy call just to determine the actual size required */
        SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
        if(deviceDetails != NULL)
            free(deviceDetails);
        deviceDetails = malloc(size);
        deviceDetails->cbSize = sizeof(*deviceDetails);
        /* this call is for real: */
        SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL);
        DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
        /* attempt opening for R/W -- we don't care about devices which can't be accessed */
        handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL);
        if(handle == INVALID_HANDLE_VALUE){
            DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
            /* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */
            continue;
        }
        deviceAttributes.Size = sizeof(deviceAttributes);
        HidD_GetAttributes(handle, &deviceAttributes);
        DEBUG_PRINT(("device attributes: vid=%d pid=%d\n", deviceAttributes.VendorID, deviceAttributes.ProductID));
        if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
            continue;   /* ignore this device */
        errorCode = USB_ERROR_NOTFOUND;
        if(vendorName != NULL && productName != NULL){
            char    buffer[512];
            if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
                DEBUG_PRINT(("error obtaining vendor name\n"));
                errorCode = USB_ERROR_IO;
                continue;
            }
            convertUniToAscii(buffer);
            DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
            if(strcmp(vendorName, buffer) != 0)
                continue;
            if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
                DEBUG_PRINT(("error obtaining product name\n"));
                errorCode = USB_ERROR_IO;
                continue;
            }
            convertUniToAscii(buffer);
            DEBUG_PRINT(("productName = \"%s\"\n", buffer));
            if(strcmp(productName, buffer) != 0)
                continue;
        }
        break;  /* we have found the device we are looking for! */
    }
    SetupDiDestroyDeviceInfoList(deviceInfoList);
    if(deviceDetails != NULL)
        free(deviceDetails);
    if(handle != INVALID_HANDLE_VALUE){
        *device = (usbDevice_t *)handle;
        errorCode = 0;
    }
    return errorCode;
}
Exemplo n.º 28
0
Arquivo: hid.c Projeto: bagong/hidapi
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	BOOL res;
	struct hid_device_info *root = NULL; /* return object */
	struct hid_device_info *cur_dev = NULL;

	/* Windows objects for interacting with the driver. */
	GUID InterfaceClassGuid;
	HidD_GetHidGuid(&InterfaceClassGuid);
	SP_DEVINFO_DATA devinfo_data;
	SP_DEVICE_INTERFACE_DATA device_interface_data;
	SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
	HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
	int device_index = 0;
	int i;

	if (hid_init() < 0)
		return NULL;

	/* Initialize the Windows objects. */
	memset(&devinfo_data, 0x0, sizeof(devinfo_data));
	devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
	device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

	/* Get information for all the devices belonging to the HID class. */
	device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

	/* Iterate over each device in the HID class, looking for the right one. */

	for (;;) {
		HANDLE write_handle = INVALID_HANDLE_VALUE;
		DWORD required_size = 0;
		HIDD_ATTRIBUTES attrib;

		res = SetupDiEnumDeviceInterfaces(device_info_set,
			NULL,
			&InterfaceClassGuid,
			device_index,
			&device_interface_data);

		if (!res) {
			/* A return of FALSE from this function means that
			   there are no more devices. */
			break;
		}

		/* Call with 0-sized detail size, and let the function
		   tell us how long the detail struct needs to be. The
		   size is put in &required_size. */
		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
			&device_interface_data,
			NULL,
			0,
			&required_size,
			NULL);

		/* Allocate a long enough structure for device_interface_detail_data. */
		device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
		device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);

		/* Get the detailed data for this device. The detail data gives us
		   the device path for this device, which is then passed into
		   CreateFile() to get a handle to the device. */
		res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
			&device_interface_data,
			device_interface_detail_data,
			required_size,
			NULL,
			NULL);

		if (!res) {
			/* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
			   Continue to the next device. */
			goto cont;
		}

		/* Make sure this device is of Setup Class "HIDClass" and has a
		   driver bound to it. */
		for (i = 0; ; i++) {
			char driver_name[256];

			/* Populate devinfo_data. This function will return failure
			   when there are no more interfaces left. */
			res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
			if (!res)
				goto cont;

			res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
			               SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
			if (!res)
				goto cont;

			if (strcmp(driver_name, "HIDClass") == 0) {
				/* See if there's a driver bound. */
				res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data,
				           SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL);
				if (res)
					break;
			}
		}

		//wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);

		/* Open a handle to the device */
		write_handle = open_device(device_interface_detail_data->DevicePath, TRUE);

		/* Check validity of write_handle. */
		if (write_handle == INVALID_HANDLE_VALUE) {
			/* Unable to open the device. */
			//register_error(dev, "CreateFile");
			goto cont_close;
		}


		/* Get the Vendor ID and Product ID for this device. */
		attrib.Size = sizeof(HIDD_ATTRIBUTES);
		HidD_GetAttributes(write_handle, &attrib);
		//wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);

		/* Check the VID/PID to see if we should add this
		   device to the enumeration list. */
		if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&
		    (product_id == 0x0 || attrib.ProductID == product_id)) {

			#define WSTR_LEN 512
			const char *str;
			struct hid_device_info *tmp;
			PHIDP_PREPARSED_DATA pp_data = NULL;
			HIDP_CAPS caps;
			BOOLEAN res;
			NTSTATUS nt_res;
			wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */
			size_t len;

			/* VID/PID match. Create the record. */
			tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			cur_dev = tmp;

			/* Get the Usage Page and Usage for this device. */
			res = HidD_GetPreparsedData(write_handle, &pp_data);
			if (res) {
				nt_res = HidP_GetCaps(pp_data, &caps);
				if (nt_res == HIDP_STATUS_SUCCESS) {
					cur_dev->usage_page = caps.UsagePage;
					cur_dev->usage = caps.Usage;
				}

				HidD_FreePreparsedData(pp_data);
			}

			/* Fill out the record */
			cur_dev->next = NULL;
			str = device_interface_detail_data->DevicePath;
			if (str) {
				len = strlen(str);
				cur_dev->path = (char*) calloc(len+1, sizeof(char));
				strncpy(cur_dev->path, str, len+1);
				cur_dev->path[len] = '\0';
			}
			else
				cur_dev->path = NULL;

			/* Serial Number */
			res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr));
			wstr[WSTR_LEN-1] = 0x0000;
			if (res) {
				cur_dev->serial_number = _wcsdup(wstr);
			}

			/* Manufacturer String */
			res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr));
			wstr[WSTR_LEN-1] = 0x0000;
			if (res) {
				cur_dev->manufacturer_string = _wcsdup(wstr);
			}

			/* Product String */
			res = HidD_GetProductString(write_handle, wstr, sizeof(wstr));
			wstr[WSTR_LEN-1] = 0x0000;
			if (res) {
				cur_dev->product_string = _wcsdup(wstr);
			}

			/* VID/PID */
			cur_dev->vendor_id = attrib.VendorID;
			cur_dev->product_id = attrib.ProductID;

			/* Release Number */
			cur_dev->release_number = attrib.VersionNumber;

			/* Interface Number. It can sometimes be parsed out of the path
			   on Windows if a device has multiple interfaces. See
			   http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or
			   search for "Hardware IDs for HID Devices" at MSDN. If it's not
			   in the path, it's set to -1. */
			cur_dev->interface_number = -1;
			if (cur_dev->path) {
				char *interface_component = strstr(cur_dev->path, "&mi_");
				if (interface_component) {
					char *hex_str = interface_component + 4;
					char *endptr = NULL;
					cur_dev->interface_number = strtol(hex_str, &endptr, 16);
					if (endptr == hex_str) {
						/* The parsing failed. Set interface_number to -1. */
						cur_dev->interface_number = -1;
					}
				}
			}
		}

cont_close:
		CloseHandle(write_handle);
cont:
		/* We no longer need the detail data. It can be freed */
		free(device_interface_detail_data);

		device_index++;

	}

	/* Close the device information handle. */
	SetupDiDestroyDeviceInfoList(device_info_set);

	return root;

}
void * _ykusb_open_device(int vendor_id, int product_id)
{
	HDEVINFO hi;
	SP_DEVICE_INTERFACE_DATA di;
	PSP_DEVICE_INTERFACE_DETAIL_DATA pi;
	int i, numDev = 0;
	LPTSTR path = 0;
	DWORD len, rc;
	HANDLE ret_handle = NULL;

	yk_errno = YK_EUSBERR;

	hi = SetupDiGetClassDevs(&GUID_DEVINTERFACE_KEYBOARD, 0, 0,
				 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (hi == INVALID_HANDLE_VALUE)
		return NULL;

	di.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);

	for (i = 0; i < 1000; i++) {
		if (!SetupDiEnumDeviceInterfaces(hi, 0, &GUID_DEVINTERFACE_KEYBOARD, i, &di))
			break;

		if (SetupDiGetDeviceInterfaceDetail(hi, &di, 0, 0, &len, 0) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
			break;

		pi = malloc (len);
		if (!pi) {
			yk_errno = YK_ENOMEM;
			goto done;
		}
		pi->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);

		rc = SetupDiGetDeviceInterfaceDetail(hi, &di, pi, len, &len, 0);
		if (rc) {
			HANDLE m_handle;

			m_handle = CreateFile(pi->DevicePath, GENERIC_WRITE,
					      FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
			if (m_handle != INVALID_HANDLE_VALUE) {
				HIDD_ATTRIBUTES devInfo;

				if (HidD_GetAttributes(m_handle, &devInfo)) {
					if (devInfo.VendorID == vendor_id && devInfo.ProductID == product_id) {
						ret_handle = m_handle;
						free (pi);
						goto done;
					}
				}
			}
			CloseHandle (m_handle);
		}

		free (pi);

		if (!rc)
			break;
	}

	yk_errno = YK_ENOKEY;

done:
	SetupDiDestroyDeviceInfoList(hi);
	return ret_handle;
}
Exemplo n.º 30
0
int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
	GUID device_id;
	HANDLE dev;
	HDEVINFO device_info;
	int i, index;
	DWORD len;
	SP_DEVICE_INTERFACE_DATA device_data;
	PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL;
	HIDD_ATTRIBUTES	attr;
	int found = 0;

	(void) timeout; /* unused */

	device_data.cbSize = sizeof(device_data);
	index = 0;

	/* get the device id */
	HidD_GetHidGuid(&device_id);

	/* get all hid devices connected */
	device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT));

	for (;; ++index) {

		if (detail_data) {
			free(detail_data);
			detail_data = NULL;
		}

		/* query the next hid device info */
		if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data)) {
			break;
		}

		/* get the size of the data block required */
		i = SetupDiGetDeviceInterfaceDetail(device_info, &device_data, NULL, 0, &len, NULL);
		detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*)malloc(len);
		detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

		/* query the data for this device */
		if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) {
			continue;
		}

		/* open the device */
		dev = CreateFile(detail_data->DevicePath,
		                 (GENERIC_READ | GENERIC_WRITE),
		                 (FILE_SHARE_READ | FILE_SHARE_WRITE),
		                 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
		if (dev == INVALID_HANDLE_VALUE) {
			continue;
		}

		/* get device attributes */
		attr.Size = sizeof(attr);
		i = HidD_GetAttributes(dev, &attr);

		if ((attr.VendorID == WM_VENDOR_ID) && (attr.ProductID == WM_PRODUCT_ID)) {
			/* this is a wiimote */
			wm[found]->dev_handle = dev;

			wm[found]->hid_overlap.hEvent = CreateEvent(NULL, 1, 1, "");
			wm[found]->hid_overlap.Offset = 0;
			wm[found]->hid_overlap.OffsetHigh = 0;

			WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_DEV_FOUND);
			WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED);

			/* try to set the output report to see if the device is actually connected */
			if (!wiiuse_set_report_type(wm[found])) {
				WIIMOTE_DISABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED);
				continue;
			}

			/* do the handshake */
			wiiuse_handshake(wm[found], NULL, 0);

			WIIUSE_INFO("Connected to wiimote [id %i].", wm[found]->unid);

			++found;
			if (found >= max_wiimotes) {
				break;
			}
		} else {
			/* not a wiimote */
			CloseHandle(dev);
		}
	}

	if (detail_data) {
		free(detail_data);
	}

	SetupDiDestroyDeviceInfoList(device_info);

	return found;
}