Thursday, March 26, 2009

I Just Wanted to Install My Dam Driver on Windows 7...

I have a simple NDIS protocol driver that has worked for years on Windows 2000 through Windows Vista - then along comes Windows 7. To be honest, getting the driver to install seamlessly on Windows 7 took more time than I had planned.

*** Deprecated Functions ***
I've been writing NDIS drivers and related user-mode components since the DOS days. Some code snippets just get mindlessly re-used without being reviewed for years.

One snippet was associated with creating a driver service. This one has legacy code that attempted to lock the service controller database using LockServiceDatabase before calling CreateService. Well, on Windows 7 this function is deprecated; it can be called - but it does absolutely nothing. That's not terrible - BUT - the deprecated function never returns success.

Consequently calling my old code snipped resulted in an infinite loop.

So, take out that code and get a little further...

*** Device Object Security ***
On Windows 7 it is important to review security descriptors that you may assign to device objects. For example, if in the past yo assigned a NULL DACL to an object, don't expect Windows 7 to ignore it. A NULL DACL basically allows any user (anonymous, guest, authenticated user or administrator) to access the object: No access limitations at all!

Change that to use a more limited DACL!

Doron Holan has some notes in his blog at http://blogs.msdn.com/doronh/archive/2007/10/16/setting-a-security-descriptor-on-a-legacy-device-object.aspx.

In my case I am setting the device security from user-mode by calling SetServiceObjectSecurity and ConvertStringSecurityDescriptorToSecurityDescriptor. The MSDN has a decent example of using the latter to make a limited DACL that makes some sense.

*** Getting Elevated Privilege ***
The NDIS protocol driver is installed using an enhanced version of the ProtInstall utility described on NDIS.com at the URL http://ndis.com/ndis-general/ndisinstall/programinstall.htm.

The enhancement is basically to set an appropriate security descriptor (discussed above...) on the device object after installing the driver.

Of course, both calling the INetCfg API to install the driver and calling SetServiceObjectSecurity both require elevated privileges.

I'm not a Windows Installer SDK whiz and have grown tired of paying for installer tools that do more than I want (and must be updated for a fee with each Windows release). So, I have a simple Windows Installer project built under Visual Studio 2005. The installer installs both the driver(s) and some simple companion applications and support DLLs. This installer simply calls ProtInstall as a CustomAction during the Install and Uninstall phases.

Of course, these CustomActions must be executed with elevated privilege. Unfortunately, Visual Studio 2005 does NOT provide a way to specify that a CustomAction must be run with elevated privilege. This means that a user cannot simply download the MSI file and install it: The install will fail.

On Vista I took the easy way out: I required the user to download both the MSI file and the companion Setup.exe file. If the Setup.exe file is executed with elevated privilege, then execution of the MSI will inherit the elevated privilege and the CustomAction (calling ProtInstall...) will succeed.

But that's a nasty extra step. For Windows 7 I want to eliminate the need to use Setup.exe.

Fortunately Alek Davis of Intel was kind enough to have blogged about this particular problem. He provides a "bit of advice" (Actually bit 2048 in the CustomAction Type field...) that convinces the MSI installer to require elevated privilege when calling a CustomAction. The post of interest is at http://alekdavis.blogspot.com/2007/09/deploy-windows-services-on-vista.html.

After following his advice use of the extra Setup.exe bootstrapper is no longer necessary.

*** Summary ***
Thanks to having to work with Windows 7:

1.) My driver installs more cleanly - even on prior Windows versions.
2.) My software is more secure - even on prior Windows versions.

I'm tired of Windows 7 already. But it has forced me to make improvements and "That's a good thing!" (TM).

Thomas

Thursday, May 31, 2007

Installing NDIS Protocols and Filters Programmatically

The Windows INetCfg API is used to install NDIS components, and the WDK includes the BindView sample application that illustrates its use.

BindView is a flexible Windows application that can install and uninstall NDIS clients, protocols and services. It is a good tool for use at certain stages of driver development, but can't be easily adapted to support programmatic NDIS component installation.

The Windows 2000 DDK includes a command-line tool called SNetCfg which could be used to programmatically install NDIS components if it was fed with the proper arguments. However, SNetCfg was clumsy to use and was a little buggy. It was dropped from later DDK versions in favor the more user-friendly BindView tool.

What I have found is that if you finally get one simple NDIS component installer (e.g., an installer for the DDK NDISPROT driver) to work the way you want it to, then it is easy to extend that installer to work with other NDIS services and protocols.

Installing the NDISPROT NDIS Protocol Driver Programmatically

As a starting point for my own work I wanted a simple tool that would help me understand how to use the INetCfg API to install a single NDIS protocol driver. In addition, I wanted this tool to be callable from a Windows Installer as a Custom Action.

I started with the old SNetCfg application and the current BindView application and made a command-line tool called ProtInstall. I modified the code to allow it to be built under Visual Studio instead of the Windows DDK build environment.

I have posted a page on NDIS.com that describes ProtInstall. It can be found at the URL:

http://ndis.com/ndis-general/ndisinstall/programinstall.htm

That page also includes a link for downloading the ProtInstall source code.

The installer uses hard-coded service and PnP ID strings. These are all defined in the ProtInstall header files, which is intended to be a common header shared between drivers, installers and user-mode applications. So, if changes are made to this one file and referencing components are rebuilt, then they all should work properly.

ProtInstall works for me. Perhaps it can be of use to some readers as well.

Installing a NDIS 5 Intermediate Filter Drivers

This can be done by making a simple modification to the HrInstallNetComponent method in the netcgfapi.cpp module. Simply insure that the IM filter service and the companion IM filter miniport INF files are both copied using SetupCopyOEMInf call.

That's about it!

Installing a NDIS 6 Lightweight Filter Driver Programmatically

Just like installing a NDIS 5 protocol driver…

Multi-Platform NDIS Protocol and Filter Installers

Only simple additional modifications are needed to detect the OS and use different service, INF and PnP ID strings for the actual host platform.

Caveat Emptor

Although I have been using variations of ProtInstall in my own work, some folks have apparently extracted the code and included it within their own applications or services. That's fine with me, but if it doesn't work in a different application or service environment, then it's up to you to determine what's different.



NDIS Testing 1.00.00.01

My first post concerns NDIS testing with the new "Driver Test Manager" (DTM), soon to be replaced with the new and improved "Windows Logo Kit". I have been spending more time than I would like re-imaging DTM Clients and sitting in front of the DTM Studio console.

Here are a few tips that may be obvious to many of you, but you may overlook in haste to get a test submitted:

Update Your DTM Client BIOS

When you purchased your DTM Client machine it may have been setting on the shelf for a while and your "brand new" machine may have a BIOS that is out of date. If the machine has been around for a while after you acquired it the BIOS may have gotten even further out of date.

In addition, if there is a new major operating system release (e.g., Windows Vista…) there may be BIOS fixes that are needed specifically to support the new OS.

Updating the BIOS may or may not really make any difference, but it is good insurance.

Finally, if you ask for support for problems related to PnP and power the support representative will often suggest that your problem is a BIOS problem. That still could be the case, but at least you can say that you are testing with the latest BIOS.

Remove Unnecessary Devices

Use minimal devices on your DTM Client machine. Install just what you need and nothing more. It's really frustrating to encounter a crash in an unrelated driver in the middle of a three hour test run. It ruins you day unnecessarily.

Use Windows Update on Your DTM Client

Examine "All Available Updates" and get the most recent drivers for your system. Insure that there are no banged-out devices in the Device Manager.

Review Network Settings

If your DTM Client is multi-homed (i.e., multiple network adapters) carefully examine your network settings. My experience has shown that if your DTM Client/DTM Controller network topology is not robust DTM may make a bad routing choice.

The effect that I saw when I overlooked this step was that DTM seemed to "run like molasses". Some tests would appear to run very slowly while others would be cancelled by the DTM because of timeout.

An operation like Preparing DTM Client for Submission would take almost an hour if network settings are messed up and only minutes if settings are OK.

Use a Debugger

With the current DTM it is often difficult to identify the actual cause of a test failure. Sometimes you can see the actual problem in the debugger much more easily than you can in the DTM Studio.

In addition, for some tests involving sleep transitions the debugger gives helpful insight into the state of the system.

Use Reimaging Tools

It is almost certain that tests will fail and you will have to start over. (And over, and over…)

So take a snapshot of your DTM Client image using a tool that can save a complete disk partition as a file.

You will probably have to re-image more often than you hope…

Some Advice from WHQL

The July 16, 2007 issue of the WHQL and Windows Logo Program Newsletter includes some advice on avoiding test failures. The newsletter can be found at the URL:

http://www.microsoft.com/whdc/whql/resources/news/WHQLNews_071607.htm


Testing NDIS 5 Intermediate Drivers

As of this date (July, 2007) there is no WHQL/WLK test for NDIS 5 Intermediate drivers. If you want to get a WHQL signature for a NDIS 5 IM driver you must use the "Unclassified" test from the WLK.

Welcome

I will be using this space to record information about Windows kernel-mode networking topics from time-to-time. I expect the content to range from editorial to tutorial, and will include notes to myself as I research, develop and test different things.

You are welcome to read along.

Thomas F. Divine

P.S. Since I don't care for SPAM, comments will be moderated.