bool pjrc_rawhid::getDeviceDetailsWin( USBPortInfo* portInfo, HDEVINFO devInfo, PSP_DEVINFO_DATA devData, WPARAM wParam )
{
    portInfo->friendName = getDeviceProperty(devInfo, devData, SPDRP_FRIENDLYNAME);
    if( wParam == DBT_DEVICEARRIVAL)
        portInfo->physName = getDeviceProperty(devInfo, devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME);
    portInfo->enumName = getDeviceProperty(devInfo, devData, SPDRP_ENUMERATOR_NAME);
    QString hardwareIDs = getDeviceProperty(devInfo, devData, SPDRP_HARDWAREID);
    QRegExp idRx("VID_(\\w+)&PID_(\\w+)");
    if( hardwareIDs.toUpper().contains(idRx) )
    {
        bool dummy;
        portInfo->vendorID = idRx.cap(1).toInt(&dummy, 16);
        portInfo->productID = idRx.cap(2).toInt(&dummy, 16);
    }
    return true;
}
 bool QextSerialEnumerator::getDeviceDetailsWin( QextPortInfo* portInfo, HDEVINFO devInfo, PSP_DEVINFO_DATA devData, WPARAM wParam )
 {
     portInfo->friendName = getDeviceProperty(devInfo, devData, SPDRP_FRIENDLYNAME);
     if( wParam == DBT_DEVICEARRIVAL)
         portInfo->physName = getDeviceProperty(devInfo, devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME);
     portInfo->enumName = getDeviceProperty(devInfo, devData, SPDRP_ENUMERATOR_NAME);
     QString hardwareIDs = getDeviceProperty(devInfo, devData, SPDRP_HARDWAREID);
     HKEY devKey = SetupDiOpenDevRegKey(devInfo, devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
     portInfo->portName = QextSerialPort::fullPortNameWin( getRegKeyValue(devKey, TEXT("PortName")) );
     QRegExp idRx("VID_(\\w+)&PID_(\\w+)&");
     if( hardwareIDs.toUpper().contains(idRx) )
     {
         bool dummy;
         portInfo->vendorID = idRx.cap(1).toInt(&dummy, 16);
         portInfo->productID = idRx.cap(2).toInt(&dummy, 16);
         //qDebug() << "got vid:" << vid << "pid:" << pid;
     }
     return true;
 }
	//static
	void QextSerialEnumerator::setupAPIScan(QList<QextPortInfo> & infoList)
	{
		HDEVINFO devInfo = INVALID_HANDLE_VALUE;

        DWORD dwGuids = 0;
        SetupDiClassGuidsFromName(TEXT("Ports"), NULL, 0, &dwGuids);
        if (dwGuids == 0)
        {
            qCritical("SetupDiClassGuidsFromName failed. Error code: %ld", GetLastError());
            return;
        }
        GUID *pGuids = new GUID[dwGuids];
        if (!SetupDiClassGuidsFromName(TEXT("Ports"), pGuids, dwGuids, &dwGuids))
        {
            qCritical("SetupDiClassGuidsFromName second call failed. Error code: %ld", GetLastError());
            return;
        }

        devInfo = SetupDiGetClassDevs(pGuids, NULL, NULL, DIGCF_PRESENT);
        if(devInfo == INVALID_HANDLE_VALUE)
        {
            qCritical("SetupDiGetClassDevs failed. Error code: %ld", GetLastError());
            return;
		}

		//enumerate the devices
		bool ok = true;
		SP_DEVICE_INTERFACE_DATA ifcData;
		ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
		SP_DEVICE_INTERFACE_DETAIL_DATA * detData = NULL;
        SP_DEVINFO_DATA devData = {sizeof(SP_DEVINFO_DATA)};

        for (DWORD i = 0; ok; i++)
        {
            ok = SetupDiEnumDeviceInfo(devInfo, i, &devData);
            if (ok)
            {
                // Got a device. Get the details.
                QextPortInfo info;
                info.friendName = getDeviceProperty(devInfo, & devData, SPDRP_FRIENDLYNAME);
                info.physName = getDeviceProperty(devInfo, & devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME);
                info.enumName = getDeviceProperty(devInfo, & devData, SPDRP_ENUMERATOR_NAME);
                //anyway, to get the port name we must still open registry directly :( ???
                //Eh...
                HKEY devKey = SetupDiOpenDevRegKey(devInfo, & devData, DICS_FLAG_GLOBAL, 0,
                                                                                        DIREG_DEV, KEY_READ);
                info.portName = getRegKeyValue(devKey, TEXT("PortName"));
                RegCloseKey(devKey);
                if(info.portName.startsWith("COM"))
                {
                    infoList.append(info);
                }
            }
            else
            {
                if (GetLastError() != ERROR_NO_MORE_ITEMS)
                {
                    delete [] detData;
                    qCritical("SetupDiEnumDeviceInfo failed. Error code: %ld", GetLastError());
                    return;
                }
            }
        }
        delete [] detData;
        delete[] pGuids;
    }
	//static
	void QextSerialEnumerator::setupAPIScan(QList<QextPortInfo> & infoList)
	{
		HDEVINFO devInfo = INVALID_HANDLE_VALUE;
		GUID * guidDev = (GUID *) & GUID_CLASS_COMPORT;

		devInfo = SetupDiGetClassDevs(guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
		if(devInfo == INVALID_HANDLE_VALUE) {
			qCritical("SetupDiGetClassDevs failed. Error code: %ld", GetLastError());
			return;
		}

		//enumerate the devices
		bool ok = true;
		SP_DEVICE_INTERFACE_DATA ifcData;
		ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
		SP_DEVICE_INTERFACE_DETAIL_DATA * detData = NULL;
		DWORD detDataSize = 0;
		DWORD oldDetDataSize = 0;
		
		for (DWORD i = 0; ok; i++) {
			ok = SetupDiEnumDeviceInterfaces(devInfo, NULL, guidDev, i, &ifcData);
			if (ok) {
				SP_DEVINFO_DATA devData = {sizeof(SP_DEVINFO_DATA)};
				//check for required detData size
				SetupDiGetDeviceInterfaceDetail(devInfo, & ifcData, NULL, 0, & detDataSize, & devData);
				//if larger than old detData size then reallocate the buffer
				if (detDataSize > oldDetDataSize) {
					delete [] detData;
					detData = (SP_DEVICE_INTERFACE_DETAIL_DATA *) new char[detDataSize];
					detData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
					oldDetDataSize = detDataSize;
				}
				//check the details
				if (SetupDiGetDeviceInterfaceDetail(devInfo, & ifcData, detData, detDataSize, 
													NULL, & devData)) {
					// Got a device. Get the details.
					QextPortInfo info;
					info.friendName = getDeviceProperty(devInfo, & devData, SPDRP_FRIENDLYNAME);
					info.physName = getDeviceProperty(devInfo, & devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME);
					info.enumName = getDeviceProperty(devInfo, & devData, SPDRP_ENUMERATOR_NAME);
					//anyway, to get the port name we must still open registry directly :( ??? 
					//Eh...			
					HKEY devKey = SetupDiOpenDevRegKey(devInfo, & devData, DICS_FLAG_GLOBAL, 0,
														DIREG_DEV, KEY_READ);
					info.portName = getRegKeyValue(devKey, TEXT("PortName"));
					RegCloseKey(devKey);
					infoList.append(info);
				} else {
					qCritical("SetupDiGetDeviceInterfaceDetail failed. Error code: %ld", GetLastError());
					delete [] detData;
					return;
				}
			} else {
				if (GetLastError() != ERROR_NO_MORE_ITEMS) {
					delete [] detData;
					qCritical("SetupDiEnumDeviceInterfaces failed. Error code: %ld", GetLastError());
					return;
				}
			}
		}
		delete [] detData;
	}
Example #5
0
bool remove(const std::wstring& hardware_id, bool& reboot_required)
{
	bool result = false;

	HDEVINFO devices = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, NULL);

	if (devices != INVALID_HANDLE_VALUE)
	{
		std::wcerr << "Got device information set." << std::endl;

		SP_DEVINFO_LIST_DETAIL_DATA device_info_list_detail;
		memset(&device_info_list_detail, 0x00, sizeof(device_info_list_detail));
		device_info_list_detail.cbSize = sizeof(device_info_list_detail);

		if (SetupDiGetDeviceInfoListDetail(devices, &device_info_list_detail))
		{
			std::wcerr << "Got device information list details." << std::endl;

			SP_DEVINFO_DATA device_info;
			device_info.cbSize = sizeof(device_info);

			for (DWORD index = 0; SetupDiEnumDeviceInfo(devices, index, &device_info); ++index)
			{
				TCHAR device_id[MAX_DEVICE_ID_LEN];

				if (CM_Get_Device_ID_Ex(device_info.DevInst, device_id, MAX_DEVICE_ID_LEN, 0, device_info_list_detail.RemoteMachineHandle) == CR_SUCCESS)
				{
					std::list<std::wstring> device_hardware_id_list;

					if (getDeviceProperty(devices, device_info, SPDRP_HARDWAREID, device_hardware_id_list))
					{
						bool match = false;

						for (std::list<std::wstring>::const_iterator device_hardware_id = device_hardware_id_list.begin(); device_hardware_id != device_hardware_id_list.end(); ++device_hardware_id)
						{
							if (*device_hardware_id == hardware_id)
							{
								match = true;

								break;
							}
						}

						if (match)
						{
							std::wstring friendly_name;

							if (getDeviceProperty(devices, device_info, SPDRP_FRIENDLYNAME, friendly_name) && (friendly_name.length() > 0))
							{
								std::wcerr << "Removing device: " << friendly_name << " (" << device_id << ")" << std::endl;
							} else
							{
								std::wcerr << "Removing device: " << device_id << std::endl;
							}

							SP_REMOVEDEVICE_PARAMS remove_device_params;
							remove_device_params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
							remove_device_params.ClassInstallHeader.InstallFunction = DIF_REMOVE;
							remove_device_params.Scope = DI_REMOVEDEVICE_GLOBAL;
							remove_device_params.HwProfile = 0;

							result = true;

							if (!SetupDiSetClassInstallParams(devices, &device_info, &remove_device_params.ClassInstallHeader, sizeof(remove_device_params)) || 
									!SetupDiCallClassInstaller(DIF_REMOVE, devices, &device_info))
							{
								std::wcerr << "Failed to set the class installer." << std::endl;

								result = false;
							}

							if (result)
							{
								reboot_required = false;

								SP_DEVINSTALL_PARAMS device_params;

								if (SetupDiGetDeviceInstallParams(devices, &device_info, &device_params))
								{
									if (device_params.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT))
									{
										reboot_required = true;
									}
								}
							}
						}
					}
				}
			}
		}

		SetupDiDestroyDeviceInfoList(devices);
	}

	return result;
}
Example #6
0
QueryData genDrivers(QueryContext& context) {
  QueryData results;

  auto devInfoset = setupDevInfoSet();
  if (devInfoset == nullptr) {
    win32LogWARNING("Error getting device handle");
    return results;
  }

  std::vector<SP_DEVINFO_DATA> devices;
  auto ret = getDeviceList(devInfoset, devices);
  if (!ret.ok()) {
    win32LogWARNING(ret.getMessage(), ret.getCode());
    return results;
  }

  for (auto& device : devices) {
    char devId[MAX_DEVICE_ID_LEN] = {0};
    if (CM_Get_Device_ID(device.DevInst, devId, MAX_DEVICE_ID_LEN, 0) !=
        CR_SUCCESS) {
      win32LogWARNING("Failed to get device ID");
      return QueryData();
    }

    SP_DRVINFO_DATA drvInfo = {0};
    SP_DRVINFO_DETAIL_DATA drvInfoDetail = {0};
    ret = getDeviceDriverInfo(devInfoset, device, drvInfo, drvInfoDetail);

    Row r;
    r["device_id"] = devId;
    r["inf"] = drvInfoDetail.InfFileName;
    r["provider"] = drvInfo.ProviderName;
    r["manufacturer"] = drvInfo.MfgName;
    r["date"] = std::to_string(osquery::filetimeToUnixtime(drvInfo.DriverDate));
    r["description"] = drvInfo.Description;
    ULARGE_INTEGER version;
    version.QuadPart = drvInfo.DriverVersion;
    r["version"] = std::to_string(HIWORD(version.HighPart)) + "." +
                   std::to_string(HIWORD(version.LowPart)) + "." +
                   std::to_string(LOWORD(version.HighPart)) + "." +
                   std::to_string(LOWORD(version.LowPart));

    for (const auto& elem : kAdditionalDeviceProps) {
      std::string val;
      ret = getDeviceProperty(devInfoset, device, elem.second, val);
      r[elem.first] = std::move(val);
    }

    if (r.count("driver_key") > 0) {
      if (!r.at("driver_key").empty()) {
        r["driver_key"].insert(0, kDriverKeyPath);
      }
    }
    if (r.count("service") > 0) {
      if (!r.at("service").empty()) {
        r["service_key"] = kServiceKeyPath + r["service"];
        r["image"] = getDriverImagePath(r["service_key"]);
      }
    }

    results.push_back(r);
  }

  return results;
}