09ad523a |
1 | /* |
2 | * Printing interface for PuTTY. |
3 | */ |
4 | |
5 | #include <windows.h> |
6 | #include "putty.h" |
7 | |
8 | struct printer_enum_tag { |
9 | int nprinters; |
10 | LPPRINTER_INFO_5 info; |
11 | }; |
12 | |
13 | struct printer_job_tag { |
14 | HANDLE hprinter; |
15 | }; |
16 | |
17 | printer_enum *printer_start_enum(int *nprinters_ptr) |
18 | { |
19 | printer_enum *ret = smalloc(sizeof(printer_enum)); |
20 | char *buffer = NULL; |
21 | DWORD needed, nprinters; |
22 | |
23 | *nprinters_ptr = 0; /* default return value */ |
24 | buffer = smalloc(512); |
25 | if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5, |
26 | buffer, 512, &needed, &nprinters) == 0) |
27 | goto error; |
28 | |
ac6268ee |
29 | if (needed) { |
30 | buffer = srealloc(buffer, needed); |
09ad523a |
31 | |
ac6268ee |
32 | if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5, |
33 | (LPBYTE)buffer, needed, &needed, &nprinters) == 0) |
34 | goto error; |
35 | } else { |
36 | nprinters = 0; |
37 | ret->info = NULL; |
38 | } |
09ad523a |
39 | |
40 | ret->info = (LPPRINTER_INFO_5)buffer; |
41 | ret->nprinters = *nprinters_ptr = nprinters; |
42 | |
43 | return ret; |
44 | |
45 | error: |
46 | sfree(buffer); |
47 | sfree(ret); |
48 | return NULL; |
49 | } |
50 | |
51 | char *printer_get_name(printer_enum *pe, int i) |
52 | { |
53 | if (!pe) |
54 | return NULL; |
55 | if (i < 0 || i >= pe->nprinters) |
56 | return NULL; |
57 | return pe->info[i].pPrinterName; |
58 | } |
59 | |
60 | void printer_finish_enum(printer_enum *pe) |
61 | { |
62 | if (!pe) |
63 | return; |
64 | sfree(pe->info); |
65 | sfree(pe); |
66 | } |
67 | |
68 | printer_job *printer_start_job(char *printer) |
69 | { |
70 | printer_job *ret = smalloc(sizeof(printer_job)); |
71 | DOC_INFO_1 docinfo; |
72 | int jobstarted = 0, pagestarted = 0; |
73 | |
74 | ret->hprinter = NULL; |
75 | if (!OpenPrinter(printer, &ret->hprinter, NULL)) |
76 | goto error; |
77 | |
78 | docinfo.pDocName = "PuTTY remote printer output"; |
79 | docinfo.pOutputFile = NULL; |
80 | docinfo.pDatatype = "RAW"; |
81 | |
82 | if (!StartDocPrinter(ret->hprinter, 1, (LPSTR)&docinfo)) |
83 | goto error; |
84 | jobstarted = 1; |
85 | |
86 | if (!StartPagePrinter(ret->hprinter)) |
87 | goto error; |
88 | pagestarted = 1; |
89 | |
90 | return ret; |
91 | |
92 | error: |
93 | if (pagestarted) |
94 | EndPagePrinter(ret->hprinter); |
95 | if (jobstarted) |
96 | EndDocPrinter(ret->hprinter); |
97 | if (ret->hprinter) |
98 | ClosePrinter(ret->hprinter); |
99 | sfree(ret); |
100 | return NULL; |
101 | } |
102 | |
103 | void printer_job_data(printer_job *pj, void *data, int len) |
104 | { |
105 | DWORD written; |
106 | |
107 | if (!pj) |
108 | return; |
109 | |
110 | WritePrinter(pj->hprinter, data, len, &written); |
111 | } |
112 | |
113 | void printer_finish_job(printer_job *pj) |
114 | { |
115 | if (!pj) |
116 | return; |
117 | |
118 | EndPagePrinter(pj->hprinter); |
119 | EndDocPrinter(pj->hprinter); |
120 | ClosePrinter(pj->hprinter); |
121 | sfree(pj); |
122 | } |