XP Printer Driver: a Paper format independent text driver

Hi everyone,

I want say immediately that I’m a novice in DDK and I’m breaking my head with the following problem. I hope you can give me some help.

The problem:

In WinXP I need to print a text file (ASCII) to a virtual printer (based on the Generic/Text only driver) that:

1 - automatically print to a file (not on a real printer) into a specified directory,
2 - is paper format independent. I will explain: if I print a text file having some lines 500-1000 characters long, the standard Generic/Text only driver being dependent by the paper format (i.e. A4, Letter, A3, etc) will cut those lines. Also I think that the standard Generic/text driver has some bug, because the file printed is different from the original one (existing blank lines added/removed for example).

Pratically I need something that keep the ASCII file I want to print and simply save it into another file into a specified directory as it is.

I’ve accomplished the first task with a port monitor (found on Codeguru) associated with the standard Generic/Text only driver. Now my idea is to change the standard driver with another that keep all the print as it is.

Any idea?

Can you help me? What can I do to do this job?
Many thanks in advance
Robert

You probably want to use a custom print processor, as the standard
WinPrint processor probably is doing some formatting.

/christoph

Hi Christoph,
thanks 4 your reply.
Even with another print processor (like the genprint PP from DDK) the joke remain always the same. The file produced is always different from the original (several blank lines are deleted). Make your own test to believe.

To do my test I’ve created a new printer with the Generic/Text only printer driver.

Associating the FILE: port the file produced is different from the original.
Associating the C:\TEMP local directory port (created with the Codeguru’s port monitor) the file produced is different from the original.
Associating the Genprint print processor (instead of the default WinPrint) the result remain the same: the file produced is different from the original.

The 3 associations (FILE:, C:\TEMP, Genprint) produce the SAME file. So I think that the problem is the Generic/Text driver.

And…, I’ve my head burned.

What I want: a virtual printer that take a ASCII file to be printed and produce a file identical to the original one into a specified directory (the port monitor help well) taking ALL the lines as they are (even 500-1000 characters long) without cut or delete lines at all… in one word : AS IT IS.

Roberto

Maybe you don’t want or even need a printer driver. If all you want is
to copy a file from one place to another, why are you making the user
load it into an application and invoke a printer driver?

ScottR

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@batspooler.com
Sent: Monday, August 27, 2007 8:33 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] XP Printer Driver: a Paper format independent text
driver

Hi Christoph,
thanks 4 your reply.
Even with another print processor (like the genprint PP from DDK) the
joke remain always the same. The file produced is always different from
the original (several blank lines are deleted). Make your own test to
believe.

To do my test I’ve created a new printer with the Generic/Text only
printer driver.

Associating the FILE: port the file produced is different from the
original. Associating the C:\TEMP local directory port (created with the
Codeguru’s port monitor) the file produced is different from the
original. Associating the Genprint print processor (instead of the
default WinPrint) the result remain the same: the file produced is
different from the original.

The 3 associations (FILE:, C:\TEMP, Genprint) produce the SAME file. So
I think that the problem is the Generic/Text driver.

And…, I’ve my head burned.

What I want: a virtual printer that take a ASCII file to be printed and
produce a file identical to the original one into a specified directory
(the port monitor help well) taking ALL the lines as they are (even
500-1000 characters long) without cut or delete lines at all… in one
word : AS IT IS.

Roberto


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

Scott,
the reason is simple: start imaging about a business application that want to print an invoice or something else, but can’t print over a file but only on a printer. Continue imaging that the invoice must be processed by another application before it’s printed or trasformed into a PDF. The app can read text files into a directory, process them to format and print, preview, transform, send email,…, etc.
That’s all folks.
So I suppose that a stupid printer driver that take the print and write all into a file into a directory as it is (without the changes, delete or cut lines i’ve seen into the Generic/Text Only driver) could be the solution needed. But I don’t know the point of the driver where I can do this job.
Can you give me an help?
Many thanks for your reply.
Roberto

> Even with another print processor (like the genprint PP from

DDK) the joke remain always the same. The file produced is
always different from the original (several blank lines are
deleted).

Have you just compiled the genprint sample, or have you actually
modified the genprint sample to your needs (like removing the text
formatting bits)?

You can not take just any “Acme Corp.” print processor and expect it to
do what you want. Therefore I suggested you write your own print
processor, the way you need it. One way could be to use genprint as
inspiration. But genprint is for demonstrating “standard” functionality,
so you would probably have to modify (or simplify) the code for you
needs.

/christoph

Hi Christoph,
thanks for your reply. If I well understood you say me that is the print processor that produce differences between original print and file produced. OK, now I will work over the genprint sample to semplify it for my scope. If you can give me some help about (a point of start to begin or something else) please post ASAP. Everything will be a big help for me. Many thanks in advance.
Roberto

> Hi Christoph,

thanks for your reply. If I well understood you say me that
is the print processor that produce differences between
original print and file produced. OK, now I will work over
the genprint sample to semplify it for my scope. If you can
give me some help about (a point of start to begin or
something else) please post ASAP. Everything will be a big
help for me. Many thanks in advance.
Roberto

First you need a print processor, which accepts EMF, RAW and TEXT.
EMF: As in genprint
RAW: As in genprint (write to printer with WritePrinter)
TEXT: Normally a print processor would call GDI to render the text
stream, making it a EMF job. What you should do, is just resubmit it as
RAW (use WritePrinter like when handling RAW data)

Second you need a text printer driver to generate the plaintext print
job from EMF data. This is needed to convert/render GDI prints (from any
win app) to RAW. This driver will be used when calling GdiPlayPageEMF
stuff from your print processor.

Example of the job data flow:

RAW:

  1. Application writes RAW data to spooler
  2. Spooler sends RAW data to print processor
  3. Print processor sends RAW data via WritePrinter to port
  4. Port sends everything to printer

TEXT:

  1. Application writes TEXT data to spooler
  2. Spooler sends TEXT data to print processor
  3. Print processor copies TEXT as RAW data via WritePrinter to port
  4. Port sends everything to printer

GDI/EMF

  1. Application writes data to spooler via GDI
  2. Spooler spools GDI calls in EMF format
  3. Spooler sends EMF data to print processor
  4. Print processor calls back spooler EMF processing functions like
    GdiPlayPageEMF
  5. Spooler EMF processing functions like GdiPlayPageEMF call printer
    driver via DDI
  6. Printer driver generates RAW job data (in you case plaintext) from
    DDI calls, and sends it back to spooler
  7. Spooler sends RAW data to print processor
  8. Print processor sends RAW data via WritePrinter to port
  9. Port sends everything to printer

Christoph,
many many thanks for your help! One thing is even obscure for me: who is that decide the lines length, page format and so on? I’ve seen the genprint text.c, for example, and it seems that it compute the linesperpage, linelength, … but, if I modify those values the result file has always the same line length with this processor (set on TEXT data type). It seems that those values are token from a DEVMODE structure… Perhaps the dmPaperSize, dmPageLength and dmPageWidth fields?
Thanks for your help
Roberto

Roberto,

You’ve got two problems here:

1- The printing application itself will alter output based on the characteristics of the printer and the paper selected. If your print driver is reporting that it has, say, Letter sized paper then most applications will wrap or truncate lines at 11 inches minus the margins. GDI will likely clip anything exceeding the page boundaries as well. Your driver needs to report an infinite paper length, a very wide width, and zero unprintable margins. Take a look at the DrvEnablePDEV function. You need to set all the appropriate values in the DEVMODE and GDIINFO structs. You also need to report appropriate values in DrvDeviceCapabilities for the DC_PAPERS, DC_MINEXTENT, and DC_MAXEXTENT queries.

2- You’re mistaking printing for a file copy process. Most apps don’t print by taking a text file and spitting it out as is; they use the GDI to format the output. The missing blank lines are probably because the app isn’t actually printing newlines, it’s just positioning text a line lower when it calls TextOut. You’ll have to keep track of the starting Y position of text and insert your own newlines to compensate for it. You’ll probably have to do the same with the X position and insert spaces.

I did a driver exactly like this a few years ago. It’s not as simple as it sounds.

Hi, Gregory
thanks for your reply. I had the suspect about the DEVMODE struct, now it’s sure the problem became very big and hard. In the meantime I’ve tested several Text driver (like Miraplacid) without a real success. Only the “type” and “copy” commands do really what I want, I think because they never take the printer properties, even if they spool the printing jobs. But every Win application always get the printer properties, so I must turn around this manipulating the structures you have so well defined. You have reason, the work is very hard, but I must do it. So, if you have some starting point that could help me, please send to me ASAP.

In every case, many thanks for your help.
Roberto