예제 #1
0
파일: intl.c 프로젝트: RPG-7/reactos
VOID
ParseSetupInf(VOID)
{
    INFCONTEXT InfContext;
    TCHAR szBuffer[30];

    if (!SetupFindFirstLine(hSetupInf,
                            _T("Unattend"),
                            _T("LocaleID"),
                            &InfContext))
    {
        SetupCloseInfFile(hSetupInf);
        DPRINT1("SetupFindFirstLine failed\n");
        return;
    }

    if (!SetupGetStringField(&InfContext, 1, szBuffer,
                             sizeof(szBuffer) / sizeof(TCHAR), NULL))
    {
        SetupCloseInfFile(hSetupInf);
        DPRINT1("SetupGetStringField failed\n");
        return;
    }

    UnattendLCID = _tcstoul(szBuffer, NULL, 16);
    IsUnattendedSetupEnabled = 1;
    SetupCloseInfFile(hSetupInf);
}
예제 #2
0
static VOID
InitFontSizeList(HWND hWnd)
{
    HINF hInf;
    HKEY hKey;
    HWND hFontSize;
    INFCONTEXT Context;
    int i, ci = 0;
    DWORD dwSize, dwValue, dwType;

    hFontSize = GetDlgItem(hWnd, IDC_FONTSIZE_COMBO);

    hInf = SetupOpenInfFile(_T("font.inf"), NULL,
                            INF_STYLE_WIN4, NULL);

    if (hInf != INVALID_HANDLE_VALUE)
    {
        if (SetupFindFirstLine(hInf, _T("Font Sizes"), NULL, &Context))
        {
            if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontDPI"),
                             0, KEY_READ, &hKey) == ERROR_SUCCESS)
            for (;;)
            {
                TCHAR Buffer[LINE_LEN];
                TCHAR Desc[LINE_LEN];

                if (SetupGetStringField(&Context, 0, Buffer, sizeof(Buffer) / sizeof(TCHAR), NULL) &&
                    SetupGetIntField(&Context, 1, &ci))
                {
                    _stprintf(Desc, _T("%s (%d DPI)"), Buffer, ci);
                    i = SendMessage(hFontSize, CB_ADDSTRING, 0, (LPARAM)Desc);
                    if (i != CB_ERR)
                        SendMessage(hFontSize, CB_SETITEMDATA, (WPARAM)i, (LPARAM)ci);

                    dwSize = MAX_PATH;
                    dwType = REG_DWORD;

                    if (RegQueryValueEx(hKey, _T("LogPixels"), NULL,
                                        &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS)
                    {
                        if ((int)dwValue == ci)
                        {
                            SendMessage(hFontSize, CB_SETCURSEL, (WPARAM)i, 0);
                            SetWindowText(GetDlgItem(hWnd, IDC_FONTSIZE_CUSTOM), Desc);
                        }
                    }
                }

                if (!SetupFindNextLine(&Context, &Context))
                {
                    RegCloseKey(hKey);
                    break;
                }
            }
        }
    }

    SetupCloseInfFile(hInf);
}
예제 #3
0
OSStatus
CThirdPage::LoadPrintDriverDefsFromFile(Manufacturers & manufacturers, const CString & filename, bool checkForDuplicateModels )
{
    HINF			handle	= INVALID_HANDLE_VALUE;
    const TCHAR *	section = TEXT( "Manufacturer" );
    LONG			sectionCount;
    TCHAR			line[ 1000 ];
    CString			klass;
    INFCONTEXT		manufacturerContext;
    BOOL			ok;
    OSStatus		err		= 0;

    // Make sure we can open the file
    handle = SetupOpenInfFile( filename, NULL, INF_STYLE_WIN4, NULL );
    translate_errno( handle != INVALID_HANDLE_VALUE, GetLastError(), kUnknownErr );
    require_noerr( err, exit );

    // Make sure it's a printer file
    ok = SetupGetLineText( NULL, handle, TEXT( "Version" ), TEXT( "Class" ), line, sizeof( line ), NULL );
    translate_errno( ok, GetLastError(), kUnknownErr );
    require_noerr( err, exit );
    klass = line;
    require_action( klass == TEXT( "Printer" ), exit, err = kUnknownErr );

    sectionCount = SetupGetLineCount( handle, section );
    translate_errno( sectionCount != -1, GetLastError(), kUnknownErr );
    require_noerr( err, exit );

    memset( &manufacturerContext, 0, sizeof( manufacturerContext ) );

    for ( LONG i = 0; i < sectionCount; i++ )
    {
        Manufacturers::iterator	iter;
        Manufacturer	*	manufacturer;
        CString				manufacturerName;
        CString				temp;
        CStringList			modelSectionNameDecl;
        CString				modelSectionName;
        CString				baseModelName;
        CString				model;
        INFCONTEXT			modelContext;
        LONG				modelCount;
        POSITION			p;

        if ( i == 0 )
        {
            ok = SetupFindFirstLine( handle, section, NULL, &manufacturerContext );
            err = translate_errno( ok, GetLastError(), kUnknownErr );
            require_noerr( err, exit );
        }
        else
        {
            ok = SetupFindNextLine( &manufacturerContext, &manufacturerContext );
            err = translate_errno( ok, GetLastError(), kUnknownErr );
            require_noerr( err, exit );
        }

        ok = SetupGetStringField( &manufacturerContext, 0, line, sizeof( line ), NULL );
        err = translate_errno( ok, GetLastError(), kUnknownErr );
        require_noerr( err, exit );
        manufacturerName = line;

        ok = SetupGetLineText( &manufacturerContext, handle, NULL, NULL, line, sizeof( line ), NULL );
        err = translate_errno( ok, GetLastError(), kUnknownErr );
        require_noerr( err, exit );

        // Try to find some model section name that has entries. Explanation of int file structure
        // can be found at:
        //
        // <http://msdn.microsoft.com/en-us/library/ms794359.aspx>
        Split( line, ',', modelSectionNameDecl );

        p					= modelSectionNameDecl.GetHeadPosition();
        modelSectionName	= modelSectionNameDecl.GetNext( p );
        modelCount			= SetupGetLineCount( handle, modelSectionName );
        baseModelName		= modelSectionName;

        while ( modelCount <= 0 && p )
        {
            CString targetOSVersion;

            targetOSVersion		= modelSectionNameDecl.GetNext( p );
            modelSectionName	= baseModelName + TEXT( "." ) + targetOSVersion;
            modelCount			= SetupGetLineCount( handle, modelSectionName );
        }

        if ( modelCount > 0 )
        {
            manufacturerName = NormalizeManufacturerName( manufacturerName );

            iter = manufacturers.find( manufacturerName );

            if ( iter != manufacturers.end() )
            {
                manufacturer = iter->second;
                require_action( manufacturer, exit, err = kUnknownErr );
            }
            else
            {
                try
                {
                    manufacturer = new Manufacturer;
                }
                catch (...)
                {
                    manufacturer = NULL;
                }

                require_action( manufacturer, exit, err = kNoMemoryErr );

                manufacturer->name					= manufacturerName;
                manufacturers[ manufacturerName ]	= manufacturer;
            }

            memset( &modelContext, 0, sizeof( modelContext ) );

            for ( LONG j = 0; j < modelCount; j++ )
            {
                CString modelName;
                Model * model;

                if ( j == 0 )
                {
                    ok = SetupFindFirstLine( handle, modelSectionName, NULL, &modelContext );
                    err = translate_errno( ok, GetLastError(), kUnknownErr );
                    require_noerr( err, exit );
                }
                else
                {
                    SetupFindNextLine( &modelContext, &modelContext );
                    err = translate_errno( ok, GetLastError(), kUnknownErr );
                    require_noerr( err, exit );
                }

                ok = SetupGetStringField( &modelContext, 0, line, sizeof( line ), NULL );
                err = translate_errno( ok, GetLastError(), kUnknownErr );
                require_noerr( err, exit );

                modelName = line;

                if (checkForDuplicateModels == true)
                {
                    if ( MatchModel( manufacturer, ConvertToModelName( modelName ) ) != NULL )
                    {
                        continue;
                    }
                }

                //
                // Stock Vista printer inf files embed guids in the model
                // declarations for Epson printers. Let's ignore those.
                //
                if ( modelName.Find( TEXT( "{" ), 0 ) != -1 )
                {
                    continue;
                }

                try
                {
                    model = new Model;
                }
                catch (...)
                {
                    model = NULL;
                }

                require_action( model, exit, err = kNoMemoryErr );

                model->infFileName		=	filename;
                model->displayName		=	modelName;
                model->name				=	modelName;
                model->driverInstalled	=	false;

                manufacturer->models.push_back(model);
            }
        }
    }

exit:

    if ( handle != INVALID_HANDLE_VALUE )
    {
        SetupCloseInfFile( handle );
        handle = NULL;
    }

    return err;
}
예제 #4
0
/**
 * 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;
}
예제 #5
0
int usb_install_driver_np(const char *inf_file)
{
  HDEVINFO dev_info;
  SP_DEVINFO_DATA dev_info_data;
  INFCONTEXT inf_context;
  HINF inf_handle;
  DWORD config_flags, problem, status;
  BOOL reboot;
  char inf_path[MAX_PATH];
  char id[MAX_PATH];
  char tmp_id[MAX_PATH];
  char *p;
  int dev_index;
  HINSTANCE newdev_dll = NULL;
  HMODULE setupapi_dll = NULL;

  update_driver_for_plug_and_play_devices_t UpdateDriverForPlugAndPlayDevices;
  setup_copy_oem_inf_t SetupCopyOEMInf;
  newdev_dll = LoadLibrary("newdev.dll");

  if(!newdev_dll)
    {
      usb_error("usb_install_driver(): loading newdev.dll failed\n");
      return -1;
    }
  
  UpdateDriverForPlugAndPlayDevices =  
    (update_driver_for_plug_and_play_devices_t) 
    GetProcAddress(newdev_dll, "UpdateDriverForPlugAndPlayDevicesA");

  if(!UpdateDriverForPlugAndPlayDevices)
    {
      usb_error("usb_install_driver(): loading newdev.dll failed\n");
      return -1;
    }

  setupapi_dll = GetModuleHandle("setupapi.dll");
  
  if(!setupapi_dll)
    {
      usb_error("usb_install_driver(): loading setupapi.dll failed\n");
      return -1;
    }
  SetupCopyOEMInf = (setup_copy_oem_inf_t)
    GetProcAddress(setupapi_dll, "SetupCopyOEMInfA");
  
  if(!SetupCopyOEMInf)
    {
      usb_error("usb_install_driver(): loading setupapi.dll failed\n");
      return -1;
    }

  dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);


  /* retrieve the full .inf file path */
  if(!GetFullPathName(inf_file, MAX_PATH, inf_path, NULL))
    {
      usb_error("usb_install_driver(): .inf file %s not found\n", 
                inf_file);
      return -1;
    }

  /* open the .inf file */
  inf_handle = SetupOpenInfFile(inf_path, NULL, INF_STYLE_WIN4, NULL);

  if(inf_handle == INVALID_HANDLE_VALUE)
    {
      usb_error("usb_install_driver(): unable to open .inf file %s\n", 
                inf_file);
      return -1;
    }

  /* find the .inf file's device description section marked "Devices" */
  if(!SetupFindFirstLine(inf_handle, "Devices", NULL, &inf_context))
    {
      usb_error("usb_install_driver(): .inf file %s does not contain "
                "any device descriptions\n", inf_file);
      SetupCloseInfFile(inf_handle);
      return -1;
    }


  do {
    /* get the device ID from the .inf file */
    if(!SetupGetStringField(&inf_context, 2, id, sizeof(id), NULL))
      {
        continue;
      }

    /* convert the string to lowercase */
    strlwr(id);

    reboot = FALSE;

    /* copy the .inf file to the system directory so that is will be found */
    /* when new devices are plugged in */
    SetupCopyOEMInf(inf_path, NULL, SPOST_PATH, 0, NULL, 0, NULL, NULL);

    /* update all connected devices matching this ID, but only if this */
    /* driver is better or newer */
    UpdateDriverForPlugAndPlayDevices(NULL, id, inf_path, INSTALLFLAG_FORCE, 
                                      &reboot);
    

    /* now search the registry for device nodes representing currently  */
    /* unattached devices */


    /* get all USB device nodes from the registry, present and non-present */
    /* devices */
    dev_info = SetupDiGetClassDevs(NULL, "USB", NULL, DIGCF_ALLCLASSES);
    
    if(dev_info == INVALID_HANDLE_VALUE)
      {
        SetupCloseInfFile(inf_handle);
        break;
      }
 
    dev_index = 0;

    /* enumerate the device list to find all attached and unattached */
    /* devices */
    while(SetupDiEnumDeviceInfo(dev_info, dev_index, &dev_info_data))
      {
        /* get the harware ID from the registry, this is a multi-zero string */
        if(SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
                                            SPDRP_HARDWAREID, NULL,  
                                            (BYTE *)tmp_id, 
                                            sizeof(tmp_id), NULL))
          {
            /* check all possible IDs contained in that multi-zero string */
            for(p = tmp_id; *p; p += (strlen(p) + 1))
              {
                /* convert the string to lowercase */
                strlwr(p);
		
                /* found a match? */
                if(strstr(p, id))
                  {
                    /* is this device disconnected? */
                    if(CM_Get_DevNode_Status(&status,
                                             &problem,
                                             dev_info_data.DevInst,
                                             0) == CR_NO_SUCH_DEVINST)
                      {
                        /* found a device node that represents an unattached */
                        /* device */
                        if(SetupDiGetDeviceRegistryProperty(dev_info, 
                                                            &dev_info_data,
                                                            SPDRP_CONFIGFLAGS, 
                                                            NULL,  
                                                            (BYTE *)&config_flags, 
                                                            sizeof(config_flags),
                                                            NULL))
                          {
                            /* mark the device to be reinstalled the next time it is */
                            /* plugged in */
                            config_flags |= CONFIGFLAG_REINSTALL;
			    
                            /* write the property back to the registry */
                            SetupDiSetDeviceRegistryProperty(dev_info, 
                                                             &dev_info_data,
                                                             SPDRP_CONFIGFLAGS,
                                                             (BYTE *)&config_flags, 
                                                             sizeof(config_flags));
                          }
                      }
                    /* a match was found, skip the rest */
                    break;
                  }
              }
          }
        /* check the next device node */
        dev_index++;
      }
    
    SetupDiDestroyDeviceInfoList(dev_info);

    /* get the next device ID from the .inf file */ 
  } while(SetupFindNextLine(&inf_context, &inf_context));

  /* we are done, close the .inf file */
  SetupCloseInfFile(inf_handle);

  usb_registry_stop_libusb_devices(); /* stop all libusb devices */
  usb_registry_start_libusb_devices(); /* restart all libusb devices */

  return 0;
}