Hello all,

I support a PostScript OEM plugin system on a high-security printer, and
every job pops up a dialog box for a PIN, and this is passed in the
PostScript stream to the printer, where entry of this PIN by the operator is
required to release the job. The customer is a large bank who prints checks
from these workstations.

Word 2003 broke this badly.

My hook for the dialog box in the UI is IPrintOemUI2::DocumentEvent time's
DOCUMENTEVENT_STARTDOCPOST, which provides us the Job ID. We encode the
credentials into a single string, and store them into the
JOB_INFO_2.pParameters with SetJob(). Since the Job ID is passed to the
DrvStartDoc() call, we can use GetJob() to retrieve the string and pass the
credentials to the printer using PSINJECT.

Note that we'd rather put this data int the DEVMODE, but the DrvXXX hooks
we're using in the rendering part don't give us a handle to the OEM DEVMODE:
the public part is as expected, but the PostScript driver proper owns the
first part of the private data, and there's not a portable way to get to
*our* part. If there's a way to use the DEVMODE, we don't know it.

Anyway, using metafile spooling ("Advanced printing") breaks this, because
the rendering DLL's DrvStartDoc doesn't get a JobID, but even with
PRINTER_ATTRIBUTE_RAW_ONLY we're not getting a JobID the first print after
Word 2003 launches. It's passed a zero, we can't get the Job ID, and we have
no way to get at the PIN. We fail the job closed so that we don't leave a
check lying around on the printer if we can't get a Job ID.

I cannot for the life of me figure out why a Job ID would not be provided to
DrvStartDoc().

I have tried printing direct, tried disabling background printing, and even
paused the printer while sending that first job. I can see the spool file
with the PostScript content (so it can't be spooling a metafile, right?),
and I see the credential string in the .SHD file which sits next to the .SPL
spooler file. It's just not making it available to us.

A normal print job looks like this from the point of view of DOCUMENTEVENTS
in the UI

DOCUMENTEVENT_STARTDOCPRE
DOCUMENTEVENT_STARTDOCPOST <-- prompt for credentials, store in
Job
DOCUMENTEVENT_STARTPAGE
DOCUMENTEVENT_ENDPAGE
DOCUMENTEVENT_ENDDOC

But the *first* time we print out of Word 2003, we're seeing:

DOCUMENTEVENT_STARTDOCPRE
DOCUMENTEVENT_STARTDOCPOST
DOCUMENTEVENT_RESETDCPRE <-- reapply DEVMODE
DOCUMENTEVENT_RESETDCPOST
DOCUMENTEVENT_ENDPAGE
DOCUMENTEVENT_ENDDOC

It appears that the ResetDC (which presumably is there to adjust the
DEVMODE) somehow kills the job ID as seen in the spooler, and it's
completely confounding us. This may not be related, but it's the only thing
we can see, and it's reproduceable every time.

Older versions of Office work fine, other applications word fine, and even
Excel 2003 works fine, but Word and PowerPoint (at least) do this.

We're hoping that somebody has an idea here.

Steve

--
Steve Friedl / UNIX Wizard / Microsoft Security MVP / www.unixwiz.net

Re: PS driver loses JobID? by Steve

Steve
Mon May 22 00:14:27 CDT 2006

Well I found it: IProntOemUI2::StartDoc() can be called more than once in a
job, and only the first time does it get the Job ID. If the application
calls ResetDC, we're given another StartDoc() with a new DEVMODE, but with a
zero Job ID - clearly we should have saved the Job ID from the first time.

Well I had been doing that, but I failed to implement ResetPDEV() to copy
the private OEM PDEV structure, so the ResetDC-provoked ResetPDEV() created
a new PDEV without copying our private data from the old one. So it thinks
it has no Job ID, and it all breaks.

Implementing ResetPDEV() - a trivial matter - made everything work.

Sorry for false alarm :-)

Steve
--
Steve Friedl / UNIX Wizard / Microsoft MVP / www.unixwiz.net


"Steve Friedl" <Steve_Friedl@newsgroups.nospam> wrote in message
news:u9FkGOUfGHA.4304@TK2MSFTNGP05.phx.gbl...
> Hello all,
>
> I support a PostScript OEM plugin system on a high-security printer, and
> every job pops up a dialog box for a PIN, and this is passed in the
> PostScript stream to the printer, where entry of this PIN by the operator
> is required to release the job. The customer is a large bank who prints
> checks from these workstations.
>
> Word 2003 broke this badly.
>
> My hook for the dialog box in the UI is IPrintOemUI2::DocumentEvent time's
> DOCUMENTEVENT_STARTDOCPOST, which provides us the Job ID. We encode the
> credentials into a single string, and store them into the
> JOB_INFO_2.pParameters with SetJob(). Since the Job ID is passed to the
> DrvStartDoc() call, we can use GetJob() to retrieve the string and pass
> the credentials to the printer using PSINJECT.
>
> Note that we'd rather put this data int the DEVMODE, but the DrvXXX hooks
> we're using in the rendering part don't give us a handle to the OEM
> DEVMODE: the public part is as expected, but the PostScript driver proper
> owns the first part of the private data, and there's not a portable way to
> get to *our* part. If there's a way to use the DEVMODE, we don't know it.
>
> Anyway, using metafile spooling ("Advanced printing") breaks this, because
> the rendering DLL's DrvStartDoc doesn't get a JobID, but even with
> PRINTER_ATTRIBUTE_RAW_ONLY we're not getting a JobID the first print after
> Word 2003 launches. It's passed a zero, we can't get the Job ID, and we
> have no way to get at the PIN. We fail the job closed so that we don't
> leave a check lying around on the printer if we can't get a Job ID.
>
> I cannot for the life of me figure out why a Job ID would not be provided
> to DrvStartDoc().
>
> I have tried printing direct, tried disabling background printing, and
> even paused the printer while sending that first job. I can see the spool
> file with the PostScript content (so it can't be spooling a metafile,
> right?), and I see the credential string in the .SHD file which sits next
> to the .SPL spooler file. It's just not making it available to us.
>
> A normal print job looks like this from the point of view of
> DOCUMENTEVENTS in the UI
>
> DOCUMENTEVENT_STARTDOCPRE
> DOCUMENTEVENT_STARTDOCPOST <-- prompt for credentials, store
> in Job
> DOCUMENTEVENT_STARTPAGE
> DOCUMENTEVENT_ENDPAGE
> DOCUMENTEVENT_ENDDOC
>
> But the *first* time we print out of Word 2003, we're seeing:
>
> DOCUMENTEVENT_STARTDOCPRE
> DOCUMENTEVENT_STARTDOCPOST
> DOCUMENTEVENT_RESETDCPRE <-- reapply DEVMODE
> DOCUMENTEVENT_RESETDCPOST
> DOCUMENTEVENT_ENDPAGE
> DOCUMENTEVENT_ENDDOC
>
> It appears that the ResetDC (which presumably is there to adjust the
> DEVMODE) somehow kills the job ID as seen in the spooler, and it's
> completely confounding us. This may not be related, but it's the only
> thing we can see, and it's reproduceable every time.
>
> Older versions of Office work fine, other applications word fine, and even
> Excel 2003 works fine, but Word and PowerPoint (at least) do this.
>
> We're hoping that somebody has an idea here.
>
> Steve
>
> --
> Steve Friedl / UNIX Wizard / Microsoft Security MVP / www.unixwiz.net
>