1 /* GTK - The GIMP Toolkit
2  * gtkprintoperation.c: Print Operation
3  * Copyright (C) 2006, Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef _MSC_VER
20 #ifndef _WIN32_WINNT
21 /* Vista or newer */
22 #define _WIN32_WINNT 0x0600
23 #endif
24 #ifndef WINVER
25 #define WINVER _WIN32_WINNT
26 #endif
27 #endif
28 
29 #include "config.h"
30 #include "gtkprint-win32.h"
31 
32 void
gtk_print_win32_devnames_free(GtkPrintWin32Devnames * devnames)33 gtk_print_win32_devnames_free (GtkPrintWin32Devnames *devnames)
34 {
35   g_free (devnames->driver);
36   g_free (devnames->device);
37   g_free (devnames->output);
38   g_free (devnames);
39 }
40 
41 GtkPrintWin32Devnames *
gtk_print_win32_devnames_from_win32(HGLOBAL global)42 gtk_print_win32_devnames_from_win32 (HGLOBAL global)
43 {
44   LPDEVNAMES win = GlobalLock (global);
45   gunichar2 *data = (gunichar2 *)win;
46   GtkPrintWin32Devnames *devnames = g_new (GtkPrintWin32Devnames, 1);
47 
48   devnames->driver = g_utf16_to_utf8 (data + win->wDriverOffset,
49 				      -1, NULL, NULL, NULL);
50   devnames->device = g_utf16_to_utf8 (data + win->wDeviceOffset,
51 				      -1, NULL, NULL, NULL);
52   devnames->output = g_utf16_to_utf8 (data + win->wOutputOffset,
53 				      -1, NULL, NULL, NULL);
54   devnames->flags = win->wDefault;
55 
56   GlobalUnlock (global);
57 
58   return devnames;
59 }
60 
61 HGLOBAL
gtk_print_win32_devnames_to_win32(const GtkPrintWin32Devnames * devnames)62 gtk_print_win32_devnames_to_win32 (const GtkPrintWin32Devnames *devnames)
63 {
64   HGLOBAL global;
65   LPDEVNAMES windevnames;
66   gunichar2 *data;
67   gunichar2 *driver, *device, *output;
68   glong driver_len, device_len, output_len;
69   int i;
70 
71   driver = g_utf8_to_utf16 (devnames->driver, -1, NULL, &driver_len, NULL);
72   device = g_utf8_to_utf16 (devnames->device, -1, NULL, &device_len, NULL);
73   output = g_utf8_to_utf16 (devnames->output, -1, NULL, &output_len, NULL);
74 
75   global = GlobalAlloc (GMEM_MOVEABLE,
76 			sizeof (DEVNAMES) +
77 			(driver_len + 1) * 2 +
78 			(device_len + 1) * 2 +
79 			(output_len + 1) * 2);
80 
81   windevnames = GlobalLock (global);
82   data = (gunichar2 *)windevnames;
83   i = sizeof(DEVNAMES) / sizeof (gunichar2);
84 
85   windevnames->wDriverOffset = i;
86   memcpy (data + i, driver, (driver_len + 1) * sizeof (gunichar2));
87   i += driver_len + 1;
88   windevnames->wDeviceOffset = i;
89   memcpy (data + i, device, (device_len + 1) * sizeof (gunichar2));
90   i += device_len + 1;
91   windevnames->wOutputOffset = i;
92   memcpy (data + i, output, (output_len + 1) * sizeof (gunichar2));
93   i += output_len + 1;
94   windevnames->wDefault = devnames->flags;
95   GlobalUnlock (global);
96 
97   g_free (driver);
98   g_free (device);
99   g_free (output);
100 
101   return global;
102 }
103 
104 HGLOBAL
gtk_print_win32_devnames_to_win32_from_printer_name(const char * printer_name)105 gtk_print_win32_devnames_to_win32_from_printer_name (const char *printer_name)
106 {
107   HGLOBAL global;
108   GtkPrintWin32Devnames *devnames;
109 
110   devnames = gtk_print_win32_devnames_from_printer_name(printer_name);
111   if (devnames)
112     {
113       global = gtk_print_win32_devnames_to_win32 (devnames);
114       gtk_print_win32_devnames_free (devnames);
115     }
116   else
117     global = NULL;
118 
119   return global;
120 }
121 
122 /*
123  * Used to get printer device information from a printer name.  This
124  * can fail if the user has no right to read printer properties, so
125  * this function can return NULL.
126  */
127 GtkPrintWin32Devnames *
gtk_print_win32_devnames_from_printer_name(const char * printer_name)128 gtk_print_win32_devnames_from_printer_name (const char *printer_name)
129 {
130   HANDLE hprinter;
131   gunichar2* win32_printer_name;
132   GtkPrintWin32Devnames *devnames;
133 
134   win32_printer_name = g_utf8_to_utf16 (printer_name, -1, NULL, NULL, NULL);
135   if (OpenPrinterW (win32_printer_name, &hprinter, NULL))
136     {
137       DWORD needed;
138       PRINTER_INFO_2W* printer_info;
139 
140       GetPrinterW (hprinter, 2, NULL, 0, &needed);
141       printer_info = (PRINTER_INFO_2W* )g_malloc ((gsize) needed);
142       GetPrinterW (hprinter, 2, (LPBYTE) printer_info, needed, &needed);
143       devnames = g_new (GtkPrintWin32Devnames, 1);
144       devnames->driver = g_utf16_to_utf8 (printer_info->pDriverName, -1, NULL, NULL, NULL);
145       devnames->device = g_strdup (printer_name);
146       devnames->output = g_utf16_to_utf8 (printer_info->pPortName, -1, NULL, NULL, NULL);
147       devnames->flags  = 0;
148       ClosePrinter (hprinter);
149       g_free (printer_info);
150     }
151   else
152     {
153       /* Could not open printer */
154       devnames = NULL;
155     }
156   g_free (win32_printer_name);
157 
158   return devnames;
159 }
160