2 * Set printer capabilities in DsDriver Keys on remote printer
3 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program 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
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* This needs to be defined for certain compilers */
27 #define SAMBA_PORT _T("Samba")
29 TCHAR
*PrintLastError(void)
31 static TCHAR msgtxt
[1024*sizeof(TCHAR
)];
33 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
,
40 void map_orientation(HANDLE ph
, TCHAR
*printer
, TCHAR
*port
)
43 TCHAR portrait_only
[] = _T("PORTRAIT\0");
44 TCHAR both
[] = _T("LANDSCAPE\0PORTRAIT\0");
46 /* orentation of 90 or 270 indicates landscape supported, 0 means it isn't */
47 rot
= DeviceCapabilities(printer
, port
, DC_BINNAMES
, NULL
, NULL
);
49 printf("printOrientationsSupported:\n");
52 printf("\tPORTRAIT\n\tLANDSCAPE\n");
53 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printOrientationsSupported"), REG_MULTI_SZ
,
56 printf("\tPORTRAIT\n");
57 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printOrientationsSupported"), REG_MULTI_SZ
,
58 portrait_only
, sizeof(portrait_only
));
62 void map_resolution(HANDLE ph
, TCHAR
*printer
, TCHAR
*port
)
64 DWORD num
, *res
, maxres
= 0, i
;
66 num
= DeviceCapabilities(printer
, port
, DC_ENUMRESOLUTIONS
, NULL
, NULL
);
67 if ((DWORD
) -1 == num
)
69 res
= malloc(num
*2*sizeof(DWORD
));
70 num
= DeviceCapabilities(printer
, port
, DC_ENUMRESOLUTIONS
, (BYTE
*) res
, NULL
);
71 for (i
=0; i
< num
*2; i
++) {
72 maxres
= (res
[i
] > maxres
) ? res
[i
] : maxres
;
74 printf("printMaxResolutionSupported: %d\n", maxres
);
75 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printMaxResolutionSupported"), REG_DWORD
,
76 (BYTE
*) &maxres
, sizeof(maxres
));
79 void map_extents(HANDLE ph
, TCHAR
*printer
, TCHAR
*port
)
81 DWORD extentval
, xval
, yval
;
83 extentval
= DeviceCapabilities(printer
, port
, DC_MINEXTENT
, NULL
, NULL
);
84 xval
= (DWORD
) (LOWORD(extentval
));
85 yval
= (DWORD
) (HIWORD(extentval
));
86 printf("printMinXExtent: %d\n", xval
);
87 printf("printMinYExtent: %d\n", yval
);
88 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printMinXExtent"), REG_DWORD
, (BYTE
*) &xval
, sizeof(xval
));
89 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printMinYExtent"), REG_DWORD
, (BYTE
*) &yval
, sizeof(yval
));
90 extentval
= DeviceCapabilities(printer
, port
, DC_MAXEXTENT
, NULL
, NULL
);
91 xval
= (DWORD
) (LOWORD(extentval
));
92 yval
= (DWORD
) (HIWORD(extentval
));
93 printf("printMaxXExtent: %d\n", xval
);
94 printf("printMaxYExtent: %d\n", yval
);
95 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printMaxXExtent"), REG_DWORD
, (BYTE
*) &xval
, sizeof(xval
));
96 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printMaxYExtent"), REG_DWORD
, (BYTE
*) &yval
, sizeof(yval
));
99 void map_printrateunit(HANDLE ph
, TCHAR
*printer
, TCHAR
*port
)
102 TCHAR ppm
[] = _T("PagesPerMinute");
103 TCHAR ipm
[] = _T("InchesPerMinute");
104 TCHAR lpm
[] = _T("LinesPerMinute");
105 TCHAR cps
[] = _T("CharactersPerSecond");
107 unit
= DeviceCapabilities(printer
, port
, DC_PRINTRATEUNIT
, NULL
, NULL
);
109 case PRINTRATEUNIT_PPM
:
110 printf("printRateUnit: %s\n", ppm
);
111 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printRateUnit"), REG_SZ
, ppm
, sizeof(ppm
));
113 case PRINTRATEUNIT_IPM
:
114 printf("printRateUnit: %s\n", ipm
);
115 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printRateUnit"), REG_SZ
, ipm
, sizeof(ipm
));
117 case PRINTRATEUNIT_LPM
:
118 printf("printRateUnit: %s\n", lpm
);
119 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printRateUnit"), REG_SZ
, lpm
, sizeof(lpm
));
121 case PRINTRATEUNIT_CPS
:
122 printf("printRateUnit: %s\n", cps
);
123 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, _T("printRateUnit"), REG_SZ
, cps
, sizeof(cps
));
126 printf("printRateUnit: unknown value %d\n", unit
);
130 void map_generic_boolean(HANDLE ph
, TCHAR
*printer
, TCHAR
*port
, WORD cap
, TCHAR
*key
)
133 /* DeviceCapabilities doesn't always return 1 for true...just nonzero */
134 boolval
= (BYTE
) (DeviceCapabilities(printer
, port
, cap
, NULL
, NULL
) ? 1 : 0);
135 printf("%s: %s\n", key
, boolval
? "TRUE" : "FALSE");
136 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, key
, REG_BINARY
, &boolval
, sizeof(boolval
));
139 void map_generic_dword(HANDLE ph
, TCHAR
*printer
, TCHAR
*port
, WORD cap
, TCHAR
*key
)
143 dword
= DeviceCapabilities(printer
, port
, cap
, NULL
, NULL
);
144 if ((DWORD
) -1 == dword
)
147 printf("%s: %d\n", key
, dword
);
148 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, key
, REG_DWORD
, (BYTE
*) &dword
, sizeof(dword
));
151 void map_generic_multi_sz(HANDLE ph
, TCHAR
*printer
, TCHAR
*port
, WORD cap
, TCHAR
*key
, int size
)
154 TCHAR
*strings_out
, *strings_cur
;
157 num_items
= DeviceCapabilities(printer
, port
, cap
, NULL
, NULL
);
158 if ((DWORD
) -1 == num_items
)
160 strings_in
= malloc(num_items
* size
);
161 strings_out
= calloc(num_items
, size
);
162 num_items
= DeviceCapabilities(printer
, port
, cap
, strings_in
, NULL
);
163 printf("%s:\n", key
);
164 for (i
=0, strings_cur
= strings_out
; i
< num_items
; i
++) {
165 _tcsncpy(strings_cur
, &strings_in
[i
*size
], size
);
166 printf("\t%s\n", strings_cur
);
167 strings_cur
+= _tcslen(strings_cur
) + 1;
170 SetPrinterDataEx(ph
, SPLDS_DRIVER_KEY
, key
, REG_MULTI_SZ
, strings_out
,
171 (strings_cur
- strings_out
+ 1) * sizeof(TCHAR
));
177 int main(int argc
, char *argv
[])
183 TCHAR
*port
= SAMBA_PORT
;
184 PRINTER_DEFAULTS admin_access
= {NULL
, NULL
, PRINTER_ACCESS_ADMINISTER
};
185 PRINTER_INFO_7 publish
= {NULL
, DSPRINT_PUBLISH
};
188 printf("Usage: %s <printername>\n", argv
[0]);
194 if (!(OpenPrinter(printer
, &ph
, &admin_access
))) {
195 printf("OpenPrinter failed, error = %s\n", PrintLastError());
199 GetPrinterDriver(ph
, NULL
, 1, NULL
, 0, &needed
);
201 printf("GetPrinterDriver failed, error = %s\n", PrintLastError());
205 driver_info
= malloc(needed
);
206 if (!(GetPrinterDriver(ph
, NULL
, 1, driver_info
, needed
, &needed
))) {
207 printf("GetPrinterDriver failed, error = %s\n", PrintLastError());
212 map_generic_multi_sz(ph
, printer
, port
, DC_BINNAMES
, _T("printBinNames"), 24);
213 map_generic_boolean(ph
, printer
, port
, DC_COLLATE
, _T("printCollate"));
214 map_generic_dword(ph
, printer
, port
, DC_COPIES
, _T("printMaxCopies"));
215 map_generic_dword(ph
, printer
, port
, DC_DRIVER
, _T("driverVersion"));
216 map_generic_boolean(ph
, printer
, port
, DC_DUPLEX
, _T("printDuplexSupported"));
217 map_extents(ph
, printer
, port
);
218 map_resolution(ph
, printer
, port
);
219 map_orientation(ph
, printer
, port
);
220 map_generic_multi_sz(ph
, printer
, port
, DC_PAPERNAMES
, _T("printMediaSupported"), 64);
221 #if (WINVER >= 0x0500)
222 map_generic_boolean(ph
, printer
, port
, DC_COLORDEVICE
, _T("printColor"));
223 map_generic_multi_sz(ph
, printer
, port
, DC_PERSONALITY
, _T("printLanguage"), 64);
224 map_generic_multi_sz(ph
, printer
, port
, DC_MEDIAREADY
, _T("printMediaReady"),64);
225 map_generic_dword(ph
, printer
, port
, DC_PRINTERMEM
, _T("printMemory"));
226 map_generic_dword(ph
, printer
, port
, DC_PRINTRATE
, _T("printRate"));
227 map_printrateunit(ph
, printer
, port
);
229 map_generic_boolean(ph
, printer
, port
, DC_STAPLE
, _T("printStaplingSupported"));
231 #ifdef DC_PRINTRATEPPM
232 map_generic_dword(ph
, printer
, port
, DC_PRINTRATEPPM
, _T("printPagesPerMinute"));
235 SetPrinter(ph
, 7, (BYTE
*) &publish
, 0);