File copy during dpinst.exe

Hi All,

During driver entry, a firmware file needs to be picked up from:

Windows/System32/drivers/firmware_file.hex

and get downloaded to the device. As a result, during driver installation the file needs to be copied from the installation media to Windows/System32/drivers folder. I am trying how to do this with dpinst.exe.

I thought that I can configure this through inf. Currently my .inf file looks as follows:

[Version]
Signature = “$Windows NT$”
Class = Net
ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318}
Provider = %MYCOMPANY%usb
CatalogFile = myproduct.cat
DriverVer=05/26/2016,10.18.37.599
;DriverVer = 04/20/2011,2.0.0.62

;;;;; Installation Configuration ;;;;;
[SourceDisksNames]
1 = %DiskDescription%,myproduct.sys,

[SourceDisksFiles]
myproduct.sys = 1,
firmware_file.hex = 1,

[DestinationDirs]
my_company.CopyFiles = 12
DefaultDestDirs = 11
CoInstaller_CopyFiles = 11

[DefaultInstall]
;Include=netvwifibus.inf
;Needs=VWiFiBus.CopyFiles
Characteristics = 0x84
BusType = 15
AddReg = my_company.reg
DelReg = my_company.DelReg
CopyFiles = my_company.CopyFiles
*IfType = 71 ; IF_TYPE_IEEE80211
*MediaType = 16 ; NdisMediumNative802_11
*PhysicalMediaType = 9 ; NdisPhysicalMediumNative802_11

[DefaultInstall.Services]
Include=netvwifibus.inf
Needs=VWiFiBus.CopyFiles
AddService = my_company_my_product, 2, my_company.Service, my_company.EventLog

[DefaultInstall.Service]
DisplayName = %my_company.Service.DispName%
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
StartType = 3 ;SERVICE_DEMAND_START
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\myproduct.sys
LoadOrderGroup = NDIS

[my_company.CopyFiles]
myproduct.sys,2

[CoInstaller_CopyFiles]
wdfcoinstaller01005.dll
;;;;; Installation Configuration ;;;;;

[Manufacturer]
%MYCOMPANY% = my_company, NTamd64.6.1

[ControlFlags]
ExcludeFromSelect = *

[my_company.NTamd64.6.1]
;DisplayName Section Hardware ID
;----------- ------- --------------------------
%MYCOMPANY.DeviceDesc% = my_company.ndi, USB\VID_16C1&PID_1CDE

[my_company.ndi.NTamd64]
Include=netvwifibus.inf
Needs=VWiFiBus.CopyFiles
Characteristics = 0x84
BusType = 15
AddReg = my_company.reg
DelReg = my_company.DelReg
CopyFiles = my_company.CopyFiles
*IfType = 71 ; IF_TYPE_IEEE80211
*MediaType = 16 ; NdisMediumNative802_11
*PhysicalMediaType = 9 ; NdisPhysicalMediumNative802_11

[my_company.ndi.NTamd64.Services]
Include=netvwifibus.inf
Needs=VWiFiBus.CopyFiles
AddService = my_company_my_product, 2, my_company.Service, my_company.EventLog

[my_company.ndi.NTamd64.HW]
Include=netvwifibus.inf
Needs=VWiFiBus.PnPFilterRegistration
AddReg = my_company_os61.vwifi.reg

[my_company.reg]
HKR, Ndi, Service, 0, “my_company_my_product”
HKR, Ndi\Interfaces, UpperRange, 0, “ndis5”
HKR, Ndi\Interfaces, LowerRange, 0, “wlan,ethernet,vwifi”
HKR, , forceNormalSlotMrvl, 0x00002, “1”
HKR, , htAdhocEnable, 0x00002, “0”

[my_company.Service]
DisplayName = %my_company.Service.DispName%
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
StartType = 3 ;SERVICE_DEMAND_START
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\myproduct.sys
LoadOrderGroup = NDIS

[my_company.EventLog]
AddReg = my_company.AddEventLog.reg

[my_company.AddEventLog.reg]
HKR, , EventMessageFile, 0x00020000, “%%SystemRoot%%\System32\netevent.dll”
HKR, , TypesSupported, 0x00010001, 7

[myproduct.Dev.NT.CoInstallers]
AddReg=CoInstaller_AddReg
CopyFiles=CoInstaller_CopyFiles

[SourceDisksFiles]
wdfcoinstaller01005.dll=1 ; make sure the number matches with SourceDisksNames

[CoInstaller_AddReg]
HKR,CoInstallers32,0x00010000, “wdfcoinstaller01005.dll,WdfCoInstaller”

[myproduct.Dev.NT.Wdf]
KmdfService = myproduct, myproduct_wdfsect

[myproduct_wdfsect]
KmdfLibraryVersion = 1.5

;; Adds the VWiFi PNP filter
[my_company_os61.vwifi.reg]
HKR,“UpperFilters”,0x00010000,“vwifibus”

[Strings]
Msft = “Microsoft”
MYCOMPANY = “MyCompanyName”
MYCOMPANY.DeviceDesc= “my_company MyProduct”
my_company.Service.DispName = “my_company my_product”
DiskDescription = “myCompany USB”

Any ideas, what is wrong?

xxxxx@purelifi.com wrote:

Hi All,

During driver entry, a firmware file needs to be picked up from:

Windows/System32/drivers/firmware_file.hex

and get downloaded to the device. As a result, during driver installation the file needs to be copied from the installation media to Windows/System32/drivers folder. I am trying how to do this with dpinst.exe.

I thought that I can configure this through inf. Currently my .inf file looks as follows:

Any ideas, what is wrong?

Sure, I do. You tell the INF where the firmware_file.hex comes from,
but you never tell it to do the copy. In this section:
[my_company.CopyFiles]
myproduct.sys,2
you need to add:
firmware_file.hex,2


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

Thanks for your response. So I have done that and now when I right click on the .inf file and then select install the firmware_file.hex is indeed copied under c:\windows\system32\drivers.

However, when the user uses the dpinst.exe to install the driver, then the firmware_file.hex is not copied, while the rest of the driver installation happens normally.

I wonder whether my sign process is causing this. This is how I sign my driver:

SET PROJECT_BASE=C:\Users\MyCompany\windows

“c:\Program Files (x86)\Windows Kits\8.1\bin\x86\inf2cat.exe” /os:“7_X64,8_X64,6_3_X64” /driver:%PROJECT_BASE%\Source\x64\Win7Debug\
“c:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe” sign /v /debug ^
/ac %PROJECT_BASE%\WindowsSignature\MyCertificate\AddTrustExternalCARoot_kmod.crt ^
/tr http://timestamp.comodoca.com/rfc3161 ^
/n “MyCompany Ltd” ^
/f %PROJECT_BASE%\WindowsSignature\Comodo_CSC.pfx /p “my_password” ^
%PROJECT_BASE%\Source\x64\Win7Debug\my_driver.sys

“c:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe” sign /v /debug ^
/ac %PROJECT_BASE%\WindowsSignature\MyCertificate\AddTrustExternalCARoot_kmod.crt ^
/tr http://timestamp.comodoca.com/rfc3161 ^
/n “MyCompany Ltd” ^
/f %PROJECT_BASE%\WindowsSignature\Comodo_CSC.pfx /p “my_password” ^
%PROJECT_BASE%\Source\x64\Win7Debug\my_driver.cat

“c:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe” verify /v /kp Source\x64\Win7Debug\my_driver.sys
“c:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe” verify /v /kp /c Source\x64\Win7Debug\my_driver.cat %PROJECT_BASE%\Source\x64\Win7Debug\my_driver.sys

Any ideas?

On May 29, 2016, at 10:49 AM, xxxxx@purelifi.com wrote:

Thanks for your response. So I have done that and now when I right click on the .inf file and then select install the firmware_file.hex is indeed copied under c:\windows\system32\drivers.

However, when the user uses the dpinst.exe to install the driver, then the firmware_file.hex is not copied, while the rest of the driver installation happens normally.

Are you sure? Remember, Dpinst doesn’t actually run the INF file. It just copies it to the Driver Store. The INF won’t be run until your device actually appears on the USB bus. Is your hardware inserted in the system? Do you see evidence of that in \windows\inf\setup.dev.log?

I wonder whether my sign process is causing this. This is how I sign my driver:

No. Out of superstition, I always sign the SYS file before I create the CAT file. The CAT file contains a checksum of all of the files referenced in the INF, and if any of the checksums change, the CAT file is invalid. I’m told that signing the checksum does not include the certificates, so it doesn’t hurt to sign after creating the CAT.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

Yes, I am positive. However, by what you say it makes sense. I want the firmware_file.hex to be copied during installation. If the .inf file is not read / executed during installation then the CopyFiles directive would be ineffective… Am I missing something?

Should the device be plugged in during driver installation in order for the firmware_file.hex to be copied? I suppose in this way the .inf file would be executed…

The same way as the driver .sys file is only copied to drivers directory, your firmware file also needs to be copied only when a device is first plugged in.
But you could save yourself the hassle (and also saved a trouble of reading a file in kernel mode) if you generated a C array from your file and compiled it into your driver.

I see… In any case, I didn’t have much luck with dpinst.exe and I resorted to using NSIS as a wrapper around dpinst.exe.

I have one more question. When I uninstall the drivers from the ‘Program Files’, I would like the firmware_file.hex to be removed. Can this be defined somewhere?

xxxxx@purelifi.com wrote:

Yes, I am positive. However, by what you say it makes sense. I want the firmware_file.hex to be copied during installation. If the .inf file is not read / executed during installation then the CopyFiles directive would be ineffective… Am I missing something?

The issue I am talking about is the difference between
“pre-installation” and “installation”. When you run dpinst, you are
“pre-installing” the driver. The INF gets scanned for obvious errors
and signature checking, but the only net effect is that the package is
copied into the driver store. Unless there is a matching device plugged
in, the INF file is not “installed”. The services are not created, and
the AddReg and CopyFiles directives do not run.

Later, when a device gets plugged in, the system looks in the driver
store for a matching INF. If it finds one, THAT’S when the sections in
the INF are executed.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

xxxxx@purelifi.com wrote:

I see… In any case, I didn’t have much luck with dpinst.exe and I resorted to using NSIS as a wrapper around dpinst.exe.

I have one more question. When I uninstall the drivers from the ‘Program Files’, I would like the firmware_file.hex to be removed. Can this be defined somewhere?

This is a topic of some minor controversy. Microsoft would like the
files from your INF to remain on the system forever. There are still
traces in the registry that point to your driver, so removing the files
introduces a potential inconsistency, should someone plug one in again.

However, I always do it. If you run DPInst on your INF file and specify
the /u parameter, it will reverse whatever changes it made at install time.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> “pre-installation” and “installation”. When you run dpinst, you are

“pre-installing” the driver.

Or, more exactly - you’re “installing a driver package”.

The INF gets scanned for obvious errors
and signature checking, but the only net effect is that the package is
copied into the driver store.

Yes.

Later, when a device gets plugged in, the system looks in the driver
store for a matching INF. If it finds one, THAT’S when the sections in
the INF are executed.

I would name this “devnode creation”. Yes, the second, and the distinct step.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

> This is a topic of some minor controversy. Microsoft would like the

files from your INF to remain on the system forever.

“devcon dp_delete”?

Or the GUI checkbox of “Remove the driver files”, when you delete a devnode?


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

I see… OK, so I am covered with driver installation and uninstallation. Thank you for your support.

Finally, I would like my client to be able to downgrade their driver if they wish so. dpinst.xml option doesn’t seem to do this job.

Would you know how this can be implemented?

xxxxx@purelifi.com wrote:

I see… OK, so I am covered with driver installation and uninstallation. Thank you for your support.

Finally, I would like my client to be able to downgrade their driver if they wish so. dpinst.xml option doesn’t seem to do this job.
>
> Would you know how this can be implemented?

In my NSIS scripts, the first thing I do is check to see whether my
uninstall registry key exists, implying that I have already been
installed. If it exists, then I run “dpinst /u” to uninstall the old
driver. That way, there’s no question about upgrade/downgrade.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

“In my NSIS scripts, the first thing I do is check to see whether my uninstall registry key exists, implying that I have already been installed.”

This is a great idea! Could you tell me how you do that?

xxxxx@purelifi.com wrote:

“In my NSIS scripts, the first thing I do is check to see whether my uninstall registry key exists, implying that I have already been installed.”

This is a great idea! Could you tell me how you do that?

The ugly script trickery here is removing the quote marks to get the
path to DPInst:

; If the uninstall key exists, run DPInst to uninstall.

ReadRegStr $0 HKLM
“Software\Microsoft\Windows\CurrentVersion\Uninstall\MyProject”
“UninstallString”
StrCmp $0 “” after
; We always put double-quotes in the path, so $0 starts with one.
StrCpy $1 $0
loop:
IntOp $1 $1 - 1
StrCpy $2 $0 1 $1
StrCmp $2 “" 0 loop
StrCpy $0 $0 $1
StrCpy $0 '$0\DPInst.exe” /q /u $0\MyProject.inf"’
DetailPrint “Uninstalling old driver”
DetailPrint $0
ExecWait $0
after:


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Nice tip. Under HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\ there is no MyProject. Instead my registry entries are all apparently random hexadecimal strings.

Do you know why this is the case? Is the ‘MyProject’ defined somewhere in the code or VS?

I have simplified your solution to the following:

Delete c:\Windows\System32\drivers\mydriver.sys
ExecWait “dpinst.exe /U mydriver.inf”
ExecWait “dpinst.exe”

What do you think of this solution?

xxxxx@purelifi.com wrote:

Nice tip. Under HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\ there is no MyProject. Instead my registry entries are all apparently random hexadecimal strings.

Do you know why this is the case? Is the ‘MyProject’ defined somewhere in the code or VS?

Well, the “MyProject” thing is an entry that I add at the end of my
script, to register my uninstaller. Are you already building an
uninstaller? NSIS makes that very easy, but you have to register the
uninstaller yourself.

And “MyProject” is a generic name, replaced by whatever product I happen
to be installing.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

xxxxx@purelifi.com wrote:

I have simplified your solution to the following:

Delete c:\Windows\System32\drivers\mydriver.sys
ExecWait “dpinst.exe /U mydriver.inf”
ExecWait “dpinst.exe”

What do you think of this solution?

You must not arbitrarily delete your driver file. The “dpinst /u” will
do that, but in a supported way, by asking the existing instances to
stop first. That command won’t work on Windows 10, because the driver
file is kept open while the river is alive.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.