OSDN Git Service

Add VC++ Project files for PuTTY DLL without exported functions.
[ffftp/ffftp.git] / putty / WINDOWS / WINPRINT.C
1 /*\r
2  * Printing interface for PuTTY.\r
3  */\r
4 \r
5 #include "putty.h"\r
6 #include <winspool.h>\r
7 \r
8 struct printer_enum_tag {\r
9     int nprinters;\r
10     DWORD enum_level;\r
11     union {\r
12         LPPRINTER_INFO_4 i4;\r
13         LPPRINTER_INFO_5 i5;\r
14     } info;\r
15 };\r
16 \r
17 struct printer_job_tag {\r
18     HANDLE hprinter;\r
19 };\r
20 \r
21 static char *printer_add_enum(int param, DWORD level, char *buffer,\r
22                               int offset, int *nprinters_ptr)\r
23 {\r
24     DWORD needed = 0, nprinters = 0;\r
25 \r
26     buffer = sresize(buffer, offset+512, char);\r
27 \r
28     /*\r
29      * Exploratory call to EnumPrinters to determine how much space\r
30      * we'll need for the output. Discard the return value since it\r
31      * will almost certainly be a failure due to lack of space.\r
32      */\r
33     EnumPrinters(param, NULL, level, buffer+offset, 512,\r
34                  &needed, &nprinters);\r
35 \r
36     if (needed < 512)\r
37         needed = 512;\r
38 \r
39     buffer = sresize(buffer, offset+needed, char);\r
40 \r
41     if (EnumPrinters(param, NULL, level, buffer+offset,\r
42                      needed, &needed, &nprinters) == 0)\r
43         return NULL;\r
44 \r
45     *nprinters_ptr += nprinters;\r
46 \r
47     return buffer;\r
48 }\r
49 \r
50 printer_enum *printer_start_enum(int *nprinters_ptr)\r
51 {\r
52     printer_enum *ret = snew(printer_enum);\r
53     char *buffer = NULL, *retval;\r
54 \r
55     *nprinters_ptr = 0;                /* default return value */\r
56     buffer = snewn(512, char);\r
57 \r
58     /*\r
59      * Determine what enumeration level to use.\r
60      * When enumerating printers, we need to use PRINTER_INFO_4 on\r
61      * NT-class systems to avoid Windows looking too hard for them and\r
62      * slowing things down; and we need to avoid PRINTER_INFO_5 as\r
63      * we've seen network printers not show up.\r
64      * On 9x-class systems, PRINTER_INFO_4 isn't available and\r
65      * PRINTER_INFO_5 is recommended.\r
66      * Bletch.\r
67      */\r
68     if (osVersion.dwPlatformId != VER_PLATFORM_WIN32_NT) {\r
69         ret->enum_level = 5;\r
70     } else {\r
71         ret->enum_level = 4;\r
72     }\r
73 \r
74     retval = printer_add_enum(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,\r
75                               ret->enum_level, buffer, 0, nprinters_ptr);\r
76     if (!retval)\r
77         goto error;\r
78     else\r
79         buffer = retval;\r
80 \r
81     switch (ret->enum_level) {\r
82       case 4:\r
83         ret->info.i4 = (LPPRINTER_INFO_4)buffer;\r
84         break;\r
85       case 5:\r
86         ret->info.i5 = (LPPRINTER_INFO_5)buffer;\r
87         break;\r
88     }\r
89     ret->nprinters = *nprinters_ptr;\r
90     \r
91     return ret;\r
92 \r
93     error:\r
94     sfree(buffer);\r
95     sfree(ret);\r
96     *nprinters_ptr = 0;\r
97     return NULL;\r
98 }\r
99 \r
100 char *printer_get_name(printer_enum *pe, int i)\r
101 {\r
102     if (!pe)\r
103         return NULL;\r
104     if (i < 0 || i >= pe->nprinters)\r
105         return NULL;\r
106     switch (pe->enum_level) {\r
107       case 4:\r
108         return pe->info.i4[i].pPrinterName;\r
109       case 5:\r
110         return pe->info.i5[i].pPrinterName;\r
111       default:\r
112         return NULL;\r
113     }\r
114 }\r
115 \r
116 void printer_finish_enum(printer_enum *pe)\r
117 {\r
118     if (!pe)\r
119         return;\r
120     switch (pe->enum_level) {\r
121       case 4:\r
122         sfree(pe->info.i4);\r
123         break;\r
124       case 5:\r
125         sfree(pe->info.i5);\r
126         break;\r
127     }\r
128     sfree(pe);\r
129 }\r
130 \r
131 printer_job *printer_start_job(char *printer)\r
132 {\r
133     printer_job *ret = snew(printer_job);\r
134     DOC_INFO_1 docinfo;\r
135     int jobstarted = 0, pagestarted = 0;\r
136 \r
137     ret->hprinter = NULL;\r
138     if (!OpenPrinter(printer, &ret->hprinter, NULL))\r
139         goto error;\r
140 \r
141     docinfo.pDocName = "PuTTY remote printer output";\r
142     docinfo.pOutputFile = NULL;\r
143     docinfo.pDatatype = "RAW";\r
144 \r
145     if (!StartDocPrinter(ret->hprinter, 1, (LPSTR)&docinfo))\r
146         goto error;\r
147     jobstarted = 1;\r
148 \r
149     if (!StartPagePrinter(ret->hprinter))\r
150         goto error;\r
151     pagestarted = 1;\r
152 \r
153     return ret;\r
154 \r
155     error:\r
156     if (pagestarted)\r
157         EndPagePrinter(ret->hprinter);\r
158     if (jobstarted)\r
159         EndDocPrinter(ret->hprinter);\r
160     if (ret->hprinter)\r
161         ClosePrinter(ret->hprinter);\r
162     sfree(ret);\r
163     return NULL;\r
164 }\r
165 \r
166 void printer_job_data(printer_job *pj, void *data, int len)\r
167 {\r
168     DWORD written;\r
169 \r
170     if (!pj)\r
171         return;\r
172 \r
173     WritePrinter(pj->hprinter, data, len, &written);\r
174 }\r
175 \r
176 void printer_finish_job(printer_job *pj)\r
177 {\r
178     if (!pj)\r
179         return;\r
180 \r
181     EndPagePrinter(pj->hprinter);\r
182     EndDocPrinter(pj->hprinter);\r
183     ClosePrinter(pj->hprinter);\r
184     sfree(pj);\r
185 }\r