Network printers weren't showing up on at least NT4. This version
[u/mdw/putty] / printing.c
index cd4baa9..d40e2ac 100644 (file)
@@ -5,46 +5,88 @@
 #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 0
+#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;
-    }
 
-    ret->info = (LPPRINTER_INFO_5)buffer;
-    ret->nprinters = *nprinters_ptr = nprinters;
+    retval = printer_add_enum(PRINTER_ENUM_LOCAL, buffer, 0, nprinters_ptr);
+    if (!retval)
+        goto error;
+    else
+        buffer = retval;
+    retval = printer_add_enum(PRINTER_ENUM_CONNECTIONS, buffer,
+                              sizeof(ENUM_TYPE) * *nprinters_ptr,
+                              nprinters_ptr);
+    if (!retval)
+        goto error;
+    else
+        buffer = retval;
+
+    ret->info = (ENUM_PTR)buffer;
+    ret->nprinters = *nprinters_ptr;
     
     return ret;
 
     error:
     sfree(buffer);
     sfree(ret);
+    *nprinters_ptr = 0;
     return NULL;
 }
 
@@ -54,7 +96,7 @@ char *printer_get_name(printer_enum *pe, int i)
        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)