File copy during dpinst.exe

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.

Hi Tim,

Thanks for the review. Would you know how do I register the uninstaller with NSIS?

All the best,

Angelos

xxxxx@purelifi.com wrote:

Thanks for the review. Would you know how do I register the uninstaller with NSIS?

Have you looked? MANY of the example scripts in the NSIS distribution
demonstrate this. I use a text substitution tool before I create the
script; @UNINSTALLER@ is the name of the uninstall executable to be
created (like “uninst_xxx.exe”) and @UNINSTALLERNAME@ is the friendly
name to be displayed in the Programs and Features control panel applet,
like “MyCompany MyProject Drivers”. The WriteUninstaller command tells
it to create an uninstaller and include it in the installer, and the
WriteRegStr commands create registry entries to add it to the list.

; Create the uninstaller.

WriteRegStr HKLM
“Software\Microsoft\Windows\CurrentVersion\Uninstall\MyProject” \
“DisplayName” “@UNINSTALLERNAME@”
WriteRegStr HKLM
“Software\Microsoft\Windows\CurrentVersion\Uninstall\MyProject” \
“UninstallString” ‘“$INSTDIR@UNINSTALLER@”’

WriteUninstaller “@UNINSTALLER@”

Then, of course, you need a
Section “Uninstall”
that includes all of the files to be removed. As I say, there are
samples to show this.


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

> The ugly script trickery here is removing the quote marks to get the

path to DPInst:

That seems like overkill, in the uninstaller $InstDir is the path to the folder where your uninstaller .exe is located. You also have the more specific $ExeDir.

Also, before your loop you do “StrCpy $1 $0” but then treat $1 as a number. $1 will always be treated as 0 the first time you hit the loop if $0 begins with a quote. The 3rd and 4th StrCpy parameters can be negative but if that is what you want you might as well assign 0 to $1 IMHO.

On Jun 5, 2016, at 4:18 AM, xxxxx@techie.com wrote:

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

That seems like overkill, in the uninstaller $InstDir is the path to the folder where your uninstaller .exe is located. You also have the more specific $ExeDir.

Yes, but that part is not running in the uninstaller. It’s in the installer, checking to see whether the uninstaller exists.

Also, before your loop you do “StrCpy $1 $0” but then treat $1 as a number.

Yes, it should be StrLen.

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

I have adapted the installer and it works great. One question however is the following: After dpinst.exe finishes the installation, the following registry folder is getting created:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\44BD8E38D812182C11B90D9AC7218BDA11112BBC

The problem is that the last part of this key , e.g. 44BD8E38D812182C11B90D9AC7218BDA11112BBC is not defined in my code and I don’t know how to define it.

I have observed that after recompilation this code changes.

Would you know how this string is getting specified? I have read that it is ProductCode which is specified by the GUID. But I didn’t understand how to specify the GUID.

xxxxx@purelifi.com wrote:

I have adapted the installer and it works great. One question however is the following: After dpinst.exe finishes the installation, the following registry folder is getting created:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\44BD8E38D812182C11B90D9AC7218BDA11112BBC

The problem is that the last part of this key , e.g. 44BD8E38D812182C11B90D9AC7218BDA11112BBC is not defined in my code and I don’t know how to define it.

I have observed that after recompilation this code changes.

Would you know how this string is getting specified? I have read that it is ProductCode which is specified by the GUID. But I didn’t understand how to specify the GUID.

That’s being added by DPInst, and is a way to run “dpinst /u”
automatically. Since my clients found it confusing to have two
uninstall entries (one for my NSIS script, and one for DPInst), and
since I wanted to be in control, I learned that you can add
to your dpinst.xml configuration file to
suppress this.


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

Hi Tim, so there is no way to control this string?

xxxxx@purelifi.com wrote:

Hi Tim, so there is no way to control this string?

No, but why would you care? It will appear in “Programs and Features” as

Windows Driver Package – Xxxxxx.Inf (date time)

If the user runs that, the registry entry will be removed, along with
the driver package. If you don’t want to allow users to call that
separately, then just suppress it with the dpinst.xml configuration option.


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