#include <windows.h>
#include "putty.h"
+/*
+ * Boggle. Flipping between the two branches of this #if appears to
+ * make all the difference as to whether network printers show up
+ * under PRINTER_ENUM_CONNECTIONS on NT 4. I don't pretend to
+ * understand this...
+ */
+#if 1
+#define ENUM_LEVEL 5
+#define ENUM_PTR LPPRINTER_INFO_5
+#define ENUM_TYPE PRINTER_INFO_5
+#define ENUM_MEMBER pPrinterName
+#else
+#define ENUM_LEVEL 1
+#define ENUM_PTR LPPRINTER_INFO_1
+#define ENUM_TYPE PRINTER_INFO_1
+#define ENUM_MEMBER pName
+#endif
+
struct printer_enum_tag {
int nprinters;
- LPPRINTER_INFO_5 info;
+ ENUM_PTR info;
};
struct printer_job_tag {
HANDLE hprinter;
};
+static char *printer_add_enum(int param, char *buffer,
+ int offset, int *nprinters_ptr)
+{
+ DWORD needed, nprinters;
+
+ buffer = srealloc(buffer, offset+512);
+
+ if (EnumPrinters(param, NULL, ENUM_LEVEL, buffer+offset,
+ 512, &needed, &nprinters) == 0)
+ return NULL;
+
+ if (needed < 512)
+ needed = 512;
+
+ buffer = srealloc(buffer, offset+needed);
+
+ if (EnumPrinters(param, NULL, ENUM_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 = smalloc(sizeof(printer_enum));
- char *buffer = NULL;
- DWORD needed, nprinters;
+ char *buffer = NULL, *retval;
*nprinters_ptr = 0; /* default return value */
buffer = smalloc(512);
- if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5,
- buffer, 512, &needed, &nprinters) == 0)
- goto error;
-
- if (needed) {
- buffer = srealloc(buffer, needed);
- if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5,
- (LPBYTE)buffer, needed, &needed, &nprinters) == 0)
- goto error;
- } else {
- nprinters = 0;
- ret->info = NULL;
- }
+ retval = printer_add_enum(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
+ buffer, 0, nprinters_ptr);
+ if (!retval)
+ goto error;
+ else
+ buffer = retval;
- ret->info = (LPPRINTER_INFO_5)buffer;
- ret->nprinters = *nprinters_ptr = nprinters;
+ ret->info = (ENUM_PTR)buffer;
+ ret->nprinters = *nprinters_ptr;
return ret;
error:
sfree(buffer);
sfree(ret);
+ *nprinters_ptr = 0;
return NULL;
}
return NULL;
if (i < 0 || i >= pe->nprinters)
return NULL;
- return pe->info[i].pPrinterName;
+ return pe->info[i].ENUM_MEMBER;
}
void printer_finish_enum(printer_enum *pe)