Exemplo n.º 1
0
UINT DevDir(PCTSTR ptzDir, PCTSTR ptzDevID, PCTSTR ptzClass)
{
	TCHAR tzPath[MAX_NAME];
	if (ptzDir[0] == '\\')
	{
		ptzDir++;
		TCHAR tzDrives[MAX_NAME];
		GetLogicalDriveStrings(MAX_NAME, tzDrives);
		for (PTSTR p = tzDrives; *p; p += UStrLen(p) + 1)
		{
			UStrPrint(tzPath, TEXT("%s%s"), p, ptzDir);
			DevDir(tzPath, ptzDevID, ptzClass);
		}
		return S_OK;
	}

	WIN32_FIND_DATA fd;
	UStrPrint(tzPath, TEXT("%s\\INF\\*.INF"), ptzDir);
	HANDLE hFind = FindFirstFile(tzPath, &fd);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		return ERROR_FILE_NOT_FOUND;
	}

	do
	{
		UStrPrint(tzPath, TEXT("%s\\INF\\%s"), ptzDir, fd.cFileName);
		if (ptzClass)
		{
			GUID idClass;
			TCHAR tzClass[MAX_NAME];
			SetupDiGetINFClass(tzPath, &idClass, tzClass, MAX_NAME, NULL);
			if (UStrCmpI(tzClass, ptzClass))
			{
				continue;
			}
		}
		PCTSTR p = DevGetInf(ptzDevID, tzPath);
		if (p)
		{
			DevIns(p, tzPath, 0);
		}
	}
	while (FindNextFile(hFind, &fd));

	FindClose(hFind);
	return S_OK;
}
Exemplo n.º 2
0
int
InstallRootEnumeratedDriver(
    IN HWND hWnd,
    IN LPTSTR HardwareId,
    IN LPTSTR INFFile
    )
{
    HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
    SP_DEVINFO_DATA DeviceInfoData;
    GUID ClassGUID;
    TCHAR ClassName[MAX_CLASS_NAME_LEN];
    DWORD Err = NO_ERROR;
    BOOL reboot;
    LPTSTR MultiSzHardwareId = NULL;
    DWORD cbMultiSzHardwareId;

    //
    // SPDRP_HARDWAREID needs to be a multi_sz string so allocate a buffer that is
    // two characters more than the HardwareId passed in and use that buffer.
    //
    cbMultiSzHardwareId = (lstrlen(HardwareId) + 2) * sizeof(TCHAR);
    MultiSzHardwareId = malloc(cbMultiSzHardwareId);
    if (!MultiSzHardwareId) {
        MessageBox(hWnd, "Cannot allocate memory", "Error", MB_OK);
        Err = ERROR_NOT_ENOUGH_MEMORY;
        goto clean;
    }
    ZeroMemory(MultiSzHardwareId, cbMultiSzHardwareId);
    StringCbCopy(MultiSzHardwareId, cbMultiSzHardwareId, HardwareId);


    //
    // Use the INF File to extract the Class GUID. 
    //
    if (!SetupDiGetINFClass(INFFile, &ClassGUID, ClassName, sizeof(ClassName), 0)) {
        Err = GetLastError();
        DisplayError(hWnd, TEXT("GetINFClass"));
        DisplayError(hWnd, TEXT(INFFile));
        goto clean;
    }
    
    //
    // Create the container for the to-be-created Device Information Element.
    //
    DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID, 0);
    if(DeviceInfoSet == INVALID_HANDLE_VALUE) {
        Err = GetLastError();
        DisplayError(hWnd, TEXT("CreateDeviceInfoList"));
        goto clean;
    }
    
    // 
    // Now create the element. 
    // Use the Class GUID and Name from the INF file.
    //
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    if (!SetupDiCreateDeviceInfo(DeviceInfoSet,
                                 ClassName,
                                 &ClassGUID,
                                 NULL,
                                 0,
                                 DICD_GENERATE_ID,
                                 &DeviceInfoData)) {
        Err = GetLastError();
        DisplayError(hWnd, TEXT("CreateDeviceInfo"));
        goto clean;
    }
    
    //
    // Add the HardwareID to the Device's HardwareID property.
    //
    if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
                                         &DeviceInfoData,
                                         SPDRP_HARDWAREID,
                                         (LPBYTE)MultiSzHardwareId,
                                         cbMultiSzHardwareId)) {
        Err = GetLastError();
        DisplayError(hWnd, TEXT("SetDeviceRegistryProperty"));
        goto clean;
    }
    
    //
    // Transform the registry element into an actual devnode 
    // in the PnP HW tree.
    //
    if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
                                   DeviceInfoSet,
                                   &DeviceInfoData)) {
        Err = GetLastError();
        DisplayError(hWnd, TEXT("CallClassInstaller(REGISTERDEVICE)"));
        goto clean;
    }
    
    //
    // The element is now registered. We must explicitly remove the 
    // device using DIF_REMOVE, if we encounter any failure from now on.
    //
    
    //
    // Install the Driver.  We don't actually care about @reboot, but
    // supplying it avoids an annoying popup on Windows 2000.
    //
    if (!UpdateDriverForPlugAndPlayDevices(hWnd,
                                           HardwareId,
                                           INFFile,
                                           INSTALLFLAG_FORCE,
                                           &reboot))
    {
        Err = GetLastError();
        DisplayError(hWnd, TEXT("UpdateDriverForPlugAndPlayDevices"));
        
        if (!SetupDiCallClassInstaller(DIF_REMOVE,
                                       DeviceInfoSet,
                                       &DeviceInfoData)) {
            DisplayError(hWnd, TEXT("CallClassInstaller(REMOVE)"));
        }
    }
    
    //
    //  Cleanup.
    //    
clean:
    if (DeviceInfoSet != INVALID_HANDLE_VALUE) {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    }

    if (MultiSzHardwareId) {
        free(MultiSzHardwareId);
    }
    
    if (Err == NO_ERROR) {
        return 0;
    } else {
        return 1;
    }
}
Exemplo n.º 3
0
NDASDI_API
BOOL 
WINAPI 
NdasDiInstallRootEnumeratedDevice(
	IN HWND hwndParent,
	IN LPCTSTR szInfPath, 
	IN LPCTSTR szHardwareId,
	IN DWORD InstallFlags,
	IN LPBOOL pbRebootRequired OPTIONAL)
{
	_ASSERTE(NULL == pbRebootRequired || !IsBadWritePtr(pbRebootRequired, sizeof(BOOL)));

	BOOL fReturn = FALSE;
	BOOL fSuccess = FALSE;

    DWORD len;

    SP_DEVINFO_DATA DeviceInfoData;
    GUID ClassGuid;
    TCHAR ClassName[MAX_CLASS_NAME_LEN];
	
	LPTSTR lpszFullInfPath = ResolveFullPath(szInfPath, NULL, NULL, 0);
	if (NULL == lpszFullInfPath) {
		goto cleanup;
	}

    //
    // List of hardware ID's must be double zero-terminated
    //
    TCHAR hardwareIdList[LINE_LEN+4] = {0};
	size_t cchHardwareIdList = RTL_NUMBER_OF(hardwareIdList);
	size_t cchRemaining = cchHardwareIdList;
	
	HRESULT hr = StringCchCopyNEx(
		hardwareIdList, 
		LINE_LEN + 4, 
		szHardwareId, 
		LINE_LEN,
		NULL,
		&cchRemaining,
		STRSAFE_FILL_BEHIND_NULL);

	_ASSERTE(SUCCEEDED(hr));

	cchHardwareIdList -= cchRemaining - 1;

    //
    // Use the INF File to extract the Class GUID.
    //
    fSuccess = SetupDiGetINFClass(
		lpszFullInfPath,
		&ClassGuid,
		ClassName,
		RTL_NUMBER_OF(ClassName),
		NULL);

	if (!fSuccess) {
		goto cleanup;
	}
	
    //
    // Create the container for the to-be-created Device Information Element.
    //
    HDEVINFO DeviceInfoSet = SetupDiCreateDeviceInfoList(
		&ClassGuid,
		hwndParent);

    if(INVALID_HANDLE_VALUE == DeviceInfoSet) {
		goto cleanup;
    }

    //
    // Now create the element.
    // Use the Class GUID and Name from the INF file.
    //
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    fSuccess = SetupDiCreateDeviceInfo(
		DeviceInfoSet,
        ClassName,
        &ClassGuid,
        NULL,
        hwndParent,
        DICD_GENERATE_ID,
        &DeviceInfoData);

	if (!fSuccess) {
		goto cleanup;
	}

    //
    // Add the HardwareID to the Device's HardwareID property.
    //
    fSuccess = SetupDiSetDeviceRegistryProperty(
		DeviceInfoSet,
        &DeviceInfoData,
        SPDRP_HARDWAREID,
        (LPBYTE)hardwareIdList,
        cchHardwareIdList * sizeof(TCHAR));
	
	if (!fSuccess) {
		goto cleanup;
	}

    //
    // Transform the registry element into an actual devnode
    // in the PnP HW tree.
    //
	fSuccess = SetupDiCallClassInstaller(
		DIF_REGISTERDEVICE,
        DeviceInfoSet,
        &DeviceInfoData);
	
	if (!fSuccess) {
		goto cleanup;
	}

	//
	// The element is now registered.
	// You must explicitly remove the device using DIF_REMOVE,
	// if any failure is encountered from now on.
	//

	//
    // update the driver for the device we just created
    //

	fSuccess = UpdateDriverForPlugAndPlayDevices(
		hwndParent,
		szHardwareId,
		lpszFullInfPath,
		InstallFlags,
		pbRebootRequired);

	if (!fSuccess) {
		DWORD err = GetLastError();
		fSuccess = SetupDiCallClassInstaller(
			DIF_REMOVE,
			DeviceInfoSet,
			&DeviceInfoData);
		//
		// BUGBUG: If it may still require reboot?
		//
		SetLastError(err);
		goto cleanup;
	}

	fReturn = TRUE;
	
cleanup:

	// save the last error
	DWORD err = GetLastError();

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

	if (NULL != lpszFullInfPath) {
		LocalFree(lpszFullInfPath);
	}

	// restore the last error
	SetLastError(err);

	return fReturn;
}
Exemplo n.º 4
0
static int TryInstallDevice(
    const char *pInfFilePath,
    const char *pDevId,
    const char *pDevInstID,
    PCNC_DEV_CALLBACK pDevCallBack,
    void *pDevCallBackParam,
    bool updateDriver,
    BOOL *pRebootRequired)
{
  GUID classGUID;
  char className[32];

  if (!SetupDiGetINFClass(pInfFilePath, &classGUID, className, sizeof(className)/sizeof(className[0]), 0)) {
    ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiGetINFClass(%s)", pInfFilePath);
    return IDCANCEL;
  }

  //Trace("className=%s\n", className);

  HDEVINFO hDevInfo;

  hDevInfo = SetupDiCreateDeviceInfoList(&classGUID, 0);

  if (hDevInfo == INVALID_HANDLE_VALUE) {
    ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiCreateDeviceInfoList()");
    return IDCANCEL;
  }

  int res = IDCONTINUE;
  SP_DEVINFO_DATA devInfoData;

  devInfoData.cbSize = sizeof(devInfoData);

  if (!pDevInstID) {
    if (StrCmpNI(pDevId, "root\\", 5) == 0) {
      /*
       * root\<enumerator-specific-device-ID>
       */

      if (!SetupDiCreateDeviceInfo(hDevInfo, pDevId + 5, &classGUID, NULL, 0, DICD_GENERATE_ID, &devInfoData))
        res = IDCANCEL;
    } else {
      SetLastError(ERROR_INVALID_DEVINST_NAME);
      res = IDCANCEL;
    }
  }
  else
  if (StrChr(pDevInstID, '\\')) {
    /*
     * <enumerator>\<enumerator-specific-device-ID>\<instance-specific-ID>
     */

    if (!SetupDiCreateDeviceInfo(hDevInfo, pDevInstID, &classGUID, NULL, 0, 0, &devInfoData))
      res = IDCANCEL;

    if (res != IDCONTINUE && GetLastError() == ERROR_DEVINST_ALREADY_EXISTS) {
      char *pTmpDevInstID = NULL;

      if (SetStr(&pTmpDevInstID, pDevInstID)) {
        char *pSave;
        char *p;

        p = STRTOK_R(pTmpDevInstID, "\\", &pSave);

        if (p && !lstrcmp(p, REGSTR_KEY_ROOTENUM)) {
          p = STRTOK_R(NULL, "\\", &pSave);

          if (SetupDiCreateDeviceInfo(hDevInfo, p, &classGUID, NULL, 0, DICD_GENERATE_ID, &devInfoData))
            res = IDCONTINUE;
        }

        SetStr(&pTmpDevInstID, NULL);
      } else {
        SetLastError(ERROR_DEVINST_ALREADY_EXISTS);
      }
    }
  } else {
    /*
     * <enumerator-specific-device-ID>
     */

    if (!SetupDiCreateDeviceInfo(hDevInfo, pDevInstID, &classGUID, NULL, 0, DICD_GENERATE_ID, &devInfoData))
      res = IDCANCEL;
  }

  if (res != IDCONTINUE) {
    ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiCreateDeviceInfo()");
    goto exit1;
  }

  char hardwareId[MAX_DEVICE_ID_LEN + 1 + 1];

  SNPRINTF(hardwareId, sizeof(hardwareId)/sizeof(hardwareId[0]) - 1, "%s", pDevId);

  int hardwareIdLen;

  hardwareIdLen = lstrlen(hardwareId) + 1 + 1;
  hardwareId[hardwareIdLen - 1] = 0;

  if (!SetupDiSetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_HARDWAREID,
                                        (LPBYTE)hardwareId, hardwareIdLen * sizeof(hardwareId[0])))
  {
    res = IDCANCEL;
    ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiSetDeviceRegistryProperty()");
    goto exit1;
  }

  if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDevInfo, &devInfoData)) {
    res = IDCANCEL;
    ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiCallClassInstaller()");
    goto exit1;
  }

  if (pDevCallBack) {
    DevProperties devProperties;

    if (!devProperties.DevId(pDevId)) {
      res = IDCANCEL;
      goto exit2;
    }

    if (!pDevCallBack(hDevInfo, &devInfoData, &devProperties, NULL, pDevCallBackParam)) {
      res = IDCANCEL;
      goto exit2;
    }
  }

  if (updateDriver)
    res = UpdateDriver(pInfFilePath, pDevId, 0, TRUE, pRebootRequired);

exit2:

  if (res != IDCONTINUE) {
    if (!SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, &devInfoData))
      ShowLastError(MB_OK|MB_ICONWARNING, "SetupDiCallClassInstaller()");
  }

exit1:

  SetupDiDestroyDeviceInfoList(hDevInfo);

  return res;
}
Exemplo n.º 5
0
bool install(const std::wstring& inf, const std::wstring& hardware_id, bool& reboot_required)
{
	TCHAR inf_path[MAX_PATH];

	if (GetFullPathName(inf.c_str(), MAX_PATH, inf_path, NULL) >= MAX_PATH)
	{
		return false;
	}

	std::wcerr << "INF file full path: " << inf_path << std::endl;

	bool result = false;

	TCHAR hardware_id_list[LINE_LEN + 4];
	ZeroMemory(hardware_id_list, sizeof(hardware_id_list));

	if (SUCCEEDED(StringCchCopy(hardware_id_list, LINE_LEN, hardware_id.c_str())))
	{
		std::wcerr << "Hardware identifier list: " << hardware_id_list << std::endl;

		GUID class_guid;
		TCHAR class_name[MAX_CLASS_NAME_LEN];

		if (SetupDiGetINFClass(inf_path, &class_guid, class_name, sizeof(class_name) / sizeof(class_name[0]), 0))
		{
			std::wcerr << "Class name: " << class_name << std::endl;

			HDEVINFO device_info_set = INVALID_HANDLE_VALUE;

			device_info_set = SetupDiCreateDeviceInfoList(&class_guid, 0);

			if (device_info_set != INVALID_HANDLE_VALUE)
			{
				std::wcerr << "Device information set created." << std::endl;

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

				if (SetupDiCreateDeviceInfo(device_info_set,
							class_name,
							&class_guid,
							NULL,
							0,
							DICD_GENERATE_ID,
							&device_info_data))
				{
					std::wcerr << "Device information element created." << std::endl;

					if (SetupDiSetDeviceRegistryProperty(device_info_set,
								&device_info_data,
								SPDRP_HARDWAREID,
								(LPBYTE)hardware_id_list,
								(lstrlen(hardware_id_list) + 1 + 1) * sizeof(TCHAR)))
					{
						std::wcerr << "Hardware id set." << std::endl;

						if (SetupDiCallClassInstaller(DIF_REGISTERDEVICE, device_info_set, &device_info_data))
						{
							std::wcerr << "Device registered." << std::endl;

							result = update(inf, hardware_id, reboot_required);
						}
					}
				}

				SetupDiDestroyDeviceInfoList(device_info_set);
			}
		}
	}

	return result;
}
Exemplo n.º 6
0
int InstallInf(_TCHAR *inf)
{
	GUID ClassGUID;
	TCHAR ClassName[256];
	HDEVINFO DeviceInfoSet = 0;
	SP_DEVINFO_DATA DeviceInfoData;
	TCHAR FullFilePath[1024];
	PUpdateDriverForPlugAndPlayDevices pfnUpdateDriverForPlugAndPlayDevices;
	HMODULE hNewDev = NULL;
	DWORD Reboot;
	HWND hwnd = NULL;
	int ret = -1;

	if (!GetFullPathName(inf, sizeof(FullFilePath), FullFilePath, NULL)) {
		logError("GetFullPathName: %x\n", GetLastError());
		return ret;
	}
	logInfo("Inf file: %s\n", FullFilePath);

	hNewDev = LoadLibrary(_T("newdev.dll"));
	if (!hNewDev) {
		logError("newdev.dll: %x\n", GetLastError());
		return ret;
	}

	pfnUpdateDriverForPlugAndPlayDevices = (PUpdateDriverForPlugAndPlayDevices)
									GetProcAddress(hNewDev, (LPCSTR)"UpdateDriverForPlugAndPlayDevicesA");
	if (!pfnUpdateDriverForPlugAndPlayDevices) {
		logError("UpdateDriverForPlugAndPlayDevices: %x\n", GetLastError());
		goto FreeLib;
	}
 
	if (!SetupDiGetINFClass(FullFilePath, &ClassGUID, ClassName, sizeof(ClassName), 0)) {
		logError("SetupDiGetINFClass: %x\n", GetLastError());
		goto FreeLib;
	}
#if 0
	logPrint("{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}\n",
			ClassGUID.Data1, ClassGUID.Data2, ClassGUID.Data3, ClassGUID.Data4[0],
			ClassGUID.Data4[1], ClassGUID.Data4[2], ClassGUID.Data4[3], ClassGUID.Data4[4],
			ClassGUID.Data4[5], ClassGUID.Data4[6], ClassGUID.Data4[7]);
#endif

	if ((DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0)) == INVALID_HANDLE_VALUE) {
		logError("SetupDiCreateDeviceInfoList: %x\n", GetLastError());
		goto FreeLib;
	}
	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	if (!SetupDiCreateDeviceInfo(DeviceInfoSet,
								ClassName,
								&ClassGUID,
								NULL,
								0,
								DICD_GENERATE_ID,
								&DeviceInfoData)) {
		logError("SetupDiCreateDeviceInfo: %x\n", GetLastError());
		goto SetupDiCreateDeviceInfoListError;
	}

	if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, 
										(LPBYTE)DRIVER_NAME,
										(lstrlen(DRIVER_NAME)+2))) {
		logError("SetupDiSetDeviceRegistryProperty: %x\n", GetLastError());
		goto SetupDiCreateDeviceInfoListError;
	}
	if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData)) {
		logError("SetupDiCallClassInstaller: %x\n", GetLastError());
		goto SetupDiCreateDeviceInfoListError;
	}
    ret = pfnUpdateDriverForPlugAndPlayDevices(NULL, DRIVER_NAME, FullFilePath, 0, &Reboot);
	if (Reboot == DI_NEEDRESTART || Reboot == DI_NEEDREBOOT) {
		if (SetupPromptReboot(NULL, hwnd, FALSE) == -1) {
			; // ToDo ??
		}
	}
	ret = 0;

SetupDiCreateDeviceInfoListError:
	SetupDiDestroyDeviceInfoList(DeviceInfoSet);
FreeLib:
	FreeLibrary(hNewDev);
	return ret;
}
Exemplo n.º 7
0
DWORD
InstallSoftwareBusPnpEnumerator(LPWSTR InfPath, LPCWSTR HardwareIdList)
{
    HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
    SP_DEVINFO_DATA DeviceInfoData;
    GUID ClassGUID;
    TCHAR ClassName[50];
    int Result = 0;
    HMODULE hModule = NULL;
    UpdateDriverForPlugAndPlayDevicesProto UpdateProc;
    BOOL reboot = FALSE;
    DWORD flags = 0;

    if (!SetupDiGetINFClass(InfPath,&ClassGUID,ClassName,sizeof(ClassName)/sizeof(ClassName[0]),0))
    {
        return -1;
    }

    DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0);
    if(DeviceInfoSet == INVALID_HANDLE_VALUE)
    {
        return -1;
    }

    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    if (!SetupDiCreateDeviceInfo(DeviceInfoSet, ClassName, &ClassGUID, NULL, 0, DICD_GENERATE_ID, &DeviceInfoData))
    {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        return -1;
    }

    if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)HardwareIdList, (lstrlen(HardwareIdList)+1+1)*sizeof(TCHAR)))
    {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        return -1;
    }

    if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData))
    {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        return -1;
    }

    if(GetFileAttributes(InfPath)==(DWORD)(-1)) {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        return -1;
    }

    flags |= INSTALLFLAG_FORCE;
    hModule = LoadLibraryW(L"newdev.dll");
    if(!hModule) {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        return -1;
    }

    UpdateProc = (UpdateDriverForPlugAndPlayDevicesProto)GetProcAddress(hModule,UPDATEDRIVERFORPLUGANDPLAYDEVICES);
    if(!UpdateProc)
    {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        FreeLibrary(hModule);
        return -1;
    }

    if(!UpdateProc(NULL, HardwareIdList, InfPath, flags, &reboot))
    {
        SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        FreeLibrary(hModule);
        return -1;
    }

    FreeLibrary(hModule);
    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    return Result;
}