2

I am trying to install a driver during a windows-setup project.

The first step I do is to copy the INF file and preinstall the driver.

SetupCopyOEMInf(infFile, null, 1, 0, null, 0, 0, null);

This correctly preinstalls the driver, but the device is not ready to use until a hardware rescan is done in Device Manager. I want to automate this as well. I have tried using the setupapi.dll to invoke the hardware rescan, but it was not always successful for me. Using devcon.exe rescan always forces the hardware rescan, but it is a synchronous command, and it returns before the device is finished installing. Is there any way to get a return result after the hardware scan completes and the driver is successfully installed?

Thanks,

Misha

Edit

Here is my working code:

    public const UInt32 CR_SUCCESS = 0;
    public const UInt64 CM_REENUMERATE_SYNCHRONOUS = 1;
    public const UInt64 CM_LOCATE_DEVNODE_NORMAL = 0;

    [DllImport("setupapi.dll")]
    public static extern bool SetupCopyOEMInf(
      string SourceInfFileName,
      string OEMSourceMediaLocation,
      int OEMSourceMediaType,
      int CopyStyle,
      string DestinationInfFileName,
      int DestinationInfFileNameSize,
      int RequiredSize,
      string DestinationInfFileNameComponent
      );

    [DllImport("cfgmgr32.dll")]
    public static extern int CM_Locate_DevNode_Ex(ref IntPtr deviceHandle, int deviceId, uint flags, IntPtr machineHandle);

    [DllImport("cfgmgr32.dll")]
    public static extern int CM_Reenumerate_DevNode_Ex(IntPtr devInst, UInt64 flags);

    [DllImport("cfgmgr32.dll")]
    public static extern int CMP_WaitNoPendingInstallEvents(UInt32 timeOut);

    static void Main() {
      bool success = SetupCopyOEMInf(infFile, null, 1, 0, null, 0, 0, null);

      if(!success) {
        throw new Exception("Error installing driver");
      }

      success = RescanAllDevices();

      if (!success) {
        throw new Exception("Error installing driver");
      }
    }

    public static bool RescanAllDevices() {
      int ResultCode = 0;
      IntPtr LocalMachineInstance = IntPtr.Zero;
      IntPtr DeviceInstance = IntPtr.Zero;
      UInt32 PendingTime = 30000;

      ResultCode = CM_Locate_DevNode_Ex(ref DeviceInstance, 0, 0, LocalMachineInstance);
      if (CR_SUCCESS == ResultCode) {
        ResultCode = CM_Reenumerate_DevNode_Ex(DeviceInstance, CM_REENUMERATE_SYNCHRONOUS);
        ResultCode = CMP_WaitNoPendingInstallEvents(PendingTime);
      }
      return ResultCode == CR_SUCCESS;
    }
Community
  • 1
  • 1
Misha
  • 571
  • 5
  • 17
  • Thanks for the code! However, if the driver installation failed previously and a dummy driver was installed, then only rebooting the system installs the new driver. So, reboot seems to be the safest method. See http://stackoverflow.com/questions/14937261/equivalent-of-scan-for-hardware-changes-in-device-manager-doesnt-work-after-f – OneWorld Feb 19 '13 at 07:30

1 Answers1

0

The source for devcon is available in the WDK. It's in the src\setup\devcon directory. The logic for the rescan command is in the cmdRescan function in cmds.cpp. It would be a simple matter to copy that logic into your own code and make sure it doesn't return immediately.

Carey Gregory
  • 6,836
  • 2
  • 26
  • 47