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 | |
29 | buffer = srealloc(buffer, needed); |
30 | |
31 | if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5, |
32 | (LPBYTE)buffer, needed, &needed, &nprinters) == 0) |
33 | goto error; |
34 | |
35 | ret->info = (LPPRINTER_INFO_5)buffer; |
36 | ret->nprinters = *nprinters_ptr = nprinters; |
37 | |
38 | return ret; |
39 | |
40 | error: |
41 | sfree(buffer); |
42 | sfree(ret); |
43 | return NULL; |
44 | } |
45 | |
46 | char *printer_get_name(printer_enum *pe, int i) |
47 | { |
48 | if (!pe) |
49 | return NULL; |
50 | if (i < 0 || i >= pe->nprinters) |
51 | return NULL; |
52 | return pe->info[i].pPrinterName; |
53 | } |
54 | |
55 | void printer_finish_enum(printer_enum *pe) |
56 | { |
57 | if (!pe) |
58 | return; |
59 | sfree(pe->info); |
60 | sfree(pe); |
61 | } |
62 | |
63 | printer_job *printer_start_job(char *printer) |
64 | { |
65 | printer_job *ret = smalloc(sizeof(printer_job)); |
66 | DOC_INFO_1 docinfo; |
67 | int jobstarted = 0, pagestarted = 0; |
68 | |
69 | ret->hprinter = NULL; |
70 | if (!OpenPrinter(printer, &ret->hprinter, NULL)) |
71 | goto error; |
72 | |
73 | docinfo.pDocName = "PuTTY remote printer output"; |
74 | docinfo.pOutputFile = NULL; |
75 | docinfo.pDatatype = "RAW"; |
76 | |
77 | if (!StartDocPrinter(ret->hprinter, 1, (LPSTR)&docinfo)) |
78 | goto error; |
79 | jobstarted = 1; |
80 | |
81 | if (!StartPagePrinter(ret->hprinter)) |
82 | goto error; |
83 | pagestarted = 1; |
84 | |
85 | return ret; |
86 | |
87 | error: |
88 | if (pagestarted) |
89 | EndPagePrinter(ret->hprinter); |
90 | if (jobstarted) |
91 | EndDocPrinter(ret->hprinter); |
92 | if (ret->hprinter) |
93 | ClosePrinter(ret->hprinter); |
94 | sfree(ret); |
95 | return NULL; |
96 | } |
97 | |
98 | void printer_job_data(printer_job *pj, void *data, int len) |
99 | { |
100 | DWORD written; |
101 | |
102 | if (!pj) |
103 | return; |
104 | |
105 | WritePrinter(pj->hprinter, data, len, &written); |
106 | } |
107 | |
108 | void printer_finish_job(printer_job *pj) |
109 | { |
110 | if (!pj) |
111 | return; |
112 | |
113 | EndPagePrinter(pj->hprinter); |
114 | EndDocPrinter(pj->hprinter); |
115 | ClosePrinter(pj->hprinter); |
116 | sfree(pj); |
117 | } |