I wrote earlier in the week about some issues I had getting my INF file to work. I managed to get the drivers installed and they work with XP and Win 7 in both Admin and non-admin mode. (Thanks for all the help!)
Customers are going to have to install this update themselves, so I have been looking for a way to install the drivers in some way other than going through the Add Hardware Wizard (the hardware is non PnP, one card dats back to 1988) which has many steps and most users of recent versions of Windows have probably never used it.
I started looking at devcon.exe, but I could not get it to work. The error messages in setupapi.log indicated that some file was missing, but the driver was getting copied OK and the INF was being found.
I did find the source code for devcon in the DDK and wrote a quick and dirty MFC dialog program that encapsulates just the install functions from devcon with a simple GUI interface. In devcon, cmdInstall() calls cmdUpdate() at the end, so I ported both of those functions to my app.
All functions in the install chain are working OK except the last call in cmdUpdate(). There is a call to GetProcAddress, which retrieves a pointer to UpdateDriverForPlugAndPlayDevices() in newdev.dll. That succeeds, but then the call to the function fails. The information I found about the function says that if UpdateDriverForPlugAndPlayDevices() fails, it will return FALSE and the error can be retrieved with GetLastError(), which I did. I don’t know if the extra step of calling the function from a pointer messed up GetLastError(), but it is returning 0xe0000203 (-536870397 decimal).
Specific code is at the bottom of this message. The only thing I changed in this code from devon’s implementation is to change the first argument of UpdateFn from Null to m_hWnd because the description of UpdateDriverForPlugAndPlayDevices() said the first argument was the top level handle in a GUI program. It didn’t make any difference.
I also changed the call arguments of the functions to the INF file name and the HWID string (“ROOT\IODEVICE”), but the other calls in the two functions work, so I don’t think there is anything amiss with the arguments. I stripped out a few command line checks that aren’t relevant, but those are the only changes I made to these functions.
I’m not sure UpdateDriverForPlugAndPlayDevices() is the right thing to call here as it is a self described Plug and Play function and the hardware is not PnP.
Definitions:
typedef BOOL (WINAPI *UpdateDriverForPlugAndPlayDevicesProto)(__in HWND hwndParent,__in LPCTSTR HardwareId,
__in LPCTSTR FullInfPath,__in DWORD InstallFlags,
__out_opt PBOOL bRebootRequired);
#ifdef _UNICODE
#define UPDATEDRIVERFORPLUGANDPLAYDEVICES “UpdateDriverForPlugAndPlayDevicesW”
#else
#define UPDATEDRIVERFORPLUGANDPLAYDEVICES “UpdateDriverForPlugAndPlayDevicesA”
#endif
UpdateDriverForPlugAndPlayDevicesProto UpdateFn;
HMODULE newdevMod = LoadLibrary(TEXT(“newdev.dll”));
From cmdUpdate()
UpdateFn = (UpdateDriverForPlugAndPlayDevicesProto)GetProcAddress(newdevMod,UPDATEDRIVERFORPLUGANDPLAYDEVICES);
if(!UpdateFn)
{
err=GetLastError();
str.Format(“cmdUpdate: GetProcAddress failed error=%d”,err);
AfxMessageBox(str,MB_OK|MB_ICONEXCLAMATION,0);
goto final;
}
FormatToStream(stdout,inf ? MSG_UPDATE_INF : MSG_UPDATE,hwid,inf);
if(!UpdateFn(m_hWnd,hwid,inf,flags,&reboot))
{
err=GetLastError();
str.Format(“cmdUpdate: UpdateDriverForPlugAndPlayDevices failed error=%d”,err);
AfxMessageBox(str,MB_OK|MB_ICONEXCLAMATION,0);
goto final;
}