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