How can I develop windows driver that does not touch hardware? - windows

I need to create a WDM driver that emulates a device that is not present. The driver needs to be loaded when the O/S boots, opened and closed via SetupDiXXX and CreateFile, needs to respond to DeviceIoControl, etc.
I have the driver coded, but XP refuses to load it. The system event viewer says:
The MyDevice service failed to
start due to the following error: The
service cannot be started, either
because it is disabled or because it
has no enabled devices associated with
it.
Given that, I think the problem is in the INF file (reference below). Is it? How should I go about fixing it?
;; MyDevice.inf
[Version]
Signature="$Windows 95$"
Class=MyDeviceDeviceClass
ClassGUID={ff646f80-8def-11d2-9449-00105a075f6b}
Provider=%ProviderName%
DriverVer= 12/21/2009,1.0.0.1
[ClassInstall32]
Addreg=Class_AddReg
[Class_AddReg]
HKR,,,,%DeviceClassName%
HKR,,Icon,,"-18"
[DestinationDirs]
MyDevice_Files_Driver = 10,System32\Drivers
[Manufacturer]
%MfgName%=Mfg0
[Mfg0]
%DeviceDesc%=MyDevice_DDI, *MyDevice
[MyDevice_DDI]
CopyFiles=MyDevice_Files_Driver
AddReg=MyDevice_9X_AddReg
[MyDevice_DDI.NT]
CopyFiles=MyDevice_Files_Driver
AddReg=MyDevice_NT_AddReg
[MyDevice_DDI.NT.Services]
Addservice = MyDevice, 0x00000002, MyDevice_AddService
[MyDevice_AddService]
DisplayName = %SvcDesc%
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %10%\System32\Drivers\MyDevice.sys
[MyDevice_NT_AddReg]
HKLM, "System\CurrentControlSet\Services\MyDevice\Parameters","BreakOnEntry", 0x00010001, 0
[MyDevice_Files_Driver]
MyDevice.sys
[Strings]
ProviderName="Acme"
MfgName="Acme"
DeviceDesc="Acme"
DeviceClassName="Device class for MyDevice"
SvcDesc="MyDevice NT service"

Self answered:
I changed the INF to include the following:
[Mfg0]
%DeviceDesc%=MyDevice_DDI, *MyDevice\ipm1
The "\ipm1" is new, and a little voodoo in my eyes. I got it from an example in Chris Cant's "Writing Windows WDM Device Drvers".
The big change is using the "Add New Hardware" wizard from the control panel to install the driver. Right-click installing the INF is not enough. I suspect the reason is that it invokes the PnP manager which correctly fails to find hardware for the driver to control.

Related

How to force Windows Device Manager refresh device name display after I change FriendlyName registry value

Microsoft WDK's Toaster sample code contains a ClassInstaller example(tostrcls.dll). It shows the ability to customize "device friendly name" displayed by Device Manager. The ability is achieved by modifying FriendlyName's value for the device's hardware key . After modifying FriendlyName, a close and reopen of the Device Manager window(devmgmt.msc) will reflect such changes. So far, so good.
However, in order to tell Device Manager window to reflect the change immediately(without close and reopen its window), some extra code has to be run. classInst.c takes the following way:
spDevInstall.FlagsEx |= DI_FLAGSEX_PROPCHANGE_PENDING;
SetupDiSetDeviceInstallParams(Params->DeviceInfoSet,
Params->DeviceInfoData,
&spDevInstall);
That works, but NOT optimal. DI_FLAGSEX_PROPCHANGE_PENDING causes the device to go through a STOP/START cycle. I mean, the driver's ToasterEvtDeviceReleaseHardware and ToasterEvtDevicePrepareHardware get executed. I think this is an undesired side-effect.
So my question is clear. Is there a way to refresh Device Manager's display without bothering with the driver code?
I got the answer from WDK7 PnpPorts project(which is the ClassInstaller that implement the Windows COM Port "Port Setting" tab).
Just change
spDevInstall.FlagsEx |= DI_FLAGSEX_PROPCHANGE_PENDING;
to
spDevInstall.Flags |= DI_PROPERTIES_CHANGE;
all done.
Note: The device-restarting behavior of DI_FLAGSEX_PROPCHANGE_PENDING is documented in WDK7 chm page "DIF_ADDPROPERTYPAGE_ADVANCED" but not in "SP_DEVINSTALL_PARAMS". I only check the latter, so missed it.

Install Windows Sample port monitor localmon (Win7 32-bits) from VS2013 Update 4

I downloaded the example for a port monitor including localmon (http://tinyurl.com/kg8bvt7).
It compiles in VS2013. I managed to add a driver package to the solution. And I setup a test PC using WDK 8.1 (wdktestsetup.exe). I can ping this test PC from my development PC.
However, if I go to the Properties page of my driver package and choose "Deployment" I enabled deployment (check mark), specified the target computer name by it's IP address, choose "Install and verify" and from the combobox I selected "Default Printer Driver Package Installation Task (possible reboot)", then I still get an error when I try to deploy.
I build for "Win7 Debug" configuration and "Win32" platform.
The error which I get is:
Error 1 error : Could not connect to the remote computer for deployment. C:\Program Files (x86)\Windows Kits\8.1\build\Win32\ImportAfter\DriverDeployment.targets 69 9 monitors
Error 2 error : Printer model name must be supplied for printer driver deployment. The model name must be supplied on the DriverInstall->Deployment property page. C:\Program Files (x86)\Windows Kits\8.1\build\Win32\ImportAfter\DriverDeployment.targets 69 9 monitors
I searched on info for the second error ... and I found this help:
http://msdn.microsoft.com/es-es/library/dn641620%28v=vs.85%29.aspx
In section "Configure driver solution for debugging and deployment" it states that you should be able to "Type the name of the driver in the Optional Arguments field". I do not see such an Optional Arguments field in my VS2013 ...
Any hints on what I could try?
Thanks.
In the deployment property page, under the "Install and Verify" option, there is a text box where you can add text. That's where you should supply the printer model name.
If you can't see that text box, you might want to resize the property page to increase its height. I seem to remember that there was an issue in WDK 8 where there would be no vertical scroll bar on that property page, even though there should be. I'm not 100% sure if it was fixed in WDK 8.1.

User defined database location

My application, originally created in win XP using vb6, stores program specific values in the registry. One of those values is where the database the program uses is located. The user can put it where ever they like and the program starts it prime the db location screen with the values last saved from the registry. This form uses the DriveListBox, DirListBox, and the FileListBox components. When running this application on Win 7, i am getting an error trying to set the dir list to the value stored in the registry which is a network drive. This all work fine if the drive the db is stored on is local.
The code is:
On Error GoTo HandleError
dbLocation = GetSetting(App.Title, "Settings", "DBLocation", dbserver)
If dbLocation = dbserver Then
Dir1.Path = GetSetting(App.Title, "Database", "ServerDBPath", "C:\") <----- fails
Else
Dir1.Path = GetSetting(App.Title, "Database", "LocalDBPath", "C:\")
End If
Drive1.Drive = Dir1.Path
Exit Sub
HandleError:
MsgBox "Error connecting to the network. Check network connections and try again.", vbOKOnly, "Connection error"
Drive1.Drive = "C:\"
I am suspecting the problem is with the directory list box. If i remove my error handling, the error thrown is "Device Unavailabe"
Any ideas on what happening? Are the components I am using not valid for win 7? For this application, the database has to be on a network drive so it is accessable from several PCs running the program. All of the PCs are running on Windows 7.
The drive, directory and file controls that come with VB6 are hopelessly out of date. They have not significantly changed since VB3 - and that was back in the mid nineties. These were designed for use with Windows 3.1! You would be better off using the Open File and Save File dialogues which come with the Common Dialogues library.
As for the dlls for vb6 provided in windows 7, see http://msdn.microsoft.com/en-us/vstudio/ms788708.aspx
GetSetting is a VB6 call to the registry. Windows 7 on a 64bit machine moved the location of the registry for 32bit apps to something like WOW3264.

How to find the latest com port created in my pc?

How to find the latest virtual COM port created in my Pc??
device manager -> ports -> devicename ( COM X ).
How to find that "COM x" programatically?
Look at the SetupApi, specifically the SetupDiEnumDeviceInfo() and CM_Get_Device_ID() functions.
This project has some sample code that shows the usage.
"Install Date" is one of the properties on the details tab of a hardware properties page from device manager.
I expected to be able to find a key in the registry for it:
HKLM\SSYSTEM\CurrentControlSet\Enum\...
But there isn't a key, or at least, I can't find one.
Will a search by VendorID + DeviceID/ProductID be sufficient?

Is it possible to unload a kernel driver without a reboot?

I'm playing about with one of the kernel driver examples in the Win7 DDK. I can modify compile and build my *.sys file. I can install it too with its INF (using device manager or devcon) or using the Service control manager directly. When I make the next change though and generate an updated *.sys file I seem to get a conflict between this new file and my now stopped driver (I've tried using Servcie Control Manager 'stop' and 'delete service' etc). If I reboot, I can install the new driver and run it fine. Similarly, if I choose uninstall in Device Manager, Windows prompts me to reboot.
So, how can one easily test incremental modifications to a kernal driver easily?
Thanks
Looking at the Setup API logs might be a good place to start: http://msdn.microsoft.com/en-us/library/ff550887%28v=VS.85%29.aspx
If devcon prompts for a reboot, you could look at the code in the DDK, debug why it's asking and dig into the issue that way as well.
Yes. sc stop <driver name> should stop your driver. If your driver is associated with a particular PnP devnode, it should be unloaded after the devnode is removed.
If you want to be able to unload your driver you have to set up a function which basically executes each time the driver is unloaded - most likely you will put code which frees allocated buffers and any other resource which might be "alive" during the lifecycle of the of the driver. Here is an example code:
VOID Unload(IN PDRIVER_OBJECT pDriverObject) {
//do whatever you like here
//this deletes the device
IoDeleteDevice( pDriverObject->DeviceObject);
return;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING regPath) {
//initialize your driver and the major function array
//set the unload function
pDriverObject->DriverUnload = &Unload;
}
Try compiling, signing, and loading this code:
#include <ntddk.h>
VOID OnUnload( IN PDRIVER_OBJECT driverObjectA ) {
DbgPrint("Unload\n");
}
NTSTATUS DriverEntry( PDRIVER_OBJECT driverObjectA, PUNICODE_STRING RegistryPath ){
DbgPrint("DriverEntry\n");
driverObjectA->DriverUnload = OnUnload;
return STATUS_SUCCESS;
}
Then download DebugView, unzip it, run it as administrator, and then "Capture Kernel" under the "Capture" menu item. Download, unzip, and run the OSR Driver Loader, register the driver, the "Start Service". You will observe a "DriverEntry" log message in DbgView. Now in the the OSR Driver loader, "Stop Service" and observe an Unload message. Hopefully that gets you going.

Resources