Bug 687250 - %printer% OutputFile truncated output
Summary: %printer% OutputFile truncated output
Status: NOTIFIED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: Printer Driver (show other bugs)
Version: 0.00
Hardware: PC Windows XP
: P2 major
Assignee: Henry Stiles
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-01-14 08:55 UTC by Luke Bakken
Modified: 2008-12-19 08:31 UTC (History)
1 user (show)

See Also:
Customer:
Word Size: ---


Attachments
Pack of 3 suggested patches (ZIP file). (2.30 KB, application/x-zip-compressed)
2007-04-09 11:03 UTC, SaGS
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Luke Bakken 2004-01-14 08:55:34 UTC
I'm using Ghostscript 8.13. I have created two printers, each using the FILE:
port. One is an Apple LW 16/600 (named lw_file) and the other a Lexmark Optra N
PS (named lex_file). I'm using this PDF file
http://www.tinaja.com/glib/psinscrt.pdf and the following two command files. The
first is input.tempfile and the second input.lw_file:

-I"C:\gs\gs8.13\lib;C:\gs\fonts;C:\gs\gs8.13\Resource"
-dNOPAUSE
-dBATCH
-sDEVICE=pswrite
-dDEVICEXRESOLUTION=600
-dDEVICEYRESOLUTION=600
-dDEVICEWIDTH=5100
-dDEVICEHEIGHT=6600
-sOutputFile=c:\temp\testit.ps
-dNOPLATFONTS
-sFONTPATH="c:\psfonts"

-I"C:\gs\gs8.13\lib;C:\gs\fonts;C:\gs\gs8.13\Resource"
-dNOPAUSE
-dBATCH
-sDEVICE=pswrite
-dDEVICEXRESOLUTION=600
-dDEVICEYRESOLUTION=600
-dDEVICEWIDTH=5100
-dDEVICEHEIGHT=6600
-sOutputFile="%printer%lw_file"
-dNOPLATFONTS
-sFONTPATH="c:\psfonts"

This command produces a correct ps file:
gswin32c @input.tempfile psinscrt.pdf

This command produces a truncated ps file:
gswin32c @input.lw_file psinscrt.pdf

The second command also truncates output using the lex_file printer.

Let me know if I can provide any more info!
Comment 1 Ray Johnston 2004-01-14 10:52:49 UTC
The %printer% IODevice creates a thread to communicate.

Is the printer you have connected spooled ?

What 'port' is used by the printer ?

What do you mean by 'truncated output' ?

It's just a shot in the dark, but please try increasing the
timeout in mswin_printer_fclose() at the end of src/gp_msprn.c
from:

	WaitForSingleObject(hthread, 60000);

to a much longer value, such as:

	WaitForSingleObject(hthread, 6000000);
Comment 2 Luke Bakken 2004-01-14 11:47:01 UTC
> Is the printer you have connected spooled?

Yes, but I can change that.

> What 'port' is used by the printer ?

FILE:

> What do you mean by 'truncated output' ?

I mean that output to this device doesn't have all the information that a
-sOutputFile=c:\temp\filename.ps does. In my test cases, the output sent to the
printer (and then saved to a file with the FILE: device) is sometimes 1/2 of
what would have been sent to a file. If I change the printer port so that it
prints to my "real" Laserwriter 16/600, then I will not get every page that I
should.

>	WaitForSingleObject(hthread, 6000000);

I will get the ghostscript source and try this when I get a chance. Thanks!
Luke
Comment 3 Luke Bakken 2004-01-14 11:52:02 UTC
I changed the printer to not spool at all, but got the same results:

01/14/2004  11:50 AM         1,441,792 lw_output.ps
01/14/2004  11:50 AM         1,480,138 testit.ps

Those two ps files should be close to the same size, but the lw_output.ps file
ends suddenly, while the testit.ps file goes all the way to the %%EOF. They were
produced in the same manner that I described in my original bug report, i.e.
testit.ps was the result of an -sOutputFile=c:\temp\testit.ps and lw_output.ps
was the result of an -sOutputFile="%printer%lw_file" with the printer on a FILE:
port.
Comment 4 Luke Bakken 2004-01-14 16:10:07 UTC
> > WaitForSingleObject(hthread, 6000000);
> I will get the ghostscript source and try this when I get a chance. Thanks!

I got the source and made the change and there was no difference.
Comment 5 Luke Bakken 2004-01-14 16:48:46 UTC
Good news! I visited this MS page:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_93g2.asp

And following the example, modified gp_msprn.c and the result is that it's all
appearing to work now. Here is the patch in 'diff -u' format (which is what I
hope you want):

--- gp_msprn_org.c      2002-02-22 19:24:52.000000000 -0800
+++ gp_msprn_new.c      2004-01-14 16:38:09.796875000 -0800
@@ -109,6 +109,11 @@
                close(fd);
                return;
            }
+           if(!StartPagePrinter(hprinter)) {
+               AbortPrinter(hprinter);
+               close(fd);
+               return;
+               }
        }
        if (!WritePrinter(hprinter, (LPVOID) data, count, &written)) {
            AbortPrinter(hprinter);
@@ -119,6 +124,7 @@
     if (hprinter != INVALID_HANDLE_VALUE) {
        if (count == 0) {
            /* EOF */
+           EndPagePrinter(hprinter);
            EndDocPrinter(hprinter);
            ClosePrinter(hprinter);
        }
Comment 6 Luke Bakken 2007-01-25 10:04:42 UTC
Hello,

I have checked the file gp_msprn.c here

http://svn.ghostscript.com:8080/ghostscript/trunk/gs/src/gp_msprn.c

and did not see the patch I provided added. Was it determined that this change 
was not necessary to fix the behavior I described?
Comment 7 Ray Johnston 2007-04-07 13:08:42 UTC
Patch committed after testing -- rev 7832.
Comment 8 SaGS 2007-04-09 11:03:03 UTC
Created attachment 2870 [details]
Pack of 3 suggested patches (ZIP file).

The patch in comment #5 is incorrect. Also, I strongly believe the 
error reported here actually happens on 64-bit Windows only, and for 
a reason the respective patch does not address.

Brief description:

(A)
The call to StartPagePrinter() in comment #5 is misplaced. As-is:
- there are many "pages", one StartPagePrinter() for each 4K of data,
  which is an unnecessary overhead;
- all but the last of these calls don't have a matching call to 
  EndPagePrinter(), which is wrong.

(B)
While we are here: MSDN docs don't say that AbortPrinter() closes the 
handle returned by OpenPrinter(). Calling ClosePrinter() in all cases 
also permits to simplify the code.

(C)
I don't think the problem reported here is caused by the missing 
Start/EndPagePrinter(). After all, if WritePrinter() would fail in 
the absence of a previous StartPagePrinter(), NO data would be written 
to the printer, while comment #3 shows that most of the data IS 
written. I could not reproduce the problem on 32-bit Windows at all. 
Unfortunately, I don't have a 64-bit system to test.

However, I think the problem appears on 64-bit Windows. Here's why:

- the type of tid_t.tid is unsigned long, which is 32-bit even on 
  64-bit Windows;
- this field is used to store a HANDLE, which is 64-bit on _WIN64, 
  so the value gets truncated;
- receiving an invalid handle, WaitForSingleObject() returns 
  immediately with a failure; so, the application exits without 
  waiting for all data to be sent to the printer.
Comment 9 Luke Bakken 2007-04-09 11:11:19 UTC
Responding to the comment #8:

(A) StartPagePrinter() should definitely be moved so it's not executed before
each write. It should be moved after the call to StartDocPrinter().

(C) It's been a long time since I reported this, but I could reproduce the
behavior every time and the supplied patch (even with the mismatched
StartPage/EndPage calls) did fix the problem. YMMV, I suppose. If you'd like, I
could re-try to reproduce this when I have time.