I have kernel driver. When installing on 32 bit systems and Windows XP and below, I had no problem and used SetupCopyOEMInf, but 64 bit drivers are required to be signed. I have signed it and I need to have a cat file with the driver copied somewhere on the computer, and this method of install doesn't work. How should I install it?
EDIT: Clarified the question.
In Windows Vista and Windows 7 there a new utility for handling drivers setup call PnPUtil. It handles exactly this kind of work. Just copy all your driver relevant files(*.inf, *.cat, *.sys) to a directory on the target computer and use PnPUtil -i -a <InfName>.inf
Note: You will need to be in an administrator context to successfully use this tool.
You need to get an Authenticode signature, create a catalog file, and sign it with that. Microsoft decided that, for 64-bit systems, it will require the driver to come untampered from the vendor, by checking it signature.
(Note: This is not the same as WHQL, which tests the quality of the driver. Authenticode merely indicates that the driver hasn't been tampered with by some malicious user or virus; it doesn't say anything about what the driver does, so it's a relatively easy -- although pricey -- signature to obtain.)
Another solution is test-signing, if you don't plan on redistributing your program.
https://technet.microsoft.com/library/dd919230.aspx
Related
I have an installer package for a 32-bit Application (built with MakeMsi, originally for Windows XP, and simplicisticly maintained since then), that fails registering a COM server on modern (64-bit) Windows systems (7, 8, 10). This is what I see when trying to install my MSI normally:
Application Error
Exception EOleSysError in module xyz at 000F0B01. Error accessing the OLE registry.
If I bring the MSI in compatibility mode Previous version of Windows, the COM server registers successfully. Since "it's working" somehow, I didn't invest much time in exploring the reasons so far. But finally, I'm exhausted to remember our customers (and sometimes also me) again and again of this precondition, so I wish to fix this issue.
The registration (and de-registration) is done via CustomActions, as I see looking into it using Orca:
"[INSTALLDIR.MYAPP]\placeholder.exe" -regserver
"[INSTALLDIR.MYAPP]\placeholder.exe" -unregserver
For each of those entries, Type is 1122 and Source is INSTALLDIR.MYAPP.
I could imagine that the COM server is started with insufficient privileges in the installation procedure, but aren't installers run automatically with administrator rights? I mean, when I (as a standard user) start the installer by double-clicking it, it shows the UAC prompt before the actual installation takes place. Why are the COM servers not run with elevated rights for their registration and de-registration? It's confusing...
How should I change my MSI to make Windows installer process it successfully?
I assume you know that the problem is in the executable that you're running as a custom action, not anything in Windows Installer. That means the issue will be the code in the executable, and it's probably old and incompatible with later OS versions. You'll need to look at the code to see what it's doing that is unsupported.
Many installs don't bother with self-registration. That data is all static data that can be extracted once and included in the MSI file in registry entries and other COM class tables. This means that there is no need to run code at all during the install.
After learning how to register COM servers the right way, I still was interested to understand, why my MSI package worked before. In other words: what is the crucial change after Windows XP? ...I meanwhile also checked that the MSI works when I run it as an administrator...
As I figured out reading the WiX toolset documentation, there is an attribute Impersonate for CustomAction that controls if the CA is executed with elevated privileges:
This attribute specifies whether the Windows Installer, which executes as LocalSystem, should impersonate the user context of the installing user when executing this custom action. Typically the value should be 'yes', except when the custom action needs elevated privileges to apply changes to the machine.
It refers to the msidbCustomActionTypeNoImpersonateflag in the Type field of the CustomAction Table. The value 1122 I observed in my MSI is decompiled into this:
1024 (flag): msidbCustomActionTypeInScript, or, deferred execution, runs in installation script
64 (flag): msidbCustomActionTypeContinue, or, ignore exit code and continue
34: Custom Action Type 34, or, launch executable via commandline
What I used to "fix" the problem the fast way is, enable the msidbCustomActionTypeNoImpersonate flag (2048) in the CA type (in WiX this would be Impersonate="no").
Translated into my MakeMsi script, I had to use the System attribute in the Type of the ExeCa command as to make self registration work as before:
Type="Deferred Sync AnyRc System"
I'm fully aware that this is only a workaround, since running a COM server for (un-)register is dangerous. And so the solution mentioned in the second section of PhilDWs answer should be preferred: manage COM related static information via registry entries in the MSI. But sometimes you need a fast solution, and sometimes there is no other option, see Euro Micellis comment.
I am trying to check if drivers are installed for a particular USB device as part of an installation process. Unfortunately the manufacturer has several different installers for the same driver and there seems to be no consistent place in the registry to check if the driver is installed. However it's obvious that Windows must know if a driver is installed for a given USB device ID (Eg VID and PID) and I presume this is recorded in the registry?
How can I check to see if the driver is installed only by querying the registry, without relying on looking for installer-specific keys such as references to the uninstaller (which is unreliable) or calling Windows API functions?
Don't query the registry. There's no documented location for this, and it changes. Definitely between versions, possibly with service packs.
The proper way is to use Windows API functions, and it's unclear why you would reject this solution.
I faced the same Problem as you as I wanted to check in Installshield if a device driver was already installed.
I first tried the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\ path as mentioned in USB Device Registry Entries, and it worked on 2 Windows 10 systems I tried but on a 3rd System it was not located here anymore but in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceMigration\Devices\USB\, I assume it has with a Windows 10 update to do but I am not sure…
I finally found out, that on all Systems I was able to find the VID/PID text (in my case VID_0483&PID_DF11) in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class, which is pretty much what people programmatically do here .
Anyway as MSaters suggested I would rather use a C# Windows query like System.Management.SelectQuery query = new System.Management.SelectQuery("Win32_SystemDriver"); (see How to check whether a driver is installed?) as I am not sure, that the registry query allways work but it is in my case not possible.
Edit:
I found out, that Windows creates the registry entry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\ as soon as the device is connected, even without drivers installed, that means that it is an incorrect way to check if the driver is installed.
There is another way though, the registry entry contains "VID_XXXX&PID_YYYY" then a "SERIAL" as subfolder, in my case (VID=1FC9, PID=000C, SERIAL=ABCD) \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_1FC9&PID_000C\ABCD, you can then check the presence of an entry called Driver, it seems like it is only created after you install your Driver.
And for some reason the entry to look for under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceMigration\Devices\USB\VID_1FC9&PID_000C\ABCD seems not to be Driver but DriverInfName
To install a driver, you typically send the command:
DefaultInstall 128 {inf path}
to the InstallHinfSection via direct call or RunDLL.
This works wonderfully. I can install my driver anywhere (including 64-bit Win 2008 R2, which means I've got all the code signing right too).
HOWEVER, the above fails when launched from a Windows service. I've read about service vs client installs, and hoped I had met all the requirements for a silent service install (built a .CAT file, it is signed along with the driver, etc).
But no dice - it just fails. Comparing the errors in SetupAPI.log between an interactive install and the install from the service doesn't show any differences (other than the interactive takes the steps of copying the driver file and succeeds, where the other doesn't).
The driver itself is not in use (my service is the only one that uses it). Is there ANY way for a service to silently update a driver without requiring user interaction?
I called Microsoft and discussed this with a support engineer.
Turns out that using DefaultInstall with InstallHinfSection is somewhat obsolete, but still works. And it just happens to work without prompting the user if the driver is signed by a certificate that they recognize because DefaultInstall is 'dumb'. Yet the driver itself is still allowed to launch because it's cross-signed with the Microsoft cert. A nice little loop-hole I guess. The trick is it has to be installed by a service that is set to Interact with Desktop (a requirement). Using something like PsExec or RemCom is a way to do this if your service isn't currently running in that way.
In the future, this might not continue to work. At that point, get the driver's .cat file into the Windows\System32\Catroot{F7... folder but it can't just be copied directly in -- there is an API.
If the .cat was put in first, then the driver theoretically shouldn't need to prompt to ask if the certificate for the driver is acceptable to the user, because catroot is the 'acceptable to the user' list of certs and drivers.
Also, having the catalog file installed before attempting the driver install might help since the catalog contains the security certificate that the driver will present (though not necessarily in this case -- but it might help in the future (and possibly with Win 2003)
Basically the support engineer was surprised this worked at all and we went around and around on how it might be working... Hopefully this helps someone else.
We have a usb device and the drivers (.inf, libusb.dll, libusb.sys) and can install it using Windows' Device Installation Wizard (by pointing to the .inf file). However, we need to install the drivers without using the wizard (passively, so the user doesn't need to do anything). Does anyone know how this can be achieved?
You added the "installer" tag, so I'm assuming you're talking about some kind of installation package, like Windows Installer, InstallShield InstallScript, etc.
If that's the case, you should probably use Microsoft's DIFx framework.
DIFx makes it easier for you to create
high-quality driver packages,
customize the installation of driver
packages, allow the installation of
driver packages in combination with
application software, and use the
standard Windows APIs and installation
tools. DIFx also makes it easier for
end users to diagnose device and
driver problems. End users can be
confident that, if necessary, drivers
can be uninstalled or rolled back.
I've used DIFx from both Windows Installer-based installs and InstallScript installs. Very user-friendly, easy to debug, and effective.
My colleague came up with an answer that is working very well. It appears that, unless you hardware/driver combination is WHQL signed, the Add New Hardware Wizard will always appear in Win XP. However, with the following method it is possible to have the "Search" button in the wizard find your driver automatically. In Windows 7, there is no prompt and the device installs just fine. You'll need to watch out on 64-bit machines, though, as they have much stricter signing enforcement.
So here is the relevant excerpt from the whole document:
Use the DIFxAPi merge module. (Read a good introduction to drivers in Windows, the use of INF files, and DIFxAPP.) The DIFxAPI merge module is included in the WDK in the ‘WDDK//redist\DIFx\DIFxApp\MergeModule\’ directory. The merge module can be included in an MSI package and can be set to install multiple device drivers. Here are the steps to create an MSI with the DIFxAPP merge module:
In the setup folder, create a separate directory in the Application Folder for the driver package and add the driver files to the folder.
Add the DIFxApp.msm to the setup project.
Build the setup
Use Orca to edit the MSI database table and add the INF component to the DIFxAPP merge modules table.
The Orca installation is included in the Windows SDK in the ‘C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin’ directory. (The Windows SDK can be downloaded from Microsoft)
Run Orca and select the MSI package that needs to be modified.
Read part 5 for automation.
In the ‘File’ table, locate the INF file of the driver package you would like to install and copy the Component value.
Create a new row in the MsiDriverPackages table. Add the Component value into Component field. The following flags can be used (although some are ignored by Windows 7):
0 - Not set (default)
1 – Force installation of driver, even if it the currently installed drivers is
a better match than the driver being installed
2 – Suppress message box telling user to plug in devices after the driver
has been installed.
4 – Suppress adding an entry in Add/Remove Programs for driver.
Driver will be uninstalled when main application is uninstalled.
8 – Install unsigned driver packages
16 – Remove driver binaries during uninstall.
Save the MSI. In order to automate the process, the editing of the MSI database can be recorded to a Transform and then the Transform can be applied in a post build process.
Open the MSI in Orca.
Select Transform->New Transform
Complete steps 3 and 4 in the above directions.
Select Tranform->Generate transform and save the transform.
Add the following line to the post build of the Setup Project
MsiDb.exe -t transform.mst -d $(TargetDir)\DriverInstall.msi
Note: MsiDB.exe comes with the Microsoft SDK and is located in
C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin
If you get an error installing from the MSI (e.g. I got error code 2356 which ended up being due to an invalid Flag value), use Orca's Validate function to see if there are any errors. EDIT: Fixing these errors still has not gotten rid of the error. I remember reading that inf files should be in their own sub-directory, but that didn't fix my problem either.
I'm trying to install a DMO which requires me to write to HKCR\DirectShow\MediaObjects\Categories\57f2db8b-e6bb-4513-9d43-dcd2a6593125, this registry path is protected by TrustedInstaller and it seems that this protection is new in Windows 7 (it work on previous platforms).
How am I suppose to install DMOs?
There are plenty of places that suggest to take ownership on the this registry key but this just doesn't feel right.
BTW, were using boilerplate Wix3 to write the registry values.
The Windows Installer cannot be used to update Windows. I know it sounds funny but Windows Installer is for "applications" and the Trusted Installer is for "the operating system". To update pieces of the operating system, you need to use an operating system service pack or KB.
If this is a documented place in the registry that you are supposed to be able to extend then I would guess it would be necessary to contact Microsoft about the key being protected. My guess would be that it is a bug.
If it is a bug in Windows then Microsoft hopefully would provide a work around or fix. Maybe the answer is to take ownership of the registry but I agree that doesn't seem right.