+++ /dev/null
-/*\r
- * Printing interface for PuTTY.\r
- */\r
-\r
-#include "putty.h"\r
-#include <winspool.h>\r
-\r
-struct printer_enum_tag {\r
- int nprinters;\r
- DWORD enum_level;\r
- union {\r
- LPPRINTER_INFO_4 i4;\r
- LPPRINTER_INFO_5 i5;\r
- } info;\r
-};\r
-\r
-struct printer_job_tag {\r
- HANDLE hprinter;\r
-};\r
-\r
-static char *printer_add_enum(int param, DWORD level, char *buffer,\r
- int offset, int *nprinters_ptr)\r
-{\r
- DWORD needed = 0, nprinters = 0;\r
-\r
- buffer = sresize(buffer, offset+512, char);\r
-\r
- /*\r
- * Exploratory call to EnumPrinters to determine how much space\r
- * we'll need for the output. Discard the return value since it\r
- * will almost certainly be a failure due to lack of space.\r
- */\r
- EnumPrinters(param, NULL, level, buffer+offset, 512,\r
- &needed, &nprinters);\r
-\r
- if (needed < 512)\r
- needed = 512;\r
-\r
- buffer = sresize(buffer, offset+needed, char);\r
-\r
- if (EnumPrinters(param, NULL, level, buffer+offset,\r
- needed, &needed, &nprinters) == 0)\r
- return NULL;\r
-\r
- *nprinters_ptr += nprinters;\r
-\r
- return buffer;\r
-}\r
-\r
-printer_enum *printer_start_enum(int *nprinters_ptr)\r
-{\r
- printer_enum *ret = snew(printer_enum);\r
- char *buffer = NULL, *retval;\r
-\r
- *nprinters_ptr = 0; /* default return value */\r
- buffer = snewn(512, char);\r
-\r
- /*\r
- * Determine what enumeration level to use.\r
- * When enumerating printers, we need to use PRINTER_INFO_4 on\r
- * NT-class systems to avoid Windows looking too hard for them and\r
- * slowing things down; and we need to avoid PRINTER_INFO_5 as\r
- * we've seen network printers not show up.\r
- * On 9x-class systems, PRINTER_INFO_4 isn't available and\r
- * PRINTER_INFO_5 is recommended.\r
- * Bletch.\r
- */\r
- if (osVersion.dwPlatformId != VER_PLATFORM_WIN32_NT) {\r
- ret->enum_level = 5;\r
- } else {\r
- ret->enum_level = 4;\r
- }\r
-\r
- retval = printer_add_enum(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,\r
- ret->enum_level, buffer, 0, nprinters_ptr);\r
- if (!retval)\r
- goto error;\r
- else\r
- buffer = retval;\r
-\r
- switch (ret->enum_level) {\r
- case 4:\r
- ret->info.i4 = (LPPRINTER_INFO_4)buffer;\r
- break;\r
- case 5:\r
- ret->info.i5 = (LPPRINTER_INFO_5)buffer;\r
- break;\r
- }\r
- ret->nprinters = *nprinters_ptr;\r
- \r
- return ret;\r
-\r
- error:\r
- sfree(buffer);\r
- sfree(ret);\r
- *nprinters_ptr = 0;\r
- return NULL;\r
-}\r
-\r
-char *printer_get_name(printer_enum *pe, int i)\r
-{\r
- if (!pe)\r
- return NULL;\r
- if (i < 0 || i >= pe->nprinters)\r
- return NULL;\r
- switch (pe->enum_level) {\r
- case 4:\r
- return pe->info.i4[i].pPrinterName;\r
- case 5:\r
- return pe->info.i5[i].pPrinterName;\r
- default:\r
- return NULL;\r
- }\r
-}\r
-\r
-void printer_finish_enum(printer_enum *pe)\r
-{\r
- if (!pe)\r
- return;\r
- switch (pe->enum_level) {\r
- case 4:\r
- sfree(pe->info.i4);\r
- break;\r
- case 5:\r
- sfree(pe->info.i5);\r
- break;\r
- }\r
- sfree(pe);\r
-}\r
-\r
-printer_job *printer_start_job(char *printer)\r
-{\r
- printer_job *ret = snew(printer_job);\r
- DOC_INFO_1 docinfo;\r
- int jobstarted = 0, pagestarted = 0;\r
-\r
- ret->hprinter = NULL;\r
- if (!OpenPrinter(printer, &ret->hprinter, NULL))\r
- goto error;\r
-\r
- docinfo.pDocName = "PuTTY remote printer output";\r
- docinfo.pOutputFile = NULL;\r
- docinfo.pDatatype = "RAW";\r
-\r
- if (!StartDocPrinter(ret->hprinter, 1, (LPSTR)&docinfo))\r
- goto error;\r
- jobstarted = 1;\r
-\r
- if (!StartPagePrinter(ret->hprinter))\r
- goto error;\r
- pagestarted = 1;\r
-\r
- return ret;\r
-\r
- error:\r
- if (pagestarted)\r
- EndPagePrinter(ret->hprinter);\r
- if (jobstarted)\r
- EndDocPrinter(ret->hprinter);\r
- if (ret->hprinter)\r
- ClosePrinter(ret->hprinter);\r
- sfree(ret);\r
- return NULL;\r
-}\r
-\r
-void printer_job_data(printer_job *pj, void *data, int len)\r
-{\r
- DWORD written;\r
-\r
- if (!pj)\r
- return;\r
-\r
- WritePrinter(pj->hprinter, data, len, &written);\r
-}\r
-\r
-void printer_finish_job(printer_job *pj)\r
-{\r
- if (!pj)\r
- return;\r
-\r
- EndPagePrinter(pj->hprinter);\r
- EndDocPrinter(pj->hprinter);\r
- ClosePrinter(pj->hprinter);\r
- sfree(pj);\r
-}\r