Windows 7 Install Unsigned Drivers CAT fix

This will let you install an unsigned driver (locally or on a remote pc) WITHOUT needing to reboot it or disable the driver signing (which needs a reboot).

Get Windows Driver Kit
Download and install the SDK, Windows Driver Kit Version 7.1.0 ISO (650Mb)

Mount the ISO and run kitsetup.exe, select 'Build Environments' & 'Tools', install to default c:\WinDDK\7600.16385.1 (Takes 1.5Gb!)

Files Needed from SDK

 * Note, Using 64 bit versions here, I usually rename devcon.exe to devcon64.exe and dpinst.exe to dpinst64.exe to avoid confusion.

General Info

 * Note, Throughout you are using the localmachine NOT user certificate store, (for a GUI you need to go via the mmc > add snapin, NOT certmgr.msc which opens the user one)


 * Note, This example assumes your drivers are in "E:\Laserjet 1020", and we are using 64bit Windows 7

=Example 1=

Fix the (broken) driver .inf up
If you have downloaded the HP LaserJet 1022 series driver and found it doesn't contain the 1022 driver, only the 1020, this bit is for you. (Specifically the hardware ID's for the 1022 are missing)

" 2010-11-09, Version:2.0, 2.82M Note: This driver works both the LaserJet 1020 and 1022 Series printers. The Plug and Play Bundle provides basic printing functions. " - No!!

Change (in HPLJ1020.INF, from extracted lj1020-HB-pnp-win64-en.exe)

[HP] "HP LaserJet 1020" = LJ1020,USBPRINT\Hewlett-Packardhp_La26DD, Hewlett-Packardhp_La26DD

[HP.NTx86] "HP LaserJet 1020" = LJ1020,USBPRINT\Hewlett-Packardhp_La26DD, Hewlett-Packardhp_La26DD

[HP.NTamd64] "HP LaserJet 1020" = LJ1020,USBPRINT\Hewlett-Packardhp_La26DD, Hewlett-Packardhp_La26DD

To

[HP] "HP LaserJet 1020" = LJ1020,USBPRINT\Hewlett-Packardhp_La26DD, Hewlett-Packardhp_La26DD "HP LaserJet 1022" = LJ1020,USBPRINT\Hewlett-PackardHP_LaE75C, Hewlett-PackardHP_LaE75C "HP LaserJet 1022n" = LJ1020,USBPRINT\Hewlett-PackardHP_LaD566, Hewlett-PackardHP_LaD566

[HP.NTx86] "HP LaserJet 1020" = LJ1020,USBPRINT\Hewlett-Packardhp_La26DD, Hewlett-Packardhp_La26DD "HP LaserJet 1022" = LJ1020,USBPRINT\Hewlett-PackardHP_LaE75C, Hewlett-PackardHP_LaE75C "HP LaserJet 1022n" = LJ1020,USBPRINT\Hewlett-PackardHP_LaD566, Hewlett-PackardHP_LaD566

[HP.NTamd64] "HP LaserJet 1020" = LJ1020,USBPRINT\Hewlett-Packardhp_La26DD, Hewlett-Packardhp_La26DD "HP LaserJet 1022" = LJ1020,USBPRINT\Hewlett-PackardHP_LaE75C, Hewlett-PackardHP_LaE75C "HP LaserJet 1022n" = LJ1020,USBPRINT\Hewlett-PackardHP_LaD566, Hewlett-PackardHP_LaD566


 * Note, " = LJ1020", should be " = LJ1020.NTamd64" in 64 bit section etc. which is wrong in original driver, but as the sections below are the same it doesn't effect anything !
 * Note, don't both fiddling with the driver date as you may have seen elsewhere, (in my experience it doesn't effect anything.)

Save the .inf, notice now the signing is broken as the .cat catalog doesn't match and dpinst and devcon wont work without clicking through prompts, not much use for a silent remote install!

Generate new .cat files
C:\WinDDK\7600.16385.1\bin\selfsign\Inf2Cat.exe /driver:"E:\Laserjet 1020" /os:7_X64 /verbose C:\WinDDK\7600.16385.1\bin\selfsign\Inf2Cat.exe /driver:"E:\Laserjet 1020" /os:7_X86 /verbose

e.g.

C:\WinDDK\7600.16385.1\bin\selfsign>inf2cat /driver:"E:\Laserjet 1020" /os:7_X64 /verbose Processing directory (E:\Laserjet 1020\) file (properties.ini) Processing directory (E:\Laserjet 1020\) file (setup.exe) Processing directory (E:\Laserjet 1020\) file (strings.dll) Processing directory (E:\Laserjet 1020\) file (productinst.exe) Processing directory (E:\Laserjet 1020\) file (license.txt) Processing directory (E:\Laserjet 1020\) file (hplj1020.inf) Processing directory (E:\Laserjet 1020\) file (drv64.cab) Processing cabinet (drv64.cab) file (gchp1020.dll) Processing cabinet (drv64.cab) file (pphp1020.dll)  Processing directory (E:\Laserjet 1020\English) file (zshp1020.chm) Processing directory (E:\Laserjet 1020\English) file (sdhp1020.sdd) Parsing INF: E:\Laserjet 1020\hplj1020.inf Finished parsing INFs Processing INF: E:\Laserjet 1020\hplj1020.inf Finished processing INFs Testing driver package... Testing driver package...  Testing driver package... Testing driver package... Testing driver package...

Signability test complete.

Errors: None

Warnings: None

Catalog generation complete. E:\Laserjet 1020\hp102064.cat


 * Note, altering any files after this will break it again as they are all hashed into the .cat.
 * Note, right clicking on .cat's properties should show they are now unsigned. (no tab for signing)

Fixing fails
If you get Signability test failed.

Errors: 22.9.4: Missing AMD64 CatalogFile entry (CatalogFile.ntamd64, CatalogFile.nt, CatalogFile) from [Version] section in \trimble.inf

It is most likely missing a catolog file definition under the [version] section. So just add a line at the bottom of that section with "CatalogFile=yourthing.cat"

Create certificate for signing
This creates a (-r self) signed certificate needed for SignTool.exe in the ROOT store (Trusted Root Certification Authority/Certificates) in the Localmachine

This contains a public AND private key, you MUST have the private key present at this time to be able to sign. (richud.com can be any text string, so long as its consistant)

c:\WinDDK\7600.16385.1\bin\amd64\MakeCert.exe -r -n "CN=richud.com" -ss ROOT -sr LocalMachine

If you look in the ROOT store, you should see a certificate Issued To "richud.com", Issued By "richud.com", Intended Purpose , with an Expiration Date 01/01/2040.

(self) Sign the new .cat files
This signs the .cat files using the certificate in the ROOT store you just created.

C:\WinDDK\7600.16385.1\bin\amd64\SignTool.exe sign /s ROOT /n richud.com /t http://timestamp.verisign.com/scripts/timestamp.dll "E:\Laserjet 1020\hp102032.cat" C:\WinDDK\7600.16385.1\bin\amd64\SignTool.exe sign /s ROOT /n richud.com /t http://timestamp.verisign.com/scripts/timestamp.dll "E:\Laserjet 1020\hp102064.cat"

e.g.

c:\WinDDK\7600.16385.1\bin\amd64>SignTool sign /s ROOT /n richud.com /t http://timestamp.verisign.com/scripts/timestamp.dll "E:\Laserjet 1020\hp102032.cat" Done Adding Additional Store Successfully signed and timestamped: E:\Laserjet 1020\hp102032.cat


 * Note, you could also sign a .sys file similarily.
 * Note, looking at the .cat's properties should now show a 'Digital Signatures' tab, in this case 'Name of signer' is richud.com



Export the (public) key
This exports just the public part of the key (all you need now) C:\WinDDK\7600.16385.1\bin\amd64\CertMgr.exe -put -c -s ROOT -n richud.com "E:\Laserjet 1020\richud.com.cer" CertMgr Succeeded

Delete original key
Assuming you are done signing the catalog files you can now delete the original public/private key.

C:\WinDDK\7600.16385.1\bin\amd64\CertMgr.exe -del -n richud.com -c -s -r localMachine ROOT CertMgr Succeeded

Install public key back
Now to test it [this is now effectively a 'new' clean machine as you removed the cert above], you need to import the public half of the original key (the one you just saved and had used for signing the .cat files) back into BOTH the ROOT(Trusted Root Certification Authority) and Trusted Publishers stores. i.e. this is what you would do on a target machine.

C:\WinDDK\7600.16385.1\bin\amd64\CertMgr.exe -add "E:\Laserjet 1020\richud.com.cer" -c -s -r localMachine TrustedPublisher C:\WinDDK\7600.16385.1\bin\amd64\CertMgr.exe -add "E:\Laserjet 1020\richud.com.cer" -c -s -r localMachine ROOT

If you have put them in the wrong place, or gone wrong, dpinst/devcon will error when trying to install the driver, see below for the common ones I came across!

What is the significance?
To install the drivers on another machine, all you now need is CertMgr.exe and the .cer file, (and the driver files.)

Simply run the above two lines on the target machine and then you can install the driver silently and/or remotely as normal with dpinst! No more stupid signing prompts/errors.

Using dpinst
 * 
 * Note, Using dpinst.xml to install non present devices here, which has advantages over using command line switches, like sub folder searching.
 * Note, dpinst64.exe = C:\WinDDK\7600.16385.1\redist\DIFx\dpinst\EngMui\amd64\dpinst.exe, as mentioned earlier I renamed it to stop getting 32/64 bit versions muddled up.


 * Note, Keeping dpinst64.exe and dpinst.xml in the same folder stops having to worry about paths, dpinst always looks in it's path for the xml.

E:\dpinst64.exe /c /path "E:\Laserjet 1020"

e.g. (this is pre-installing, the hardware isn't present in this example)

E:\dpinst64.exe /c /path "E:\Laserjet 1020"

INFO:  Option set: dumping log info to console. INFO:  Current working directory: 'E:\' INFO:  Running on path 'E:\Laserjet 1020' INFO:  DPInst.xml does not list the current UI language. INFO:  User UI Language is 0x409. INFO:  Install option set: Suppressing Wizard but no OS popups. INFO:  Install option set: Running in quiet mode. Suppressing Wizard and OS popups. INFO:  Install option set: legacy mode on. INFO:  Found driver package: 'E:\Laserjet 1020\HPLJ1020.INF'. INFO:  Preinstalling 'e:\laserjet 1020\hplj1020.inf' ... INFO:  ENTER:  DriverPackagePreinstallW INFO:  Driver package is already preinstalled 'e:\laserjet 1020\hplj1020.inf'. SUCCESS:e:\laserjet 1020\hplj1020.inf is preinstalled. INFO:  RETURN: DriverPackagePreinstallW  (0xB7) INFO:  ENTER:  DriverPackageGetPathW INFO:  RETURN: DriverPackageGetPathW  (0x0) INFO:  ENTER:  DriverPackageInstallW WARNING:DRIVER_PACKAGE_LEGACY_MODE flag set but not supported on Plug and Play driver on VISTA. Flag will be ignored. INFO:  Installing INF file 'e:\laserjet 1020\hplj1020.inf' (Plug and Play). INFO:  Looking for Model Section [HP.NTamd64]... INFO:  Looking for Model Section [LJ1020]... INFO:  Looking for Model Section [LJ1020]... INFO:  No matching devices found in INF "C:\Windows\System32\DriverStore\FileRepository\hplj1020.inf_amd64_neutral_b6dc366bad614dc7\hplj1020.inf" on the Machine. INFO:  No drivers installed. No devices found that match driver(s) contained in 'C:\Windows\System32\DriverStore\FileRepository\hplj1020.inf_amd64_neutral_b6dc366bad614dc7\hplj1020.inf'. INFO:  RETURN: DriverPackageInstallW  (0xE000020B) INFO:  No matching device was found for 'e:\laserjet 1020\hplj1020.inf'. Driver will be installed when plugged in. INFO:  Returning with code 0x100

If you browse to C:\Windows\System32\DriverStore\FileRepository\hplj1020.inf_amd64_neutral_775c61a218c8e049 you should see it is there with all the files!



c:\Windows\DPINST.LOG will show your dpinst64.exe log file if you weren't using /c to dump to console.

c:\windows\inf\setupapi.dev.log and (c:\windows\inf\setupapi.app.log) will also how very detailed logging or the driver installing for debug purposes.

See here for a live example installing remotely

Using devcon
Not entirely happy about how this works, so use dpinst (hopefully update one day)

devcon64.exe install "E:\Laserjet 1020\hplj1020.inf" "USBPRINT\Hewlett-PackardHP_LaE75C"

Uninstall
dpinst64.exe /u "E:\Laserjet 1020\hplj1020.inf"

or

Something like this, remembering to use the Instance ID, not the Hardware ID!

devcon64.exe remove "USBPRINT\HEWLETT-PACKARDHP_LASERJET_1020*"

=Example 2, no .cat to begin with=

Often companies use the generic usb to serial driver and provide just an inf file. This relies on the Windows inbuilt USBSER.SYS

All you need is the .inf (which is effectively generic) as it will include their device VID and PID.

Fixup the .inf if needed
Firstly it probably won't have a catalog entry (CatalogFile=) so you must add it at the bottom of [version] section, as below.

In this example, we have trimble.inf (supplied) and we are going to call the .cat, can you guess? , trimble.cat ! [Version] Signature="$Windows NT$" Class=Ports ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} Provider=%ProviderName% DriverVer=05/24/2011,1.0.0.0 CatalogFile=trimble.cat

Run through the above stages
Everything else is as above. This is just a quick run through of the stages.

(I have just the modified trimble.inf in this folder "S:\Software\Engineering\Trimble\driver")

S:\Software\Engineering\Trimble>Inf2Cat.exe /driver:"S:\Software\Engineering\Trimble\driver" /os:7_X64 /verbose Processing directory (S:\Software\Engineering\Trimble\driver\) file (trimble.inf) Parsing INF: S:\Software\Engineering\Trimble\driver\trimble.inf Finished parsing INFs Processing INF: S:\Software\Engineering\Trimble\driver\trimble.inf Finished processing INFs Testing driver package...  Testing driver package...

Signability test complete.

Errors: None

Warnings: None

Catalog generation complete. S:\Software\Engineering\Trimble\driver\trimble.cat

S:\Software\Engineering\Trimble>MakeCert.exe -r -n "CN=trimble" -ss ROOT -sr LocalMachine Succeeded

S:\Software\Engineering\Trimble>SignTool.exe sign /s ROOT /n trimble /t http://timestamp.verisign.com/scripts/timestamp.dll "S:\Software\Engineering\Trimble\driver\trimble.cat" Done Adding Additional Store Successfully signed and timestamped: S:\Software\Engineering\Trimble\driver\trimble.cat

S:\Software\Engineering\Trimble>CertMgr.exe -put -c -s ROOT -n trimble "S:\Software\Engineering\Trimble\trimble.cer" CertMgr Succeeded

All you need to do is copy these to a target machine along with dpinst.exe/dpinst.xml and certmgr.exe Trimble\driver\trimble.inf Trimble\driver\trimble.cat Trimble\trimble.cer Trimble\dpinst.xml Trimble\dpinst.exe  (i rename mine to dpinst64.exe usually to avoid confusion) Trimble\certmgr.exe

..Then simply do this from Trimble\, and they should appear in the Windows\system32\DriverStore, nicely pre-installed. So you should now have

CertMgr.exe -add "trimble.cer" -c -s -r localMachine TrustedPublisher CertMgr.exe -add "trimble.cer" -c -s -r localMachine ROOT dpinst64.exe

=Errors you may encounter=

Missing or incorrect Trusted Publishers/Certificates
devcon Windows Security - "Would you like to install this device software" - tick box "Always trust software from"

dpinst RETURN: DriverPackagePreinstallW (0xE0000242)

There is more information about fixing broken Trusted publishers/Certificates here

Missing or incorrect Trusted Root Certification Authorities/Certificates
devcon "windows cant verify the publisher of this driver software"

dpinst RETURN: DriverPackagePreinstallW (0xE0000247)

Other
dpinst (no .cat file)

RETURN: DriverPackagePreinstallW (0xE000023F)

dpinst (INFO:  No drivers installed. No devices found that match driver(s) contained in 'C:\Windows\System32\DriverStore\FileRepository\xxxxxxxxxxxxx

INFO:  RETURN: DriverPackageInstallW  (0xE000020B)

this is if you are preinstalling and hardware doesnt exist, which is normal and not really an error as such. It should mention "Driver will be installed when plugged in." below these lines.

dpinst

ERROR: RETURN UpdateDriverForPlugAndPlayDevices. (Error code 0x490: Element not found.)

Remove any entries from 'Printers' in device manager (need to show "hidden devices")

Other vaguely useful certmgr examples
Copy a certificate between stores

certmgr.exe -add -c -s -n richud.com -r localmachine TrustedPublisher -c -s -r localmachine ROOT

Copy .cer into a store

certmgr.exe -add c:\richud.com.cer -c -s -r localMachine TrustedPublisher

certmgr.exe -add c:\richud.com.cer -c -s -r localMachine ROOT

=Comments=