Example #1
0
// Find and connect Wiimotes.
// Does not replace already found Wiimotes even if they are disconnected.
// wm is an array of max_wiimotes Wiimotes
// Returns the total number of found and connected Wiimotes.
void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board)
{
	if (!s_loaded_ok)
		return;

	ProcessWiimotes(true, [](HANDLE hRadio, const BLUETOOTH_RADIO_INFO& rinfo, BLUETOOTH_DEVICE_INFO_STRUCT& btdi)
	{
		ForgetWiimote(btdi);
		AttachWiimote(hRadio, rinfo, btdi);
	});

	// Get the device id
	GUID device_id;
	pHidD_GetHidGuid(&device_id);

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

	SP_DEVICE_INTERFACE_DATA device_data;
	device_data.cbSize = sizeof(device_data);
	PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = nullptr;

	for (int index = 0; SetupDiEnumDeviceInterfaces(device_info, nullptr, &device_id, index, &device_data); ++index)
	{
		// Get the size of the data block required
		DWORD len;
		SetupDiGetDeviceInterfaceDetail(device_info, &device_data, nullptr, 0, &len, nullptr);
		detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)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, nullptr, nullptr))
		{
			std::basic_string<TCHAR> device_path(detail_data->DevicePath);
			Wiimote* wm = new WiimoteWindows(device_path);
			bool real_wiimote = false, is_bb = false;

			CheckDeviceType(device_path, real_wiimote, is_bb);
			if (is_bb)
			{
				found_board = wm;
			}
			else if (real_wiimote)
			{
				found_wiimotes.push_back(wm);
			}
			else
			{
				delete wm;
			}
		}

		free(detail_data);
	}

	SetupDiDestroyDeviceInfoList(device_info);

	// Don't mind me, just a random sleep to fix stuff on Windows
	//if (!wiimotes.empty())
	//    SLEEP(2000);

}
Example #2
0
// Find and connect Wiimotes.
// Does not replace already found Wiimotes even if they are disconnected.
// wm is an array of max_wiimotes Wiimotes
// Returns the total number of found and connected Wiimotes.
void WiimoteScannerWindows::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
                                         Wiimote*& found_board)
{
  if (!s_loaded_ok)
    return;

  ProcessWiimotes(true, [](HANDLE hRadio, const BLUETOOTH_RADIO_INFO& rinfo,
                           BLUETOOTH_DEVICE_INFO_STRUCT& btdi) {
    ForgetWiimote(btdi);
    AttachWiimote(hRadio, rinfo, btdi);
  });

  // Get the device id
  GUID device_id;
  pHidD_GetHidGuid(&device_id);

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

  SP_DEVICE_INTERFACE_DATA device_data = {};
  device_data.cbSize = sizeof(device_data);
  PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = nullptr;

  for (int index = 0;
       SetupDiEnumDeviceInterfaces(device_info, nullptr, &device_id, index, &device_data); ++index)
  {
    // Get the size of the data block required
    DWORD len;
    SetupDiGetDeviceInterfaceDetail(device_info, &device_data, nullptr, 0, &len, nullptr);
    detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(len);
    detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    SP_DEVINFO_DATA device_info_data = {};
    device_info_data.cbSize = sizeof(SP_DEVINFO_DATA);

    // Query the data for this device
    if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, nullptr,
                                        &device_info_data))
    {
      std::basic_string<TCHAR> device_path(detail_data->DevicePath);
      bool IsUsingToshibaStack = CheckForToshibaStack(device_info_data.DevInst);

      WinWriteMethod write_method = GetInitialWriteMethod(IsUsingToshibaStack);

      if (!IsNewWiimote(UTF16ToUTF8(device_path)) || !IsWiimote(device_path, write_method))
      {
        free(detail_data);
        continue;
      }

      auto* wiimote = new WiimoteWindows(device_path, write_method);
      if (wiimote->IsBalanceBoard())
        found_board = wiimote;
      else
        found_wiimotes.push_back(wiimote);
    }

    free(detail_data);
  }

  SetupDiDestroyDeviceInfoList(device_info);
}
Example #3
0
// PC に接続ずみの「USB 接続赤外線リモコンキット」のデバイスパスを取得
DWORD GetDevicePath(OUT char *pszDevicePath, IN DWORD cchBuf)
{
    // USB IR REMOCON 固有の ID 文字列
    char *szIdStr1 = "vid_22ea&pid_001e";
    char *szIdStr2 = "mi_03";
    int i;
    char *pszProp;
    HDEVINFO DeviceInfoTable = NULL;
    SP_DEVICE_INTERFACE_DATA DeviceIfData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceIfDetailData;
    SP_DEVINFO_DATA DevInfoData;
    DWORD InterfaceIndex, dwSize, dwError = ERROR_SUCCESS;
    HGLOBAL hMem = NULL;
    BOOL bFound;
    GUID InterfaceClassGuid;
    HMODULE hHidDLL;
    DEF_HidD_GetHidGuid pHidD_GetHidGuid;
    size_t len;

    //GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30};
    // HIDClass の GUID を取得
    hHidDLL = LoadLibrary("hid.dll");
    pHidD_GetHidGuid = (DEF_HidD_GetHidGuid)GetProcAddress(hHidDLL, "HidD_GetHidGuid");
    pHidD_GetHidGuid(&InterfaceClassGuid);
    FreeLibrary(hHidDLL);

    // HIDClass に属するデバイス群の含まれるデバイス情報セットを取得
    DeviceInfoTable = SetupDiGetClassDevs(&InterfaceClassGuid,
                            NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if(!DeviceInfoTable) {
        dwError = GetLastError();
        goto DONE;
    }
    // デバイス情報セットを走査し IR REMOCON デバイスを探す
    for (InterfaceIndex = 0; InterfaceIndex < 10000000; InterfaceIndex++) {
        DeviceIfData.cbSize = sizeof(DeviceIfData);
        if(SetupDiEnumDeviceInterfaces(DeviceInfoTable, NULL,
                            &InterfaceClassGuid, InterfaceIndex, &DeviceIfData)) {
            dwError = GetLastError();
            if (dwError == ERROR_NO_MORE_ITEMS) {
                goto DONE;
            }
        }
        else {
            dwError = GetLastError();
            goto DONE;
        }
        // 現在見ているデバイスの VID, PID の含まれるハードウェア ID 文字列を取得
        DevInfoData.cbSize = sizeof(DevInfoData);
        SetupDiEnumDeviceInfo(DeviceInfoTable, InterfaceIndex, &DevInfoData);
        SetupDiGetDeviceRegistryProperty(DeviceInfoTable, &DevInfoData,
                                    SPDRP_HARDWAREID, NULL, NULL, 0, &dwSize);
        hMem = GlobalAlloc(0, dwSize);
        if (!hMem) {
            dwError = GetLastError();
            goto DONE;
        }
        SetupDiGetDeviceRegistryProperty(DeviceInfoTable, &DevInfoData,
                            SPDRP_HARDWAREID, NULL, (PBYTE)hMem, dwSize, NULL);
        pszProp = strdup((char*)hMem);
        GlobalFree(hMem);
        hMem = NULL;
        
        // 取得したハードウェア ID 文字列に USB IR REMOCON 固有の VID, PID が含まれるか
        len = strlen(pszProp);
        for (i = 0; i < (int)len; i++) {
            pszProp[i] = tolower(pszProp[i]);
        }
        bFound = FALSE;
        if (strstr(pszProp, szIdStr1) != NULL && strstr(pszProp, szIdStr2) != NULL) {
            bFound = TRUE;
        }
        free(pszProp);

        // USB IR REMOCON 発見
        if (bFound) {
            // USB IR REMOCON のデバイスパスを得る
            SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, &DeviceIfData,
                                                    NULL, 0, &dwSize, NULL);
            hMem = GlobalAlloc(0, dwSize);
            if (!hMem) {
                dwError = GetLastError();
                goto DONE;
            }
            pDeviceIfDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)hMem;
            pDeviceIfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
            if (SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, &DeviceIfData,
                                        pDeviceIfDetailData, dwSize, NULL, NULL)) {
                if (cchBuf > dwSize - sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)) {
                    // 成功
                    strcpy(pszDevicePath, pDeviceIfDetailData->DevicePath);
                    dwError = ERROR_SUCCESS;
                } else {
                    dwError = ERROR_NOT_ENOUGH_MEMORY;
                    goto DONE;
                }
                goto DONE;
            }
            else {
                dwError = GetLastError();
                goto DONE;
            }
        }
    }
DONE:
    if (hMem) {
        GlobalFree(hMem);
    }
    if (DeviceInfoTable) {
        SetupDiDestroyDeviceInfoList(DeviceInfoTable);
    }
    return dwError;
}