Beispiel #1
0
BOOL CEnumerateSerial::EnumeratePorts()
{
  int SPDRPlist[] = {
    SPDRP_HARDWAREID, SPDRP_DEVICEDESC, SPDRP_FRIENDLYNAME, SPDRP_MFG,
    SPDRP_LOCATION_INFORMATION, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, 
    -1};

  // Clear anything from previous enumerate...
  ResetPortList();

  // First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName...
  DWORD dwGuids = 0;
  SetupDiClassGuidsFromName(_T("Ports"), NULL, 0, &dwGuids);
  if (dwGuids == 0) return FALSE;

  // Allocate the needed memory...
  CHeapPtr<GUID> GuidArray;
  GUID *pGuids = (GUID*)GuidArray.Allocate(sizeof(GUID) * dwGuids);
  if (pGuids==NULL) {
    SetLastError(ERROR_OUTOFMEMORY);
    return FALSE;
  }

  // Call the function again...
  if (!SetupDiClassGuidsFromName(_T("Ports"), pGuids, dwGuids, &dwGuids))
    return FALSE;

  // Now create a "device information set" which is required to enumerate all the ports...
  HDEVINFO hDevInfoSet = SetupDiGetClassDevs(pGuids, NULL, NULL, DIGCF_PRESENT);
  if (hDevInfoSet == INVALID_HANDLE_VALUE)
    return FALSE;

  // Finally do the enumeration...
  int nIndex = 0;
  SP_DEVINFO_DATA devInfo;
  CHeapPtr<TCHAR> tempstr(1000);
  CSerialPortInfo *portinfo = NULL;

  // Enumerate the current device...
  devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
  while (SetupDiEnumDeviceInfo(hDevInfoSet, nIndex, &devInfo))
  {
    portinfo = NULL;

    // Get the registry key which stores the ports settings...
    HKEY hDeviceKey = SetupDiOpenDevRegKey(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
    if (hDeviceKey) {
      tempstr.FillZero();
      DWORD dwSize = tempstr.SizeOf(); 
      DWORD dwType = 0;

      // Read name of port.  If formatted as "COMxx" then allocate a port slot...
  	  if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>((TCHAR*)tempstr), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
        if (_tcslen(tempstr) > 3)
          if ((_tcsnicmp(tempstr, _T("COM"), 3) == 0) && IsNumber(&(tempstr[3])))
            portinfo = AddPort(_ttoi(&(tempstr[3])));

      // Close the key now that we are finished with it...
      RegCloseKey(hDeviceKey);
    }

    // If a serial port, then try getting additional useful descriptive info...
    if (portinfo) {
      for (int i=0; SPDRPlist[i]>=0; i++) {
        tempstr.FillZero(); 
        DWORD dwSize = tempstr.SizeOf(); 
        DWORD dwType = 0;
        if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRPlist[i], &dwType, reinterpret_cast<PBYTE>((TCHAR*)tempstr), dwSize, &dwSize) && ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ)))
          switch (SPDRPlist[i]) {
            case SPDRP_MFG : portinfo->SetManufacturer(tempstr); break;
            case SPDRP_HARDWAREID : portinfo->SetHardwareID(tempstr); break;
            case SPDRP_DEVICEDESC : portinfo->SetDeviceDesc(tempstr); break;
            case SPDRP_FRIENDLYNAME : portinfo->SetFriendlyName(tempstr); break;
            case SPDRP_LOCATION_INFORMATION : portinfo->SetLocationInfo(tempstr); break;
            case SPDRP_PHYSICAL_DEVICE_OBJECT_NAME : portinfo->SetPhysLocation(tempstr); break;
          }
      }

      // Get COM port properties...
      HANDLE hPort = ::CreateFile(portinfo->GetPortDeviceName(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
      if (hPort != INVALID_HANDLE_VALUE) {
        COMMPROP cp;
        GetCommProperties(hPort, &cp);
        portinfo->SetCommProp(cp);
        TRACE ("Port %d:  CommProp: maxbaud=%08x  settablebaud=%08x\n",portinfo->GetPortNum(),cp.dwMaxBaud,cp.dwSettableBaud);
        CloseHandle(hPort);
      }
    }
    
    ++nIndex;
  }

  // Free up the "device information set" now that we are finished with it
  SetupDiDestroyDeviceInfoList(hDevInfoSet);

  // Return the success indicator
  return TRUE;
}
Beispiel #2
0
static PyObject *
winutil_get_removable_drives(PyObject *self, PyObject *args) {
    HDEVINFO hDevInfo;
	BOOL  iterate = TRUE, ddebug = FALSE;
	PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetailData;
    DWORD i;
    unsigned int j;
    size_t length;
    WCHAR volume[BUFSIZE];
    struct tagDrives g_drives[MAX_DRIVES];
    PyObject *volumes, *key, *candidates, *pdebug = Py_False, *temp;

    if (!PyArg_ParseTuple(args, "|O", &pdebug)) {
    	return NULL;
    }

    // Find all removable drives
    for (j = 0; j < MAX_DRIVES; j++) g_drives[j].letter = 0;
    if (!get_all_removable_disks(g_drives)) return NULL;

    volumes = PyDict_New();
    if (volumes == NULL) return PyErr_NoMemory();
    ddebug = PyObject_IsTrue(pdebug);

    hDevInfo = create_device_info_set((LPGUID)&GUID_DEVINTERFACE_VOLUME,
                            NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (hDevInfo == INVALID_HANDLE_VALUE) { Py_DECREF(volumes); return NULL; }

    // Enumerate through the set
    for (i=0; iterate; i++) {
        candidates = PyList_New(0);
        if (candidates == NULL) { Py_DECREF(volumes); return PyErr_NoMemory();}

        interfaceDetailData = get_device_ancestors(hDevInfo, i, candidates, &iterate, ddebug);
        if (interfaceDetailData == NULL) {
            PyErr_Print(); 
            Py_DECREF(candidates); candidates = NULL; 
            continue;
        }

        length = wcslen(interfaceDetailData->DevicePath);
        interfaceDetailData->DevicePath[length] = L'\\';
        interfaceDetailData->DevicePath[length+1] = 0;

        if (ddebug) console_out(L"Device path: %s\n", interfaceDetailData->DevicePath);
        // On Vista+ DevicePath contains the information we need.
        temp = PyUnicode_FromWideChar(interfaceDetailData->DevicePath, length);
        if (temp == NULL) return PyErr_NoMemory();
        PyList_Append(candidates, temp);
        Py_DECREF(temp);
        if(GetVolumeNameForVolumeMountPointW(interfaceDetailData->DevicePath, volume, BUFSIZE)) {
            if (ddebug) console_out(L"Volume: %s\n", volume);
            
            for(j = 0; j < MAX_DRIVES; j++) {
                if(g_drives[j].letter != 0 && wcscmp(g_drives[j].volume, volume)==0) {
                    if (ddebug) printf("Found drive: %c\n", (char)g_drives[j].letter); fflush(stdout);
                    key = PyBytes_FromFormat("%c", (char)g_drives[j].letter);
                    if (key == NULL) return PyErr_NoMemory();
                    PyDict_SetItem(volumes, key, candidates);
                    Py_DECREF(key); key = NULL;
                    break;
                }
            }

        }
        Py_XDECREF(candidates); candidates = NULL;
        PyMem_Free(interfaceDetailData);
    } //for

    SetupDiDestroyDeviceInfoList(hDevInfo);
    return volumes;
}
Beispiel #3
0
irecv_error_t mobiledevice_connect(irecv_client_t* client) {
	irecv_error_t ret;

	SP_DEVICE_INTERFACE_DATA currentInterface;
	HDEVINFO usbDevices;
	DWORD i;
	LPSTR path;
	irecv_client_t _client = (irecv_client_t) malloc(sizeof(struct irecv_client));
	memset(_client, 0, sizeof(struct irecv_client));

	// Get DFU paths
	usbDevices = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DFU, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if(!usbDevices) {
		return IRECV_E_UNABLE_TO_CONNECT;
	}
	currentInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	for(i = 0; SetupDiEnumDeviceInterfaces(usbDevices, NULL, &GUID_DEVINTERFACE_DFU, i, &currentInterface); i++) {
		DWORD requiredSize = 0;
		PSP_DEVICE_INTERFACE_DETAIL_DATA details;
		SetupDiGetDeviceInterfaceDetail(usbDevices, &currentInterface, NULL, 0, &requiredSize, NULL);
		details = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(requiredSize);
		details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		if(!SetupDiGetDeviceInterfaceDetail(usbDevices, &currentInterface, details, requiredSize, NULL, NULL)) {
			irecv_close(_client);
			free(details);
			SetupDiDestroyDeviceInfoList(usbDevices);
			return IRECV_E_UNABLE_TO_CONNECT;
		} else {
			LPSTR result = (LPSTR) malloc(requiredSize - sizeof(DWORD));
			memcpy((void*) result, details->DevicePath, requiredSize - sizeof(DWORD));
			free(details);
			path = (LPSTR) malloc(requiredSize - sizeof(DWORD));
			memcpy((void*) path, (void*) result, requiredSize - sizeof(DWORD));
			TCHAR* pathEnd = strstr(path, "#{");
			*pathEnd = '\0';
			_client->DfuPath = result;
			break;
		}
	}
	SetupDiDestroyDeviceInfoList(usbDevices);
	// Get iBoot path
	usbDevices = SetupDiGetClassDevs(&GUID_DEVINTERFACE_IBOOT, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if(!usbDevices) {
		irecv_close(_client);
		return IRECV_E_UNABLE_TO_CONNECT;
	}
	currentInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	for(i = 0; SetupDiEnumDeviceInterfaces(usbDevices, NULL, &GUID_DEVINTERFACE_IBOOT, i, &currentInterface); i++) {
		DWORD requiredSize = 0;
		PSP_DEVICE_INTERFACE_DETAIL_DATA details;
		SetupDiGetDeviceInterfaceDetail(usbDevices, &currentInterface, NULL, 0, &requiredSize, NULL);
		details = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(requiredSize);
		details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		if(!SetupDiGetDeviceInterfaceDetail(usbDevices, &currentInterface, details, requiredSize, NULL, NULL)) {
			irecv_close(_client);
			free(details);
			SetupDiDestroyDeviceInfoList(usbDevices);
			return IRECV_E_UNABLE_TO_CONNECT;
		} else {
			LPSTR result = (LPSTR) malloc(requiredSize - sizeof(DWORD));
			memcpy((void*) result, details->DevicePath, requiredSize - sizeof(DWORD));
			free(details);

			if(strstr(result, path) == NULL) {
				free(result);
				continue;
			}
			
			_client->iBootPath = result;
			break;
		}
	}
	SetupDiDestroyDeviceInfoList(usbDevices);
	free(path);
	
	ret = mobiledevice_openpipes(_client);
	if (ret != IRECV_E_SUCCESS) return ret;
	
	*client = _client;
	return IRECV_E_SUCCESS;
}
Beispiel #4
0
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 = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };
	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;

}
/**
 * Install the VBox video driver.
 *
 * @returns TRUE on success.
 * @returns FALSE on failure.
 * @param   szDriverDir     The base directory where we find the INF.
 */
BOOL installVideoDriver(TCHAR* szDriverDir)
{
  HDEVINFO hDevInfo;
  SP_DEVINSTALL_PARAMS DeviceInstallParams={0};
  SP_DRVINFO_DATA drvInfoData={0};
  SP_DRVINFO_DETAIL_DATA DriverInfoDetailData={0};

  DWORD cbReqSize;

  /* Vars used for reading the INF */
  HINF hInf;
  TCHAR szServiceSection[LINE_LEN];
  INFCONTEXT serviceContext;
  TCHAR szServiceData[LINE_LEN];
  TCHAR deviceRegStr[1000];//I'm lazy here. 1000 ought to be enough for everybody...

  SP_DEVINFO_DATA deviceInfoData;
  DWORD configFlags;

  HKEY hkey;
  DWORD disp;
  TCHAR regKeyName[LINE_LEN];

  BOOL rc;

  /* Create an empty list */
  hDevInfo = SetupDiCreateDeviceInfoList((LPGUID) &GUID_DEVCLASS_DISPLAY,
                                         NULL);

  if (hDevInfo == INVALID_HANDLE_VALUE)
    return FALSE;

  memset(&DeviceInstallParams, 0, sizeof(SP_DEVINSTALL_PARAMS));
  DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);

  rc=SetupDiGetDeviceInstallParams(hDevInfo,
                                   NULL,
                                   &DeviceInstallParams);

  if(!rc)
    return FALSE;

  DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  DeviceInstallParams.Flags |= DI_NOFILECOPY | /* We did our own file copying */
    DI_DONOTCALLCONFIGMG |
    DI_ENUMSINGLEINF; /* .DriverPath specifies an inf file */


  /* Path to inf file */
  wsprintf(DeviceInstallParams.DriverPath,
           TEXT("%ws\\%ws"),
           szDriverDir, TEXT(VBOXGUEST_VIDEO_INF_NAME));

  rc=SetupDiSetDeviceInstallParams(hDevInfo,
                                   NULL,
                                   &DeviceInstallParams);
  if(!rc)
    return FALSE;

  /* Read the drivers from the inf file */
  if (!SetupDiBuildDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER))
    {
      SetupDiDestroyDeviceInfoList(hDevInfo);
      return FALSE;
    }

  /* Get the first found driver.
     Our Inf file only contains one so this is fine  */
  drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  if(FALSE==SetupDiEnumDriverInfo(hDevInfo, NULL, SPDIT_CLASSDRIVER,
                                  0, &drvInfoData)){
    SetupDiDestroyDeviceInfoList(hDevInfo);
    return FALSE;
  }

  /* Get necessary driver details */
  DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
  if (!(!SetupDiGetDriverInfoDetail(hDevInfo,
                                    NULL,
                                    &drvInfoData,
                                    &DriverInfoDetailData,
                                    DriverInfoDetailData.cbSize,
                                    &cbReqSize)
        &&GetLastError()== ERROR_INSUFFICIENT_BUFFER) )
    {
      SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
      SetupDiDestroyDeviceInfoList(hDevInfo);
      return FALSE;
    }

  hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName,
                          NULL, INF_STYLE_WIN4, NULL);

  if (hInf == INVALID_HANDLE_VALUE)
    {
      SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
      SetupDiDestroyDeviceInfoList(hDevInfo);
      return FALSE;
    }

  /* First install the service */
  wsprintf(szServiceSection, TEXT("%ws.Services"),
           DriverInfoDetailData.SectionName);

  if(!SetupFindFirstLine(hInf, szServiceSection, NULL, &serviceContext))
    {
      /* No service line?? Can't be... */
      closeAndDestroy(hDevInfo, hInf);
      return FALSE;
    }

  /* Get the name */
  SetupGetStringField(&serviceContext,
                      1,
                      szServiceData,
                      sizeof(szServiceData),
                      NULL);

  wsprintf(deviceRegStr, TEXT("Root\\LEGACY_%ws\\0000"), szServiceData);

  memset(&deviceInfoData, 0, sizeof(SP_DEVINFO_DATA));
  deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

  if (SetupDiOpenDeviceInfo(hDevInfo, deviceRegStr, NULL, 0, &deviceInfoData) //Check for existing
      ||(SetupDiCreateDeviceInfo(hDevInfo, deviceRegStr,                      //Create new
                                 (LPGUID) &GUID_DEVCLASS_DISPLAY,
                                 NULL, //Do we need a description here?
                                 NULL, //No user interface
                                 0,
                                 &deviceInfoData) &&
         SetupDiRegisterDeviceInfo(hDevInfo,
                                   &deviceInfoData,
                                   0,
                                   NULL,
                                   NULL,
                                   NULL)) )
    {
      /* We created a new key in the registry */

      memset(&DeviceInstallParams, 0,sizeof(SP_DEVINSTALL_PARAMS));
      DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);

      SetupDiGetDeviceInstallParams(hDevInfo,
                                    &deviceInfoData,
                                    &DeviceInstallParams);

      DeviceInstallParams.Flags |= DI_NOFILECOPY | //We already copied the files
        DI_DONOTCALLCONFIGMG |
        DI_ENUMSINGLEINF; //Use our INF file only

      /* Path to inf file */
      wsprintf(DeviceInstallParams.DriverPath,
               TEXT("%ws\\%ws"),
               szDriverDir, TEXT(VBOXGUEST_VIDEO_INF_NAME));

      SetupDiSetDeviceInstallParams(hDevInfo,
                                    &deviceInfoData,
                                    &DeviceInstallParams);


      if(!SetupDiBuildDriverInfoList(hDevInfo,
                                     &deviceInfoData,
                                     SPDIT_CLASSDRIVER))
        {
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }

      drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
      if (!SetupDiEnumDriverInfo(hDevInfo,
                                 &deviceInfoData,
                                 SPDIT_CLASSDRIVER,
                                 0,
                                 &drvInfoData))
        {
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }

      if(!SetupDiSetSelectedDriver(hDevInfo,
                                   &deviceInfoData,
                                   &drvInfoData))
        {
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }

      if(!SetupDiInstallDevice(hDevInfo,
                               &deviceInfoData))
        {
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }
    }

  /* Make sure the device is enabled */
  if (SetupDiGetDeviceRegistryProperty(hDevInfo,
                                       &deviceInfoData, SPDRP_CONFIGFLAGS,
                                       NULL, (LPBYTE) &configFlags,
                                       sizeof(DWORD),
                                       NULL)
      && (configFlags & CONFIGFLAG_DISABLED))
    {
      configFlags &= ~CONFIGFLAG_DISABLED;

      SetupDiSetDeviceRegistryProperty(hDevInfo,
                                       &deviceInfoData,
                                       SPDRP_CONFIGFLAGS,
                                       (LPBYTE) &configFlags,
                                       sizeof(DWORD));
    }

  wsprintf(regKeyName,
           TEXT("System\\CurrentControlSet\\Services\\%ws\\Device%d"),
           szServiceData, 0); //We only have one device

  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                     regKeyName,
                     0,
                     NULL,
                     REG_OPTION_NON_VOLATILE,
                     KEY_READ | KEY_WRITE,
                     NULL,
                     &hkey,
                     &disp) == ERROR_SUCCESS)
    {
      /* Insert description */
      RegSetValueEx(hkey,
                    TEXT("Device Description"),
                    0,
                    REG_SZ,
                    (LPBYTE) DriverInfoDetailData.DrvDescription,
                    (lstrlen(DriverInfoDetailData.DrvDescription) + 1) *
                    sizeof(TCHAR) );

      TCHAR szSoftwareSection[LINE_LEN];

      wsprintf(szSoftwareSection,
               TEXT("%ws.SoftwareSettings"),
               szServiceData);

      if (!SetupInstallFromInfSection(NULL,
                                      hInf,
                                      szSoftwareSection,
                                      SPINST_REGISTRY,
                                      hkey,
                                      NULL,
                                      0,
                                      NULL,
                                      NULL,
                                      NULL,
                                      NULL))
        {
          RegCloseKey(hkey);
          closeAndDestroy(hDevInfo, hInf);
          return FALSE;
        }

      RegCloseKey(hkey);
    }

  /* Install OpenGL stuff */
  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                     TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"),
                     0,
                     NULL,
                     REG_OPTION_NON_VOLATILE,
                     KEY_READ | KEY_WRITE,
                     NULL,
                     &hkey,
                     &disp) == ERROR_SUCCESS)
    {
      /* Do installation here if ever necessary. Currently there is no OpenGL stuff */

      RegCloseKey(hkey);
    }


  /* Cleanup */
  closeAndDestroy(hDevInfo, hInf);

#if 0
  /* If this key is inserted into the registry, windows will show the desktop
     applet on next boot. We decide in the installer if we want that so the code
     is disabled here. */
  /* Set registry keys so windows picks up the changes */
  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                     TEXT("SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\NewDisplay"),
                     0,
                     NULL,
                     REG_OPTION_NON_VOLATILE,
                     KEY_READ | KEY_WRITE,
                     NULL,
                     &hkey,
                     &disp) == ERROR_SUCCESS)
    {
      RegCloseKey(hkey);
    }
#endif

  /* We must reboot at some point */
  if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                     TEXT("SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\RebootNecessary"),
                     0,
                     NULL,
                     REG_OPTION_NON_VOLATILE,
                     KEY_READ | KEY_WRITE,
                     NULL,
                     &hkey,
                     &disp) == ERROR_SUCCESS)
    {
      RegCloseKey(hkey);
    }

  return TRUE;
}
/*
 * Finds information about USB HID devices using setup class API.
 *
 * The sequence of entries in array must match with what java layer expect. If a particular USB
 * attribute is not set in descriptor or can not be obtained "---" is placed in its place.
 *
 * The array returned will be in following sequence; transport, device node, vendor ID,
 * product ID, serial, product, manufacturer, USB bus number, USB device number, location.
 *
 * For an HID interface in a USB device, Windows create a device instance for the USB interface
 * (GUID_DEVINTERFACE_HID_DEVICE) and another device instance for the HID collection (GUID_DEVINTERFACE_HID).
 * This function relate HID collection device instance to its USB interface (physical USB device) through
 * HardwareID. A hardware ID is a vendor-defined identification string that Windows uses to match a
 * device to an INF file. In most cases, a device has associated with it a list of hardware IDs.
 * (However, there are exceptions − see Identifiers for 1394 Devices). When an enumerator reports a
 * list of hardware IDs for a device, the hardware IDs should be listed in order of decreasing suitability.
 *
 * This key contains symbolic links to HID device instances :
 * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\{4d1e55b2-f16f-11cf-88cb-001111000030}
 * 
 * This function basically collect information from USB and HID subsystems and relate them to identify a device
 * and then create a unified information to be sent to java application.
 */
jobjectArray enumerate_usb_hid_devices(JNIEnv *env, jint vendor_to_match) {

	int q = 0;
	int i = 0;
	int x = 0;
	BOOL ret = FALSE;
	LONG status = 0;
	DWORD error_code = 0;
	DWORD errorVal = 0;
	DWORD size = 0;
	DWORD charbuffer_size = 0;
	DWORD driver_name_size = 0;
	ULONG buffer_size = 0;
	ULONG devprop_buffer_size = 0;
	DEVPROPTYPE proptype;
	DWORD regproptype;

	CONFIGRET cmret = 0;
	DEVINST firstchild = 0;
	DEVINST next_sibling = 0;
	DEVINST current_sibling = 0;

	struct hiddev_inst_cont_id *instidinfo;
	struct hiddev_instance_list hiddevinst_list = { 0 };
	struct jstrarray_list list = { 0 };

	DWORD hid_member_index = 0;
	HDEVINFO hid_dev_info_set;
	SP_DEVINFO_DATA hid_dev_instance;

	DWORD usb_member_index = 0;
	HDEVINFO usb_dev_info_set;
	SP_DEVINFO_DATA usb_dev_instance;

	/* size of these buffers is hardcoded in functions using them */
	TCHAR buffer[1024];
	TCHAR devprop_buffer[1024];
	TCHAR keybuf[1024];
	TCHAR charbuffer[512];
	TCHAR tmpbuf[128];
	char cmerror[256];

	jstring usb_dev_info;
	jclass strClass = NULL;
	jobjectArray usbHidDevicesFound = NULL;

	/* allocate memory to hold information used during processing and returning information
	   to caller. */
	x = init_hiddev_instance_list(&hiddevinst_list, 25);
	if (x < 0) {
		return clean_throw_exp_usbenumeration(env, 0, 1, 0, E_CALLOCSTR, NULL, NULL, NULL, NULL);
	}

	/* ~~~~~~~~~~~~~ ENUMERATE ALL HID DEVICES ~~~~~~~~~~~~~ */

	/* get information set for all HID devices matching the GUID. It an array of 
	   structures containing information about all attached and enumerated HID devices.	*/
	hid_dev_info_set = SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (hid_dev_info_set == INVALID_HANDLE_VALUE) {
		return clean_throw_exp_usbenumeration(env, 1, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, NULL, &hiddevinst_list, NULL, &hid_dev_info_set);
	}

	/* enumerate all devices in this information set starting from 0th index */
	hid_member_index = 0;
	while (1) {
		ZeroMemory(&hid_dev_instance, sizeof(hid_dev_instance));
		hid_dev_instance.cbSize = sizeof(hid_dev_instance);

		/* from information set, get device by index */
		ret = SetupDiEnumDeviceInfo(hid_dev_info_set, hid_member_index, &hid_dev_instance);
		if (ret == FALSE) {
			error_code = GetLastError();
			if (error_code == ERROR_NO_MORE_ITEMS) {
				break;
			}else {
				return clean_throw_exp_usbenumeration(env, 1, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, NULL, &hiddevinst_list, NULL, &hid_dev_info_set);
			}
		}

		/* for this device find its instance ID, for example; HID\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000
		 * this is variable 'Device Instance Path' in device manager. */
		memset(buffer, '\0', 1024);
		ret = SetupDiGetDeviceInstanceId(hid_dev_info_set, &hid_dev_instance, buffer, 1024, &size);
		if (ret == FALSE) {
			return clean_throw_exp_usbenumeration(env, 1, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, NULL, &hiddevinst_list, NULL, &hid_dev_info_set);
		}

		/* get HardwareID of this device;
		   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\HID\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000\HardwareID */
		memset(keybuf, '\0', 1024);
		_stprintf_s(keybuf, 1024, TEXT("SYSTEM\\CurrentControlSet\\Enum\\%s"), buffer);

		charbuffer_size = sizeof(charbuffer);
		memset(charbuffer, '\0', 512);

		status = RegGetValue(HKEY_LOCAL_MACHINE, keybuf, TEXT("HardwareID"), RRF_RT_REG_MULTI_SZ, NULL, (PVOID)charbuffer, &charbuffer_size);
		if (status != ERROR_SUCCESS) {
			return clean_throw_exp_usbenumeration(env, 1, 2, GetLastError(), NULL, NULL, &hiddevinst_list, NULL, &hid_dev_info_set);
		}

		/* save device instance and hardware id (including terminating null character) in the
		   list for later comparision */
		instidinfo = NULL;
		instidinfo = (struct hiddev_inst_cont_id *) malloc(sizeof(struct hiddev_inst_cont_id));
		if (instidinfo == NULL) {
			return clean_throw_exp_usbenumeration(env, 1, 1, 0, E_MALLOCSTR, NULL, &hiddevinst_list, NULL, &hid_dev_info_set);
		}
		_tcscpy_s(instidinfo->instance, 512, buffer);
		_tcscpy_s(instidinfo->hwid, 512, charbuffer);

		insert_hiddev_instance_list(&hiddevinst_list, instidinfo);

		/* increment to get the next HID device instance */
		hid_member_index++;
	}

	/* release HID info set as it is no longer needed */
	SetupDiDestroyDeviceInfoList(hid_dev_info_set);

	/* allocate memory to hold information used during processing and returning information
	to caller. */
	x = init_jstrarraylist(&list, 100);
	if (x < 0) {
		return clean_throw_exp_usbenumeration(env, 2, 1, 0, E_CALLOCSTR, NULL, &hiddevinst_list, NULL, NULL);
	}

	/* From here onwards, enumerate over all USB interfaces looking for HID interface and try to
	   associate with its device instance and then create information that will be passed to
	   application. */

	/* ~~~~~~~~~~~~~ ENUMERATE ALL USB DEVICES ~~~~~~~~~~~~~ */

	/* get information set for all usb devices matching the GUID */
	usb_dev_info_set = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (usb_dev_info_set == INVALID_HANDLE_VALUE) {
		return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
	}

	/* enumerate all devices in this information set */
	usb_member_index = 0;
	while (1) {
		ZeroMemory(&usb_dev_instance, sizeof(usb_dev_instance));
		usb_dev_instance.cbSize = sizeof(usb_dev_instance);

		/* from information set, get device by index */
		ret = SetupDiEnumDeviceInfo(usb_dev_info_set, usb_member_index, &usb_dev_instance);
		if (ret == FALSE) {
			error_code = GetLastError();
			if (error_code == ERROR_NO_MORE_ITEMS) {
				break;
			}else {
				return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
			}
		}

		/* for this device find its instance ID (USB\VID_04D8&PID_00DF\000098037)
		 * this is the variable 'Device Instance Path' in device manager. */
		memset(buffer, '\0', sizeof(buffer));
		ret = SetupDiGetDeviceInstanceId(usb_dev_info_set, &usb_dev_instance, buffer, 1024, &size);
		if (ret == FALSE) {
			return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
		}

		/* fetch and examine USB interface */
		cmret = CM_Get_Child(&firstchild, usb_dev_instance.DevInst, 0);
		if (cmret != CR_SUCCESS) {
			if (cmret == CR_NO_SUCH_DEVNODE) {
				/* this device does not have any child, so check if this is a HID class device or not */
				memset(devprop_buffer, '\0', 1024);
				ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_CLASSGUID, &regproptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size);
				if (ret == FALSE) {
					return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}

				/* check if this is a HID device interface, if it is not than loop back to examine next USB device */
				ret = _tcsicmp(devprop_buffer, TEXT("{745A17A0-74D3-11D0-B6FE-00A0C90F57DA}"));
				if (ret != 0) {
					usb_member_index++;
					continue;
				}

				/* reaching here means that the device is a HID device, so create all the information
				that will be passed to java layer. */

				/* get the HardwareID of this USB HID interface. HardwareID is multi-sz, however
				   we use only 1st string from multi-string HardwareID for our matching.
				   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000\HardwareID 
				   The buffer contains device instance path of USB device */
				memset(keybuf, '\0', 1024);
				_stprintf_s(keybuf, 1024, TEXT("SYSTEM\\CurrentControlSet\\Enum\\%s"), buffer);

				charbuffer_size = sizeof(charbuffer);
				memset(charbuffer, '\0', 512);

				/* USB\VID_04D8&PID_00DF&REV_0101 and USB\VID_04D8&PID_00DF and so on */
				status = RegGetValue(HKEY_LOCAL_MACHINE, keybuf, TEXT("HardwareID"), RRF_RT_REG_MULTI_SZ, NULL, (PVOID)charbuffer, &charbuffer_size);
				if (status != ERROR_SUCCESS) {
					return clean_throw_exp_usbenumeration(env, 3, 2, GetLastError(), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}

				/* charbuffer now contains hardwareID, cook it a little bit to enable suitable matching */
				if ((charbuffer[0] == 'U') && (charbuffer[1] == 'S') && (charbuffer[2] == 'B')) {
					charbuffer[0] = 'H';
					charbuffer[1] = 'I';
					charbuffer[2] = 'D';
				}

				for (q = 0; q < hiddevinst_list.index; q++) {

					/* check association between HID collection device instance and USB device instance */
					ret = _tcsicmp(charbuffer, hiddevinst_list.base[q]->hwid);
					if (ret != 0) {
						continue;
					}

					/* reaching here means this HID collection belongs to this USB HID device, so glean information
					   to be passed to java layer. */

					/* TRANSPORT */
					usb_dev_info = (*env)->NewStringUTF(env, "USB");
					if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
						return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}
					insert_jstrarraylist(&list, usb_dev_info);

					/* DEVICE NODE */
					usb_dev_info = (*env)->NewString(env, hiddevinst_list.base[q]->instance, (jsize)_tcslen(hiddevinst_list.base[q]->instance));
					if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
						return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}
					insert_jstrarraylist(&list, usb_dev_info);

					/* USB-IF VENDOR ID
					   (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */
					x = 0;
					while (buffer[x] != '\0') {
						if ((buffer[x] == 'V') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) {
							break;
						}
						x++;
					}
					x = x + 4;
					i = 0;
					while (buffer[x] != '&') {
						tmpbuf[i] = buffer[x];
						i++;
						x++;
					}
					tmpbuf[i] = '\0'; /* indicate end of string */
					usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf));
					if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
						return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}
					insert_jstrarraylist(&list, usb_dev_info);

					/* USB product ID
					   (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */
					x = 6;
					while (buffer[x] != '\0') {
						if ((buffer[x] == 'P') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) {
							break;
						}
						x++;
					}
					x = x + 4;
					i = 0;
					while (buffer[x] != '\\') {
						tmpbuf[i] = buffer[x];
						i++;
						x++;
					}
					tmpbuf[i] = '\0'; /* indicate end of string */
					usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf));
					if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
						return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}
					insert_jstrarraylist(&list, usb_dev_info);

					/* SERIAL NUMBER */
					x++;
					i = 0;
					while (buffer[x] != '\0') {
						tmpbuf[i] = buffer[x];
						i++;
						x++;
					}
					tmpbuf[i] = '\0';
					usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf));
					if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
						return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}
					insert_jstrarraylist(&list, usb_dev_info);

					/* PRODUCT
					   (iProduct field of USB device descriptor) */
					memset(devprop_buffer, '\0', sizeof(devprop_buffer));
					ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_BusReportedDeviceDesc, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0);
					if (ret == FALSE) {
						/* fallback to SPDRP_DEVICEDESC if DEVPKEY_Device_BusReportedDeviceDesc fails */
						ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_DEVICEDESC, &regproptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size);
						if (ret == FALSE) {
							/* if second attempt fails, throw error, we need to investigate drivers/firmware etc */
							return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
						}
					}
					usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
					insert_jstrarraylist(&list, usb_dev_info);

					/* MANUFACTURER */
					memset(devprop_buffer, '\0', sizeof(devprop_buffer));
					ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_Manufacturer, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0);
					if (ret == FALSE) {
						return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}
					usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
					insert_jstrarraylist(&list, usb_dev_info);

					/* LOCATION
					   (Location paths + Location info, get separately and then create a single string) */

					// PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(3)
					memset(devprop_buffer, '\0', sizeof(devprop_buffer));
					ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_PATHS, &regproptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size);
					if (ret == FALSE) {
						return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}
					// Port_#0003.Hub_#0001
					memset(charbuffer, '\0', sizeof(charbuffer));
					ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_INFORMATION, &regproptype, (BYTE *)charbuffer, sizeof(charbuffer), &size);
					if (ret == FALSE) {
						return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}

					i = 0;
					x = (int)_tcslen(devprop_buffer);
					devprop_buffer[x] = '-';
					x++;
					for (i = 0; i < (int)_tcslen(charbuffer); i++) {
						devprop_buffer[x] = charbuffer[i];
						x++;
					}
					devprop_buffer[x] = '\0';

					usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
					insert_jstrarraylist(&list, usb_dev_info);
				}

				/* loop back to get next USB device */
				usb_member_index++;
				continue;
			}else {
				/* error happend when getting child of USB device */
				_snprintf_s(cmerror, 256, 256, "CM_Get_Child failed with CR_xxxx error code : 0x%X\0", cmret);
				return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
			}
		}

		/* reaching here means that this USB device has at-least one child device node, examine first child now */
		devprop_buffer_size = sizeof(devprop_buffer);
		memset(devprop_buffer, '\0', 1024);

		cmret = CM_Get_DevNode_Registry_Property(firstchild, CM_DRP_CLASSGUID, &proptype, (PVOID)devprop_buffer, &devprop_buffer_size, 0);
		if (cmret != CR_SUCCESS) {
			_snprintf_s(cmerror, 256, 256, "CM_Get_DevNode_Registry_Property failed with CR_xxxx error code : 0x%X\0", cmret);
			return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
		}

		/* check if first child is a HID device interface */
		ret = _tcsicmp(devprop_buffer, TEXT("{745A17A0-74D3-11D0-B6FE-00A0C90F57DA}"));
		if (ret == 0) {
			/* reaching here means that this sibling (interface) is a HID type, get its device instance path */
			memset(devprop_buffer, '\0', 1024);
			cmret = CM_Get_Device_ID(firstchild, devprop_buffer, 1024, 0);
			if (cmret != CR_SUCCESS) {
				_snprintf_s(cmerror, 256, 256, "CM_Get_Device_ID failed with CR_xxxx error code : 0x%X\0", cmret);
				return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
			}

			/* get the HardwareID of this USB HID interface. HardwareID is multi-sz, however
			   we use only 1st string from multi-string HardwareID for our matching.
			   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000\HardwareID */
			memset(charbuffer, '\0', 512);
			buffer_size = sizeof(charbuffer);
			cmret = CM_Get_DevNode_Registry_Property(firstchild, CM_DRP_HARDWAREID, NULL, (PVOID)charbuffer, &buffer_size, 0);
			if (cmret != CR_SUCCESS) {
				_snprintf_s(cmerror, 256, 256, "CM_Get_Device_ID failed with CR_xxxx error code : 0x%X\0", cmret);
				return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
			}

			if ((charbuffer[0] == 'U') && (charbuffer[1] == 'S') && (charbuffer[2] == 'B')) {
				charbuffer[0] = 'H';
				charbuffer[1] = 'I';
				charbuffer[2] = 'D';
			}

			for (q = 0; q < hiddevinst_list.index; q++) {

				/* check association between HID collection device instance and USB interface device instance */
				ret = _tcsncicmp(charbuffer, hiddevinst_list.base[q]->hwid, 512);
				if (ret != 0) {
					continue;
				}

				/* reaching here means this HID collection belongs to this USB HID interface, so glean information
				   to be passed to java layer. */

				/* TRANSPORT */
				usb_dev_info = (*env)->NewStringUTF(env, "USB");
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* DEVICE NODE */
				usb_dev_info = (*env)->NewString(env, hiddevinst_list.base[q]->instance, (jsize)_tcslen(hiddevinst_list.base[q]->instance));
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* USB-IF VENDOR ID
				   (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */
				x = 0;
				while (buffer[x] != '\0') {
					if ((buffer[x] == 'V') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) {
						break;
					}
					x++;
				}
				x = x + 4;
				i = 0;
				while (buffer[x] != '&') {
					tmpbuf[i] = buffer[x];
					i++;
					x++;
				}
				tmpbuf[i] = '\0'; /* indicate end of string */
				usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf));
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* USB product ID
				   (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */
				x = 6;
				while (buffer[x] != '\0') {
					if ((buffer[x] == 'P') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) {
						break;
					}
					x++;
				}
				x = x + 4;
				i = 0;
				while (buffer[x] != '\\') {
					tmpbuf[i] = buffer[x];
					i++;
					x++;
				}
				tmpbuf[i] = '\0'; /* indicate end of string */
				usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf));
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* SERIAL NUMBER */
				x++;
				i = 0;
				while (buffer[x] != '\0') {
					tmpbuf[i] = buffer[x];
					i++;
					x++;
				}
				tmpbuf[i] = '\0';
				usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf));
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* PRODUCT
				   (iProduct field of USB device descriptor) */
				memset(devprop_buffer, '\0', sizeof(devprop_buffer));
				ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_BusReportedDeviceDesc, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0);
				if (ret == FALSE) {
					/* fallback to SPDRP_DEVICEDESC if DEVPKEY_Device_BusReportedDeviceDesc fails */
					ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_DEVICEDESC, &regproptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size);
					if (ret == FALSE) {
						/* if second attempt fails, throw error, we need to investigate drivers/firmware etc */
						return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}
				}
				usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
				insert_jstrarraylist(&list, usb_dev_info);

				/* MANUFACTURER */
				memset(devprop_buffer, '\0', sizeof(devprop_buffer));
				ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_Manufacturer, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0);
				if (ret == FALSE) {
					return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
				insert_jstrarraylist(&list, usb_dev_info);

				/* LOCATION
				  (Location paths + Location info, get separately and then create a single string) */

				// PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(3)
				memset(devprop_buffer, '\0', sizeof(devprop_buffer));
				ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_PATHS, &regproptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size);
				if (ret == FALSE) {
					return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				// Port_#0003.Hub_#0001
				memset(charbuffer, '\0', sizeof(charbuffer));
				ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_INFORMATION, &regproptype, (BYTE *)charbuffer, sizeof(charbuffer), &size);
				if (ret == FALSE) {
					return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}

				i = 0;
				x = (int)_tcslen(devprop_buffer);
				devprop_buffer[x] = '-';
				x++;
				for (i = 0; i < (int)_tcslen(charbuffer); i++) {
					devprop_buffer[x] = charbuffer[i];
					x++;
				}
				devprop_buffer[x] = '\0';

				usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
				insert_jstrarraylist(&list, usb_dev_info);
			}
		}

		/* check if this usb device has more than one interface. if it has enumerate over each
		   one by one and collecting information for every HID interface found and sending it to 
		   java layer. */
		current_sibling = firstchild;
		while (1) {
			cmret = CM_Get_Sibling(&next_sibling, current_sibling, 0);
			if (cmret != CR_SUCCESS) {
				if (cmret == CR_NO_SUCH_DEVNODE) {
					/* done iterating over all interfaces, move to next examine next USB device */
					break;
				}else {
					_snprintf_s(cmerror, 256, 256, "CM_Get_Sibling failed with CR_xxxx error code : 0x%X\0", cmret);
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
			}

			/* reaching here means USB device has more than 1 interfaces, get class of this interface (sibling) */
			devprop_buffer_size = sizeof(devprop_buffer);
			memset(devprop_buffer, '\0', sizeof(devprop_buffer));
			cmret = CM_Get_DevNode_Registry_Property(next_sibling, CM_DRP_CLASSGUID, &proptype, (VOID *)devprop_buffer, &devprop_buffer_size, 0);
			if (cmret != CR_SUCCESS) {
				_snprintf_s(cmerror, 256, 256, "CM_Get_DevNode_Registry_Property failed with CR_xxxx error code : 0x%X\0", cmret);
				return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
			}

			/* check if this is a HID device interface */
			ret = _tcsicmp(devprop_buffer, TEXT("{745A17A0-74D3-11D0-B6FE-00A0C90F57DA}"));
			if (ret != 0) {
				/* this is not HID interface, move to check next interface */
				current_sibling = next_sibling;
				continue;
			}

			/* reaching here means that this sibling (interface) is a HID type, get its device instance path */
			memset(devprop_buffer, '\0', 1024);
			cmret = CM_Get_Device_ID(next_sibling, devprop_buffer, 1024, 0);
			if (cmret != CR_SUCCESS) {
				_snprintf_s(cmerror, 256, 256, "CM_Get_Device_ID failed with CR_xxxx error code : 0x%X\0", cmret);
				return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
			}

			/* get the HardwareID of this USB HID interface. HardwareID is multi-sz, however
			   we use only 1st string from multi-string HardwareID for our matching.
			   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000\HardwareID */
			memset(charbuffer, '\0', 512);
			buffer_size = sizeof(charbuffer);

			cmret = CM_Get_DevNode_Registry_Property(next_sibling, CM_DRP_HARDWAREID, NULL, (PVOID)charbuffer, &buffer_size, 0);
			if (cmret != CR_SUCCESS) {
				_snprintf_s(cmerror, 256, 256, "CM_Get_Device_ID failed with CR_xxxx error code : 0x%X\0", cmret);
				return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
			}

			if ((charbuffer[0] == 'U') && (charbuffer[1] == 'S') && (charbuffer[2] == 'B')) {
				charbuffer[0] = 'H';
				charbuffer[1] = 'I';
				charbuffer[2] = 'D';
			}

			for (q = 0; q < hiddevinst_list.index; q++) {

				/* check association between HID collection device instance and USB interface device instance */
				ret = _tcsncicmp(charbuffer, hiddevinst_list.base[q]->hwid, 512);
				if (ret != 0) {
					continue;
				}

				/* reaching here means this HID collection belongs to this USB HID interface, so glean information
				   to be passed to java layer. */

				/* TRANSPORT */
				usb_dev_info = (*env)->NewStringUTF(env, "USB");
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* DEVICE NODE */
				usb_dev_info = (*env)->NewString(env, hiddevinst_list.base[q]->instance, (jsize)_tcslen(hiddevinst_list.base[q]->instance));
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* USB-IF VENDOR ID
				   (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */
				x = 0;
				while (buffer[x] != '\0') {
					if ((buffer[x] == 'V') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) {
						break;
					}
					x++;
				}
				x = x + 4;
				i = 0;
				while (buffer[x] != '&') {
					tmpbuf[i] = buffer[x];
					i++;
					x++;
				}
				tmpbuf[i] = '\0'; /* indicate end of string */
				usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf));
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* USB product ID
				   (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */
				x = 6;
				while (buffer[x] != '\0') {
					if ((buffer[x] == 'P') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) {
						break;
					}
					x++;
				}
				x = x + 4;
				i = 0;
				while (buffer[x] != '\\') {
					tmpbuf[i] = buffer[x];
					i++;
					x++;
				}
				tmpbuf[i] = '\0'; /* indicate end of string */
				usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf));
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* SERIAL NUMBER */
				x++;
				i = 0;
				while (buffer[x] != '\0') {
					tmpbuf[i] = buffer[x];
					i++;
					x++;
				}
				tmpbuf[i] = '\0';
				usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf));
				if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
					return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				insert_jstrarraylist(&list, usb_dev_info);

				/* PRODUCT
				   (iProduct field of USB device descriptor) */
				memset(devprop_buffer, '\0', sizeof(devprop_buffer));
				ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_BusReportedDeviceDesc, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0);
				if (ret == FALSE) {
					/* fallback to SPDRP_DEVICEDESC if DEVPKEY_Device_BusReportedDeviceDesc fails */
					ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_DEVICEDESC, &regproptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size);
					if (ret == FALSE) {
						/* if second attempt fails, throw error, we need to investigate drivers/firmware etc */
						return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
					}
					usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
					insert_jstrarraylist(&list, usb_dev_info);
				}else {
					usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
					insert_jstrarraylist(&list, usb_dev_info);
				}

				/* MANUFACTURER */
				memset(devprop_buffer, '\0', sizeof(devprop_buffer));
				ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_Manufacturer, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0);
				if (ret == FALSE) {
					return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
				insert_jstrarraylist(&list, usb_dev_info);

				/* LOCATION
				   (Location paths + Location info, get separately and then create a single string) */

				// PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(3)
				memset(devprop_buffer, '\0', sizeof(devprop_buffer));
				ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_PATHS, &regproptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size);
				if (ret == FALSE) {
					return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}
				// Port_#0003.Hub_#0001
				memset(charbuffer, '\0', sizeof(charbuffer));
				ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_INFORMATION, &regproptype, (BYTE *)charbuffer, sizeof(charbuffer), &size);
				if (ret == FALSE) {
					return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
				}

				i = 0;
				x = (int)_tcslen(devprop_buffer);
				devprop_buffer[x] = '-';
				x++;
				for (i = 0; i < (int)_tcslen(charbuffer); i++) {
					devprop_buffer[x] = charbuffer[i];
					x++;
				}
				devprop_buffer[x] = '\0';

				usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer));
				insert_jstrarraylist(&list, usb_dev_info);
			}

			/* set this sibling as base sibling for fetching next sibling, loop over to get and check next
			   interface (sibling) */
			current_sibling = next_sibling;
		}

		/* increment to get and examine the next usb device for HID class */
		usb_member_index++;
	}

	strClass = (*env)->FindClass(env, JAVALSTRING);
	if ((strClass == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
		return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_FINDCLASSSSTRINGSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
	}

	usbHidDevicesFound = (*env)->NewObjectArray(env, (jsize)list.index, strClass, NULL);
	if ((usbHidDevicesFound == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
		return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWOBJECTARRAYSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
	}

	for (x = 0; x < list.index; x++) {
		(*env)->SetObjectArrayElement(env, usbHidDevicesFound, x, list.base[x]);
		if ((*env)->ExceptionOccurred(env)) {
			return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_SETOBJECTARRAYSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL);
		}
	}

	/* clean up and return result to java layer application */
	free_jstrarraylist(&list);
	free_hiddev_instance_list(&hiddevinst_list);
	SetupDiDestroyDeviceInfoList(usb_dev_info_set);
	return usbHidDevicesFound;
}
Beispiel #7
0
ULONG GetSymbolicLink(void)
{		
	//OutputDebugString("GetSymbolicLink\r\n");
	int found_index = 0;
    HDEVINFO hDevInfo;

    // obtain a handle to device information set for all
    // kernel streaming audio devices present on the system
    hDevInfo = SetupDiGetClassDevs(
                        &CamacGuid,
                        NULL,
                        NULL,
                        DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);

    if (hDevInfo == INVALID_HANDLE_VALUE)
    { // function returned 0
      // No audio devices are present on the system
        return 0;
    }
    else
    {
        TCHAR HardwareID[512];
        USHORT found_index = 0;
	
        // Enumerate first device of our class. 

        SP_DEVICE_INTERFACE_DATA ifdata;
		ifdata.cbSize = sizeof(ifdata);

		for ( DWORD devindex = 0;
				SetupDiEnumInterfaceDevice(hDevInfo, NULL,&CamacGuid, devindex, &ifdata);
				++devindex )
		{

			// Determine the symbolic link name for this device instance. Since
			// this is variable in length, make an initial call to determine
			// the required length.

			DWORD needed;
			SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifdata, NULL, 0, &needed, NULL);
				// this call determines the size of memory to allocate

			PSP_INTERFACE_DEVICE_DETAIL_DATA detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(needed);
				// zero the structure
				memset (detail,0,needed);

				// set the size of the structure without the string at the end
			detail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

			SP_DEVINFO_DATA did = {sizeof(SP_DEVINFO_DATA)};
			SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifdata, detail, needed, NULL, &did);
			
			// Determine the device's link name
			SetupDiGetDeviceRegistryProperty(hDevInfo, &did,SPDRP_HARDWAREID, NULL, (PBYTE) HardwareID, sizeof(HardwareID), NULL);

			memset(symbolic_link, 0, sizeof(symbolic_link));
			strncpy(symbolic_link, detail->DevicePath, sizeof(symbolic_link));

			free((PVOID) detail);
			ifdata.cbSize = sizeof(ifdata); // reinitialize for next use
		}

		SetupDiDestroyDeviceInfoList(hDevInfo);
    }

    return found_index;
}
Beispiel #8
0
/** @brief detect devices based on usb pid / vid.
 *  @return list with usb VID / PID values.
 */
QMap<uint32_t, QString> System::listUsbDevices(void)
{
    QMap<uint32_t, QString> usbids;
    // usb pid detection
    LOG_INFO() << "Searching for USB devices";
#if defined(Q_OS_LINUX)
#if defined(LIBUSB1)
    libusb_device **devs;
    if(libusb_init(NULL) != 0) {
        LOG_ERROR() << "Initializing libusb-1 failed.";
        return usbids;
    }

    if(libusb_get_device_list(NULL, &devs) < 1) {
        LOG_ERROR() << "Error getting device list.";
        return usbids;
    }
    libusb_device *dev;
    int i = 0;
    while((dev = devs[i++]) != NULL) {
        QString name;
        unsigned char buf[256];
        uint32_t id;
        struct libusb_device_descriptor descriptor;
        if(libusb_get_device_descriptor(dev, &descriptor) == 0) {
            id = descriptor.idVendor << 16 | descriptor.idProduct;

            libusb_device_handle *dh;
            if(libusb_open(dev, &dh) == 0) {
                libusb_get_string_descriptor_ascii(dh, descriptor.iManufacturer, buf, 256);
                name += QString::fromLatin1((char*)buf) + " ";
                libusb_get_string_descriptor_ascii(dh, descriptor.iProduct, buf, 256);
                name += QString::fromLatin1((char*)buf);
                libusb_close(dh);
            }
            if(name.isEmpty())
                name = tr("(no description available)");
            if(id) {
                usbids.insertMulti(id, name);
                LOG_INFO("USB: 0x%08x, %s", id, name.toLocal8Bit().data());
            }
        }
    }

    libusb_free_device_list(devs, 1);
    libusb_exit(NULL);
#else
    usb_init();
    usb_find_busses();
    usb_find_devices();
    struct usb_bus *b;
    b = usb_busses;

    while(b) {
        if(b->devices) {
            struct usb_device *u;
            u = b->devices;
            while(u) {
                uint32_t id;
                id = u->descriptor.idVendor << 16 | u->descriptor.idProduct;
                // get identification strings
                usb_dev_handle *dev;
                QString name;
                char string[256];
                int res;
                dev = usb_open(u);
                if(dev) {
                    if(u->descriptor.iManufacturer) {
                        res = usb_get_string_simple(dev, u->descriptor.iManufacturer,
                                                    string, sizeof(string));
                        if(res > 0)
                            name += QString::fromLatin1(string) + " ";
                    }
                    if(u->descriptor.iProduct) {
                        res = usb_get_string_simple(dev, u->descriptor.iProduct,
                                                    string, sizeof(string));
                        if(res > 0)
                            name += QString::fromLatin1(string);
                    }
                    usb_close(dev);
                }
                if(name.isEmpty()) name = tr("(no description available)");

                if(id) {
                    usbids.insertMulti(id, name);
                    LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name;
                }
                u = u->next;
            }
        }
        b = b->next;
    }
#endif
#endif

#if defined(Q_OS_MACX)
    kern_return_t result = KERN_FAILURE;
    CFMutableDictionaryRef usb_matching_dictionary;
    io_iterator_t usb_iterator = IO_OBJECT_NULL;
    usb_matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName);
    result = IOServiceGetMatchingServices(kIOMasterPortDefault, usb_matching_dictionary,
                                          &usb_iterator);
    if(result) {
        LOG_ERROR() << "USB: IOKit: Could not get matching services.";
        return usbids;
    }

    io_object_t usbCurrentObj;
    while((usbCurrentObj = IOIteratorNext(usb_iterator))) {
        uint32_t id;
        QString name;
        /* get vendor ID */
        CFTypeRef vidref = NULL;
        int vid = 0;
        vidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idVendor"),
                                kCFAllocatorDefault, 0);
        CFNumberGetValue((CFNumberRef)vidref, kCFNumberIntType, &vid);
        CFRelease(vidref);

        /* get product ID */
        CFTypeRef pidref = NULL;
        int pid = 0;
        pidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idProduct"),
                                kCFAllocatorDefault, 0);
        CFNumberGetValue((CFNumberRef)pidref, kCFNumberIntType, &pid);
        CFRelease(pidref);
        id = vid << 16 | pid;

        /* get product vendor */
        char vendor_buf[256];
        CFIndex vendor_buflen = 256;
        CFTypeRef vendor_name_ref = NULL;

        vendor_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj,
                                 kIOServicePlane, CFSTR("USB Vendor Name"),
                                 kCFAllocatorDefault, 0);
        if(vendor_name_ref != NULL) {
            CFStringGetCString((CFStringRef)vendor_name_ref, vendor_buf, vendor_buflen,
                               kCFStringEncodingUTF8);
            name += QString::fromUtf8(vendor_buf) + " ";
            CFRelease(vendor_name_ref);
        }
        else {
            name += QObject::tr("(unknown vendor name) ");
        }

        /* get product name */
        char product_buf[256];
        CFIndex product_buflen = 256;
        CFTypeRef product_name_ref = NULL;

        product_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj,
                                kIOServicePlane, CFSTR("USB Product Name"),
                                kCFAllocatorDefault, 0);
        if(product_name_ref != NULL) {
            CFStringGetCString((CFStringRef)product_name_ref, product_buf, product_buflen,
                               kCFStringEncodingUTF8);
            name += QString::fromUtf8(product_buf);
            CFRelease(product_name_ref);
        }
        else {
            name += QObject::tr("(unknown product name)");
        }

        if(id) {
            usbids.insertMulti(id, name);
            LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name;
        }

    }
    IOObjectRelease(usb_iterator);
#endif

#if defined(Q_OS_WIN32)
    HDEVINFO deviceInfo;
    SP_DEVINFO_DATA infoData;
    DWORD i;

    // Iterate over all devices
    // by doing it this way it's unneccessary to use GUIDs which might be not
    // present in current MinGW. It also seemed to be more reliably than using
    // a GUID.
    // See KB259695 for an example.
    deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);

    infoData.cbSize = sizeof(SP_DEVINFO_DATA);

    for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) {
        DWORD data;
        LPTSTR buffer = NULL;
        DWORD buffersize = 0;
        QString description;

        // get device desriptor first
        // for some reason not doing so results in bad things (tm)
        while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
            SPDRP_DEVICEDESC, &data, (PBYTE)buffer, buffersize, &buffersize)) {
            if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                if(buffer) free(buffer);
                // double buffer size to avoid problems as per KB888609
                buffer = (LPTSTR)malloc(buffersize * 2);
            }
            else {
                break;
            }
        }
        description = QString::fromWCharArray(buffer);

        // now get the hardware id, which contains PID and VID.
        while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData,
            SPDRP_HARDWAREID, &data, (PBYTE)buffer, buffersize, &buffersize)) {
            if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                if(buffer) free(buffer);
                // double buffer size to avoid problems as per KB888609
                buffer = (LPTSTR)malloc(buffersize * 2);
            }
            else {
                break;
            }
        }

        unsigned int vid, pid;
        // convert buffer text to upper case to avoid depending on the case of
        // the keys (W7 uses different casing than XP at least).
        int len = _tcslen(buffer);
        while(len--) buffer[len] = _totupper(buffer[len]);
        if(_stscanf(buffer, _TEXT("USB\\VID_%x&PID_%x"), &vid, &pid) == 2) {
            uint32_t id;
            id = vid << 16 | pid;
            usbids.insert(id, description);
            LOG_INFO("USB VID: %04x, PID: %04x", vid, pid);
        }
        if(buffer) free(buffer);
    }
    SetupDiDestroyDeviceInfoList(deviceInfo);

#endif
    return usbids;
}
/// <summary>
/// Get physical device paths.
/// </summary>
/// <param name="drives">Found drives</param>
/// <returns>Error code</returns>
DWORD PhysicalDisk::GetPhysicalPaths( std::vector<std::wstring>& drives )
{
    HDEVINFO diskClassDevices = nullptr;
    GUID diskClassDeviceInterfaceGuid = GUID_DEVINTERFACE_DISK;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { 0 };
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = nullptr;
    DWORD requiredSize = 0;
    DWORD deviceIndex = 0;

    HANDLE disk = INVALID_HANDLE_VALUE;
    STORAGE_DEVICE_NUMBER diskNumber = { 0 };
    DWORD bytesReturned = 0;

    //
    // Get the handle to the device information set for installed
    // disk class devices. Returns only devices that are currently
    // present in the system and have an enabled disk device
    // interface.
    //
    diskClassDevices = SetupDiGetClassDevs( &diskClassDeviceInterfaceGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
    if (diskClassDevices == INVALID_HANDLE_VALUE)
        return GetLastError();

    ZeroMemory( &deviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA) );
    deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    for (; SetupDiEnumDeviceInterfaces( diskClassDevices, NULL, &diskClassDeviceInterfaceGuid, deviceIndex, &deviceInterfaceData ); ++deviceIndex)
    {
        SetupDiGetDeviceInterfaceDetailW( diskClassDevices, &deviceInterfaceData, NULL, 0, &requiredSize, NULL );
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            goto Exit;

        deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc( requiredSize );

        ZeroMemory( deviceInterfaceDetailData, requiredSize );
        deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        if (!SetupDiGetDeviceInterfaceDetail( diskClassDevices, &deviceInterfaceData, deviceInterfaceDetailData, requiredSize, NULL, NULL ))
            goto Exit;

        disk = CreateFile( deviceInterfaceDetailData->DevicePath,
                           GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
                           NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

        if (disk == INVALID_HANDLE_VALUE)
            goto Exit;

        if (!DeviceIoControl( disk, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &diskNumber, sizeof(STORAGE_DEVICE_NUMBER), &bytesReturned, NULL ))
            goto Exit;

        CloseHandle( disk );
        disk = INVALID_HANDLE_VALUE;

        drives.emplace_back( L"\\\\?\\PhysicalDrive" + std::to_wstring( diskNumber.DeviceNumber ) );

        if (deviceInterfaceDetailData)
        {
            free( deviceInterfaceDetailData );
            deviceInterfaceDetailData = nullptr;
        }
    }

Exit:

    if (INVALID_HANDLE_VALUE != diskClassDevices)
        SetupDiDestroyDeviceInfoList( diskClassDevices );

    if (INVALID_HANDLE_VALUE != disk)
        CloseHandle( disk );

    if (deviceInterfaceDetailData)
        free( deviceInterfaceDetailData );

    return GetLastError();
}
Beispiel #10
0
	__declspec(dllexport) BOOL  __stdcall GetDeviceHandle ( CONST GUID * guidDeviceInterface,PHANDLE hDeviceHandle)
	{	
		BOOL bResult = TRUE;
		HDEVINFO hDeviceInfo;
		SP_DEVINFO_DATA DeviceInfoData;

		SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
		PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL;

		ULONG requiredLength=0;

		LPTSTR lpDevicePath = NULL;

		DWORD index = 0;

		// Get information about all the installed devices for the specified
		// device interface class.
		hDeviceInfo = SetupDiGetClassDevs( 
			guidDeviceInterface,
			NULL, 
			NULL,
			DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

		if (hDeviceInfo == INVALID_HANDLE_VALUE) 
		{ 
			// ERROR 
			printf("Error SetupDiGetClassDevs: %d.\n", GetLastError());
			goto done;
		}

		//Enumerate all the device interfaces in the device information set.
		DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

		//for (index = 0; SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData); index++)
		if(SetupDiEnumDeviceInfo(hDeviceInfo, 0, &DeviceInfoData))
		{
			//Reset for this iteration
			if (lpDevicePath)
			{
				LocalFree(lpDevicePath);
			}

			if (pInterfaceDetailData)
			{
				LocalFree(pInterfaceDetailData);
			}

			deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);

			//Get information about the device interface.
			bResult = SetupDiEnumDeviceInterfaces( 
				hDeviceInfo,
				&DeviceInfoData,
				guidDeviceInterface,
				0, 
				&deviceInterfaceData);

			// Check if last item
			if (GetLastError () == ERROR_NO_MORE_ITEMS)
			{
				//break;
			}

			//Check for some other error
			if (!bResult) 
			{
				printf("Error SetupDiEnumDeviceInterfaces: %d.\n", GetLastError());
				goto done;
			}

			//Interface data is returned in SP_DEVICE_INTERFACE_DETAIL_DATA
			//which we need to allocate, so we have to call this function twice.
			//First to get the size so that we know how much to allocate
			//Second, the actual call with the allocated buffer

			bResult = SetupDiGetDeviceInterfaceDetail(
				hDeviceInfo,
				&deviceInterfaceData,
				NULL, 0,
				&requiredLength,
				NULL);


			//Check for some other error
			if (!bResult) 
			{
				if ((ERROR_INSUFFICIENT_BUFFER==GetLastError()) && (requiredLength>0))
				{
					//we got the size, allocate buffer
					pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);

					if (!pInterfaceDetailData) 
					{ 
						// ERROR 
						printf("Error allocating memory for the device detail buffer.\n");
						goto done;
					}
				}
				else
				{
					printf("Error SetupDiEnumDeviceInterfaces: %d.\n", GetLastError());
					goto done;
				}
			}

			//get the interface detailed data
			pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

			//Now call it with the correct size and allocated buffer
			bResult = SetupDiGetDeviceInterfaceDetail(
				hDeviceInfo,
				&deviceInterfaceData,
				pInterfaceDetailData,
				requiredLength,
				NULL,
				&DeviceInfoData);

			//Check for some other error
			if (!bResult) 
			{
				printf("Error SetupDiGetDeviceInterfaceDetail: %d.\n", GetLastError());
				goto done;
			}

			//copy device path

			size_t nLength = wcslen (pInterfaceDetailData->DevicePath) + 1;  
			lpDevicePath = (TCHAR *) LocalAlloc (LPTR, nLength * sizeof(TCHAR));
			StringCchCopy(lpDevicePath, nLength, pInterfaceDetailData->DevicePath);

			lpDevicePath[nLength-1] = 0;

			//printf("Device path:  %s\n", lpDevicePath);

		}

		if (!lpDevicePath)
		{
			//Error.
			printf("Error %d.", GetLastError());
			goto done;
		}

		//Open the device
		*hDeviceHandle = CreateFile (
			lpDevicePath,
			GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ | FILE_SHARE_WRITE,
			NULL,
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL,
			NULL);

		if (*hDeviceHandle == INVALID_HANDLE_VALUE)
		{
			//Error.
			printf("Error %d.", GetLastError());
			goto done;
		}



done:
		LocalFree(lpDevicePath);
		LocalFree(pInterfaceDetailData);    
		bResult = SetupDiDestroyDeviceInfoList(hDeviceInfo);

		return bResult;
	}	
Beispiel #11
0
int battery_init() {
	

	#define GBS_HASBATTERY 0x1
	#define GBS_ONBATTERY  0x2

	DWORD dwResult = GBS_ONBATTERY;
	HDEVINFO hdev = NULL;
	int idev = 0;
	BOOL b;
	DWORD cbRequired = 0;
	SP_DEVICE_INTERFACE_DATA did;

	hdev = SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 
                                0, 
                                0, 
                                DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (INVALID_HANDLE_VALUE == hdev) {
		//return hdev;
		printf("GUID_DEVCLASS_BATTERY error\n");
		return -1;
	}

	for (idev = 0; idev < 100; idev++) {
		printf("for\n");
		
		memset(&did, 0, sizeof(did));
		did.cbSize = sizeof(did);

		b = SetupDiEnumDeviceInterfaces(hdev,
                                      0,
                                      &GUID_DEVCLASS_BATTERY,
                                      idev,
                                      &did);
		if (!b) {
			break;
		}

        SetupDiGetDeviceInterfaceDetail(hdev,
                                        &did,
                                        0,
                                        0,
                                        &cbRequired,
                                        0);

		if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
			PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd =
			 (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc(LPTR, cbRequired);

			if (!pdidd) {
				log_err("battery_init: LocalAlloc failed, size %d", cbRequired);
				SetupDiDestroyDeviceInfoList(hdev);
				return -1;
			}

			pdidd->cbSize = sizeof(*pdidd);
            if (SetupDiGetDeviceInterfaceDetail(hdev,
                                                &did,
                                                pdidd,
                                                cbRequired,
                                                &cbRequired,
                                                0))
            {
				// Enumerated a battery.  Ask it for information.
				HANDLE hBattery = CreateFile(pdidd->DevicePath,
                                 GENERIC_READ | GENERIC_WRITE,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 NULL,
                                 OPEN_EXISTING,
                                 FILE_ATTRIBUTE_NORMAL,
                                 NULL);
				if (INVALID_HANDLE_VALUE != hBattery) {
					//printf("battery handle: %d\n", hBattery);
					//_bat[idev] = hBattery;
					_bathandle  = hBattery;
					LocalFree(pdidd);
					break;
				} else {
					log_warn("battery_init: failed to open device file: %s", pdidd->DevicePath);
				}
			} else {
					log_warn("battery_init:SetupDiGetDeviceInterfaceDetail failed");
			}

			LocalFree(pdidd);
		} // end if ERROR_INSUFFICIENT_BUFFER

	} // end for
      
	SetupDiDestroyDeviceInfoList(hdev);

	if (_bathandle != 0) {
		BATTERY_INFORMATION BatteryInfo;

		memset(&BatteryInfo, 0, sizeof(BATTERY_INFORMATION));
	
		if (BatteryQueryInformation(_bathandle,
									BatteryInformation,
									(LPVOID)&BatteryInfo,
									sizeof(BatteryInfo))) {
			_max_capacity = (float) BatteryInfo.FullChargedCapacity;
		} else {
			log_err("battery_info: failed to retrieve the maximum capacity of the battery");
			 CloseHandle(_bathandle);
			 _bathandle = 0;
			return -1;
		}

		battery_print_info(_bathandle);
	}
	printf("battery_init end \n");
	return 0;
}
Beispiel #12
0
BOOLEAN
FindKnownHidDevices (
   OUT PHID_DEVICE * HidDevices, // A array of struct _HID_DEVICE
   OUT PULONG        NumberDevices // the length of this array.
   )
/*++
Routine Description:
   Do the required PnP things in order to find all the HID devices in
   the system at this time.
--*/
{
    HDEVINFO                            hardwareDeviceInfo;
    SP_DEVICE_INTERFACE_DATA            deviceInfoData;
    ULONG                               i;
    BOOLEAN                             done;
    PHID_DEVICE                         hidDeviceInst;
    GUID                                hidGuid;
    PSP_DEVICE_INTERFACE_DETAIL_DATA    functionClassDeviceData = NULL;
    ULONG                               predictedLength = 0;
    ULONG                               requiredLength = 0;
    PHID_DEVICE                         newHidDevices;


    HidD_GetHidGuid (&hidGuid);

    *HidDevices = NULL;
    *NumberDevices = 0;

    //
    // Open a handle to the plug and play dev node.
    //
    hardwareDeviceInfo = SetupDiGetClassDevs ( &hidGuid,
                                               NULL, // Define no enumerator (global)
                                               NULL, // Define no
                                               (DIGCF_PRESENT | // Only Devices present
                                                DIGCF_DEVICEINTERFACE)); // Function class devices.

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

    //
    // Take a wild guess to start
    //
    
    *NumberDevices = 4;
    done = FALSE;
    deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);

    i=0;
    while (!done) 
    {
        *NumberDevices *= 2;

        if (*HidDevices) 
        {
            newHidDevices =
               realloc (*HidDevices, (*NumberDevices * sizeof (HID_DEVICE)));

            if (NULL == newHidDevices)
            {
                free(*HidDevices);
            }

            *HidDevices = newHidDevices;
        }
        else
        {
            *HidDevices = calloc (*NumberDevices, sizeof (HID_DEVICE));
        }

        if (NULL == *HidDevices) 
        {
            SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
            return FALSE;
        }

        hidDeviceInst = *HidDevices + i;

        for (; i < *NumberDevices; i++, hidDeviceInst++) 
        {
            if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
                                             0, // No care about specific PDOs
                                             &hidGuid,
                                             i,
                                             &deviceInfoData))
            {
                //
                // allocate a function class device data structure to receive the
                // goods about this particular device.
                //

                SetupDiGetDeviceInterfaceDetail (
                        hardwareDeviceInfo,
                        &deviceInfoData,
                        NULL, // probing so no output buffer yet
                        0, // probing so output buffer length of zero
                        &requiredLength,
                        NULL); // not interested in the specific dev-node


                predictedLength = requiredLength;

                functionClassDeviceData = malloc (predictedLength);
                if (functionClassDeviceData)
                {
                    functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
                    ZeroMemory(functionClassDeviceData->DevicePath, sizeof(functionClassDeviceData->DevicePath));
                }
                else
                {
                    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
                    return FALSE;
                }

                //
                // Retrieve the information from Plug and Play.
                //

                if (! SetupDiGetDeviceInterfaceDetail (
                           hardwareDeviceInfo,
                           &deviceInfoData,
                           functionClassDeviceData,
                           predictedLength,
                           &requiredLength,
                           NULL)) 
                {
                    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
                    free(functionClassDeviceData);
                    return FALSE;
                }

                //
                // Open device with just generic query abilities to begin with
                //
                
                if (! OpenHidDevice (functionClassDeviceData -> DevicePath, 
                               FALSE,      // ReadAccess - none
                               FALSE,      // WriteAccess - none
                               FALSE,       // Overlapped - no
                               FALSE,       // Exclusive - no
                               hidDeviceInst))
                {
                    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
                    free(functionClassDeviceData);
                    return FALSE;
                }

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

    *NumberDevices = i;

    SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
    free(functionClassDeviceData);
    return TRUE;
}
Beispiel #13
0
/*
 * Refresh the list of USB devices
 */
BOOL GetUSBDevices(DWORD devnum)
{
	// The first two are standard Microsoft drivers (including the Windows 8 UASP one).
	// The rest are the vendor UASP drivers I know of so far - list may be incomplete!
	const char* storage_name[] = { "USBSTOR", "UASPSTOR", "VUSBSTOR", "ETRONSTOR", "ASUSSTPT" };
	const char* scsi_name = "SCSI";
	const char* usb_speed_name[USB_SPEED_MAX] = { "USB", "USB 1.0", "USB 1.1", "USB 2.0", "USB 3.0" };
	// Hash table and String Array used to match a Device ID with the parent hub's Device Interface Path
	htab_table htab_devid = HTAB_EMPTY;
	StrArray dev_if_path;
	char letter_name[] = " (?:)";
	char uefi_togo_check[] = "?:\\EFI\\Rufus\\ntfs_x64.efi";
	BOOL r = FALSE, found = FALSE, is_SCSI;
	HDEVINFO dev_info = NULL;
	SP_DEVINFO_DATA dev_info_data;
	SP_DEVICE_INTERFACE_DATA devint_data;
	PSP_DEVICE_INTERFACE_DETAIL_DATA_A devint_detail_data;
	DEVINST parent_inst, grandparent_inst, device_inst;
	DWORD size, i, j, k, l, datatype, drive_index;
	ULONG list_size[ARRAYSIZE(storage_name)] = { 0 }, list_start[ARRAYSIZE(storage_name)] = { 0 }, full_list_size, ulFlags;
	HANDLE hDrive;
	LONG maxwidth = 0;
	int s, score, drive_number, remove_drive;
	char drive_letters[27], *device_id, *devid_list = NULL, entry_msg[128];
	char *label, *entry, buffer[MAX_PATH], str[MAX_PATH], *method_str;
	usb_device_props props;

	IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList));
	StrArrayClear(&DriveID);
	StrArrayClear(&DriveLabel);
	StrArrayCreate(&dev_if_path, 128);
	// Add a dummy for string index zero, as this is what non matching hashes will point to
	StrArrayAdd(&dev_if_path, "");

	device_id = (char*)malloc(MAX_PATH);
	if (device_id == NULL)
		goto out;

	// Build a hash table associating a CM Device ID of an USB device with the SetupDI Device Interface Path
	// of its parent hub - this is needed to retrieve the device speed
	dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_USB_HUB, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
	if (dev_info != INVALID_HANDLE_VALUE) {
		if (htab_create(DEVID_HTAB_SIZE, &htab_devid)) {
			dev_info_data.cbSize = sizeof(dev_info_data);
			for (i=0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) {
				if (usb_debug)
					uprintf("Processing Hub %d:", i + 1);
				devint_detail_data = NULL;
				devint_data.cbSize = sizeof(devint_data);
				// Only care about the first interface (MemberIndex 0)
				if ( (SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_USB_HUB, 0, &devint_data))
				  && (!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, NULL, 0, &size, NULL)) 
				  && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
				  && ((devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size)) != NULL) ) {
					devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
					if (SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) {

						// Find the Device IDs for all the children of this hub
						if (CM_Get_Child(&device_inst, dev_info_data.DevInst, 0) == CR_SUCCESS) {
							device_id[0] = 0;
							s = StrArrayAdd(&dev_if_path, devint_detail_data->DevicePath);
							if ((s>= 0) && (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS)) {
								if ((k = htab_hash(device_id, &htab_devid)) != 0) {
									htab_devid.table[k].data = (void*)(uintptr_t)s;
								}
								if (usb_debug)
									uprintf("  Found ID[%03d]: %s", k, device_id);
								while (CM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) {
									device_id[0] = 0;
									if (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS) {
										if ((k = htab_hash(device_id, &htab_devid)) != 0) {
											htab_devid.table[k].data = (void*)(uintptr_t)s;
										}
										if (usb_debug)
											uprintf("  Found ID[%03d]: %s", k, device_id);
									}
								}
							}
						}
					}
					free(devint_detail_data);
				}
			}
		}
		SetupDiDestroyDeviceInfoList(dev_info);
	}
	free(device_id);

	// Build a single list of Device IDs from all the storage enumerators we know of
	full_list_size = 0;
	ulFlags = CM_GETIDLIST_FILTER_SERVICE;
	if (nWindowsVersion >= WINDOWS_7)
		ulFlags |= CM_GETIDLIST_FILTER_PRESENT;
	for (s=0; s<ARRAYSIZE(storage_name); s++) {
		// Get a list of device IDs for all USB storage devices
		// This will be used to find if a device is UASP
		if (CM_Get_Device_ID_List_SizeA(&list_size[s], storage_name[s], ulFlags) != CR_SUCCESS)
			list_size[s] = 0;
		if (list_size[s] != 0)
			full_list_size += list_size[s]-1;	// remove extra NUL terminator
	}
	devid_list = NULL;
	if (full_list_size != 0) {
		full_list_size += 1;	// add extra NUL terminator
		devid_list = (char*)malloc(full_list_size);
		if (devid_list == NULL) {
			uprintf("Could not allocate Device ID list\n");
			return FALSE;
		}
		for (s=0, i=0; s<ARRAYSIZE(storage_name); s++) {
			list_start[s] = i;
			if (list_size[s] > 1) {
				if (CM_Get_Device_ID_ListA(storage_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS)
					continue;
				if (usb_debug) {
					uprintf("Processing IDs belonging to %s:", storage_name[s]);
					for (device_id = &devid_list[i]; *device_id != 0; device_id += strlen(device_id) + 1)
						uprintf("  %s", device_id);
				}
				// The list_size is sometimes larger than required thus we need to find the real end
				for (i += list_size[s]; i > 2; i--) {
					if ((devid_list[i-2] != '\0') && (devid_list[i-1] == '\0') && (devid_list[i] == '\0'))
						break;
				}
			}
		}
	}

	// Now use SetupDi to enumerate all our storage devices
	dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
	if (dev_info == INVALID_HANDLE_VALUE) {
		uprintf("SetupDiGetClassDevs (Interface) failed: %s\n", WindowsErrorString());
		goto out;
	}
	dev_info_data.cbSize = sizeof(dev_info_data);
	for (i=0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) {
		memset(buffer, 0, sizeof(buffer));
		method_str = "";
		if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME,
				&datatype, (LPBYTE)buffer, sizeof(buffer), &size)) {
			uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s\n", WindowsErrorString());
			continue;
		}
		// UASP drives are listed under SCSI (along with regular SYSTEM drives => "DANGER, WILL ROBINSON!!!")
		is_SCSI = (safe_stricmp(buffer, scsi_name) == 0);
		if ((safe_stricmp(buffer, storage_name[0]) != 0) && (!is_SCSI))
			continue;

		// We can't use the friendly name to find if a drive is a VHD, as friendly name string gets translated
		// according to your locale, so we poke the Hardware ID
		memset(&props, 0, sizeof(props));
		memset(buffer, 0, sizeof(buffer));
		props.is_VHD = SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_HARDWAREID,
			&datatype, (LPBYTE)buffer, sizeof(buffer), &size) && IsVHD(buffer);
		if (usb_debug)
			uprintf("Processing Device: '%s'", buffer);

		memset(buffer, 0, sizeof(buffer));
		if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME,
				&datatype, (LPBYTE)buffer, sizeof(buffer), &size)) {
			uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString());
			// We can afford a failure on this call - just replace the name with "USB Storage Device (Generic)"
			safe_strcpy(buffer, sizeof(buffer), lmprintf(MSG_045));
		} else if ((!props.is_VHD) && (devid_list != NULL)) {
			// Get the properties of the device. We could avoid doing this lookup every time by keeping
			// a lookup table, but there shouldn't be that many USB storage devices connected...
			// NB: Each of these Device IDs have an _only_ child, from which we get the Device Instance match.
			for (device_id = devid_list; *device_id != 0; device_id += strlen(device_id) + 1) {
				if ( (CM_Locate_DevNodeA(&parent_inst, device_id, 0) == CR_SUCCESS)
				  && (CM_Get_Child(&device_inst, parent_inst, 0) == CR_SUCCESS)
				  && (device_inst == dev_info_data.DevInst) ) {
					// If we're not dealing with the USBSTOR part of our list, then this is an UASP device
					props.is_UASP = ((((uintptr_t)device_id)+2) >= ((uintptr_t)devid_list)+list_start[1]);
					// Now get the properties of the device, and its Device ID, which we need to populate the properties
					j = htab_hash(device_id, &htab_devid);
					if (usb_debug)
						uprintf("  Matched with ID[%03d]: %s", j, device_id);
					// If the hash didn't match a populated string in dev_if_path[] (htab_devid.table[j].data > 0),
					// we might have an extra vendor driver in between (e.g. "ASUS USB 3.0 Boost Storage Driver"
					// for UASP devices in ASUS "Turbo Mode" or "Apple Mobile Device USB Driver" for iPods)
					// so try to see if we can match the grandparent.
					if ( ((uint32_t)htab_devid.table[j].data == 0)
					  && (CM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS)
					  && (CM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) {
						device_id = str;
						method_str = "[GP]";
						j = htab_hash(device_id, &htab_devid);
						if (usb_debug)
							uprintf("  Matched with (GP) ID[%03d]: %s", j, device_id);
					}
					if ((uint32_t)htab_devid.table[j].data > 0)
						GetUSBProperties(dev_if_path.String[(uint32_t)htab_devid.table[j].data], device_id, &props);
					if (usb_debug)
						uprintf("  Props VID:PID = %04X:%04X", props.vid, props.pid);

					// If previous calls still didn't succeed, try reading the VID:PID from the device_id
					if ((props.vid == 0) && (props.pid == 0)) {
						BOOL post_backslash = FALSE;
						method_str = "[ID]";
						for (j=0, k=0; (j<strlen(device_id))&&(k<2); j++) {
							// The ID is in the form USB_VENDOR_BUSID\VID_xxxx&PID_xxxx\...
							if (device_id[j] == '\\')
								post_backslash = TRUE;
							if (!post_backslash)
								continue;
							if (device_id[j] == '_') {
								props.pid = (uint16_t)strtoul(&device_id[j+1], NULL, 16);
								if (k++==0)
									props.vid = props.pid;
							}
						}
					}
				}
			}
		}
		if (props.is_VHD) {
			uprintf("Found VHD device '%s'", buffer);
		} else {
			if ((props.vid == 0) && (props.pid == 0)) {
				if (is_SCSI) {
					// If we have an SCSI drive and couldn't get a VID:PID, we are most likely
					// dealing with a system drive => eliminate it!
					if (usb_debug)
						uprintf("  Non USB => Eliminated");
					continue;
				}
				safe_strcpy(str, sizeof(str), "????:????");	// Couldn't figure VID:PID
			} else {
				static_sprintf(str, "%04X:%04X", props.vid, props.pid);
			}
			if (props.speed >= USB_SPEED_MAX)
				props.speed = 0;
			uprintf("Found %s%s%s device '%s' (%s) %s\n", props.is_UASP?"UAS (":"", 
				usb_speed_name[props.speed], props.is_UASP?")":"", buffer, str, method_str);
			if (props.is_LowerSpeed)
				uprintf("NOTE: This device is an USB 3.0 device operating at lower speed...");
		}
		devint_data.cbSize = sizeof(devint_data);
		hDrive = INVALID_HANDLE_VALUE;
		devint_detail_data = NULL;
		for (j=0; ;j++) {
			safe_closehandle(hDrive);
			safe_free(devint_detail_data);

			if (!SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_DISK, j, &devint_data)) {
				if(GetLastError() != ERROR_NO_MORE_ITEMS) {
					uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString());
				} else {
					uprintf("A device was eliminated because it didn't report itself as a disk\n");
				}
				break;
			}

			if (!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, NULL, 0, &size, NULL)) {
				if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
					devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size);
					if (devint_detail_data == NULL) {
						uprintf("Unable to allocate data for SP_DEVICE_INTERFACE_DETAIL_DATA\n");
						continue;
					}
					devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
				} else {
					uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s\n", WindowsErrorString());
					continue;
				}
			}
			if (devint_detail_data == NULL) {
				uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated\n");
				continue;
			}
			if(!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) {
				uprintf("SetupDiGetDeviceInterfaceDetail (actual) failed: %s\n", WindowsErrorString());
				continue;
			}

			hDrive = CreateFileA(devint_detail_data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,
				NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
			if(hDrive == INVALID_HANDLE_VALUE) {
				uprintf("Could not open '%s': %s\n", devint_detail_data->DevicePath, WindowsErrorString());
				continue;
			}

			drive_number = GetDriveNumber(hDrive, devint_detail_data->DevicePath);
			if (drive_number < 0)
				continue;

			drive_index = drive_number + DRIVE_INDEX_MIN;
			if (!IsMediaPresent(drive_index)) {
				uprintf("Device eliminated because it appears to contain no media\n");
				safe_closehandle(hDrive);
				safe_free(devint_detail_data);
				break;
			}

			if (GetDriveLabel(drive_index, drive_letters, &label)) {
				if ((!enable_HDDs) && (!props.is_VHD) &&
					((score = IsHDD(drive_index, (uint16_t)props.vid, (uint16_t)props.pid, buffer)) > 0)) {
					uprintf("Device eliminated because it was detected as an USB Hard Drive (score %d > 0)\n", score);
					uprintf("If this device is not an USB Hard Drive, please e-mail the author of this application\n");
					uprintf("NOTE: You can enable the listing of USB Hard Drives in 'Advanced Options' (after clicking the white triangle)");
					safe_closehandle(hDrive);
					safe_free(devint_detail_data);
					break;
				}

				// The empty string is returned for drives that don't have any volumes assigned
				if (drive_letters[0] == 0) {
					entry = lmprintf(MSG_046, label, drive_number,
						SizeToHumanReadable(GetDriveSize(drive_index), FALSE, use_fake_units));
				} else {
					// Find the UEFI:TOGO partition(s) (and eliminate them form our listing)
					for (k=0; drive_letters[k]; k++) {
						uefi_togo_check[0] = drive_letters[k];
						if (PathFileExistsA(uefi_togo_check)) {
							for (l=k; drive_letters[l]; l++)
								drive_letters[l] = drive_letters[l+1];
							k--;
						}
					}
					// We have multiple volumes assigned to the same device (multiple partitions)
					// If that is the case, use "Multiple Volumes" instead of the label
					safe_strcpy(entry_msg, sizeof(entry_msg), ((drive_letters[0] != 0) && (drive_letters[1] != 0))?
						lmprintf(MSG_047):label);
					for (k=0, remove_drive=0; drive_letters[k] && (!remove_drive); k++) {
						// Append all the drive letters we detected
						letter_name[2] = drive_letters[k];
						if (right_to_left_mode)
							safe_strcat(entry_msg, sizeof(entry_msg), RIGHT_TO_LEFT_MARK);
						safe_strcat(entry_msg, sizeof(entry_msg), letter_name);
						if (drive_letters[k] == (PathGetDriveNumberU(app_dir) + 'A'))
							remove_drive = 1;
						if (drive_letters[k] == (PathGetDriveNumberU(system_dir) + 'A'))
							remove_drive = 2;
					}
					// Make sure that we don't list any drive that should not be listed
					if (remove_drive) {
						uprintf("Removing %C: from the list: This is the %s!", drive_letters[--k],
							(remove_drive==1)?"disk from which " APPLICATION_NAME " is running":"system disk");
						safe_closehandle(hDrive);
						safe_free(devint_detail_data);
						break;
					}
					safe_sprintf(&entry_msg[strlen(entry_msg)], sizeof(entry_msg) - strlen(entry_msg),
						"%s [%s]", (right_to_left_mode)?RIGHT_TO_LEFT_MARK:"", SizeToHumanReadable(GetDriveSize(drive_index), FALSE, use_fake_units));
					entry = entry_msg;
				}

				// Must ensure that the combo box is UNSORTED for indexes to be the same
				StrArrayAdd(&DriveID, buffer);
				StrArrayAdd(&DriveLabel, label);

				IGNORE_RETVAL(ComboBox_SetItemData(hDeviceList, ComboBox_AddStringU(hDeviceList, entry), drive_index));
				maxwidth = max(maxwidth, GetEntryWidth(hDeviceList, entry));
				safe_closehandle(hDrive);
				safe_free(devint_detail_data);
				break;
			}
		}
	}
	SetupDiDestroyDeviceInfoList(dev_info);

	// Adjust the Dropdown width to the maximum text size
	SendMessage(hDeviceList, CB_SETDROPPEDWIDTH, (WPARAM)maxwidth, 0);

	if (devnum >= DRIVE_INDEX_MIN) {
		for (i=0; i<ComboBox_GetCount(hDeviceList); i++) {
			if ((DWORD)ComboBox_GetItemData(hDeviceList, i) == devnum) {
				found = TRUE;
				break;
			}
		}
	}
	if (!found)
		i = 0;
	IGNORE_RETVAL(ComboBox_SetCurSel(hDeviceList, i));
	SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_DEVICE, 0);
	SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_FILESYSTEM,
		ComboBox_GetCurSel(hFileSystem));
	r = TRUE;

out:
	// Set 'Start' as the selected button, so that tab selection works
	SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hMainDialog, IDC_START), TRUE);
	safe_free(devid_list);
	StrArrayDestroy(&dev_if_path);
	htab_destroy(&htab_devid);
	return r;
}
Beispiel #14
0
void DetectAlreadyConnectedDevices(ThreadObject* tpThreads[])
{
	HDEVINFO hDevInfo = SetupDiGetClassDevs(
		&GUID_DEVINTERFACE_DISK,
		NULL,
		NULL,
		DIGCF_PRESENT |
		DIGCF_DEVICEINTERFACE
		);
	SP_DEVINFO_DATA spDeviceInfoData;
	ZeroMemory(&spDeviceInfoData, sizeof(SP_DEVINFO_DATA));
	spDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	LPTSTR pszPropertyBuffer[BUFFER];
	DWORD dwRequiredSize;
	DWORD dwRequiredBufferSize;
	DWORD dwProperyDatatype;
	BOOL bResult;

	for (DWORD dwDeviceInfoIndex = 0; SetupDiEnumDeviceInfo(
		hDevInfo,
		dwDeviceInfoIndex,
		&spDeviceInfoData
		);
	dwDeviceInfoIndex++)
	{
		bResult = SetupDiGetDeviceRegistryProperty(
			hDevInfo,
			&spDeviceInfoData,
			SPDRP_ENUMERATOR_NAME,
			&dwProperyDatatype,
			(LPBYTE)pszPropertyBuffer,
			BUFFER,
			&dwRequiredBufferSize);

		if (_tcscmp((LPTSTR)pszPropertyBuffer, TEXT("USBSTOR")) == 0)
		{
			SP_DEVICE_INTERFACE_DATA spDeviceInterfaceData;
			ZeroMemory(&spDeviceInterfaceData, sizeof(spDeviceInterfaceData));
			spDeviceInterfaceData.cbSize = sizeof(spDeviceInterfaceData);
			PSP_DEVICE_INTERFACE_DETAIL_DATA pspDeviceInterfaceDetailData = NULL;

			for (DWORD dwDeviceInterfacesIndex = 0; bResult = SetupDiEnumDeviceInterfaces(
				hDevInfo,
				&spDeviceInfoData,
				&GUID_DEVINTERFACE_DISK,
				dwDeviceInterfacesIndex++,
				&spDeviceInterfaceData
				);
			dwDeviceInterfacesIndex++)
			{
				DWORD dwError = GetLastError();
				if (!bResult)
				{
					if (dwError == ERROR_NO_MORE_DEVICES || dwError == ERROR_NO_MORE_ITEMS)
						break;
				}

				/*
				Get the required size for the
				PSP_DEVICE_INTERFACE_DETAIL_DATA
				structure
				*/
				bResult = SetupDiGetDeviceInterfaceDetail(
					hDevInfo,
					&spDeviceInterfaceData,
					NULL,
					0,
					&dwRequiredSize,
					NULL
					);

				/*
				Allocate that required size
				*/
				if (!bResult)
				{
					if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
					{
						pspDeviceInterfaceDetailData = new SP_DEVICE_INTERFACE_DETAIL_DATA[dwRequiredSize];//(PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, dwRequiredSize);
						pspDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
					}
					else
						break;
				}

				/*
				Get the details on that device
				*/
				bResult = SetupDiGetDeviceInterfaceDetail(
					hDevInfo,
					&spDeviceInterfaceData,
					pspDeviceInterfaceDetailData,
					dwRequiredSize,
					NULL,
					NULL
					);
				if (bResult)
				{
					STORAGE_DEVICE_NUMBER storageDeviceNumber;
					ZeroMemory(&storageDeviceNumber, sizeof(STORAGE_DEVICE_NUMBER));
					storageDeviceNumber.DeviceNumber = 0;
					DWORD dwSize = 0;

					/*
					Get the device handle
					*/
					HANDLE hDrive = CreateFile(
						pspDeviceInterfaceDetailData->DevicePath,
						GENERIC_READ,
						FILE_SHARE_READ |
						FILE_SHARE_WRITE,
						NULL,
						OPEN_EXISTING,
						0,
						0
						);
					if (hDrive != INVALID_HANDLE_VALUE)
					{
						/*
						Get the device number
						*/
						bResult = DeviceIoControl(
							hDrive,
							IOCTL_STORAGE_GET_DEVICE_NUMBER,
							NULL,
							0,
							&storageDeviceNumber,
							sizeof(storageDeviceNumber),
							&dwSize,
							NULL
							);
						if (bResult)
						{
							char cDrive = GetVolumeLabelByDiskNumber(storageDeviceNumber.DeviceNumber);
							if (cDrive)
							{
								int iIndex = cDrive - 'A';
								printf("%c:\\ will be watched\n", cDrive);
								tpThreads[iIndex] = new ThreadObject(Inspection, (LPVOID)cDrive);
								tpThreads[iIndex]->Start();
							}
						}
					}
					CloseHandle(hDrive);
				}
				delete pspDeviceInterfaceDetailData;
			}
		}
	}
	SetupDiDestroyDeviceInfoList(hDevInfo);
}
Beispiel #15
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))
		{
			auto const wm = new Wiimote;
			wm->devicepath = detail_data->DevicePath;
			bool real_wiimote = false, is_bb = false;

			CheckDeviceType(wm->devicepath, 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);

}
DEVINST GetDrivesDevInstByDeviceNumber(long DeviceNumber, UINT DriveType, char* szDosDeviceName)
{
	bool IsFloppy = (strstr(szDosDeviceName, "\\Floppy") != NULL); // who knows a better way?

	GUID* guid;

	switch (DriveType) {
	case DRIVE_REMOVABLE:
		if ( IsFloppy ) {
			guid = (GUID*)&GUID_DEVINTERFACE_FLOPPY;
		} else {
			guid = (GUID*)&GUID_DEVINTERFACE_DISK;
		}
		break;
	case DRIVE_FIXED:
		guid = (GUID*)&GUID_DEVINTERFACE_DISK;
		break;
	case DRIVE_CDROM:
		guid = (GUID*)&GUID_DEVINTERFACE_CDROM;
		break;
	default:
		return 0;
	}

	// Get device interface info set handle for all devices attached to system
	HDEVINFO hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

	if (hDevInfo == INVALID_HANDLE_VALUE)	{
		return 0;
	}

	// Retrieve a context structure for a device interface of a device information set
	DWORD dwIndex = 0;
	long res;

	BYTE Buf[1024];
	PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
	SP_DEVICE_INTERFACE_DATA         spdid;
	SP_DEVINFO_DATA                  spdd;
	DWORD                            dwSize;
	
	spdid.cbSize = sizeof(spdid);

	while ( true )	{
		res = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guid, dwIndex, &spdid);
		if ( !res ) {
			break;
		}

		dwSize = 0;
		SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize, NULL); // check the buffer size

		if ( dwSize!=0 && dwSize<=sizeof(Buf) ) {

			pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!

			ZeroMemory(&spdd, sizeof(spdd));
			spdd.cbSize = sizeof(spdd);

			long res = SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, dwSize, &dwSize, &spdd);
			if ( res ) {
				// open the disk or cdrom or floppy
				HANDLE hDrive = CreateFile(pspdidd->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
				if ( hDrive != INVALID_HANDLE_VALUE ) {
					// get its device number
					STORAGE_DEVICE_NUMBER sdn;
					DWORD dwBytesReturned = 0;
					res = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL);
					if ( res ) {
						if ( DeviceNumber == (long)sdn.DeviceNumber ) {  // match the given device number with the one of the current device
							CloseHandle(hDrive);
							SetupDiDestroyDeviceInfoList(hDevInfo);
							return spdd.DevInst;
						}
					}
					CloseHandle(hDrive);
				}
			}
		}
		dwIndex++;
	}

	SetupDiDestroyDeviceInfoList(hDevInfo);

	return 0;
}
Beispiel #17
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;
}
void * _ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
{
	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) {
						size_t j;
						for (j = 0; j < pids_len; j++) {
							if (devInfo.ProductID == product_ids[j]) {
								if(ret_handle == NULL) {
									ret_handle = m_handle;
									break;
								} else {
									yk_errno = YK_EMORETHANONE;
									ret_handle = NULL;
									CloseHandle (m_handle);
									goto done;
								}
							}
						}
					}
				}
			}
			if(ret_handle == NULL) {
				CloseHandle (m_handle);
			}
		}

		free (pi);
	}
	if(ret_handle != NULL) {
		goto done;
	}

	yk_errno = YK_ENOKEY;

done:
	SetupDiDestroyDeviceInfoList(hi);
	return ret_handle;
}
/*
 * The sequence of entries in array must match with what java layer expect (6 informations
 * per USB device). If a particular USB attribute is not set in descriptor or can not be
 * obtained "---" is placed in its place.
 *
 * Returns array of USB device's information found, empty array if no USB device is found,
 * NULL if an error occurs (additionally throws exception).
 */
jobjectArray list_usb_devices(JNIEnv *env, jint vendor_to_match) {

	int x = 0;
	int i = 0;
	int vid = 0;
	BOOL ret = FALSE;
	DWORD error_code = 0;
	DWORD size = 0;
	TCHAR *ptrend;
	DWORD usb_member_index = 0;
	HDEVINFO usb_dev_info_set;
	SP_DEVINFO_DATA usb_dev_instance;
	DEVPROPTYPE proptype;
	DWORD regproptype;
	TCHAR buffer[1024];
	TCHAR charbuffer[1024];

	struct jstrarray_list list = { 0 };
	jstring usb_dev_info;
	jclass strClass = NULL;
	jobjectArray usbDevicesFound = NULL;

	init_jstrarraylist(&list, 50);

	/* get information set for all usb devices matching the GUID */
	usb_dev_info_set = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (usb_dev_info_set == INVALID_HANDLE_VALUE) {
		SetupDiDestroyDeviceInfoList(usb_dev_info_set);
		free_jstrarraylist(&list);
		throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL);
		return NULL;
	}

	/* enumerate all devices in this information set */
	usb_member_index = 0;
	while (1) {
		ZeroMemory(&usb_dev_instance, sizeof(usb_dev_instance));
		usb_dev_instance.cbSize = sizeof(usb_dev_instance);

		/* from information set, get device by index */
		ret = SetupDiEnumDeviceInfo(usb_dev_info_set, usb_member_index, &usb_dev_instance);
		if (ret == FALSE) {
			error_code = GetLastError();
			if (error_code == ERROR_NO_MORE_ITEMS) {
				break;
			}
			else {
				SetupDiDestroyDeviceInfoList(usb_dev_info_set);
				free_jstrarraylist(&list);
				throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(error_code), NULL);
				return NULL;
			}
		}

		/* for this device find its instance ID (USB\VID_04D8&PID_00DF\000098037)
		 * this is the variable 'Device Instance Path' in device manager. */
		memset(buffer, '\0', sizeof(buffer));
		ret = SetupDiGetDeviceInstanceId(usb_dev_info_set, &usb_dev_instance, buffer, sizeof(buffer), &size);
		if (ret == FALSE) {
			SetupDiDestroyDeviceInfoList(usb_dev_info_set);
			free_jstrarraylist(&list);
			throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL);
			return NULL;
		}

		/* USB-IF vendor ID, extract and match, if matched continue further otherwise loop back */
		x = 0;
		while (buffer[x] != '\0') {
			if((buffer[x] == 'V') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) {
				break;
			}
			x++;
		}
		x = x + 4;
		i = 0;
		while (buffer[x] != '&') {
			charbuffer[i] = buffer[x];
			i++;
			x++;
		}
		charbuffer[i] = '\0'; /* indicate end of string */

		vid = (int)_tcstol(charbuffer, &ptrend, 16);

		if(vendor_to_match != 0) {
			/* we need to apply filter for identify specific vendor */
			if(vid != vendor_to_match) {
				usb_member_index++;
				continue;
			}
		}

		usb_dev_info = (*env)->NewString(env, charbuffer, (jsize) _tcslen(charbuffer));
		if((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
			(*env)->ExceptionClear(env);
			SetupDiDestroyDeviceInfoList(usb_dev_info_set);
			free_jstrarraylist(&list);
			throw_serialcom_exception(env, 3, 0, E_NEWSTRSTR);
			return NULL;
		}
		insert_jstrarraylist(&list, usb_dev_info);

		/* USB product ID */
		x = 6;
		while (buffer[x] != '\0') {
			if ((buffer[x] == 'P') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) {
				break;
			}
			x++;
		}
		x = x + 4;
		i = 0;
		while (buffer[x] != '\\') {
			charbuffer[i] = buffer[x];
			i++;
			x++;
		}
		charbuffer[i] = '\0';

		usb_dev_info = (*env)->NewString(env, charbuffer, (jsize) _tcslen(charbuffer));
		if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
			(*env)->ExceptionClear(env);
			SetupDiDestroyDeviceInfoList(usb_dev_info_set);
			free_jstrarraylist(&list);
			throw_serialcom_exception(env, 3, 0, E_NEWSTRSTR);
			return NULL;
		}
		insert_jstrarraylist(&list, usb_dev_info);

		/* SERIAL NUMBER */
		x++;
		i = 0;
		while (buffer[x] != '\0') {
			charbuffer[i] = buffer[x];
			i++;
			x++;
		}
		charbuffer[i] = '\0';

		usb_dev_info = (*env)->NewString(env, charbuffer, (jsize) _tcslen(charbuffer));
		if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
			(*env)->ExceptionClear(env);
			SetupDiDestroyDeviceInfoList(usb_dev_info_set);
			free_jstrarraylist(&list);
			throw_serialcom_exception(env, 3, 0, E_NEWSTRSTR);
			return NULL;
		}
		insert_jstrarraylist(&list, usb_dev_info);
		
		/* PRODUCT
			(idProduct field of USB device descriptor) */
		memset(buffer, '\0', sizeof(buffer));
		ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_BusReportedDeviceDesc, &proptype, (BYTE *)buffer, sizeof(buffer), &size, 0);
		if (ret == FALSE) {
			/* fallback to SPDRP_DEVICEDESC if DEVPKEY_Device_BusReportedDeviceDesc fails */
			ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_DEVICEDESC, &regproptype, (BYTE *)buffer, sizeof(buffer), &size);
			if (ret == FALSE) {
				/* if second attempt fails, throw error, we need to investigate drivers/firmware etc */
				SetupDiDestroyDeviceInfoList(usb_dev_info_set);
				free_jstrarraylist(&list);
				throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL);
				return NULL;
			}
			usb_dev_info = (*env)->NewString(env, buffer, (jsize)_tcslen(buffer));
			insert_jstrarraylist(&list, usb_dev_info);
		}else {
			usb_dev_info = (*env)->NewString(env, buffer, (jsize)_tcslen(buffer));
			insert_jstrarraylist(&list, usb_dev_info);
		}

		/* MANUFACTURER */
		memset(buffer, '\0', sizeof(buffer));
		ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_Manufacturer, &proptype, (BYTE *)buffer, sizeof(buffer), &size, 0);
		if (ret == FALSE) {
			SetupDiDestroyDeviceInfoList(usb_dev_info_set);
			free_jstrarraylist(&list);
			throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL);
			return NULL;
		}
		usb_dev_info = (*env)->NewString(env, buffer, (jsize) _tcslen(buffer));
		insert_jstrarraylist(&list, usb_dev_info);

		/* LOCATION (Location paths + Location info, get separately and then create a single string) */
		memset(buffer, '\0', sizeof(buffer));
		ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_PATHS, &regproptype, (BYTE *)buffer, sizeof(buffer), &size);
		if (ret == FALSE) {
			SetupDiDestroyDeviceInfoList(usb_dev_info_set);
			free_jstrarraylist(&list);
			throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL);
			return NULL;
		}

		memset(charbuffer, '\0', sizeof(charbuffer));
		ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_INFORMATION, &regproptype, (BYTE *)charbuffer, sizeof(charbuffer), &size);
		if (ret == FALSE) {
			SetupDiDestroyDeviceInfoList(usb_dev_info_set);
			free_jstrarraylist(&list);
			throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL);
			return NULL;
		}

		i = 0;
		x = (int)_tcslen(buffer);
		buffer[x] = '-';
		x++;
		for (i = 0; i < (int)_tcslen(charbuffer); i++) {
			buffer[x] = charbuffer[i];
			x++;
		}
		buffer[x] = '\0';

		usb_dev_info = (*env)->NewString(env, buffer, (jsize)_tcslen(buffer));
		insert_jstrarraylist(&list, usb_dev_info);

		/* loop to get next USB device */
		usb_member_index++;
	}

	SetupDiDestroyDeviceInfoList(usb_dev_info_set);

	strClass = (*env)->FindClass(env, JAVALSTRING);
	if((strClass == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
		(*env)->ExceptionClear(env);
		free_jstrarraylist(&list);
		throw_serialcom_exception(env, 3, 0, E_FINDCLASSSSTRINGSTR);
		return NULL;
	}

	usbDevicesFound = (*env)->NewObjectArray(env, (jsize)list.index, strClass, NULL);
	if((usbDevicesFound == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
		(*env)->ExceptionClear(env);
		free_jstrarraylist(&list);
		throw_serialcom_exception(env, 3, 0, E_NEWOBJECTARRAYSTR);
		return NULL;
	}

	for (x = 0; x < list.index; x++) {
		(*env)->SetObjectArrayElement(env, usbDevicesFound, x, list.base[x]);
		if ((*env)->ExceptionOccurred(env)) {
			(*env)->ExceptionClear(env);
			free_jstrarraylist(&list);
			throw_serialcom_exception(env, 3, 0, E_SETOBJECTARRAYSTR);
			return NULL;
		}
	}

	free_jstrarraylist(&list);
	return usbDevicesFound;
}
Beispiel #20
0
////////////////////////////////////////////////////////////////////////////////
//	O p e n U S B D e v i c e
////////////////////////////////////////////////////////////////////////////////
HANDLE OpenUSBDevice( LPCSTR lpMfg, LPCSTR lpPdt, USB_ERROR_INFO *lpUsbErrorInfo )
{	
	int									ii;
	DWORD								dwBytes;
	BOOL								bFoundMfg;
	BOOL								bFoundPdt;
	LPTSTR								lpToken, lpWorkToken;
	int									nDeviceIndex;
	HDEVINFO							hDevInfo;
	HANDLE								hUsbPrinter;
	char								szUsb1284[1024];
	GUID								guidUSBDeviceSupport;
	SP_DEVICE_INTERFACE_DATA			deviceInterfaceData;
	PSP_DEVICE_INTERFACE_DETAIL_DATA	deviceInterfaceDetailData;
	HINSTANCE							pSetupAPI					= NULL;

	FAR HDEVINFO ( FAR WINAPI *SetupDiGetClassDevs )(CONST GUID *, PCTSTR, HWND, DWORD);
	FAR BOOL ( FAR WINAPI *SetupDiEnumDeviceInterfaces )(HDEVINFO, PSP_DEVINFO_DATA, CONST GUID *,DWORD, PSP_DEVICE_INTERFACE_DATA);
	FAR BOOL ( FAR WINAPI *SetupDiGetDeviceInterfaceDetail )(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA);
	FAR BOOL ( FAR WINAPI *SetupDiDestroyDeviceInfoList )(HDEVINFO);



	//
	// The functions SetupDiGetClassDevs, SetupDiEnumDeviceInterfaces , 
	// SetupDiGetDeviceInterfaceDetail, SetupDiDestroyDeviceInfoList
	// are supported only on Windows 2000 and above and Windows 98 and above.
	// So link them dynamically to avoid windows errors.
	//
	pSetupAPI = LoadLibrary( "Setupapi" );

	if ( pSetupAPI != NULL )
	{

		SetupDiGetClassDevs = ( HDEVINFO ( WINAPI * )(CONST GUID *, PCTSTR, HWND, DWORD)) GetProcAddress( pSetupAPI, "SetupDiGetClassDevsA" );

		if ( SetupDiGetClassDevs == NULL )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiGetClassDevs");
		    FreeLibrary( pSetupAPI );
			return 0;
		}

		SetupDiEnumDeviceInterfaces = ( BOOL ( WINAPI * )(HDEVINFO, PSP_DEVINFO_DATA, CONST GUID *,DWORD, PSP_DEVICE_INTERFACE_DATA)) GetProcAddress( pSetupAPI, "SetupDiEnumDeviceInterfaces" );

		if ( SetupDiEnumDeviceInterfaces == NULL )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiEnumDeviceInterfaces");
		    FreeLibrary( pSetupAPI );
			return 0;
		}

		SetupDiGetDeviceInterfaceDetail = ( BOOL ( WINAPI * )(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA)) GetProcAddress( pSetupAPI, "SetupDiGetDeviceInterfaceDetailA" );

		if ( SetupDiGetDeviceInterfaceDetail == NULL )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiGetDeviceInterfaceDetailA");
		    FreeLibrary( pSetupAPI );
			return 0;
		}

		SetupDiDestroyDeviceInfoList = ( BOOL ( WINAPI * )(HDEVINFO)) GetProcAddress( pSetupAPI, "SetupDiDestroyDeviceInfoList" );

		if ( SetupDiDestroyDeviceInfoList == NULL )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiDestroyDeviceInfoList");
		    FreeLibrary( pSetupAPI );
			return 0;
		}
	}
	else
	{
		lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_HANDLE;
		strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to load Setupapi!");
		return 0;
	}


	//
	// get a handle to the set of device information returned by the Win32 API
	// functions.  This handle points to an object that is then operated on 
	// by the SetupDiEnumDeviceInterfaces function.
	//
	InitError( lpUsbErrorInfo );
	guidUSBDeviceSupport = GUID_CLASS_USB_DEVICE;
	hDevInfo = SetupDiGetClassDevs(	&guidUSBDeviceSupport,
									NULL,
									NULL,
									0x12 );	// TODO : Determine the constant
	if ( INVALID_HANDLE_VALUE == hDevInfo )
	{
		if ( NULL != lpUsbErrorInfo )
		{
			// get the last error from system
			lpUsbErrorInfo->dwSysLastError = GetLastError();

			// get the system defined message
			FormatMessage(	FORMAT_MESSAGE_FROM_SYSTEM			|
								FORMAT_MESSAGE_IGNORE_INSERTS,
							NULL,
							lpUsbErrorInfo->dwSysLastError,
							MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
							lpUsbErrorInfo->szSysErrorMsg,
							sizeof(lpUsbErrorInfo->szSysErrorMsg) / sizeof(lpUsbErrorInfo->szSysErrorMsg[0]),
							NULL );
		}
	}


	//
	//
	//	
	nDeviceIndex = 0;
	bFoundMfg = bFoundPdt = FALSE;
	hUsbPrinter = INVALID_HANDLE_VALUE;
	deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
	for ( nDeviceIndex = 0; SetupDiEnumDeviceInterfaces(	hDevInfo,
											NULL,
											&guidUSBDeviceSupport,
											nDeviceIndex,
											&deviceInterfaceData ); 
		nDeviceIndex++ ) 
	{




		//
		// determine the amout of memory we need to allocate for the next
		// call to this function
		//
		dwBytes= 0;
		ii = SetupDiGetDeviceInterfaceDetail(	hDevInfo,
												&deviceInterfaceData,
												NULL,
												0,
												&dwBytes,
												NULL );
		if ( 0 == dwBytes )
		{
			//
			// Reinitialize the data for next pass
			// through this loop.
			//
			deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
			continue;
		}


		
		deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(dwBytes);
		deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);


		//
		// get the device path for the current device we are enumerating over.
		//
		ii = SetupDiGetDeviceInterfaceDetail(	hDevInfo,
												&deviceInterfaceData,
												deviceInterfaceDetailData,
												dwBytes,
												&dwBytes,
												NULL );
		if ( 0 == ii )
		{
			//
			// Free DetailData struct and reinitialize the data for next pass
			//through this loop.
			//
			free(deviceInterfaceDetailData);
			deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
			continue;
		}


		//
		// get handle to the device so that we can 
		//
		hUsbPrinter = CreateFile(	deviceInterfaceDetailData->DevicePath,
									GENERIC_READ		| 
										GENERIC_WRITE,
									FILE_SHARE_WRITE	|
										FILE_SHARE_READ,
									NULL,
									OPEN_EXISTING,
									0,
									NULL );


		//
		//
		//
		if ( INVALID_HANDLE_VALUE == hUsbPrinter )
		{
			//
			// Free DetailData struct and reinitialize the data for next pass
			// through this loop.
			//
			free(deviceInterfaceDetailData);
			deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
			continue;
		}



		//
		//
		//
		dwBytes = 0;
		memset( szUsb1284, 0, sizeof(szUsb1284) );
		ii = DeviceIoControl(	hUsbPrinter,
								IOCTL_USBPRINT_GET_1284_ID,
								NULL,
								0,
								szUsb1284,
								sizeof(szUsb1284),
								&dwBytes,
								NULL );

		//
		// parse the PNP string returned from the device.
		//		
		lpToken = strtok( szUsb1284, PNP_DELIMITOR );
		while ( NULL != lpToken )
		{
			// have the manfacturer.
			lpWorkToken = strstr(lpToken,MFG_TOKEN);
			if ( lpWorkToken != NULL )
			{
				RTrim(lpWorkToken);
				if ( strcmp( lpMfg, lpWorkToken + MFG_TOKEN_LEN ) == 0 )
					bFoundMfg = TRUE;
			}

			//	model of the printer
			lpWorkToken = strstr(lpToken,MDL_TOKEN);
			if ( lpWorkToken != NULL )
			{
				RTrim(lpWorkToken);
				if ( strcmp( lpPdt, lpWorkToken + MDL_TOKEN_LEN ) == 0 )
					bFoundPdt = TRUE;
			}

			// next token
			lpToken = strtok( NULL, PNP_DELIMITOR );
		}


	
		//
		//
		//
		if ( bFoundMfg && bFoundPdt )
		{
	        free(deviceInterfaceDetailData);
			break;
		}
	

		//
		//
		//
		CloseHandle( hUsbPrinter );
		hUsbPrinter = INVALID_HANDLE_VALUE;


		
		//
		// Free DetailData struct and reinitialize the data for next pass
		// through this loop.
		//
		free(deviceInterfaceDetailData);
		deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);

	}

	//
	//Destroy device information set and free all associated memory. 
	//
	SetupDiDestroyDeviceInfoList(hDevInfo);

	//
	//Free setupapi library
	//
    FreeLibrary( pSetupAPI );

	//
	//
	//
	return hUsbPrinter;
}
Beispiel #21
0
static
void
SetDeviceDetails(HWND hwndDlg, LPCGUID classGUID, LPCWSTR lpcstrDescription)
{
    HDEVINFO hInfo;
    DWORD dwIndex = 0;
    SP_DEVINFO_DATA InfoData;
    WCHAR szText[30];
    HWND hDlgCtrls[3];
    WAVEOUTCAPSW waveOut;
    UINT numDev;
    MMRESULT errCode;


    /*  enumerate waveout devices */
    numDev = waveOutGetNumDevs();
    if (numDev)
    {
        do
        {
                ZeroMemory(&waveOut, sizeof(waveOut));
                errCode = waveOutGetDevCapsW(dwIndex++, &waveOut, sizeof(waveOut));
                if (!wcsncmp(lpcstrDescription, waveOut.szPname, min(MAXPNAMELEN, wcslen(waveOut.szPname))))
                {
                    /* set the product id */
                    SetDlgItemInt(hwndDlg, IDC_STATIC_DSOUND_PRODUCTID, waveOut.wPid, FALSE);
                    /* set the vendor id */
                    SetDlgItemInt(hwndDlg, IDC_STATIC_DSOUND_VENDORID, waveOut.wMid, FALSE);
                    /* check if its a wdm audio driver */
                    if (waveOut.wPid == MM_MSFT_WDMAUDIO_WAVEOUT)
                        SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_TYPE, WM_SETTEXT, 0, (LPARAM)L"WDM");

                    /* check if device is default device */
                    szText[0] = L'\0';
                    if (dwIndex - 1 == 0) /* FIXME assume default playback device is device 0 */
                        LoadStringW(hInst, IDS_OPTION_YES, szText, sizeof(szText)/sizeof(WCHAR));
                    else
                        LoadStringW(hInst, IDS_OPTION_NO, szText, sizeof(szText)/sizeof(WCHAR));

                    szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
                    /* set default device info */
                    SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_STANDARD, WM_SETTEXT, 0, (LPARAM)szText);
                    break;
                }
                }while(errCode == MMSYSERR_NOERROR && dwIndex < numDev);
    }

    dwIndex = 0;
    /* create the setup list */
    hInfo = SetupDiGetClassDevsW(classGUID, NULL, NULL, DIGCF_PRESENT|DIGCF_PROFILE);
    if (hInfo == INVALID_HANDLE_VALUE)
        return;

    do
    {
        ZeroMemory(&InfoData, sizeof(InfoData));
        InfoData.cbSize = sizeof(InfoData);

        if (SetupDiEnumDeviceInfo(hInfo, dwIndex, &InfoData))
        {
            /* set device name */
            if (SetupDiGetDeviceInstanceId(hInfo, &InfoData, szText, sizeof(szText)/sizeof(WCHAR), NULL))
                SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_DEVICEID, WM_SETTEXT, 0, (LPARAM)szText);

            /* set the manufacturer name */
            if (SetupDiGetDeviceRegistryPropertyW(hInfo, &InfoData, SPDRP_MFG, NULL, (PBYTE)szText, sizeof(szText), NULL))
                SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_PROVIDER, WM_SETTEXT, 0, (LPARAM)szText);

            /* FIXME
             * we currently enumerate only the first adapter 
             */
            hDlgCtrls[0] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_DRIVER);
            hDlgCtrls[1] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_VERSION);
            hDlgCtrls[2] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_DATE);
            EnumerateDrivers(hDlgCtrls, hInfo, &InfoData);
            break;
        }

        if (GetLastError() == ERROR_NO_MORE_ITEMS)
            break;

        dwIndex++;
    }while(TRUE);

    /* destroy the setup list */
    SetupDiDestroyDeviceInfoList(hInfo);
}
Beispiel #22
0
////////////////////////////////////////////////////////////////////////////////
//	G e t U S B D e v i c e s
////////////////////////////////////////////////////////////////////////////////
INT GetUSBDevices( INT nMaxDevices, USB_DEVICE_NAME *lpUsbDevices, USB_ERROR_INFO *lpUsbErrorInfo )
{
	int									ii;
	DWORD								dwBytes;
	INT									nDeviceFound;
	HDEVINFO							hDevInfo;
	LPTSTR								lpToken, lpWorkToken;
	GUID								guidUSBDeviceSupport;
	HANDLE								hUsbPrinter;
	SP_DEVICE_INTERFACE_DATA			deviceInterfaceData;
	PSP_DEVICE_INTERFACE_DETAIL_DATA	deviceInterfaceDetailData;
	char								szUsb1284[1024];
	int									nDeviceIndex;
	HINSTANCE							pSetupAPI					= NULL;

	FAR HDEVINFO ( FAR WINAPI *SetupDiGetClassDevs )(CONST GUID *, PCTSTR, HWND, DWORD);
	FAR BOOL ( FAR WINAPI *SetupDiEnumDeviceInterfaces )(HDEVINFO, PSP_DEVINFO_DATA, CONST GUID *,DWORD, PSP_DEVICE_INTERFACE_DATA);
	FAR BOOL ( FAR WINAPI *SetupDiGetDeviceInterfaceDetail )(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA);
	FAR BOOL ( FAR WINAPI *SetupDiDestroyDeviceInfoList )(HDEVINFO);



	//
	// The functions SetupDiGetClassDevs, SetupDiEnumDeviceInterfaces , 
	// SetupDiGetDeviceInterfaceDetail, SetupDiDestroyDeviceInfoList
	// are supported only on Windows 2000 and above and Windows 98 and above.
	// So link them dynamically to avoid windows errors.
	//
	pSetupAPI = LoadLibrary( "Setupapi" );

	if ( pSetupAPI != NULL )
	{

		SetupDiGetClassDevs = ( HDEVINFO ( WINAPI * )(CONST GUID *, PCTSTR, HWND, DWORD)) GetProcAddress( pSetupAPI, "SetupDiGetClassDevsA" );

		if ( SetupDiGetClassDevs == NULL )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiGetClassDevs");
		    FreeLibrary( pSetupAPI );
			return 0;
		}

		SetupDiEnumDeviceInterfaces = ( BOOL ( WINAPI * )(HDEVINFO, PSP_DEVINFO_DATA, CONST GUID *,DWORD, PSP_DEVICE_INTERFACE_DATA)) GetProcAddress( pSetupAPI, "SetupDiEnumDeviceInterfaces" );

		if ( SetupDiEnumDeviceInterfaces == NULL )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiEnumDeviceInterfaces");
		    FreeLibrary( pSetupAPI );
			return 0;
		}

		SetupDiGetDeviceInterfaceDetail = ( BOOL ( WINAPI * )(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA)) GetProcAddress( pSetupAPI, "SetupDiGetDeviceInterfaceDetailA" );

		if ( SetupDiGetDeviceInterfaceDetail == NULL )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiGetDeviceInterfaceDetailA");
		    FreeLibrary( pSetupAPI );
			return 0;
		}

		SetupDiDestroyDeviceInfoList = ( BOOL ( WINAPI * )(HDEVINFO)) GetProcAddress( pSetupAPI, "SetupDiDestroyDeviceInfoList" );

		if ( SetupDiDestroyDeviceInfoList == NULL )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiDestroyDeviceInfoList");
		    FreeLibrary( pSetupAPI );
			return 0;
		}
	}
	else
	{
		lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_HANDLE;
		strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to load Setupapi!");
		return 0;
	}



	//
	// initialize local variables and initialize error
	// struct if a non NULL pointer was passed.
	// 
	nDeviceFound = 0;
	if ( NULL != lpUsbErrorInfo )
		InitError( lpUsbErrorInfo );


	//
	// validate that the user passed in the number of
	// available USE_DEVICE_NAMES to fill with inofrmation.
	//
	if ( 0 == nMaxDevices )
	{	
		if ( NULL != lpUsbErrorInfo )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_DATA;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : nMaxDevices has a value of zero!");
		}
		return 0;
	};

	
	
	//
	// check that we can pass information back to the calling application!
	//
	if ( NULL == lpUsbDevices )
	{
		if ( NULL != lpUsbErrorInfo )
		{
			lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_DATA;
			strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : lpUsbDevices is NULL!" );
		}
		return 0;
	}



	//
	// get a handle to the set of device information returned by the Win32 API
	// functions.  This handle points to an object that is then operated on 
	// by the SetupDiEnumDeviceInterfaces function.
	//
	guidUSBDeviceSupport = GUID_CLASS_USB_DEVICE;
	hDevInfo = SetupDiGetClassDevs(	&guidUSBDeviceSupport,
									0,
									0,
									0x12);	// TODO : Determine the constant
	if ( INVALID_HANDLE_VALUE == hDevInfo )
	{
		if ( NULL != lpUsbErrorInfo )
		{
			// get the last error from system
			lpUsbErrorInfo->dwSysLastError = GetLastError();

			// get the system defined message
			FormatMessage(	FORMAT_MESSAGE_FROM_SYSTEM			|
							FORMAT_MESSAGE_IGNORE_INSERTS,
							NULL,
							lpUsbErrorInfo->dwSysLastError,
							MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
							lpUsbErrorInfo->szSysErrorMsg,
							sizeof(lpUsbErrorInfo->szSysErrorMsg) / sizeof(lpUsbErrorInfo->szSysErrorMsg[0]),
							NULL );
		}
	}


	//
	//
	//
	nDeviceFound = nDeviceIndex = 0;	
	deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
	for (nDeviceIndex = 0; SetupDiEnumDeviceInterfaces( hDevInfo,
									  NULL,
									  &guidUSBDeviceSupport,
									  nDeviceIndex,
									  &deviceInterfaceData );
		nDeviceIndex++) 
	{



		//
		// determine the amout of memory we need to allocate for the next
		// call to this function
		//
		dwBytes= 0;
		ii = SetupDiGetDeviceInterfaceDetail(	hDevInfo,
												&deviceInterfaceData,
												NULL,
												0,
												&dwBytes,
												NULL );
		if ( 0 == dwBytes )
		{
			//
			// Reinitialize the data for next pass
			// through this loop.
			//
			deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
			continue;
		}


		
		//Set cbSize in the detailData structure.
		deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc (dwBytes);
		deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

			
		//
		// get the device path for the current device we are enumerating over.
		//
		ii = SetupDiGetDeviceInterfaceDetail(	hDevInfo,
												&deviceInterfaceData,
												deviceInterfaceDetailData,
												dwBytes, 
												&dwBytes,
												NULL );
		if ( 0 == ii )
		{
			//
			// Free DetailData struct and reinitialize the data for next pass
			//	through this loop.
			//
			free(deviceInterfaceDetailData);
			deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
			continue;
		}


		//
		// get handle to the device so that we can 
		//
		hUsbPrinter = CreateFile(	deviceInterfaceDetailData->DevicePath,
									GENERIC_READ		| 
										GENERIC_WRITE,
									FILE_SHARE_WRITE	|
										FILE_SHARE_READ,
									NULL,
									OPEN_EXISTING,
									0,
									NULL );


		//
		//
		//
		if ( INVALID_HANDLE_VALUE == hUsbPrinter )
		{
			//
			// Free DetailData struct and reinitialize the data for next pass
			// through this loop.
			//
			free(deviceInterfaceDetailData);
			deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
			continue;
		}



		//
		//
		//
		dwBytes = 0;
		memset( szUsb1284, 0, sizeof(szUsb1284) );
		ii = DeviceIoControl(	hUsbPrinter,
								IOCTL_USBPRINT_GET_1284_ID,
								NULL,
								0,
								szUsb1284,
								sizeof(szUsb1284),
								&dwBytes,
								NULL );

		//
		//
		//
		CloseHandle( hUsbPrinter );



		//
		// parse the PNP string returned from the device.
		//		
		lpToken = strtok( szUsb1284, PNP_DELIMITOR );
		while ( NULL != lpToken )
		{
			// have the manfacturer.
			lpWorkToken = strstr(lpToken, MFG_TOKEN);
			if (lpWorkToken != NULL)
			{
				strcpy(	lpUsbDevices[nDeviceFound].szDeviceMfg, lpWorkToken + MFG_TOKEN_LEN);
				RTrim( lpUsbDevices[nDeviceFound].szDeviceMfg );
			}

			//	model of the printer
			lpWorkToken = strstr(lpToken, MDL_TOKEN);
			if (lpWorkToken != NULL)
			{
				strcpy(	lpUsbDevices[nDeviceFound].szDevicePdt, lpWorkToken + MDL_TOKEN_LEN );
				RTrim( lpUsbDevices[nDeviceFound].szDevicePdt );
			}


			// next token
			lpToken = strtok( NULL, PNP_DELIMITOR );
		}



		//
		//  if the we don't manage to get BOTH the manufacturer and the product
		// of the USB printer then don't return information back the calling code.
		//
		if (	strlen(lpUsbDevices[nDeviceFound].szDeviceMfg) + 
				strlen(lpUsbDevices[nDeviceFound].szDevicePdt) > 1 )
		{
			nDeviceFound++;
			
			//break after getting the number of devices requested.
			if (nMaxDevices == nDeviceFound)
			{
		        free(deviceInterfaceDetailData);
				break;

			}

		}
		else
		{
			lpUsbDevices[nDeviceFound].szDeviceMfg[0] = 
			lpUsbDevices[nDeviceFound].szDevicePdt[0] = 0;
		}



		//
		// Free DetailData struct and reinitialize the data for next pass
		// through this loop.
		//
        free(deviceInterfaceDetailData);
		deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);

	}

	//
	//Destroy device information set and free all associated memory. 
	//
	SetupDiDestroyDeviceInfoList(hDevInfo);

	//
	//Free setupapi library
	//
    FreeLibrary( pSetupAPI );

	return nDeviceFound;

}
/**
 * Do some cleanup of data we used. Called by installVideoDriver()
 */
void closeAndDestroy(HDEVINFO hDevInfo, HINF hInf)
{
  SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
  SetupDiDestroyDeviceInfoList(hDevInfo);
  SetupCloseInfFile(hInf);
}
Beispiel #24
0
void ofSerial::enumerateWin32Ports(){

    // thanks joerg for fixes...

	if (bPortsEnumerated == true) return;

	HDEVINFO hDevInfo = NULL;
	SP_DEVINFO_DATA DeviceInterfaceData;
	int i = 0;
	DWORD dataType, actualSize = 0;
	unsigned char dataBuf[MAX_PATH + 1];

	// Reset Port List
	nPorts = 0;
	// Search device set
	hDevInfo = SetupDiGetClassDevs((struct _GUID *)&GUID_SERENUM_BUS_ENUMERATOR,0,0,DIGCF_PRESENT);
	if ( hDevInfo ){
      while (TRUE){
         ZeroMemory(&DeviceInterfaceData, sizeof(DeviceInterfaceData));
         DeviceInterfaceData.cbSize = sizeof(DeviceInterfaceData);
         if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInterfaceData)){
             // SetupDiEnumDeviceInfo failed
             break;
         }

         if (SetupDiGetDeviceRegistryProperty(hDevInfo,
             &DeviceInterfaceData,
             SPDRP_FRIENDLYNAME,
             &dataType,
             dataBuf,
             sizeof(dataBuf),
             &actualSize)){

			sprintf(portNamesFriendly[nPorts], "%s", dataBuf);
			portNamesShort[nPorts][0] = 0;

			// turn blahblahblah(COM4) into COM4

            char *   begin    = NULL;
            char *   end    = NULL;
            begin          = strstr((char *)dataBuf, "COM");


            if (begin)
                {
                end          = strstr(begin, ")");
                if (end)
                    {
                      *end = 0;   // get rid of the )...
                      strcpy(portNamesShort[nPorts], begin);
                }
                if (nPorts++ > MAX_SERIAL_PORTS)
                        break;
            }
         }
            i++;
      }
   }
   SetupDiDestroyDeviceInfoList(hDevInfo);

   bPortsEnumerated = false;
}
Beispiel #25
0
static DEVINST 
GetDrivesDevInstByDeviceNumber(long DeviceNumber,
          UINT DriveType, LPWSTR szDosDeviceName)
{
    GUID *guid;
    HDEVINFO hDevInfo;
    DWORD dwIndex, dwBytesReturned;
    BOOL bRet, IsFloppy;
    BYTE Buf[1024];
    PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd;
    long res;
    HANDLE hDrive;
    STORAGE_DEVICE_NUMBER sdn;
    SP_DEVICE_INTERFACE_DATA         spdid;
    SP_DEVINFO_DATA                  spdd;
    DWORD                            dwSize;


    IsFloppy = (wcsstr(szDosDeviceName, L"\\Floppy") != NULL); // is there a better way?

    switch (DriveType) {
    case DRIVE_REMOVABLE:
        if ( IsFloppy ) {
        guid = (GUID*)&GUID_DEVINTERFACE_FLOPPY;
        } else {
        guid = (GUID*)&GUID_DEVINTERFACE_DISK;
        }
        break;
    case DRIVE_FIXED:
        guid = (GUID*)&GUID_DEVINTERFACE_DISK;
        break;
    case DRIVE_CDROM:
        guid = (GUID*)&GUID_DEVINTERFACE_CDROM;
        break;
    default:
        PyErr_SetString(PyExc_ValueError, "Invalid drive type");
        return 0;
    }

    // Get device interface info set handle
    // for all devices attached to system
    hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL,
                        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

    if (hDevInfo == INVALID_HANDLE_VALUE)  {
        PyErr_SetString(PyExc_ValueError, "Invalid handle value");
        return 0;
    }

    // Retrieve a context structure for a device interface
    // of a device information set.
    dwIndex = 0;
    bRet = FALSE;

    
    pspdidd =  (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
    spdid.cbSize = sizeof(spdid);

    while ( TRUE )  {
        bRet = SetupDiEnumDeviceInterfaces(hDevInfo, NULL,
            guid, dwIndex, &spdid);
        if ( !bRet ) {
        break;
        }

        dwSize = 0;
        SetupDiGetDeviceInterfaceDetail(hDevInfo,
        &spdid, NULL, 0, &dwSize, NULL);

        if ( dwSize!=0 && dwSize<=sizeof(Buf) ) {
        pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!

        ZeroMemory((PVOID)&spdd, sizeof(spdd));
        spdd.cbSize = sizeof(spdd);

        res =
            SetupDiGetDeviceInterfaceDetail(hDevInfo, &
                                            spdid, pspdidd,
                                            dwSize, &dwSize,
                                            &spdd);
        if ( res ) {
            hDrive = CreateFile(pspdidd->DevicePath,0,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL, OPEN_EXISTING, 0, NULL);
            if ( hDrive != INVALID_HANDLE_VALUE ) {
            dwBytesReturned = 0;
            res = DeviceIoControl(hDrive,
                            IOCTL_STORAGE_GET_DEVICE_NUMBER,
                            NULL, 0, &sdn, sizeof(sdn),
                            &dwBytesReturned, NULL);
            if ( res ) {
                if ( DeviceNumber == (long)sdn.DeviceNumber ) {
                CloseHandle(hDrive);
                SetupDiDestroyDeviceInfoList(hDevInfo);
                return spdd.DevInst;
                }
            }
            CloseHandle(hDrive);
            }
        }
        }
        dwIndex++;
    }

    SetupDiDestroyDeviceInfoList(hDevInfo);
    PyErr_SetString(PyExc_ValueError, "Invalid device number");

    return 0;
}
Beispiel #26
0
/////////////////////////////////////////////////////////////////////////////////
// FindAC97Device
/////////////////////////////////////////////////////////////////////////////////
// This function stores the device info and device data of the "ac97smpl" driver.
// It first creates a list of all devices that have a topology filter exposed
// and then searches through the list to find the device with the service
// "ac97smpl". The information is stored in pspRequest.
//
// For simplicity we search for the service name "ac97smpl".
// Alternately, one could get more information about the device or driver,
// then decide if it is suitable (regardless of its name).
//
// Arguments:
//    pspRequest        pointer to Property sheet page request structure.
//    DeviceInfoData    pointer to Device info data structure.
//
// Return Value:
//    TRUE on success, otherwise FALSE.
//    Note: on success that we have the device list still open - we have to destroy
//    the list later. The handle is stored at pspRequest->DeviceInfoSet.
//
BOOL FindAC97Device (PSP_PROPSHEETPAGE_REQUEST  pspRequest,
                     PSP_DEVINFO_DATA DeviceInfoData)
{
    TCHAR           szServiceName[128];

    //
    // Prepare the pspRequest structure...
    //
    pspRequest->cbSize = sizeof (SP_PROPSHEETPAGE_REQUEST);
    pspRequest->DeviceInfoData = DeviceInfoData;
    pspRequest->PageRequested = SPPSR_ENUM_ADV_DEVICE_PROPERTIES;

    // ...and the DeviceInfoData structure.
    DeviceInfoData->cbSize = sizeof (SP_DEVINFO_DATA);

    // Create a list of devices with Topology interface.
    pspRequest->DeviceInfoSet = SetupDiGetClassDevs (&KSCATEGORY_TOPOLOGY,
                                     NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

    // None found?
    if (pspRequest->DeviceInfoSet == INVALID_HANDLE_VALUE)
    {
        dbgError (TEXT("Test: SetupDiGetClassDevs: "));
        return FALSE;
    }

    //
    // Go through the list of all devices found.
    //
    int nIndex = 0;

    while (SetupDiEnumDeviceInfo (pspRequest->DeviceInfoSet, nIndex, DeviceInfoData))
    {
        //
        // Get the service name for that device.
        //
        if (!SetupDiGetDeviceRegistryProperty (pspRequest->DeviceInfoSet, DeviceInfoData,
                                               SPDRP_SERVICE, NULL, (PBYTE)szServiceName,
                                               sizeof (szServiceName), NULL))
        {
            dbgError (TEXT("Test: SetupDiGetDeviceRegistryProperty: "));
            SetupDiDestroyDeviceInfoList (pspRequest->DeviceInfoSet);
            return FALSE;
        }

        //
        // We only care about service "ac97smpl"
        //
        DWORD lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
        if (CompareString (lcid, NORM_IGNORECASE, szServiceName,
                            -1, TEXT("AC97SMPL"), -1) == CSTR_EQUAL)
        {
            //
            // We found it! The information is already stored, just return.
            // Note that we have the device list still open - we have to destroy
            // the list later.
            //
            return TRUE;
        }

        // Take the next in the list.
        nIndex++;
    }

    //
    // We did not find the service.
    //
    SetupDiDestroyDeviceInfoList (pspRequest->DeviceInfoSet);
    return FALSE;
}
HRESULT RetrieveDevicePath(OUT LPTSTR DevicePath, IN ULONG BufLen, OUT PBOOL FailureDeviceNotFound) {
	HRESULT                          hr;
	ULONG                            length;
	HDEVINFO                         deviceInfo;
	SP_DEVICE_INTERFACE_DATA         interfaceData;
	ULONG                            requiredLength = 0;
	BOOL                             bResult		= FALSE;
	PSP_DEVICE_INTERFACE_DETAIL_DATA detailData		= NULL;

	if (NULL != FailureDeviceNotFound)
		*FailureDeviceNotFound = FALSE;

	// Enumerate all devices exposing the interface
	if (INVALID_HANDLE_VALUE == (deviceInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_iOS_USB_Capture, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE))) {
		hr = HRESULT_FROM_WIN32(GetLastError());
		return hr;
	}

	interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

	// Get the first interface (index 0) in the result set
	if (FALSE == (bResult = SetupDiEnumDeviceInterfaces(deviceInfo, NULL, &GUID_DEVINTERFACE_iOS_USB_Capture, 0, &interfaceData))) {
		// We would see this error if no devices were found
		if ((ERROR_NO_MORE_ITEMS == GetLastError()) && (NULL != FailureDeviceNotFound))
			*FailureDeviceNotFound = TRUE;

		hr = HRESULT_FROM_WIN32(GetLastError());
		SetupDiDestroyDeviceInfoList(deviceInfo);
		return hr;
	}

	// Get the size of the path string We expect to get a failure with insufficient buffer
	bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, NULL, 0, &requiredLength, NULL);
	if (FALSE == bResult && ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
		hr = HRESULT_FROM_WIN32(GetLastError());
		SetupDiDestroyDeviceInfoList(deviceInfo);
		return hr;
	}

	// Allocate temporary space for SetupDi structure
	if (NULL == (detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LMEM_FIXED, requiredLength))) {
		hr = E_OUTOFMEMORY;
		SetupDiDestroyDeviceInfoList(deviceInfo);
		return hr;
	}

	detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
	length = requiredLength;

	// Get the interface's path string
	if (FALSE == (bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, detailData, length, &requiredLength, NULL))) {
		hr = HRESULT_FROM_WIN32(GetLastError());
		LocalFree(detailData);
		SetupDiDestroyDeviceInfoList(deviceInfo);
		return hr;
	}

	// Give path to the caller. SetupDiGetDeviceInterfaceDetail ensured DevicePath is NULL-terminated.
	hr = StringCbCopy(DevicePath, BufLen, detailData->DevicePath);
	LocalFree(detailData);
	SetupDiDestroyDeviceInfoList(deviceInfo);
	return hr;
}
Beispiel #28
0
/////////////////////////////////////////////////////////////////////////////////
// DisplayPropertySheet
/////////////////////////////////////////////////////////////////////////////////
// This function displays the property dialog.
// It is called by CPlApplet when the ac97cpl icon gets a double click.
//
// Arguments:
//    hWnd      parent window handle
//
// Return Value:
//    None.
//
void DisplayPropertySheet (HWND hWnd)
{
    SP_PROPSHEETPAGE_REQUEST    pspRequest;         // structure passed to ac97prop
    SP_DEVINFO_DATA             DeviceInfoData;     // pspRequest points to it.
    HMODULE                     hDLL;               // Module handle of library
    LPFNADDPROPSHEETPAGES       AC97PropPageProvider; // function to be called.
    PROPSHEETHEADER             psh;
    WCHAR                       wszFormat[128];
    size_t                      iRes;

    // You could move this to CPL_INIT, then it would be called
    // before the control panel window appears.
    // In case of an failure the icon would not be displayed. In our sample
    // however, the icon will be displayed and when the user clicks on it he
    // gets the error message.
    if (!FindAC97Device(&pspRequest, &DeviceInfoData))
    {
        iRes = LoadString(ghInstance, IDS_AC97_WARNING_MUST_INSTALL_DRIVER, wszFormat, ARRAYSIZE(wszFormat));
        if (iRes >0)
        {
            MessageBox (hWnd, wszFormat, AppletName, MB_ICONSTOP | MB_OK);
        }
        return;
    }

    // Load the library and get the function pointer.
    if (!GetDLLInfo (&hDLL, &AC97PropPageProvider))
    {
        iRes = LoadString(ghInstance, IDS_AC97_WARNING_PROPERTYPAGE_DLL_COULD_NOT_LOAD, wszFormat, ARRAYSIZE(wszFormat));
        if (iRes >0)
        {
            MessageBox (hWnd, wszFormat, AppletName, MB_ICONSTOP | MB_OK);
        }

        SetupDiDestroyDeviceInfoList (pspRequest.DeviceInfoSet);
        return;
    }

    //
    // Prepare the header for the property sheet.
    //
    psh.nStartPage = 0;
    psh.dwSize = sizeof(psh);
    psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW;
    psh.hwndParent = hWnd;
    psh.hInstance = ghInstance;
    psh.pszIcon = NULL;
    psh.pszCaption = MAKEINTRESOURCE(IDS_AC97CPL);
    psh.nPages = 1;

    // Call the function to request the property sheet page.
    if (!(*AC97PropPageProvider) ((LPVOID)&pspRequest, AddPropSheet, (LPARAM)&psh.phpage))
    {
        iRes = LoadString(ghInstance, IDS_AC97_WARNING_PROPERTYPAGEPROVIDER_FAILURE, wszFormat, ARRAYSIZE(wszFormat));
        if (iRes >0)
        {
            MessageBox (hWnd, wszFormat, AppletName, MB_ICONSTOP | MB_OK);
        }
        FreeLibrary (hDLL);
        SetupDiDestroyDeviceInfoList (pspRequest.DeviceInfoSet);
        return;
    }

    // Create the dialog. The function returns when the dialog is closed.
    if (PropertySheet (&psh) < 0)
    {
        //
        // Dialog closed abnormally. This might be a system failure.
        //
        iRes = LoadString(ghInstance, IDS_AC97_WARNING_REINSTALL_DRIVER, wszFormat, ARRAYSIZE(wszFormat));
        if (iRes >0)
        {
            MessageBox (hWnd, wszFormat, AppletName, MB_ICONSTOP | MB_OK);
        }
    }

    // Clean up.
    FreeLibrary (hDLL);
    LocalFree (psh.phpage);
    SetupDiDestroyDeviceInfoList (pspRequest.DeviceInfoSet);
}
Beispiel #29
0
bool cmtScanPorts(
	List<CmtPortInfo>& ports, uint32_t baudrate, uint32_t singleScanTimeout,
	uint32_t scanTries)
{
	CmtPortInfo current;
	ports.clear();  // clear the list
#ifdef _WIN32
	HDEVINFO hDevInfo;
	SP_DEVINFO_DATA DeviceInfoData;
	DWORD i;

	// Create a HDEVINFO with all present devices.

	// GUID for Ports: 4D36E978-E325-11CE-BFC1-08002BE10318
	GUID portGuid = {0x4D36E978,
					 0xE325,
					 0x11CE,
					 {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18}};

	//	"4D36E978-E325-11CE-BFC1-08002BE10318"
	hDevInfo =
		SetupDiGetClassDevs(&portGuid, 0, 0, DIGCF_PRESENT | DIGCF_PROFILE);

	if (hDevInfo == INVALID_HANDLE_VALUE) return false;

	// Enumerate through all devices in Set.
	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	for (i = 0;
		 !abortScan && SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i)
	{
		DWORD DataT;
		char buffer[256];
		bool isBT = false;

//
// Call function with null to begin with,
// then use the returned buffer size
// to Alloc the buffer. Keep calling until
// success or an unknown failure.
//
#if 1
		if (SetupDiGetDeviceRegistryProperty(
				hDevInfo, &DeviceInfoData, SPDRP_MFG, &DataT, (PBYTE)buffer,
				256, nullptr))
		{
			// on failure, this is not an Xsens Device
			// on success, we need to check if the device is an Xsens Device
			// if (_strnicmp(buffer,"xsens",5))
			//	scan = true;
			// else
			if (!_strnicmp(
					buffer, "(Standard port types)",
					strlen("(Standard port types)")))
				continue;
			if (_strnicmp(buffer, "xsens", 5))  // if this is NOT an xsens
			// device, treat it as a BT
			// device
			{
				isBT = true;
				if (_strnicmp(buffer, "WIDCOMM", 7))  // if this is NOT a
					// WIDCOMM (Ezureo / TDK
					// stack), skip it
					continue;
			}
		}
#endif
		// we found an Xsens Device, add its port nr to the list
		// Get the registry key which stores the ports settings
		HKEY hDeviceKey = SetupDiOpenDevRegKey(
			hDevInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV,
			KEY_QUERY_VALUE);
		if (hDeviceKey != INVALID_HANDLE_VALUE)
		{
			// Read in the name of the port
			char pszPortName[256];
			DWORD dwSize = 256;
			DWORD dwType = 0;
			if ((RegQueryValueExA(
					 hDeviceKey, "PortName", nullptr, &dwType,
					 (LPBYTE)pszPortName, &dwSize) == ERROR_SUCCESS) &&
				(dwType == REG_SZ))
			{
				// If it looks like "COMX" then
				// add it to the array which will be returned
				int32_t nLen = (int32_t)strlen(pszPortName);
				if (nLen > 3)
				{
					if (_strnicmp(pszPortName, "COM", 3)) continue;
					int32_t nPort = atoi(&pszPortName[3]);
					if (nPort)
					{
						current.m_portNr = (uint8_t)nPort;
						if (isBT)
							current.m_baudrate = CMT_BAUD_RATE_460K8;
						else
							current.m_baudrate = baudrate;
						ports.append(current);
					}
				}
			}
		}
		// Close the key now that we are finished with it
		RegCloseKey(hDeviceKey);
	}

	//  Cleanup

	SetupDiDestroyDeviceInfoList(hDevInfo);

	// Now sort the list by ascending port nr
	ports.sortAscending();

	// Add the standard com ports 1 and 2 unless they are already in the list
	bool add1 = true, add2 = true;
	if ((ports.length() > 0) && (ports[0].m_portNr == 1)) add1 = false;
	if (ports.length() > 0)
	{
		if (ports[0].m_portNr == 2)
			add2 = false;
		else if (ports.length() > 1)
			if (ports[1].m_portNr == 2) add2 = false;
	}
	if (add1)
	{
		current.m_portNr = 1;
		current.m_baudrate = baudrate;
		ports.append(current);
	}
	if (add2)
	{
		current.m_portNr = 2;
		current.m_baudrate = baudrate;
		ports.append(current);
	}
#else
	DIR* dir;
	struct dirent* entry;

	if ((dir = opendir("/dev/")) == nullptr) return false;

	while ((entry = readdir(dir)))
		if (strncmp("ttyS", entry->d_name, 4) == 0 ||
			strncmp("ttyUSB", entry->d_name, 6) == 0)
		{
			sprintf(current.m_portName, "/dev/%s", entry->d_name);
			current.m_baudrate = baudrate;
			ports.append(current);
		}
	closedir(dir);

	ports.sortAscending();
#endif

	// try to connect so we can detect if there really is an MT / XM attached
	unsigned p = 0;
	while (!abortScan && p < ports.length())
	{
		if (cmtScanPort(
				ports[p], ports[p].m_baudrate, singleScanTimeout, scanTries))
			++p;
		else
			ports.remove(p);
	}

	if (abortScan) return abortScan = false;

	// Now sort the final list by ascending port nr
	ports.sortAscending();
	abortScan = false;
	return true;
}
Beispiel #30
0
//
// If succeeded, returns the device file of the LANSCSI Bus Enumerator
// If failed, return INVALID_HANDLE_VALUE
//
static HANDLE OpenBusInterface(VOID)
{
	BOOL fSuccess = FALSE;
	DWORD err = ERROR_SUCCESS;
	HANDLE hDevice = INVALID_HANDLE_VALUE;
    HDEVINFO hDevInfoSet = INVALID_HANDLE_VALUE;
	SP_INTERFACE_DEVICE_DATA devIntfData = {0};
    PSP_INTERFACE_DEVICE_DETAIL_DATA devIntfDetailData = NULL;
    ULONG predictedLength = 0;
    ULONG requiredLength = 0;

	hDevInfoSet = SetupDiGetClassDevs (
		(LPGUID)&GUID_LANSCSI_BUS_ENUMERATOR_INTERFACE_CLASS,
		NULL, // Define no enumerator (global)
		NULL, // Define no
		(DIGCF_PRESENT | // Only Devices present
		DIGCF_INTERFACEDEVICE)); // Function class devices.

    if (INVALID_HANDLE_VALUE == hDevInfoSet)
    {
		DebugPrintErrEx(_T("OpenBusInterface: SetupDiGetClassDevs failed: "));
		goto cleanup;
    }

    devIntfData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);

	fSuccess = SetupDiEnumDeviceInterfaces (
		hDevInfoSet,
		0, // No care about specific PDOs
		(LPGUID)&GUID_LANSCSI_BUS_ENUMERATOR_INTERFACE_CLASS,
		0, //
		&devIntfData);

	if (!fSuccess) {
		DebugPrintErrEx(_T("OpenBusInterface: SetupDiEnumDeviceInterfaces failed: "));
		if (ERROR_NO_MORE_ITEMS == GetLastError()) {
			DebugPrint(1, _T("OpenBusInterface: Interface")
				_T(" GUID_LANSCSI_BUS_ENUMERATOR_INTERFACE_CLASS is not registered.\n"));
		}
		goto cleanup;
	}

	fSuccess = SetupDiGetInterfaceDeviceDetail (
            hDevInfoSet,
            &devIntfData,
            NULL, // probing so no output buffer yet
            0, // probing so output buffer length of zero
            &requiredLength,
            NULL // not interested in the specific dev-node
			);

	if (!fSuccess && ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
		DebugPrintErrEx(_T("OpenBusInterface: SetupDiGetInterfaceDeviceDetail failed: "));
		goto cleanup;
	}

    predictedLength = requiredLength;

	devIntfDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, predictedLength);
	devIntfDetailData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);
    
	fSuccess = SetupDiGetInterfaceDeviceDetail(
		hDevInfoSet,
		&devIntfData,
		devIntfDetailData,
		predictedLength,
		&requiredLength,
		NULL);

	if (!fSuccess) {
		DebugPrintErrEx(_T("OpenBusInterface: SetupDiGetInterfaceDeviceDetail failed: "));
		goto cleanup;
	}

	DebugPrint(3, _T("OpenBusInterface: Opening %s\n"), devIntfDetailData->DevicePath);

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

    if (INVALID_HANDLE_VALUE == hDevice) {
		DebugPrintErrEx(_T("OpenBusInterface: Device not ready: "));
		goto cleanup;
    }
    
	DebugPrint(3, _T("OpenBusInterface: Device file %s opened successfully.\n"),
		devIntfDetailData->DevicePath);

cleanup:

	err = GetLastError();

	if (INVALID_HANDLE_VALUE != hDevInfoSet) {
		SetupDiDestroyDeviceInfoList(hDevInfoSet);
	}

	if (NULL != devIntfDetailData) {
		HeapFree(GetProcessHeap(), 0, devIntfDetailData);
	}

	SetLastError(err);

	return hDevice;
}