Unidrv Rendering Plug-in Question

To extract data sent to the printer and to block print operation, Rendering Plug-in for Unidrv is developed.
We are hooking DrvTextOut() function to capture print data.

We are facing following problems

  1. When print job is sent to the HP LaserJet 4250 PCL 6 remote printer, DrvTextOut() is not getting called when printer setting ‘print on both sides’ option is checked.
    But DrvTextOut () is getting called when this option is unchecked.

  2. When DrvSendPage () is hooked , some PCL XL error “Illegal operator Sequence Operator: EndSession” is displayed on the print when tested with remote printer.

Could you please help us out to resolve above mentioned issue?

We would like to ask you,

  1. Is it right approach?
    This approach will work only for Unidrv based printer drivers .Could you please suggest us to make this approach generic for all printer drivers.
  2. Can you please let us the know the statistics of the usage for universal driver and other drivers used for printing?

xxxxx@yahoo.com wrote:

To extract data sent to the printer and to block print operation,

Yet another person spending his time working on methods of preventing
the normal operation of my computer.

Rendering Plug-in for Unidrv is developed.
We are hooking DrvTextOut() function to capture print data.

We are facing following problems

  1. When print job is sent to the HP LaserJet 4250 PCL 6 remote printer, DrvTextOut() is not getting called when printer setting ‘print on both sides’ option is checked.
    But DrvTextOut () is getting called when this option is unchecked.

It is possible that HP has its own pre-processor that is doing a
different kind of rendering, and sending bitmaps down to the printer.
How are you hooking DrvTextOut?

We would like to ask you,

  1. Is it right approach?

The right approach for what? We don’t know what you are trying to do.
If you are trying to detect certain strings in printed output, then
there is absolutely no general purpose method of doing this. Some apps
render their text to a bitmap for maximum control, and just print the
bitmap. Acrobat probably does that. They have their own PostScript
interpreter. With some fonts, the characters you see in DrvTextOut are
font indexes, not Unicode characters. In that case, the string won’t be
recognizable.

This approach will work only for Unidrv based printer drivers .Could you please suggest us to make this approach generic for all printer drivers.

Impossible.


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

“Yet another person spending his time working on methods of preventing
the normal operation of my computer.”

Tim:

After you pointed this out, I started keeping track myself, and, indeed,
they are everywhere.

mm

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Friday, June 29, 2007 14:51
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Unidrv Rendering Plug-in Question

xxxxx@yahoo.com wrote:

To extract data sent to the printer and to block print operation,

Yet another person spending his time working on methods of preventing
the normal operation of my computer.

Rendering Plug-in for Unidrv is developed.
We are hooking DrvTextOut() function to capture print data.

We are facing following problems

  1. When print job is sent to the HP LaserJet 4250 PCL 6 remote
    printer, DrvTextOut() is not getting called when printer setting ‘print
    on both sides’ option is checked.
    But DrvTextOut () is getting called when this option is unchecked.

It is possible that HP has its own pre-processor that is doing a
different kind of rendering, and sending bitmaps down to the printer.
How are you hooking DrvTextOut?

We would like to ask you,

  1. Is it right approach?

The right approach for what? We don’t know what you are trying to do.
If you are trying to detect certain strings in printed output, then
there is absolutely no general purpose method of doing this. Some apps
render their text to a bitmap for maximum control, and just print the
bitmap. Acrobat probably does that. They have their own PostScript
interpreter. With some fonts, the characters you see in DrvTextOut are
font indexes, not Unicode characters. In that case, the string won’t be
recognizable.

This approach will work only for Unidrv based printer drivers .Could
you please suggest us to make this approach generic for all printer
drivers.

Impossible.


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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Problem : I want to extract text sent to the printer and block print operation.
Approach taken:
Developed rendering plug-iN for Unidrv dll by implementating IPrintOemUni interface to hook out DrvTextOut() to extract text sent to the printer.

I am hooking DrvTextOut() by passing address of the Hooking functions to the DRVENABLEDATA structure of the IPrintOemUni::EnableDriver.

When printer setting is changed , user mode TextOut() function is getting called, but DrvTextout() is not getting hooked.
when printer setting is not changed , DrvTextout is getting called.

printer used : HP LaserJet 4250 PCL 6 remote printer

Could you please give some pointer to resolve this issue.

xxxxx@yahoo.co.in wrote:

Problem : I want to extract text sent to the printer and block print operation.
Approach taken:
Developed rendering plug-iN for Unidrv dll by implementating IPrintOemUni interface to hook out DrvTextOut() to extract text sent to the printer.

I am hooking DrvTextOut() by passing address of the Hooking functions to the DRVENABLEDATA structure of the IPrintOemUni::EnableDriver.

When printer setting is changed , user mode TextOut() function is getting called, but DrvTextout() is not getting hooked.
when printer setting is not changed , DrvTextout is getting called.

I suppose it is possible that, when changing a printer setting, the
Unidrv DLL is getting unloaded and reloaded, or perhaps a different
Unidrv DLL is getting loaded. In either case your hooks will go away.
Also remember that not all vendors use Unidrv for driving their
printers. The printer world in Windows has a surprising number of options.

printer used : HP LaserJet 4250 PCL 6 remote printer

Could you please give some pointer to resolve this issue.

I believe I already told you that your task was impossible in the
general case.


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

Thanks for your quick reply…
I am giving here some additional input regarding this issue.

Some of the hooked functions are getting called.
I am hooking all the functions that are given in \WinDDK\6000\src\print\oemdll\oemuni sample e.g DrvTextOut() , DrvSendPage(), DrvGetGlyphMode(), DrvQueryFontTree() , DrvStartDoc(), DrvEndDoc() etc.

All these hooked functions are getting called when printer setting is not changed.

But when printer setting is changed, DrvGetGlyphMode(), DrvQueryFontTree() , font related functions are getting called.
but other hooked functions DrvTextOut() , DrvSendPage(), DrvStartDoc, DrvEndDoc(), are not called.

Could you please give some pointer …

Is there any alternative way to extract text sent to the printer & block print operation.
What about hooking startDoc() and TextOut() API?

Sounds to me like the printer datatype switched from RAW to EMF when the setting was changed- in which case most of the hooked functions won’t be called until the EMF is despooled. I recall this being considered for enabling software emulation of unavailable hardware features such as duplexing in at least one driver I worked on (in an imaginary life that I am sure never really existed).

My assumption is you’re trying to debug the driver with a debugger attached to the printing application. When EMF (or any other “GDI Spooling” technology) is used, the rendering pass is driven by (architecturally) a print processor or (sometimes for “practical” reasons) a language monitor in the context of the spooler. You’ll need to attach a debugger to it as well if you want to follow the whole printing process.

Which leads me to suspect that these strings being blocked aren’t stored within the print stream, but rather in some convenient place “because it all happens in this one process”- so as soon as something you didn’t expect took place, the blocking quit working. Can’t recall how many times I advised people this happened when you didn’t put stuff in the private part of DEVMODE, but you can’t advise people who are smarter than you are…

Welcome to the wonderful world of Windows Printing (and thanks for reminding me why I’m so glad I left it)…

But I did like EMF / GDI Spooling- you can do some really creative things at the back end with it, although it usually means bypassing all the built-in support to really do the fun stuff (thus being prone to all the usual nasties of using undocumented aspects of a piece of someone else’s software). By now, there’s enough patent scariness around the whole thing it’s not (IMO) worth the trouble, hence this jaded post…

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.co.in
Sent: Tuesday, July 03, 2007 7:15 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Unidrv Rendering Plug-in Question

Thanks for your quick reply…
I am giving here some additional input regarding this issue.

Some of the hooked functions are getting called.
I am hooking all the functions that are given in \WinDDK\6000\src\print\oemdll\oemuni sample e.g DrvTextOut() , DrvSendPage(), DrvGetGlyphMode(), DrvQueryFontTree() , DrvStartDoc(), DrvEndDoc() etc.

All these hooked functions are getting called when printer setting is not changed.

But when printer setting is changed, DrvGetGlyphMode(), DrvQueryFontTree() , font related functions are getting called.
but other hooked functions DrvTextOut() , DrvSendPage(), DrvStartDoc, DrvEndDoc(), are not called.

Could you please give some pointer …

Is there any alternative way to extract text sent to the printer & block print operation.
What about hooking startDoc() and TextOut() API?


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thanks Bob,

I did understand what you are saying But with debugger attached I am not getting the alternate patn that printprocessor is taking when printer setting is changed. Could you suggest someway to find out the trace path for DrvTextOut.

As this approach i.e. rendering plug-in will work only for universal driver ,Could you suggest any generic approach to extract print data and cancel print operation.
What about writing port montior e.g localmon in WDK?

Could you please suggest me any generic approach to extract / filter print data and cancel print
operation for all types of printers?

If you want an easy, generic, device-context free way to mess with printing, go to the only place where it is anything close to easy, generic and context free- the Win32 API the app issues. Hook them and implement your monitoring and control scheme there. While I know how to hook UM code, I have little practical experience or need (might change now that I’m testing UMDF, though), so I suggest you get any how-to’s elsewhere. I hear Detours is nice…

Re: using a plugin: As Tim pointed out, even the plug-in can’t tell you what text is being printed in every case (although as I remember it, Acrobat created funky fonts with oddball names on the fly, and all of the character codes were in the “vendor-specific” [nomenclature is probably inexact, I haven’t been near printing in years, which makes me very happy] reserved range for Unicode). At any rate [back to working via a UM hook and what Tim mentioned], Glyph indexing is supported in ExtTextOut, so you’re going to have to some gnarly deciphering of fonts if you want to roll back from indices to character codes in the event you intend to cover everything, even by hooking the app.

As for a port monitor: A port monitor is generally going to see the PDL for the printer, which in terms of finding characters means all you have to do for an ironclad solution is:
[1] know every PDL on the planet [since you don’t know what the printer is using, you’re just a pipe to get data in and out of it], so you can first properly identify and then properly interpret it.
[2] have perfect character recognition from graphics, because the driver could have chosen to send text as graphics. For even more fun, if the characters are large and banding is involved, you may have to have an algorithm that can piece together the bands and recognize characters…
[3] Be able to put all of the above together to be able to suppress the output or shut off all further output and not leave the device in an unusable state. Of course, if the idea is to never let the output even appear, then there’s the issue of squirreling away GB or more of data while you decide if you want to let the thing get printed or not.

Port monitor? Probably not the way to go [but it would be my idea of “fun”].

OT- Cancellation issues trigger this- I recall I once had a driver that when the output stream failed a write because the job had been cancelled, began saving the sent data off to the side (until the resulting cancellation state detection was recognized by the earlier parts of the engine), then with the aid of the UI spooled a high-priority “cancel completion job” that sent that data [thus completing whatever output command was in process when the spooler processed the “Cancel” request, correctly], along with proper page/job end (including page eject) codes. State of the art for the competition at the time was “emit a whole bunch of NULLs and a formfeed” in a similar type of follow-on job. Only remember it because it was one of the rare times I clearly hands down beat them- my method was much faster completing a canceled job- several seconds in some cases. Oops, forgot to patent it, and now anyone [who understood this rambling sketch] can do it. Mortified, I truly be…

Yeah, I actually once wrote a GDI spooling “universal” driver in a market that already had more of them than it needed- didn’t exactly make much impact, though, and Win2K and XP introduced changes that would have broken it completely if it had…

More on-topic: I suppose there’s also a potential spec issue: For instance. if the purpose is to prevent naughty words, what do I do if the swear is printed to a symbol font? Perhaps “F***” in Zapf Dingbats is a perfectly reasonable usage…

Big Brother- coming soon to a printer near you? Given all the fine things spammers have done to evade filters, I suspect any text suppression technology is going to require endless maintenance, no matter how well technically implemented- it’s rather difficult to stop determined communication [not that the difficulty’s ever stopped those so inclined from trying].

Wow, technical trivia, autobiographical trivia, and trivial philosophy, all in one post- that’s GOOOOOOD Starbucks [and a nice mid-week holiday, to boot]!!!

Thanks a lot…
I am hooking StartDoc() API to get print job start notification & ExtTextOut() API to retrieve text. I am comparing handle to device context that I received in StartDoc() to retrieve printing related text in ExtTextOut().

Thanks…

  • Dhananjay