Where to start with driver development

Hello,

In my research about Driver Development I came up with your community. I have found very interesting resources around that helped me to understand a little better this commonly unknown world on development, at least it cleared out some initial questions.

Recently, I got into a company where the previous developer left. I have to maintain and develop a Java software, let’s call it Label Editor for now on. This company produces some mechanical machines that have an attached printer on it and was created by the company itself. The printer receives commands through this Label editor using either Ethernet or RS485 connections and their own protocol for the data.

Now the company wants to allow clients optionally stop using this Label Editor and have a “Printer Driver” who is just able to send images to the printers. They simply want to press the print button on a Windows application and choose one of the printers around.

I have been looking around and tested some of the driver samples on MSDN but I’m not really sure how to proceed. I have no deadline for now so I’m not in a hurry and I’m willing to learn all that I need to accomplish this task (but paying for a solution is also an option), I’m used to take care to research for a solution all by myself for most of the issues (My boss was counting on that) but right now I’m not really sure how to proceed with this project.

  • Should I really create a driver that can communicate using TCP/IP? (RS485/COM is a bonus for now, not a requirement)
  • Is it possible for a driver to use sockets with TCP/IP or that’s an issue?
  • Where do I start with this? I was unable to deploy the XPS driver sample. I was able to deploy a v4 printer driver but I have no idea how to run / test it.
  • How can I make the target computer show a Printer that is using the deployed driver?
  • Do I actually need a “software printer” with just an Input field for the printer identifier (it matches the last octet of the IP address) as the hardware works standalone? Usually the IP addresses only differ on last octet, the first three octets and the port are usually static so they can be a config value somewhere on the machine.
  • How do I trigger “my code” / the printer driver?
  • Can I create / attach breakpoints the same way I’m used to do with any other debugger (Through UI I mean) using windbg?
  • What approach should I take?
  • May I create a Windows service and talk with it? How to talk with it? I have already created Windows services before.
  • May I just disregard all the Windows driver stuff and try to create an IPP printer with some extra service? Someone suggested to me to either have a phisical or embed a virtual machine with Linux somewhere near to do it like that. I still don’t know how to proceed on that, need to do more research but it’s an option I didn’t look at yet.

I know this task sounds out of my capabilities, I have worked most of my years as a Full Stack Web developer with all kinds of applications so I’m not used to take care of hardware this way. I have already coded some libraries that are able to send all the data I want to one of our printers given an Image and an IP address but need to connect that with a print dialog somehow. My boss knows about my backgrounds and he has no issue with me taking months to accomplish this, also I’m very interested into knowing how this lower level software works.

Sorry for the big array of questions and thanks for your time.

If you are using Ethernet then simply open a socket (presumably your “device” has ethernet/TCP/IP?)

If you want to communicate over RS485 then look for a USB to RS485 solution from

https://www.ftdichip.com/

Where the hard work has already been done in terms of drivers.

I don’t think writing a driver is really necessary for what you want.

I am more than prepared to be stood corrected by the more enlightened members of this group.

Hi! Thanks for your answer, I think you may have misunderstood the main requirement.

I’m already able to send data to the printer through a socket over ethernet-TCP/IP. Also we use (among others) a USB-RS485 FTDI adapter. This is done through our “Label editor” to send images to this custom printers.

The issue is to make this devices be shown as a printer to the operative system so any application can send an image to print. From the point of view of an user they just want them to look like normal printers so they can use them like that.

Updated version of that ancient article on Getting Started With Windows Driver Development can be found here.

ETA: I have absolutely no idea how you surface a printer in Windows. Sorry! I’m sure other here DO know, however.p, and hopefully they’ll share.

Peter

I will try to keep writing my development process, I got into few ideas about this project but can’t say it’s easy to really move on, I will start giving some info for anyone who gets into a situation like mine.

What I’m sure is that there is no need for KMDF for now.

For now I would like to be able to write to a file and then I will be able to move on possibly. The main concept of search turned to be “Virtual printer driver”.

Some resources (I’m finding some new stuff at the time of writing so some of them I didn’t checked very much):

Also found some “pay to use” projects in this direction that would solve the main driver problem “out of the box”, either through an SDK or giving away their source code:

Even if my company may agree to pay, I prefer to keep going without that for now, I will just list them here for anyone who may use it
Checking this projects, for most of cases it looks that they implemented the OEM bitmap sample from the windows driver samples page, some of them with some Custom UI features.

Just checking their demos .inf files gave me this information.

I decided to use the OEM bitmap as a bitmap file possibly fits my later on needs, I will need a single file (no pages) with pixel colour access.

Through the process of different projects and tutorials I could learn a lot about printing architecture, windows drivers and inf files but still find very weird and messy how all this lib’s functions are named, historical reasons I assume.

Following the instructions I was able to build the bitmap project and have all the installer files through a “Driver Install Package”.
Note that user mode drivers don’t need certification (Is that correct? I did disable certification verification on the target computer so I’m not sure anymore).

I was able to deploy the files into my target test virtual machine and load the driver (using the inf file). Some explanation for new Windows Versions may be needed here as the process changed through the years and it was misleading me at the start. The way to make the “Add printer wizard” show up has changed. Skip the next paragraph if not interested:

To install your printer driver (I’m translating right away from a different language so the texts may not be exact):
win-key → configuration (click gear icon or type config right away) → Devices → Printers (on the left menu). Select add a printer… and wait for a “My printer is not on the list” link appear. Click it to open the Add Printer Wizard. Then follow the already online options: Pick the last option (Add a local or network printer manually) → Existing port “File:” → Use disk button → “Search…” button, find your inf file, usually on the output folder of your solution.


Done with the research part of the post, now the current situation.

So here I am with the loaded Printer Driver based on the Oem bitmap. The issue is, I’m not even able to confirm that it’s working or how.

I can select the printer on a print dialog from any application and nothing happens. The bitmap source code sends the data to the spooler, so it was expected for me to nothing happen but I’m unable to create a breakpoint for debugging or view any logs I did add on the code.

On this tutorial they indicate to change the giDebugLevel var in order to make the messages show.

So I run a paint and attach the process. On list modules I can see unidrv and unidrvui but not my bitmap.dll:
`
0:001> lm m uni

Browse full module list

start end module name

00007ff8-37040000 00007ff8-37163000 UNIDRVUI (deferred)
00007ff8-553c0000 00007ff8-55444000 UNIDRV (pdb symbols) C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\sym\unidrv.pdb\AC8085887A19C5169C59D1D8D730D33A1\unidrv.pdb

0:001> lm m bit
Browse full module list
start end module name
`

And I can’t change the named var on unidrv:
`
0:001> ed unidrv!giDebugLevel 1

Couldn’t resolve error at ‘unidrv!giDebugLevel 1’
`

If I print using my virtual printer driver, I can see this message:
ModLoad: 00007ff8-5e390000 00007ff8-5e3a0000 C:\Windows\system32\spool\DRIVERS\x64\3\BITMAP.DLL

Which means that my dll is actually loaded but there is no debug output and the module still not shows even running .reload command or adding the source paths through .sympath+ as named here

I have to assume that it gets unloaded again.

How can I make it to ensure my code (actually unmodified OEM Bitmap code) is running successfully?

Is there any more pointers you can give me regarding where should I put code to save into file?
My conclusion is to do it at OEMEndDoc replacing the DrvWriteSpoolBuf statments as this (already named) post does but wanted to ensure the code runs before doing any modification.

Greetings and hope this post helps other people (Or triggers someone who may see I’m incredibly wrong and gives more pointers :smiley: )

A big post I made got deleted / marked as spam. It had some interesting info and some questions on my progress, I will pretend it’s here as I assume it will be restored by the mods soon enough, I already requested so.

As I stated there, I had problems detecting if my module is really working or not. When I tried to print something, I would se a meessage on WinDbg naming my dll, but I would not see any of the debug messages I added to the code:
ModLoad: 00007ff85e2d0000 00007ff85e2e0000 C:\Windows\system32\spool\DRIVERS\x64\3\BITMAP.DLL

After some search about this issue, I found an interesting command on someone’s cheatsheet:
Break on .so/.dll load catch load <regex> sxe ld:<module>
Which is quite cool, as I though my dll was being unloaded:
sxe ld:bitmap.dll
This triggered a breakpoint when I would try to print with a printer that uses my driver.
ModLoad: 00007ff834160000 00007ff8341e4000 C:\Windows\system32\spool\DRIVERS\x64\3\UNIDRV.DLL ModLoad: 00007ff8582b0000 00007ff8582c0000 C:\Windows\system32\spool\DRIVERS\x64\3\BITMAP.DLL ntdll!NtMapViewOfSection+0x14: 00007ff864bdc5c4 c3 retAnd I could veryfy my module:
0:000> lm m bit
Browse full module list
start end module name
00007ff8582b0000 00007ff8582c0000 BITMAP (deferred)
`

Then the problem is, I expected more symbols to be present:
0:000> x bitmap!* *** WARNING: Unable to verify checksum for C:\Windows\system32\spool\DRIVERS\x64\3\BITMAP.DLL 00007ff8582b1420 BITMAP!DllGetClassObject ()
00007ff8582b1570 BITMAP!DllCanUnloadNow (<no parameter info>)
Also there is this checksum message. Is it due missing sympath or srcpath?
So I added them and did a reload:
`
0:000> .sympath+ C:\Users\WDKRemoteUser\Desktop\OemBitmap\C++\bitmap\x64\Win10Debug
Symbol search path is: srv*;C:\Users\WDKRemoteUser\Desktop\OemBitmap\C++\bitmap\x64\Win10Debug
Expanded Symbol search path is: cache*;SRV*https://msdl.microsoft.com/download/symbols;c:\users\wdkremoteuser\desktop\oembitmap\c++\bitmap\x64\win10debug

************* Path validation summary **************
Response Time (ms) Location
Deferred srv*
OK C:\Users\WDKRemoteUser\Desktop\OemBitmap\C++\bitmap\x64\Win10Debug
0:000> .srcpath+ C:\Users\WDKRemoteUser\Desktop\OemBitmap\C++\bitmap
Source search path is: C:\Users\WDKRemoteUser\Desktop\OemBitmap\C++\bitmap

************* Path validation summary **************
Response Time (ms) Location
OK C:\Users\WDKRemoteUser\Desktop\OemBitmap\C++\bitmap
`

0:000> !sym noisy noisy mode - symbol prompts on 0:000> .reload /f Reloading current modules . SYMSRV: BYINDEX: 0x5 C:\ProgramData\dbg\sym mspaint.pdb B6B55B8B65A8997B69F77C60878E15D01 [...] . SYMSRV: BYINDEX: 0x2E C:\ProgramData\dbg\sym bitmap.pdb 0D44DAAA89884472B82AD57F0790CD931 SYMSRV: UNC: C:\ProgramData\dbg\sym\bitmap.pdb\0D44DAAA89884472B82AD57F0790CD931\bitmap.pdb - path not found SYMSRV: UNC: C:\ProgramData\dbg\sym\bitmap.pdb\0D44DAAA89884472B82AD57F0790CD931\bitmap.pd_ - path not found SYMSRV: UNC: C:\ProgramData\dbg\sym\bitmap.pdb\0D44DAAA89884472B82AD57F0790CD931\file.ptr - path not found SYMSRV: RESULT: 0x80070003 SYMSRV: BYINDEX: 0x2F C:\ProgramData\dbg\sym*https://msdl.microsoft.com/download/symbols bitmap.pdb 0D44DAAA89884472B82AD57F0790CD931 SYMSRV: UNC: C:\ProgramData\dbg\sym\bitmap.pdb\0D44DAAA89884472B82AD57F0790CD931\bitmap.pdb - path not found SYMSRV: UNC: C:\ProgramData\dbg\sym\bitmap.pdb\0D44DAAA89884472B82AD57F0790CD931\bitmap.pd_ - path not found SYMSRV: UNC: C:\ProgramData\dbg\sym\bitmap.pdb\0D44DAAA89884472B82AD57F0790CD931\file.ptr - path not found SYMSRV: HTTPGET: /download/symbols/bitmap.pdb/0D44DAAA89884472B82AD57F0790CD931/bitmap.pdb SYMSRV: HttpQueryInfo: 80190194 - HTTP_STATUS_NOT_FOUND SYMSRV: HTTPGET: /download/symbols/bitmap.pdb/0D44DAAA89884472B82AD57F0790CD931/bitmap.pd_ SYMSRV: HttpQueryInfo: 80190194 - HTTP_STATUS_NOT_FOUND SYMSRV: HTTPGET: /download/symbols/bitmap.pdb/0D44DAAA89884472B82AD57F0790CD931/file.ptr SYMSRV: HttpQueryInfo: 80190194 - HTTP_STATUS_NOT_FOUND SYMSRV: RESULT: 0x80190194 DBGHELP: c:\users\wdkremoteuser\desktop\oembitmap\c++\bitmap\x64\win10debug\bitmap.pdb cached to C:\ProgramData\dbg\sym\bitmap.pdb\24D121CCC3734A6D98F6370CC4290CB91\bitmap.pdb DBGHELP: C:\ProgramData\dbg\sym\bitmap.pdb\24D121CCC3734A6D98F6370CC4290CB91\bitmap.pdb - mismatched pdb DBGHELP: c:\users\wdkremoteuser\desktop\oembitmap\c++\bitmap\x64\win10debug\DLL\bitmap.pdb - file not found DBGHELP: c:\users\wdkremoteuser\desktop\oembitmap\c++\bitmap\x64\win10debug\symbols\DLL\bitmap.pdb - file not found DBGHELP: C:\Windows\system32\spool\DRIVERS\x64\3\bitmap.pdb - file not found DBGHELP: C:\ProgramData\dbg\sym\bitmap.pdb\24D121CCC3734A6D98F6370CC4290CB91\bitmap.pdb - mismatched pdb DBGHELP: Couldn't load mismatched pdb for C:\Windows\system32\spool\DRIVERS\x64\3\BITMAP.DLL *** WARNING: Unable to verify checksum for C:\Windows\system32\spool\DRIVERS\x64\3\BITMAP.DLL DBGHELP: BITMAP - export symbols . [...] ************* Symbol Loading Error Summary ************** Module name Error BITMAP The system cannot find the file specified The SYMSRV client failed to find a file in the UNC store, or there is an invalid UNC store (an invalid path or the pingme.txt file is not present in the root directory), or the file is present in the symbol server exclusion list.

Notice the message:
DBGHELP: Couldn’t load mismatched pdb for C:\Windows\system32\spool\DRIVERS\x64\3\BITMAP.DLL
*** WARNING: Unable to verify checksum for C:\Windows\system32\spool\DRIVERS\x64\3\BITMAP.DLL

After running .reload -i, the output changed but can’t tell if it’s better:
0:000> lm m *bitmap* Browse full module list start end module name 00007ff8582b0000 00007ff8582c0000 BITMAP C (pdb symbols) C:\ProgramData\dbg\sym\bitmap.pdb\24D121CCC3734A6D98F6370CC4290CB91\bitmap.pdb 0:000> x bitmap!* DBGHELP: C:\ProgramData\dbg\sym\bitmap.pdb\24D121CCC3734A6D98F6370CC4290CB91\bitmap.pdb is a partial PDB and can't enumerate symbol information.

I’m kinda on the same situation, I can’t really verify my dll is being really loaded, can’t debug it or see the debug messages I added.

Thnks!