Beispiel #1
0
Status getDeviceDriverInfo(const device_infoset_t& infoset,
                           SP_DEVINFO_DATA& device,
                           SP_DRVINFO_DATA& rDriverInfo,
                           SP_DRVINFO_DETAIL_DATA& rDriverInfoDetail) {
  rDriverInfo.cbSize = sizeof(SP_DRVINFO_DATA);
  rDriverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);

  auto ret =
      SetupDiBuildDriverInfoList(infoset.get(), &device, SPDIT_CLASSDRIVER);
  if (ret == FALSE) {
    return Status(GetLastError(), "Error building driver info list");
  }

  ret = SetupDiEnumDriverInfo(
      infoset.get(), &device, SPDIT_CLASSDRIVER, 0, &rDriverInfo);
  if (ret == FALSE) {
    return Status(GetLastError(), "Error enumerating driver info");
  }

  ret = SetupDiGetDriverInfoDetail(infoset.get(),
                                   &device,
                                   &rDriverInfo,
                                   &rDriverInfoDetail,
                                   sizeof(SP_DRVINFO_DETAIL_DATA),
                                   nullptr);
  if (ret == FALSE) {
    auto err = GetLastError();
    // It's common to get INSUFFICIENT_BUFFER for some variable length fields in
    // SP_DRVINFO_DETAIL_DATA, but we don't care about this info so ignore it
    if (err != ERROR_INSUFFICIENT_BUFFER) {
      return Status(err, "Error getting detailed driver info");
    }
  }
  return Status();
}
/**
 * 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;
}
extern "C" DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask)
{
    BOOL ok;
    DWORD ret = 0;
    GUID netGuid;
    HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
    SP_DEVINFO_DATA DeviceInfoData;
    SP_DRVINFO_DATA DriverInfoData;
    SP_DEVINSTALL_PARAMS  DeviceInstallParams;
    TCHAR className[MAX_PATH];
    TCHAR temp[MAX_PATH];
    DWORD index = 0;
    BOOL found = FALSE;
    BOOL registered = FALSE;
    BOOL destroyList = FALSE;
    PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail;
    DWORD detailBuf[2048];    // for our purposes, 8k buffer is more
			      // than enough to obtain the hardware ID
			      // of the loopback driver.

    HKEY hkey = NULL;
    DWORD cbSize;
    DWORD dwValueType;
    TCHAR pCfgGuidString[40];

    // initialize the structure size
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);

    // copy the net class GUID
    memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET));

    // create an empty device info set associated with the net class GUID
    hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL);
    if (hDeviceInfo == INVALID_HANDLE_VALUE)
        return GetLastError();

    // get the class name from GUID
    ok = SetupDiClassNameFromGuid(&netGuid, className, MAX_PATH, NULL);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    // create a device info element and add the new device instance
    // key to registry
    ok = SetupDiCreateDeviceInfo(hDeviceInfo, className, &netGuid, NULL, NULL,
                                 DICD_GENERATE_ID, &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    // select the newly created device info to be the currently
    // selected member
    ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    // build a list of class drivers
    ok = SetupDiBuildDriverInfoList(hDeviceInfo, &DeviceInfoData,
                                    SPDIT_CLASSDRIVER);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    destroyList = TRUE;

    // enumerate the driver info list
    while (TRUE)
    {
        BOOL ret;

	ret = SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData,
				  SPDIT_CLASSDRIVER, index, &DriverInfoData);

	// if the function failed and GetLastError() returned
	// ERROR_NO_MORE_ITEMS, then we have reached the end of the
	// list.  Othewise there was something wrong with this
	// particular driver.
	if(!ret) {
	  if(GetLastError() == ERROR_NO_MORE_ITEMS)
	    break;
	  else {
	    index++;
	    continue;
	  }
	}

	pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf;
	pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);

	// if we successfully find the hardware ID and it turns out to
	// be the one for the loopback driver, then we are done.
	if (SetupDiGetDriverInfoDetail(hDeviceInfo,
				      &DeviceInfoData,
				      &DriverInfoData,
				      pDriverInfoDetail,
				      sizeof(detailBuf),
				      NULL)) {
            TCHAR * t;

	    // pDriverInfoDetail->HardwareID is a MULTISZ string.  Go through the
	    // whole list and see if there is a match somewhere.
	    t = pDriverInfoDetail->HardwareID;
	    while (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) {
	      if (!_tcsicmp(t, DRIVERHWID))
		break;

	      t += _tcslen(t) + 1;
	    }

	    if (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) {
	      found = TRUE;
	      break;
	    }
	}

        index++;
    }

    if (!found)
    {
        ret = GetLastError();
        ReportMessage(0,"Could not find the driver to install", DRIVER_DESC, NULL, 0);
        goto cleanup;
    }

    // set the loopback driver to be the currently selected
    ok = SetupDiSetSelectedDriver(hDeviceInfo, &DeviceInfoData,
                                  &DriverInfoData);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    // register the phantom device to repare for install
    ok = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDeviceInfo,
                                   &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    // registered, but remove if errors occur in the following code
    registered = TRUE;

    // ask the installer if we can install the device
    ok = SetupDiCallClassInstaller(DIF_ALLOW_INSTALL, hDeviceInfo,
                                   &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        if (ret != ERROR_DI_DO_DEFAULT)
        {
            goto cleanup;
        }
        else
            ret = 0;
    }

    // install the files first
    ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDeviceInfo,
                                   &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    // get the device install parameters and disable filecopy
    DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
    ok = SetupDiGetDeviceInstallParams(hDeviceInfo, &DeviceInfoData,
                                       &DeviceInstallParams);
    if (ok)
    {
        DeviceInstallParams.Flags |= DI_NOFILECOPY;
        ok = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData,
                                           &DeviceInstallParams);
        if (!ok)
        {
            ret = GetLastError();
            goto cleanup;
        }
    }

    //
    // Register any device-specific co-installers for this device,
    //

    ok = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS,
                                   hDeviceInfo,
                                   &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }

    //
    // install any  installer-specified interfaces.
    // and then do the real install
    //
    ok = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES,
                                   hDeviceInfo,
                                   &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        goto cleanup;
    }
    PAUSE;
    ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICE,
                                   hDeviceInfo,
                                   &DeviceInfoData);
    if (!ok)
    {
        ret = GetLastError();
        PAUSE;
        goto cleanup;
    }

    /* Skip to the end if we aren't setting the name */
    if (!pConnectionName) goto cleanup;

    // Figure out NetCfgInstanceId
    hkey = SetupDiOpenDevRegKey(hDeviceInfo,
                                &DeviceInfoData,
                                DICS_FLAG_GLOBAL,
                                0,
                                DIREG_DRV,
                                KEY_READ);
    if (hkey == INVALID_HANDLE_VALUE)
    {
        ret = GetLastError();
        goto cleanup;
    }

    cbSize = sizeof(pCfgGuidString);
    ret = RegQueryValueEx(hkey, _T("NetCfgInstanceId"), NULL,
                          &dwValueType, (LPBYTE)pCfgGuidString, &cbSize);
    RegCloseKey(hkey);

    ret = RenameConnection(pCfgGuidString, pConnectionName);
    if (ret)
    {
        ReportMessage(0,"Could not set the connection name", NULL, pConnectionName, 0);
        goto cleanup;
    }

    if (!ip) goto cleanup;
    ret = SetIpAddress(pCfgGuidString, ip, mask);
    if (ret)
    {
        ReportMessage(0,"Could not set the ip address and network mask",NULL,NULL,ret);
        goto cleanup;
    }
    ret = LoopbackBindings(pCfgGuidString);
    if (ret)
    {
        ReportMessage(0,"Could not properly set the bindings",NULL,NULL,0);
        goto cleanup;
    }
    ret = !UpdateHostsFile( pConnectionName, ip, "hosts", FALSE );
    if (ret)
    {
        ReportMessage(0,"Could not update hosts file",NULL,NULL,0);
        goto cleanup;
    }
    ret = !UpdateHostsFile( pConnectionName, ip, "lmhosts", TRUE );
    if (ret)
    {
        ReportMessage(0,"Could not update lmhosts file",NULL,NULL,0);
        goto cleanup;
    }


cleanup:
    // an error has occured, but the device is registered, we must remove it
    if (ret != 0 && registered)
        SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);

    found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData);

    // destroy the driver info list
    if (destroyList)
        SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData,
                                     SPDIT_CLASSDRIVER);
    // clean up the device info set
    if (hDeviceInfo != INVALID_HANDLE_VALUE)
        SetupDiDestroyDeviceInfoList(hDeviceInfo);

    return ret;
};
Beispiel #4
0
static HRESULT vboxDrvCfgCollectInfsSetupDi(const GUID * pGuid, LPCWSTR pPnPId, VBoxDrvCfgStringList & list)
{
    DWORD dwErr = ERROR_SUCCESS;
    int counter = 0;
    HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(
                            pGuid, /* IN LPGUID ClassGuid, OPTIONAL */
                            NULL /*IN HWND hwndParent OPTIONAL */
                            );
    if (hDevInfo != INVALID_HANDLE_VALUE)
    {
        if (SetupDiBuildDriverInfoList(hDevInfo,
                    NULL, /*IN OUT PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
                    SPDIT_CLASSDRIVER  /*IN DWORD DriverType*/
                    ))
        {
            SP_DRVINFO_DATA DrvInfo;
            DrvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
            char DetailBuf[16384];
            PSP_DRVINFO_DETAIL_DATA pDrvDetail = (PSP_DRVINFO_DETAIL_DATA)DetailBuf;

            for (DWORD i = 0; ; i++)
            {
                if (SetupDiEnumDriverInfo(hDevInfo,
                        NULL, /* IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
                        SPDIT_CLASSDRIVER , /*IN DWORD DriverType,*/
                        i, /*IN DWORD MemberIndex,*/
                        &DrvInfo /*OUT PSP_DRVINFO_DATA DriverInfoData*/
                        ))
                {
                    DWORD dwReq;
                    pDrvDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
                    if (SetupDiGetDriverInfoDetail(
                            hDevInfo, /*IN HDEVINFO DeviceInfoSet,*/
                            NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
                            &DrvInfo, /*IN PSP_DRVINFO_DATA DriverInfoData,*/
                            pDrvDetail, /*OUT PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData, OPTIONAL*/
                            sizeof(DetailBuf), /*IN DWORD DriverInfoDetailDataSize,*/
                            &dwReq /*OUT PDWORD RequiredSize OPTIONAL*/
                            ))
                    {
                        for (WCHAR * pHwId = pDrvDetail->HardwareID; pHwId && *pHwId && pHwId < (TCHAR*)(DetailBuf + sizeof(DetailBuf)/sizeof(DetailBuf[0])) ;pHwId += wcslen(pHwId) + 1)
                        {
                            if (!wcsicmp(pHwId, pPnPId))
                            {
                                NonStandardAssert(pDrvDetail->InfFileName[0]);
                                if (pDrvDetail->InfFileName)
                                {
                                    list.add(pDrvDetail->InfFileName);
                                }
                            }
                        }
                    }
                    else
                    {
                        DWORD dwErr = GetLastError();
                        NonStandardLogRelCrap((__FUNCTION__": SetupDiGetDriverInfoDetail fail dwErr=%ld, size(%d)", dwErr, dwReq));
//                        NonStandardAssert(0);
                    }

                }
                else
                {
                    DWORD dwErr = GetLastError();
                    if (dwErr == ERROR_NO_MORE_ITEMS)
                    {
                        break;
                    }

                    NonStandardAssert(0);
                }
            }

            SetupDiDestroyDriverInfoList(hDevInfo,
                      NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
                      SPDIT_CLASSDRIVER/*IN DWORD DriverType*/
                      );
        }
        else
        {
            dwErr = GetLastError();
            NonStandardAssert(0);
        }

        SetupDiDestroyDeviceInfoList(hDevInfo);
    }
    else
    {
        dwErr = GetLastError();
        NonStandardAssert(0);
    }

    return HRESULT_FROM_WIN32(dwErr);
}
Beispiel #5
0
BOOL FindCurrentDriver(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo, _In_ PSP_DRVINFO_DATA DriverInfoData)
/*++

Routine Description:

    Find the driver that is associated with the current device
    We can do this either the quick way (available in WinXP)
    or the long way that works in Win2k.

Arguments:

    Devs    )_ uniquely identify device
    DevInfo )

Return Value:

    TRUE if we managed to determine and select current driver

--*/
{
    SP_DEVINSTALL_PARAMS deviceInstallParams;
    WCHAR SectionName[LINE_LEN];
    WCHAR DrvDescription[LINE_LEN];
    WCHAR MfgName[LINE_LEN];
    WCHAR ProviderName[LINE_LEN];
    HKEY hKey = NULL;
    DWORD RegDataLength;
    DWORD RegDataType;
    DWORD c;
    BOOL match = FALSE;
    long regerr;

    ZeroMemory(&deviceInstallParams, sizeof(deviceInstallParams));
    deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);

    if(!SetupDiGetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams)) {
        return FALSE;
    }

#ifdef DI_FLAGSEX_INSTALLEDDRIVER
    //
    // Set the flags that tell SetupDiBuildDriverInfoList to just put the
    // currently installed driver node in the list, and that it should allow
    // excluded drivers. This flag introduced in WinXP.
    //
    deviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);

    if(SetupDiSetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams)) {
        //
        // we were able to specify this flag, so proceed the easy way
        // we should get a list of no more than 1 driver
        //
        if(!SetupDiBuildDriverInfoList(Devs, DevInfo, SPDIT_CLASSDRIVER)) {
            return FALSE;
        }
        if (!SetupDiEnumDriverInfo(Devs, DevInfo, SPDIT_CLASSDRIVER,
                                   0, DriverInfoData)) {
            return FALSE;
        }
        //
        // we've selected the current driver
        //
        return TRUE;
    }
    deviceInstallParams.FlagsEx &= ~(DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
#endif
    //
    // The following method works in Win2k, but it's slow and painful.
    //
    // First, get driver key - if it doesn't exist, no driver
    //
    hKey = SetupDiOpenDevRegKey(Devs,
                                DevInfo,
                                DICS_FLAG_GLOBAL,
                                0,
                                DIREG_DRV,
                                KEY_READ
                               );

    if(hKey == INVALID_HANDLE_VALUE) {
        //
        // no such value exists, so there can't be an associated driver
        //
        RegCloseKey(hKey);
        return FALSE;
    }

    //
    // obtain path of INF - we'll do a search on this specific INF
    //
    RegDataLength = sizeof(deviceInstallParams.DriverPath); // bytes!!!
    regerr = RegQueryValueEx(hKey,
                             REGSTR_VAL_INFPATH,
                             NULL,
                             &RegDataType,
                             (PBYTE)deviceInstallParams.DriverPath,
                             &RegDataLength
                             );

    if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) {
        //
        // no such value exists, so no associated driver
        //
        RegCloseKey(hKey);
        return FALSE;
    }

    //
    // obtain name of Provider to fill into DriverInfoData
    //
    RegDataLength = sizeof(ProviderName); // bytes!!!
    regerr = RegQueryValueEx(hKey,
                             REGSTR_VAL_PROVIDER_NAME,
                             NULL,
                             &RegDataType,
                             (PBYTE)ProviderName,
                             &RegDataLength
                             );

    if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) {
        //
        // no such value exists, so we don't have a valid associated driver
        //
        RegCloseKey(hKey);
        return FALSE;
    }

    //
    // obtain name of section - for final verification
    //
    RegDataLength = sizeof(SectionName); // bytes!!!
    regerr = RegQueryValueEx(hKey,
                             REGSTR_VAL_INFSECTION,
                             NULL,
                             &RegDataType,
                             (PBYTE)SectionName,
                             &RegDataLength
                             );

    if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) {
        //
        // no such value exists, so we don't have a valid associated driver
        //
        RegCloseKey(hKey);
        return FALSE;
    }

    //
    // driver description (need not be same as device description)
    // - for final verification
    //
    RegDataLength = sizeof(DrvDescription); // bytes!!!
    regerr = RegQueryValueEx(hKey,
                             REGSTR_VAL_DRVDESC,
                             NULL,
                             &RegDataType,
                             (PBYTE)DrvDescription,
                             &RegDataLength
                             );

    RegCloseKey(hKey);

    if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) {
        //
        // no such value exists, so we don't have a valid associated driver
        //
        return FALSE;
    }

    //
    // Manufacturer (via SPDRP_MFG, don't access registry directly!)
    //

    if(!SetupDiGetDeviceRegistryProperty(Devs,
                                        DevInfo,
                                        SPDRP_MFG,
                                        NULL,      // datatype is guaranteed to always be REG_SZ.
                                        (PBYTE)MfgName,
                                        sizeof(MfgName), // bytes!!!
                                        NULL)) {
        //
        // no such value exists, so we don't have a valid associated driver
        //
        return FALSE;
    }

    //
    // now search for drivers listed in the INF
    //
    //
    deviceInstallParams.Flags |= DI_ENUMSINGLEINF;
    deviceInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;

    if(!SetupDiSetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams)) {
        return FALSE;
    }
    if(!SetupDiBuildDriverInfoList(Devs, DevInfo, SPDIT_CLASSDRIVER)) {
        return FALSE;
    }

    //
    // find the entry in the INF that was used to install the driver for
    // this device
    //
    for(c=0;SetupDiEnumDriverInfo(Devs,DevInfo,SPDIT_CLASSDRIVER,c,DriverInfoData);c++) {
        if((_tcscmp(DriverInfoData->MfgName,MfgName)==0)
            &&(_tcscmp(DriverInfoData->ProviderName,ProviderName)==0)) {
            //
            // these two fields match, try more detailed info
            // to ensure we have the exact driver entry used
            //
            SP_DRVINFO_DETAIL_DATA detail;
            detail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
            if(!SetupDiGetDriverInfoDetail(Devs,DevInfo,DriverInfoData,&detail,sizeof(detail),NULL)
                    && (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
                continue;
            }
            if((_tcscmp(detail.SectionName,SectionName)==0) &&
                (_tcscmp(detail.DrvDescription,DrvDescription)==0)) {
                match = TRUE;
                break;
            }
        }
    }
    if(!match) {
        SetupDiDestroyDriverInfoList(Devs,DevInfo,SPDIT_CLASSDRIVER);
    }
    return match;
}
int uninstallCMUDriver()
{
    GUID guid = t1394CmdrGetGUID();
    HDEVINFO hDI = SetupDiGetClassDevs(&guid,NULL,NULL,DIGCF_DEVICEINTERFACE);
    if(hDI != INVALID_HANDLE_VALUE)
    {
        SP_DEVINFO_DATA devInfoData;
        int index = 0;
        devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
        while(SetupDiEnumDeviceInfo(hDI,index,&devInfoData))
        {
            printf(" - Device %d:\n",index);
            if(index == 0)
            {
                // look for OEM inf files
                if(SetupDiBuildDriverInfoList(hDI,&devInfoData,SPDIT_COMPATDRIVER))
                {
                    SP_DRVINFO_DATA drvInfoData;
                    drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
                    int driverIndex = 0;
                    while(SetupDiEnumDriverInfo(hDI,&devInfoData,SPDIT_COMPATDRIVER,driverIndex++,&drvInfoData))
                    {
                        SP_DRVINFO_DETAIL_DATA drvInfoDetail;
                        drvInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
                        BOOL ret = SetupDiGetDriverInfoDetail(hDI,&devInfoData,&drvInfoData,&drvInfoDetail,drvInfoDetail.cbSize,NULL);
                        if(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER)
                        {
                            printf("    - has OEM inf file '%s'\n",drvInfoDetail.InfFileName);
                            if(!DeleteFile(drvInfoDetail.InfFileName))
                            {
                                printf("      - could not delete '%s' : %d",drvInfoDetail.InfFileName,GetLastError());
                            }
                            drvInfoDetail.InfFileName[lstrlen(drvInfoDetail.InfFileName) - 3] = 'p';
                            if(!DeleteFile(drvInfoDetail.InfFileName))
                            {
                                printf("      - could not delete '%s' : %d",drvInfoDetail.InfFileName,GetLastError());
                            }
                        } else {
                            printf("    - SetupDiGetDriverInfoDetail: %d\n",GetLastError());
                        }
                    }
                
                    if(GetLastError() != ERROR_NO_MORE_ITEMS)
                    {
                        printf("    - SetupDiEnumDriverInfo: %d\n",GetLastError());
                    }

                    SetupDiDestroyDriverInfoList(hDI,&devInfoData,SPDIT_COMPATDRIVER);
                } else {
                    printf("    - SetupDiEnumDriverInfo: %d\n",GetLastError());
                }
            } // else already nuked oem inf files

            if(SetupDiCallClassInstaller(DIF_REMOVE,hDI,&devInfoData))
            {
                printf("    - has been removed!\n");
            } else {
                printf("    - could not be removed: %d\n",GetLastError());
            }

            index++;
        }

		if(index == 0)
		{
			printf("No Devices Found!\n");
		}

        SetupDiDestroyDeviceInfoList(hDI);
    } else {
        printf("Failed to get class devs!\n");
    }
	return 0;
}
Beispiel #7
0
//////////////////////////// 
// FETCH    USB     DRIVER      VERSION
void windozeHelpers::FetchUsbDriverVersion( const uint16_t DeviceNum, std::string & version )
{
    HDEVINFO deviceInfo = 0;
    SP_DEVICE_INTERFACE_DATA interfaceData;

     std::string msg;

    if( !EnumerateDevice( DeviceNum, deviceInfo, interfaceData, msg ) )
    {
        apgHelper::throwRuntimeException( __FILE__, msg, __LINE__, Apg::ErrorType_Connection );
    }

    
    SP_DEVINFO_DATA deviceData;
    deviceData.cbSize = sizeof(SP_DEVINFO_DATA);
    if( !SetupDiEnumDeviceInfo( deviceInfo, DeviceNum, &deviceData ) )
    {
        //getting the windows error message b4 the next winapi calls
        //nukes it out.  then throw the error
        std::string errMsg = "SetupDiEnumDeviceInfo failed "
            + windozeHelpers::GetLastWinError();

        SetupDiDestroyDeviceInfoList(deviceInfo);

        apgHelper::throwRuntimeException( __FILE__, 
           errMsg , __LINE__,Apg::ErrorType_Connection );
    }
  
    //from BOOL DumpDeviceDriverNodes in dump.cpp in 
    //C:\WinDDK\6001.18002\src\setup\devcon
    SP_DEVINSTALL_PARAMS deviceInstallParams;
    SP_DRVINFO_DATA driverInfoData;

    ZeroMemory(&deviceInstallParams, sizeof(deviceInstallParams));
    ZeroMemory(&driverInfoData, sizeof(driverInfoData));

    driverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
    deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);

    if( !SetupDiGetDeviceInstallParams(deviceInfo, &deviceData, 
        &deviceInstallParams) )
    {
       std::string errMsg = "SetupDiGetDeviceInstallParams failed "
            + windozeHelpers::GetLastWinError();

        SetupDiDestroyDeviceInfoList(deviceInfo);

        apgHelper::throwRuntimeException( __FILE__, 
           errMsg , __LINE__,Apg::ErrorType_Connection );
    }

    //
    // Set the flags that tell SetupDiBuildDriverInfoList to allow excluded drivers.
    //
    deviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);

    if( !SetupDiSetDeviceInstallParams(deviceInfo, &deviceData, 
        &deviceInstallParams) )
    {
         std::string errMsg = "SetupDiGetDeviceInstallParams failed "
            + windozeHelpers::GetLastWinError();

        SetupDiDestroyDeviceInfoList(deviceInfo);

        apgHelper::throwRuntimeException( __FILE__, 
           errMsg , __LINE__,Apg::ErrorType_Connection );
    }

    if( !SetupDiBuildDriverInfoList(deviceInfo, &deviceData, 
        SPDIT_COMPATDRIVER) )
    {
         std::string errMsg = "SetupDiBuildDriverInfoList failed "
            + windozeHelpers::GetLastWinError();

        SetupDiDestroyDeviceInfoList(deviceInfo);

        apgHelper::throwRuntimeException( __FILE__, 
           errMsg , __LINE__,Apg::ErrorType_Connection );
    }

  
    // believe the member index should be set to 0 for all
    // devices...not 100% sure what this parameter is referring
    // to, the number of devices, the number of driver interfaces,
    // number of device interfaces????
    // http://msdn.microsoft.com/en-us/library/windows/hardware/ff551018(v=vs.85).aspx
    if( !SetupDiEnumDriverInfo(deviceInfo, &deviceData, 
        SPDIT_COMPATDRIVER, 0, &driverInfoData) )
    {
        std::string errMsg = "SetupDiEnumDriverInfo failed "
            + windozeHelpers::GetLastWinError();

        SetupDiDestroyDriverInfoList(deviceInfo, &deviceData,
        SPDIT_COMPATDRIVER);
        SetupDiDestroyDeviceInfoList(deviceInfo);

        apgHelper::throwRuntimeException( __FILE__, 
           errMsg , __LINE__,Apg::ErrorType_Connection );
    }
 
    ULARGE_INTEGER Version;
    Version.QuadPart = driverInfoData.DriverVersion;
    
    std::stringstream ss;
    ss << HIWORD(Version.HighPart) << ".";
    ss << LOWORD(Version.HighPart) << ".";
    ss << HIWORD(Version.LowPart) << ".";
    ss << LOWORD(Version.LowPart);
                       
    version = ss.str();

    SetupDiDestroyDriverInfoList(deviceInfo, &deviceData,
        SPDIT_COMPATDRIVER);
    SetupDiDestroyDeviceInfoList(deviceInfo);

}