Windows 7 Install Unsigned Drivers CAT fix

From richud.com
Jump to navigation Jump to search


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.
C:\WinDDK\7600.16385.1\bin\selfsign\

Inf2Cat.exe
Microsoft.Whos.Shared.IO.Cabinets.dll
Microsoft.Whos.Shared.IO.Catalogs.dll
Microsoft.Whos.Shared.Xml.InfReader.dll
Microsoft.Whos.Winqual.Submissions.SubmissionBuilder.dll
Microsoft.Whos.Xml.NonXmlDataReader.dll
WindowsProtectedFiles.xml

C:\WinDDK\7600.16385.1\bin\amd64\ MakeCert.exe
CertMgr.exe
SignTool.exe
C:\WinDDK\7600.16385.1\Tools\devcon\amd64\devcon.exe C:\WinDDK\7600.16385.1\redist\DIFx\dpinst\EngMui\amd64\dpinst.exe

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)
<SNIP>
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...
<SNIP>
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 <All>, 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

Unsigned-driver-install-self-signed-cat-file.png

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.

Install newly fixed driver

Using dpinst

<?xml version="1.0"?><dpInst><enableNotListedLanguages/><suppressWizard/><quietInstall/><suppressEulaPage/><legacyMode/><search><subDirectory>*</subDirectory></search></dpInst>
  • 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!


Unsigned-driver-install-dpinst-filerepository.png


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...
<SNIP>
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

blog comments powered by Disqus