2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Jean François Micouleau 1998-2000.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern DOM_SID global_sid_World;
26 static TDB_CONTEXT *tdb_forms; /* used for forms files */
27 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
28 static TDB_CONTEXT *tdb_printers; /* used for printers files */
30 #define FORMS_PREFIX "FORMS/"
31 #define DRIVERS_PREFIX "DRIVERS/"
32 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
33 #define PRINTERS_PREFIX "PRINTERS/"
34 #define SECDESC_PREFIX "SECDESC/"
35 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
37 #define NTDRIVERS_DATABASE_VERSION_1 1
38 #define NTDRIVERS_DATABASE_VERSION_2 2
39 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
41 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_3
43 /* Map generic permissions to printer object specific permissions */
45 GENERIC_MAPPING printer_generic_mapping = {
52 STANDARD_MAPPING printer_std_mapping = {
59 /* We need one default form to support our default printer. Msoft adds the
60 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
61 array index). Letter is always first, so (for the current code) additions
62 always put things in the correct order. */
63 static nt_forms_struct default_forms[] = {
64 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
65 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
66 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
67 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
68 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
69 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
70 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
71 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
72 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
73 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
74 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
75 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
76 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
77 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
78 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
79 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
80 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
81 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
82 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
83 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
84 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
85 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
86 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
87 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
88 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
89 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
90 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
91 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
92 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
93 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
94 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
95 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
96 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
97 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
98 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
99 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
100 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
101 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
102 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
103 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
104 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
105 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
106 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
107 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
108 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
109 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
110 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
111 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
112 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
113 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
114 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
115 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
116 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
117 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
118 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
119 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
120 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
121 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
122 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
123 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
124 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
125 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
126 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
127 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
128 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
129 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
130 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
131 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
132 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
133 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
134 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
135 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
136 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
137 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
138 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
139 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
140 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
141 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
142 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
143 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
144 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
145 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
146 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
147 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
148 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
149 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
150 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
151 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
152 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
153 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
154 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
155 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
156 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
157 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
158 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
159 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
160 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
161 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
162 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
163 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
164 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
165 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
166 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
167 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
168 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
169 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
170 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
171 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
172 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
173 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
174 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
175 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
176 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
177 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
178 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
179 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
180 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
181 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
184 static BOOL upgrade_to_version_3(void)
186 TDB_DATA kbuf, newkey, dbuf;
188 DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
190 for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
191 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
193 dbuf = tdb_fetch(tdb_drivers, kbuf);
195 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
196 DEBUG(0,("upgrade_to_version_3:moving form\n"));
197 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
198 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
201 if (tdb_delete(tdb_drivers, kbuf) != 0) {
202 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
207 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
208 DEBUG(0,("upgrade_to_version_3:moving printer\n"));
209 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
210 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
213 if (tdb_delete(tdb_drivers, kbuf) != 0) {
214 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
219 if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
220 DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
221 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
222 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
225 if (tdb_delete(tdb_drivers, kbuf) != 0) {
226 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
231 SAFE_FREE(dbuf.dptr);
237 /****************************************************************************
238 Open the NT printing tdb.
239 ****************************************************************************/
241 BOOL nt_printing_init(void)
243 static pid_t local_pid;
244 char *vstring = "INFO/version";
246 if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
249 tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
251 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
252 lock_path("ntdrivers.tdb"), strerror(errno) ));
256 tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
258 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
259 lock_path("ntprinters.tdb"), strerror(errno) ));
263 tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
265 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
266 lock_path("ntforms.tdb"), strerror(errno) ));
270 local_pid = sys_getpid();
272 /* handle a Samba upgrade */
273 tdb_lock_bystring(tdb_drivers, vstring);
277 /* Cope with byte-reversed older versions of the db. */
278 vers_id = tdb_fetch_int32(tdb_drivers, vstring);
279 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
280 /* Written on a bigendian machine with old fetch_int code. Save as le. */
281 /* The only upgrade between V2 and V3 is to save the version in little-endian. */
282 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
283 vers_id = NTDRIVERS_DATABASE_VERSION;
286 if (vers_id != NTDRIVERS_DATABASE_VERSION) {
288 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
289 if (!upgrade_to_version_3())
292 tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
294 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
297 tdb_unlock_bystring(tdb_drivers, vstring);
299 update_c_setprinter(True);
304 /*******************************************************************
305 tdb traversal function for counting printers.
306 ********************************************************************/
308 static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
309 TDB_DATA data, void *context)
311 int *printer_count = (int*)context;
313 if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
315 DEBUG(10,("traverse_counting_printers: printer = [%s] printer_count = %d\n", key.dptr, *printer_count));
321 /*******************************************************************
322 Update the spooler global c_setprinter. This variable is initialized
323 when the parent smbd starts with the number of existing printers. It
324 is monotonically increased by the current number of printers *after*
325 each add or delete printer RPC. Only Microsoft knows why... JRR020119
326 ********************************************************************/
328 uint32 update_c_setprinter(BOOL initialize)
331 int32 printer_count = 0;
333 tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
335 /* Traverse the tdb, counting the printers */
336 tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
338 /* If initializing, set c_setprinter to current printers count
339 * otherwise, bump it by the current printer count
342 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
344 c_setprinter = printer_count;
346 DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
347 tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
349 tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
351 return (uint32)c_setprinter;
354 /*******************************************************************
355 Get the spooler global c_setprinter, accounting for initialization.
356 ********************************************************************/
358 uint32 get_c_setprinter(void)
360 int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
362 if (c_setprinter == (int32)-1)
363 c_setprinter = update_c_setprinter(True);
365 DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
367 return (uint32)c_setprinter;
370 /****************************************************************************
371 Get builtin form struct list.
372 ****************************************************************************/
374 int get_builtin_ntforms(nt_forms_struct **list)
376 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
377 return sizeof(default_forms) / sizeof(default_forms[0]);
380 /****************************************************************************
381 get a builtin form struct
382 ****************************************************************************/
384 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
388 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
389 DEBUGADD(6,("Looking for builtin form %s \n", form_name));
390 count = sizeof(default_forms) / sizeof(default_forms[0]);
391 for (i=0;i<count;i++) {
392 if (strequal(form_name,default_forms[i].name)) {
393 DEBUGADD(6,("Found builtin form %s \n", form_name));
394 memcpy(form,&default_forms[i],sizeof(*form));
402 /****************************************************************************
403 get a form struct list
404 ****************************************************************************/
405 int get_ntforms(nt_forms_struct **list)
407 TDB_DATA kbuf, newkey, dbuf;
409 nt_forms_struct form;
414 for (kbuf = tdb_firstkey(tdb_forms);
416 newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
417 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
419 dbuf = tdb_fetch(tdb_forms, kbuf);
420 if (!dbuf.dptr) continue;
422 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
423 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
424 &i, &form.flag, &form.width, &form.length, &form.left,
425 &form.top, &form.right, &form.bottom);
426 SAFE_FREE(dbuf.dptr);
427 if (ret != dbuf.dsize) continue;
429 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
431 DEBUG(0,("get_ntforms: Realloc fail.\n"));
443 /****************************************************************************
444 write a form struct list
445 ****************************************************************************/
446 int write_ntforms(nt_forms_struct **list, int number)
453 for (i=0;i<number;i++) {
454 /* save index, so list is rebuilt in correct order */
455 len = tdb_pack(buf, sizeof(buf), "dddddddd",
456 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
457 (*list)[i].left, (*list)[i].top, (*list)[i].right,
459 if (len > sizeof(buf)) break;
460 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
461 kbuf.dsize = strlen(key)+1;
465 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
471 /****************************************************************************
472 add a form struct at the end of the list
473 ****************************************************************************/
474 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
482 * NT tries to add forms even when
483 * they are already in the base
484 * only update the values if already present
489 unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
490 for (n=0; n<*count; n++) {
491 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
492 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
499 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
500 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
504 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
508 (*list)[n].flag=form->flags;
509 (*list)[n].width=form->size_x;
510 (*list)[n].length=form->size_y;
511 (*list)[n].left=form->left;
512 (*list)[n].top=form->top;
513 (*list)[n].right=form->right;
514 (*list)[n].bottom=form->bottom;
519 /****************************************************************************
520 delete a named form struct
521 ****************************************************************************/
522 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
531 unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
533 for (n=0; n<*count; n++) {
534 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
535 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
541 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
542 *ret = WERR_INVALID_PARAM;
546 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
547 kbuf.dsize = strlen(key)+1;
549 if (tdb_delete(tdb_forms, kbuf) != 0) {
557 /****************************************************************************
559 ****************************************************************************/
560 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
564 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
566 DEBUG(106, ("[%s]\n", form_name));
567 for (n=0; n<count; n++)
569 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
570 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
574 if (n==count) return;
576 (*list)[n].flag=form->flags;
577 (*list)[n].width=form->size_x;
578 (*list)[n].length=form->size_y;
579 (*list)[n].left=form->left;
580 (*list)[n].top=form->top;
581 (*list)[n].right=form->right;
582 (*list)[n].bottom=form->bottom;
585 /****************************************************************************
586 get the nt drivers list
588 traverse the database and look-up the matching names
589 ****************************************************************************/
590 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
596 TDB_DATA kbuf, newkey;
598 get_short_archi(short_archi, architecture);
599 slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
601 for (kbuf = tdb_firstkey(tdb_drivers);
603 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
604 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
606 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
607 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
612 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
619 /****************************************************************************
620 function to do the mapping between the long architecture name and
622 ****************************************************************************/
623 BOOL get_short_archi(char *short_archi, char *long_archi)
630 struct table archi_table[]=
632 {"Windows 4.0", "WIN40" },
633 {"Windows NT x86", "W32X86" },
634 {"Windows NT R4000", "W32MIPS" },
635 {"Windows NT Alpha_AXP", "W32ALPHA" },
636 {"Windows NT PowerPC", "W32PPC" },
642 DEBUG(107,("Getting architecture dependant directory\n"));
645 } while ( (archi_table[i].long_archi!=NULL ) &&
646 StrCaseCmp(long_archi, archi_table[i].long_archi) );
648 if (archi_table[i].long_archi==NULL) {
649 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
653 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
655 DEBUGADD(108,("index: [%d]\n", i));
656 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
657 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
662 /****************************************************************************
663 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
664 There are two case to be covered here: PE (Portable Executable) and NE (New
665 Executable) files. Both files support the same INFO structure, but PE files
666 store the signature in unicode, and NE files store it as !unicode.
667 returns -1 on error, 1 on version info found, and 0 on no version info found.
668 ****************************************************************************/
670 static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
676 if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
677 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
678 fname, PE_HEADER_SIZE));
682 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
683 if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
684 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
686 goto no_version_info;
689 /* Is this really a DOS header? */
690 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
691 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
692 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
693 goto no_version_info;
696 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
697 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
698 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
700 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
701 goto no_version_info;
704 if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
705 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
707 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
708 goto no_version_info;
711 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
712 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
714 int section_table_bytes;
716 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
717 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
718 fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
719 /* At this point, we assume the file is in error. It still could be somthing
720 * else besides a PE file, but it unlikely at this point.
725 /* get the section table */
726 num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
727 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
729 if ((buf=malloc(section_table_bytes)) == NULL) {
730 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
731 fname, section_table_bytes));
735 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
736 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
741 /* Iterate the section table looking for the resource section ".rsrc" */
742 for (i = 0; i < num_sections; i++) {
743 int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
745 if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
746 int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
747 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
750 if ((buf=malloc(section_bytes)) == NULL) {
751 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
752 fname, section_bytes));
756 /* Seek to the start of the .rsrc section info */
757 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
758 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
763 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
764 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
769 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
770 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
771 if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
772 /* Align to next long address */
773 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
775 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
776 *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
777 *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
779 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
780 fname, *major, *minor,
781 (*major>>16)&0xffff, *major&0xffff,
782 (*minor>>16)&0xffff, *minor&0xffff));
791 /* Version info not found, fall back to origin date/time */
792 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
796 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
797 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
798 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
799 fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
800 /* At this point, we assume the file is in error. It still could be somthing
801 * else besides a NE file, but it unlikely at this point. */
805 /* Allocate a bit more space to speed up things */
807 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
808 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
809 fname, PE_HEADER_SIZE));
813 /* This is a HACK! I got tired of trying to sort through the messy
814 * 'NE' file format. If anyone wants to clean this up please have at
815 * it, but this works. 'NE' files will eventually fade away. JRR */
816 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
817 /* Cover case that should not occur in a well formed 'NE' .dll file */
818 if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
820 for(i=0; i<byte_count; i++) {
821 /* Fast skip past data that can't possibly match */
822 if (buf[i] != 'V') continue;
824 /* Potential match data crosses buf boundry, move it to beginning
825 * of buf, and fill the buf with as much as it will hold. */
826 if (i>byte_count-VS_VERSION_INFO_SIZE) {
829 memcpy(buf, &buf[i], byte_count-i);
830 if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
831 (byte_count-i))) < 0) {
833 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
838 byte_count = bc + (byte_count - i);
839 if (byte_count<VS_VERSION_INFO_SIZE) break;
844 /* Check that the full signature string and the magic number that
845 * follows exist (not a perfect solution, but the chances that this
846 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
847 * twice, as it is simpler to read the code. */
848 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
849 /* Compute skip alignment to next long address */
850 int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
851 sizeof(VS_SIGNATURE)) & 3;
852 if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
854 *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
855 *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
856 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
857 fname, *major, *minor,
858 (*major>>16)&0xffff, *major&0xffff,
859 (*minor>>16)&0xffff, *minor&0xffff));
866 /* Version info not found, fall back to origin date/time */
867 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
872 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
873 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
874 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
885 /****************************************************************************
886 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
887 share one or more files. During the MS installation process files are checked
888 to insure that only a newer version of a shared file is installed over an
889 older version. There are several possibilities for this comparison. If there
890 is no previous version, the new one is newer (obviously). If either file is
891 missing the version info structure, compare the creation date (on Unix use
892 the modification date). Otherwise chose the numerically larger version number.
893 ****************************************************************************/
894 static int file_version_is_newer(connection_struct *conn, fstring new_file,
897 BOOL use_version = True;
902 time_t new_create_time;
906 time_t old_create_time;
910 files_struct *fsp = NULL;
912 SMB_STRUCT_STAT stat_buf;
916 ZERO_STRUCT(stat_buf);
917 new_create_time = (time_t)0;
918 old_create_time = (time_t)0;
920 /* Get file version info (if available) for previous file (if it exists) */
921 pstrcpy(filepath, old_file);
923 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
925 fsp = open_file_shared(conn, filepath, &stat_buf,
926 SET_OPEN_MODE(DOS_OPEN_RDONLY),
927 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
928 0, 0, &access_mode, &action);
930 /* Old file not found, so by definition new file is in fact newer */
931 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
936 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
937 if (ret == -1) goto error_exit;
940 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
943 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
944 old_create_time = st.st_mtime;
945 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
948 close_file(fsp, True);
950 /* Get file version info (if available) for new file */
951 pstrcpy(filepath, new_file);
952 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
954 fsp = open_file_shared(conn, filepath, &stat_buf,
955 SET_OPEN_MODE(DOS_OPEN_RDONLY),
956 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
957 0, 0, &access_mode, &action);
959 /* New file not found, this shouldn't occur if the caller did its job */
960 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
965 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
966 if (ret == -1) goto error_exit;
969 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
972 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
973 new_create_time = st.st_mtime;
974 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
977 close_file(fsp, True);
980 /* Compare versions and choose the larger version number */
981 if (new_major > old_major ||
982 (new_major == old_major && new_minor > old_minor)) {
984 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
988 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
993 /* Compare modification time/dates and choose the newest time/date */
994 if (new_create_time > old_create_time) {
995 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
999 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1006 close_file(fsp, True);
1010 /****************************************************************************
1011 Determine the correct cVersion associated with an architecture and driver
1012 ****************************************************************************/
1013 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
1014 struct current_user *user, WERROR *perr)
1022 files_struct *fsp = NULL;
1025 connection_struct *conn;
1029 *perr = WERR_INVALID_PARAM;
1031 /* If architecture is Windows 95/98/ME, the version is always 0. */
1032 if (strcmp(architecture, "WIN40") == 0) {
1033 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
1039 * Connect to the print$ share under the same account as the user connected
1040 * to the rpc pipe. Note we must still be root to do this.
1043 /* Null password is ok - we are already an authenticated user... */
1044 null_pw = data_blob(NULL, 0);
1046 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1050 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
1051 *perr = ntstatus_to_werror(nt_status);
1055 /* We are temporarily becoming the connection user. */
1056 if (!become_user(conn, conn->vuid)) {
1057 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
1058 *perr = WERR_ACCESS_DENIED;
1062 /* Open the driver file (Portable Executable format) and determine the
1063 * deriver the cversion. */
1064 slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
1066 unix_convert(driverpath,conn,NULL,&bad_path,&st);
1068 fsp = open_file_shared(conn, driverpath, &st,
1069 SET_OPEN_MODE(DOS_OPEN_RDONLY),
1070 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1071 0, 0, &access_mode, &action);
1073 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
1074 driverpath, errno));
1075 *perr = WERR_ACCESS_DENIED;
1081 int ret = get_file_version(fsp, driverpath, &major, &minor);
1082 if (ret == -1) goto error_exit;
1085 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
1090 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1091 * for more details. Version in this case is not just the version of the
1092 * file, but the version in the sense of kernal mode (2) vs. user mode
1093 * (3) drivers. Other bits of the version fields are the version info.
1096 cversion = major & 0x0000ffff;
1098 case 2: /* WinNT drivers */
1099 case 3: /* Win2K drivers */
1103 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
1104 driverpath, cversion));
1108 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
1109 driverpath, major, minor));
1112 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1113 driverpath, cversion));
1115 close_file(fsp, True);
1116 close_cnum(conn, user->vuid);
1125 close_file(fsp, True);
1127 close_cnum(conn, user->vuid);
1132 /****************************************************************************
1133 ****************************************************************************/
1134 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1135 struct current_user *user)
1137 fstring architecture;
1143 /* clean up the driver name.
1144 * we can get .\driver.dll
1145 * or worse c:\windows\system\driver.dll !
1147 /* using an intermediate string to not have overlaping memcpy()'s */
1148 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1149 fstrcpy(new_name, p+1);
1150 fstrcpy(driver->driverpath, new_name);
1153 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1154 fstrcpy(new_name, p+1);
1155 fstrcpy(driver->datafile, new_name);
1158 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1159 fstrcpy(new_name, p+1);
1160 fstrcpy(driver->configfile, new_name);
1163 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1164 fstrcpy(new_name, p+1);
1165 fstrcpy(driver->helpfile, new_name);
1168 if (driver->dependentfiles) {
1169 for (i=0; *driver->dependentfiles[i]; i++) {
1170 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1171 fstrcpy(new_name, p+1);
1172 fstrcpy(driver->dependentfiles[i], new_name);
1177 get_short_archi(architecture, driver->environment);
1179 /* jfm:7/16/2000 the client always sends the cversion=0.
1180 * The server should check which version the driver is by reading
1181 * the PE header of driver->driverpath.
1183 * For Windows 95/98 the version is 0 (so the value sent is correct)
1184 * For Windows NT (the architecture doesn't matter)
1185 * NT 3.1: cversion=0
1186 * NT 3.5/3.51: cversion=1
1190 if ((driver->cversion = get_correct_cversion( architecture,
1191 driver->driverpath, user, &err)) == -1)
1197 /****************************************************************************
1198 ****************************************************************************/
1199 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1200 struct current_user *user)
1202 fstring architecture;
1208 /* clean up the driver name.
1209 * we can get .\driver.dll
1210 * or worse c:\windows\system\driver.dll !
1212 /* using an intermediate string to not have overlaping memcpy()'s */
1213 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1214 fstrcpy(new_name, p+1);
1215 fstrcpy(driver->driverpath, new_name);
1218 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1219 fstrcpy(new_name, p+1);
1220 fstrcpy(driver->datafile, new_name);
1223 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1224 fstrcpy(new_name, p+1);
1225 fstrcpy(driver->configfile, new_name);
1228 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1229 fstrcpy(new_name, p+1);
1230 fstrcpy(driver->helpfile, new_name);
1233 if (driver->dependentfiles) {
1234 for (i=0; *driver->dependentfiles[i]; i++) {
1235 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1236 fstrcpy(new_name, p+1);
1237 fstrcpy(driver->dependentfiles[i], new_name);
1242 get_short_archi(architecture, driver->environment);
1244 /* jfm:7/16/2000 the client always sends the cversion=0.
1245 * The server should check which version the driver is by reading
1246 * the PE header of driver->driverpath.
1248 * For Windows 95/98 the version is 0 (so the value sent is correct)
1249 * For Windows NT (the architecture doesn't matter)
1250 * NT 3.1: cversion=0
1251 * NT 3.5/3.51: cversion=1
1255 if ((driver->version = get_correct_cversion(architecture,
1256 driver->driverpath, user, &err)) == -1)
1262 /****************************************************************************
1263 ****************************************************************************/
1264 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1265 uint32 level, struct current_user *user)
1270 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1271 driver=driver_abstract.info_3;
1272 return clean_up_driver_struct_level_3(driver, user);
1276 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1277 driver=driver_abstract.info_6;
1278 return clean_up_driver_struct_level_6(driver, user);
1281 return WERR_INVALID_PARAM;
1285 /****************************************************************************
1286 This function sucks and should be replaced. JRA.
1287 ****************************************************************************/
1289 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1291 dst->cversion = src->version;
1293 fstrcpy( dst->name, src->name);
1294 fstrcpy( dst->environment, src->environment);
1295 fstrcpy( dst->driverpath, src->driverpath);
1296 fstrcpy( dst->datafile, src->datafile);
1297 fstrcpy( dst->configfile, src->configfile);
1298 fstrcpy( dst->helpfile, src->helpfile);
1299 fstrcpy( dst->monitorname, src->monitorname);
1300 fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1301 dst->dependentfiles = src->dependentfiles;
1304 #if 0 /* Debugging function */
1306 static char* ffmt(unsigned char *c){
1308 static char ffmt_str[17];
1310 for (i=0; i<16; i++) {
1311 if ((c[i] < ' ') || (c[i] > '~'))
1322 /****************************************************************************
1323 ****************************************************************************/
1324 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
1325 struct current_user *user, WERROR *perr)
1327 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1328 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1329 fstring architecture;
1334 connection_struct *conn;
1341 memset(inbuf, '\0', sizeof(inbuf));
1342 memset(outbuf, '\0', sizeof(outbuf));
1346 driver=driver_abstract.info_3;
1347 else if (level==6) {
1348 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1349 driver = &converted_driver;
1351 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1355 get_short_archi(architecture, driver->environment);
1358 * Connect to the print$ share under the same account as the user connected to the rpc pipe.
1359 * Note we must be root to do this.
1363 null_pw = data_blob(NULL, 0);
1364 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1368 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1369 *perr = ntstatus_to_werror(nt_status);
1374 * Save who we are - we are temporarily becoming the connection user.
1377 if (!become_user(conn, conn->vuid)) {
1378 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1383 * make the directories version and version\driver_name
1384 * under the architecture directory.
1386 DEBUG(5,("Creating first directory\n"));
1387 slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1388 mkdir_internal(conn, new_dir);
1390 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1391 * listed for this driver which has already been moved, skip it (note:
1392 * drivers may list the same file name several times. Then check if the
1393 * file already exists in archi\cversion\, if so, check that the version
1394 * info (or time stamps if version info is unavailable) is newer (or the
1395 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1396 * Otherwise, delete the file.
1398 * If a file is not moved to archi\cversion\ because of an error, all the
1399 * rest of the 'unmoved' driver files are removed from archi\. If one or
1400 * more of the driver's files was already moved to archi\cversion\, it
1401 * potentially leaves the driver in a partially updated state. Version
1402 * trauma will most likely occur if an client attempts to use any printer
1403 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1404 * done is appropriate... later JRR
1407 DEBUG(5,("Moving files now !\n"));
1409 if (driver->driverpath && strlen(driver->driverpath)) {
1410 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
1411 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
1412 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1414 status = rename_internals(conn, new_name, old_name, True);
1415 if (!NT_STATUS_IS_OK(status)) {
1416 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1417 new_name, old_name));
1418 *perr = ntstatus_to_werror(status);
1419 unlink_internals(conn, 0, new_name);
1424 unlink_internals(conn, 0, new_name);
1427 if (driver->datafile && strlen(driver->datafile)) {
1428 if (!strequal(driver->datafile, driver->driverpath)) {
1429 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
1430 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
1431 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1433 status = rename_internals(conn, new_name, old_name, True);
1434 if (!NT_STATUS_IS_OK(status)) {
1435 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1436 new_name, old_name));
1437 *perr = ntstatus_to_werror(status);
1438 unlink_internals(conn, 0, new_name);
1443 unlink_internals(conn, 0, new_name);
1447 if (driver->configfile && strlen(driver->configfile)) {
1448 if (!strequal(driver->configfile, driver->driverpath) &&
1449 !strequal(driver->configfile, driver->datafile)) {
1450 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
1451 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
1452 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1454 status = rename_internals(conn, new_name, old_name, True);
1455 if (!NT_STATUS_IS_OK(status)) {
1456 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1457 new_name, old_name));
1458 *perr = ntstatus_to_werror(status);
1459 unlink_internals(conn, 0, new_name);
1464 unlink_internals(conn, 0, new_name);
1468 if (driver->helpfile && strlen(driver->helpfile)) {
1469 if (!strequal(driver->helpfile, driver->driverpath) &&
1470 !strequal(driver->helpfile, driver->datafile) &&
1471 !strequal(driver->helpfile, driver->configfile)) {
1472 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
1473 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
1474 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1476 status = rename_internals(conn, new_name, old_name, True);
1477 if (!NT_STATUS_IS_OK(status)) {
1478 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1479 new_name, old_name));
1480 *perr = ntstatus_to_werror(status);
1481 unlink_internals(conn, 0, new_name);
1486 unlink_internals(conn, 0, new_name);
1490 if (driver->dependentfiles) {
1491 for (i=0; *driver->dependentfiles[i]; i++) {
1492 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1493 !strequal(driver->dependentfiles[i], driver->datafile) &&
1494 !strequal(driver->dependentfiles[i], driver->configfile) &&
1495 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1497 for (j=0; j < i; j++) {
1498 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1503 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
1504 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
1505 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1507 status = rename_internals(conn, new_name, old_name, True);
1508 if (!NT_STATUS_IS_OK(status)) {
1509 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1510 new_name, old_name));
1511 *perr = ntstatus_to_werror(status);
1512 unlink_internals(conn, 0, new_name);
1517 unlink_internals(conn, 0, new_name);
1523 close_cnum(conn, user->vuid);
1526 return ver == -1 ? False : True;
1529 /****************************************************************************
1530 ****************************************************************************/
1531 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1534 fstring architecture;
1540 TDB_DATA kbuf, dbuf;
1542 get_short_archi(architecture, driver->environment);
1544 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1545 * \\server is added in the rpc server layer.
1546 * It does make sense to NOT store the server's name in the printer TDB.
1549 slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1551 /* .inf files do not always list a file for each of the four standard files.
1552 * Don't prepend a path to a null filename, or client claims:
1553 * "The server on which the printer resides does not have a suitable
1554 * <printer driver name> printer driver installed. Click OK if you
1555 * wish to install the driver on your local machine."
1557 if (strlen(driver->driverpath)) {
1558 fstrcpy(temp_name, driver->driverpath);
1559 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1562 if (strlen(driver->datafile)) {
1563 fstrcpy(temp_name, driver->datafile);
1564 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1567 if (strlen(driver->configfile)) {
1568 fstrcpy(temp_name, driver->configfile);
1569 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1572 if (strlen(driver->helpfile)) {
1573 fstrcpy(temp_name, driver->helpfile);
1574 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1577 if (driver->dependentfiles) {
1578 for (i=0; *driver->dependentfiles[i]; i++) {
1579 fstrcpy(temp_name, driver->dependentfiles[i]);
1580 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1584 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1586 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1593 len += tdb_pack(buf+len, buflen-len, "dffffffff",
1596 driver->environment,
1601 driver->monitorname,
1602 driver->defaultdatatype);
1604 if (driver->dependentfiles) {
1605 for (i=0; *driver->dependentfiles[i]; i++) {
1606 len += tdb_pack(buf+len, buflen-len, "f",
1607 driver->dependentfiles[i]);
1611 if (len != buflen) {
1614 tb = (char *)Realloc(buf, len);
1616 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1627 kbuf.dsize = strlen(key)+1;
1631 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1635 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1641 /****************************************************************************
1642 ****************************************************************************/
1643 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1645 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1648 info3.cversion = driver->version;
1649 fstrcpy(info3.name,driver->name);
1650 fstrcpy(info3.environment,driver->environment);
1651 fstrcpy(info3.driverpath,driver->driverpath);
1652 fstrcpy(info3.datafile,driver->datafile);
1653 fstrcpy(info3.configfile,driver->configfile);
1654 fstrcpy(info3.helpfile,driver->helpfile);
1655 fstrcpy(info3.monitorname,driver->monitorname);
1656 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1657 info3.dependentfiles = driver->dependentfiles;
1659 return add_a_printer_driver_3(&info3);
1663 /****************************************************************************
1664 ****************************************************************************/
1665 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1667 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1671 fstrcpy(info.name, in_prt);
1672 fstrcpy(info.defaultdatatype, "RAW");
1674 fstrcpy(info.driverpath, "");
1675 fstrcpy(info.datafile, "");
1676 fstrcpy(info.configfile, "");
1677 fstrcpy(info.helpfile, "");
1679 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1682 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1683 fstrcpy(info.dependentfiles[0], "");
1685 *info_ptr = memdup(&info, sizeof(info));
1690 /****************************************************************************
1691 ****************************************************************************/
1692 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1694 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1695 TDB_DATA kbuf, dbuf;
1696 fstring architecture;
1701 ZERO_STRUCT(driver);
1703 get_short_archi(architecture, in_arch);
1705 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1707 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1710 kbuf.dsize = strlen(key)+1;
1712 dbuf = tdb_fetch(tdb_drivers, kbuf);
1714 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1716 if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1718 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1727 driver.defaultdatatype);
1730 while (len < dbuf.dsize) {
1733 tddfs = (fstring *)Realloc(driver.dependentfiles,
1734 sizeof(fstring)*(i+2));
1735 if (tddfs == NULL) {
1736 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1739 else driver.dependentfiles = tddfs;
1741 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1742 &driver.dependentfiles[i]);
1745 if (driver.dependentfiles != NULL)
1746 fstrcpy(driver.dependentfiles[i], "");
1748 SAFE_FREE(dbuf.dptr);
1750 if (len != dbuf.dsize) {
1751 SAFE_FREE(driver.dependentfiles);
1753 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1756 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1761 /****************************************************************************
1762 ****************************************************************************/
1763 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1765 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1771 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1772 DEBUG(10,("driver key: [%s]\n", key));
1775 kbuf.dsize = strlen(key)+1;
1776 if (!tdb_exists(tdb_drivers, kbuf))
1780 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1782 DEBUGADD(10,("info3->name [%s]\n", info3->name));
1783 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
1784 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
1785 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
1786 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1787 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1788 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
1790 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
1791 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
1792 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
1794 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1795 trim_string(info3->driverpath, "\\print$\\WIN40\\0\\", 0);
1796 pstrcat(line, info3->driverpath);
1798 trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1799 pstrcat(line, info3->datafile);
1801 trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1802 pstrcat(line, info3->helpfile);
1804 trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1805 pstrcat(line, info3->monitorname);
1807 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
1810 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1812 pstrcat(line, ","); /* don't end in a "," */
1813 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1814 pstrcat(line, info3->dependentfiles[i]);
1822 /****************************************************************************
1823 Debugging function, dump at level 6 the struct in the logs.
1824 ****************************************************************************/
1826 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1829 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1832 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1838 if (driver.info_3 == NULL)
1841 info3=driver.info_3;
1843 DEBUGADD(106,("version:[%d]\n", info3->cversion));
1844 DEBUGADD(106,("name:[%s]\n", info3->name));
1845 DEBUGADD(106,("environment:[%s]\n", info3->environment));
1846 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
1847 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
1848 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
1849 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
1850 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
1851 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1853 for (i=0; info3->dependentfiles &&
1854 *info3->dependentfiles[i]; i++) {
1855 DEBUGADD(106,("dependentfile:[%s]\n",
1856 info3->dependentfiles[i]));
1863 DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
1871 /****************************************************************************
1872 ****************************************************************************/
1873 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1877 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1879 if (!nt_devmode) return len;
1881 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1882 nt_devmode->devicename,
1883 nt_devmode->formname,
1885 nt_devmode->specversion,
1886 nt_devmode->driverversion,
1888 nt_devmode->driverextra,
1889 nt_devmode->orientation,
1890 nt_devmode->papersize,
1891 nt_devmode->paperlength,
1892 nt_devmode->paperwidth,
1895 nt_devmode->defaultsource,
1896 nt_devmode->printquality,
1899 nt_devmode->yresolution,
1900 nt_devmode->ttoption,
1901 nt_devmode->collate,
1902 nt_devmode->logpixels,
1905 nt_devmode->bitsperpel,
1906 nt_devmode->pelswidth,
1907 nt_devmode->pelsheight,
1908 nt_devmode->displayflags,
1909 nt_devmode->displayfrequency,
1910 nt_devmode->icmmethod,
1911 nt_devmode->icmintent,
1912 nt_devmode->mediatype,
1913 nt_devmode->dithertype,
1914 nt_devmode->reserved1,
1915 nt_devmode->reserved2,
1916 nt_devmode->panningwidth,
1917 nt_devmode->panningheight,
1918 nt_devmode->private);
1921 if (nt_devmode->private) {
1922 len += tdb_pack(buf+len, buflen-len, "B",
1923 nt_devmode->driverextra,
1924 nt_devmode->private);
1927 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1932 /****************************************************************************
1933 ****************************************************************************/
1934 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1938 while (param != NULL) {
1939 len += tdb_pack(buf+len, buflen-len, "pfdB",
1948 len += tdb_pack(buf+len, buflen-len, "p", param);
1954 /****************************************************************************
1955 Delete a printer - this just deletes the printer info file, any open
1956 handles are not affected.
1957 ****************************************************************************/
1959 uint32 del_a_printer(char *sharename)
1964 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1967 kbuf.dsize=strlen(key)+1;
1969 tdb_delete(tdb_printers, kbuf);
1973 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
1974 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1975 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1976 /****************************************************************************
1977 ****************************************************************************/
1978 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1984 TDB_DATA kbuf, dbuf;
1987 * in addprinter: no servername and the printer is the name
1988 * in setprinter: servername is \\server
1989 * and printer is \\server\\printer
1991 * Samba manages only local printers.
1992 * we currently don't support things like path=\\other_server\printer
1995 if (info->servername[0]!='\0') {
1996 trim_string(info->printername, info->servername, NULL);
1997 trim_string(info->printername, "\\", NULL);
1998 info->servername[0]='\0';
2002 * JFM: one day I'll forget.
2003 * below that's info->portname because that's the SAMBA sharename
2004 * and I made NT 'thinks' it's the portname
2005 * the info->sharename is the thing you can name when you add a printer
2006 * that's the short-name when you create shared printer for 95/98
2007 * So I've made a limitation in SAMBA: you can only have 1 printer model
2008 * behind a SAMBA share.
2016 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
2019 info->default_priority,
2036 info->printprocessor,
2040 len += pack_devicemode(info->devmode, buf+len, buflen-len);
2042 len += pack_specifics(info->specific, buf+len, buflen-len);
2044 if (buflen != len) {
2047 tb = (char *)Realloc(buf, len);
2049 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2059 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
2062 kbuf.dsize = strlen(key)+1;
2066 ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
2069 if (!W_ERROR_IS_OK(ret))
2070 DEBUG(8, ("error updating printer to tdb on disk\n"));
2074 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2075 info->sharename, info->drivername, info->portname, len));
2081 /****************************************************************************
2082 ****************************************************************************/
2083 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
2085 NT_PRINTER_PARAM *current;
2087 DEBUG(108,("add_a_specific_param\n"));
2089 (*param)->next=NULL;
2091 if (info_2->specific == NULL)
2093 info_2->specific=*param;
2097 current=info_2->specific;
2098 while (current->next != NULL) {
2099 current=current->next;
2101 current->next=*param;
2107 /****************************************************************************
2108 ****************************************************************************/
2109 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2111 NT_PRINTER_PARAM *current;
2112 NT_PRINTER_PARAM *previous;
2114 current=info_2->specific;
2117 if (current==NULL) return (False);
2119 if ( !strcmp(current->value, param->value) &&
2120 (strlen(current->value)==strlen(param->value)) ) {
2121 DEBUG(109,("deleting first value\n"));
2122 info_2->specific=current->next;
2123 SAFE_FREE(current->data);
2125 DEBUG(109,("deleted first value\n"));
2129 current=previous->next;
2131 while ( current!=NULL ) {
2132 if (!strcmp(current->value, param->value) &&
2133 strlen(current->value)==strlen(param->value) ) {
2134 DEBUG(109,("deleting current value\n"));
2135 previous->next=current->next;
2136 SAFE_FREE(current->data);
2138 DEBUG(109,("deleted current value\n"));
2142 previous=previous->next;
2143 current=current->next;
2148 /****************************************************************************
2149 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2150 ****************************************************************************/
2151 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2153 NT_PRINTER_PARAM *param = *param_ptr;
2158 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2160 SAFE_FREE(param->data);
2161 SAFE_FREE(*param_ptr);
2164 /****************************************************************************
2165 Malloc and return an NT devicemode.
2166 ****************************************************************************/
2168 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2172 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2174 if (nt_devmode == NULL) {
2175 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2179 ZERO_STRUCTP(nt_devmode);
2181 safe_strcpy(adevice, default_devicename, sizeof(adevice));
2182 fstrcpy(nt_devmode->devicename, adevice);
2184 fstrcpy(nt_devmode->formname, "Letter");
2186 nt_devmode->specversion = 0x0401;
2187 nt_devmode->driverversion = 0x0400;
2188 nt_devmode->size = 0x00DC;
2189 nt_devmode->driverextra = 0x0000;
2190 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
2191 DEFAULTSOURCE | COPIES | SCALE |
2192 PAPERSIZE | ORIENTATION;
2193 nt_devmode->orientation = 1;
2194 nt_devmode->papersize = PAPER_LETTER;
2195 nt_devmode->paperlength = 0;
2196 nt_devmode->paperwidth = 0;
2197 nt_devmode->scale = 0x64;
2198 nt_devmode->copies = 1;
2199 nt_devmode->defaultsource = BIN_FORMSOURCE;
2200 nt_devmode->printquality = RES_HIGH; /* 0x0258 */
2201 nt_devmode->color = COLOR_MONOCHROME;
2202 nt_devmode->duplex = DUP_SIMPLEX;
2203 nt_devmode->yresolution = 0;
2204 nt_devmode->ttoption = TT_SUBDEV;
2205 nt_devmode->collate = COLLATE_FALSE;
2206 nt_devmode->icmmethod = 0;
2207 nt_devmode->icmintent = 0;
2208 nt_devmode->mediatype = 0;
2209 nt_devmode->dithertype = 0;
2211 /* non utilisés par un driver d'imprimante */
2212 nt_devmode->logpixels = 0;
2213 nt_devmode->bitsperpel = 0;
2214 nt_devmode->pelswidth = 0;
2215 nt_devmode->pelsheight = 0;
2216 nt_devmode->displayflags = 0;
2217 nt_devmode->displayfrequency = 0;
2218 nt_devmode->reserved1 = 0;
2219 nt_devmode->reserved2 = 0;
2220 nt_devmode->panningwidth = 0;
2221 nt_devmode->panningheight = 0;
2223 nt_devmode->private = NULL;
2227 /****************************************************************************
2228 Deepcopy an NT devicemode.
2229 ****************************************************************************/
2231 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2233 NT_DEVICEMODE *new_nt_devicemode = NULL;
2235 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2236 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2240 new_nt_devicemode->private = NULL;
2241 if (nt_devicemode->private != NULL) {
2242 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2243 SAFE_FREE(new_nt_devicemode);
2244 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2249 return new_nt_devicemode;
2252 /****************************************************************************
2253 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2254 ****************************************************************************/
2256 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2258 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2260 if(nt_devmode == NULL)
2263 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2265 SAFE_FREE(nt_devmode->private);
2266 SAFE_FREE(*devmode_ptr);
2269 /****************************************************************************
2270 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2271 ****************************************************************************/
2272 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2274 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2275 NT_PRINTER_PARAM *param_ptr;
2280 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2282 free_nt_devicemode(&info->devmode);
2284 for(param_ptr = info->specific; param_ptr; ) {
2285 NT_PRINTER_PARAM *tofree = param_ptr;
2287 param_ptr = param_ptr->next;
2288 free_nt_printer_param(&tofree);
2291 SAFE_FREE(*info_ptr);
2295 /****************************************************************************
2296 ****************************************************************************/
2297 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2301 NT_DEVICEMODE devmode;
2303 ZERO_STRUCT(devmode);
2305 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2307 if (!*nt_devmode) return len;
2309 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2313 &devmode.specversion,
2314 &devmode.driverversion,
2316 &devmode.driverextra,
2317 &devmode.orientation,
2319 &devmode.paperlength,
2320 &devmode.paperwidth,
2323 &devmode.defaultsource,
2324 &devmode.printquality,
2327 &devmode.yresolution,
2333 &devmode.bitsperpel,
2335 &devmode.pelsheight,
2336 &devmode.displayflags,
2337 &devmode.displayfrequency,
2341 &devmode.dithertype,
2344 &devmode.panningwidth,
2345 &devmode.panningheight,
2348 if (devmode.private) {
2349 /* the len in tdb_unpack is an int value and
2350 * devmode.driverextra is only a short
2352 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2353 devmode.driverextra=(uint16)extra_len;
2355 /* check to catch an invalid TDB entry so we don't segfault */
2356 if (devmode.driverextra == 0) {
2357 devmode.private = NULL;
2361 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2363 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2364 if (devmode.private)
2365 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2370 /****************************************************************************
2371 ****************************************************************************/
2372 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2375 NT_PRINTER_PARAM param, *p;
2380 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2383 len += tdb_unpack(buf+len, buflen-len, "fdB",
2389 *list = memdup(¶m, sizeof(param));
2391 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2397 static void map_to_os2_driver(fstring drivername)
2399 static BOOL initialised=False;
2400 static fstring last_from,last_to;
2401 char *mapfile = lp_os2_driver_map();
2402 char **lines = NULL;
2406 if (!strlen(drivername))
2413 *last_from = *last_to = 0;
2417 if (strequal(drivername,last_from)) {
2418 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2419 fstrcpy(drivername,last_to);
2423 lines = file_lines_load(mapfile, &numlines);
2424 if (numlines == 0) {
2425 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2429 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2431 for( i = 0; i < numlines; i++) {
2432 char *nt_name = lines[i];
2433 char *os2_name = strchr(nt_name,'=');
2440 while (isspace(*nt_name))
2443 if (!*nt_name || strchr("#;",*nt_name))
2447 int l = strlen(nt_name);
2448 while (l && isspace(nt_name[l-1])) {
2454 while (isspace(*os2_name))
2458 int l = strlen(os2_name);
2459 while (l && isspace(os2_name[l-1])) {
2465 if (strequal(nt_name,drivername)) {
2466 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2467 fstrcpy(last_from,drivername);
2468 fstrcpy(last_to,os2_name);
2469 fstrcpy(drivername,os2_name);
2470 file_lines_free(lines);
2475 file_lines_free(lines);
2478 /****************************************************************************
2479 get a default printer info 2 struct
2480 ****************************************************************************/
2481 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2484 NT_PRINTER_INFO_LEVEL_2 info;
2488 snum = lp_servicenumber(sharename);
2490 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2491 slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
2492 get_called_name(), sharename);
2493 fstrcpy(info.sharename, sharename);
2494 fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2495 fstrcpy(info.drivername, lp_printerdriver(snum));
2497 /* by setting the driver name to an empty string, a local NT admin
2498 can now run the **local** APW to install a local printer driver
2499 for a Samba shared printer in 2.2. Without this, drivers **must** be
2500 installed on the Samba server for NT clients --jerry */
2501 #if 0 /* JERRY --do not uncomment-- */
2502 if (!*info.drivername)
2503 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2507 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2509 pstrcpy(info.comment, "");
2510 fstrcpy(info.printprocessor, "winprint");
2511 fstrcpy(info.datatype, "RAW");
2513 info.attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK; /* attributes */
2515 info.starttime = 0; /* Minutes since 12:00am GMT */
2516 info.untiltime = 0; /* Minutes since 12:00am GMT */
2518 info.default_priority = 1;
2519 info.setuptime = (uint32)time(NULL);
2522 * I changed this as I think it is better to have a generic
2523 * DEVMODE than to crash Win2k explorer.exe --jerry
2524 * See the HP Deskjet 990c Win2k drivers for an example.
2526 * However the default devmode appears to cause problems
2527 * with the HP CLJ 8500 PCL driver. Hence the addition of
2528 * the "default devmode" parameter --jerry 22/01/2002
2531 if (lp_default_devmode(snum)) {
2532 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2536 info.devmode = NULL;
2539 /* This will get the current RPC talloc context, but we should be
2540 passing this as a parameter... fixme... JRA ! */
2542 if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2545 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2547 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2555 free_nt_devicemode(&info.devmode);
2556 return WERR_ACCESS_DENIED;
2559 /****************************************************************************
2560 ****************************************************************************/
2561 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2564 NT_PRINTER_INFO_LEVEL_2 info;
2566 TDB_DATA kbuf, dbuf;
2567 fstring printername;
2571 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2574 kbuf.dsize = strlen(key)+1;
2576 dbuf = tdb_fetch(tdb_printers, kbuf);
2578 return get_a_printer_2_default(info_ptr, sharename);
2580 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2583 &info.default_priority,
2600 info.printprocessor,
2604 /* Samba has to have shared raw drivers. */
2605 info.attributes |= (PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK);
2607 /* Restore the stripped strings. */
2608 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2609 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
2611 fstrcpy(info.printername, printername);
2613 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2616 * Some client drivers freak out if there is a NULL devmode
2617 * (probably the driver is not checking before accessing
2618 * the devmode pointer) --jerry
2620 * See comments in get_a_printer_2_default()
2623 if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode)
2625 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2627 info.devmode = construct_nt_devicemode(printername);
2630 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2632 /* This will get the current RPC talloc context, but we should be
2633 passing this as a parameter... fixme... JRA ! */
2635 nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2637 /* Fix for OS/2 drivers. */
2639 if (get_remote_arch() == RA_OS2)
2640 map_to_os2_driver(info.drivername);
2642 SAFE_FREE(dbuf.dptr);
2643 *info_ptr=memdup(&info, sizeof(info));
2645 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2646 sharename, info.printername, info.drivername));
2651 /****************************************************************************
2652 debugging function, dump at level 6 the struct in the logs
2653 ****************************************************************************/
2654 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2657 NT_PRINTER_INFO_LEVEL_2 *info2;
2659 DEBUG(106,("Dumping printer at level [%d]\n", level));
2665 if (printer.info_2 == NULL)
2669 info2=printer.info_2;
2671 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2672 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2673 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2674 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2675 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2676 DEBUGADD(106,("status:[%d]\n", info2->status));
2677 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2678 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2679 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2680 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2681 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2683 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2684 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2685 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2686 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2687 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2688 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2689 DEBUGADD(106,("location:[%s]\n", info2->location));
2690 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2691 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2692 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2693 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2699 DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
2707 /****************************************************************************
2708 Get the parameters we can substitute in an NT print job.
2709 ****************************************************************************/
2711 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2713 NT_PRINTER_INFO_LEVEL *printer = NULL;
2715 **printername = **sharename = **portname = '\0';
2717 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2720 fstrcpy(*printername, printer->info_2->printername);
2721 fstrcpy(*sharename, printer->info_2->sharename);
2722 fstrcpy(*portname, printer->info_2->portname);
2724 free_a_printer(&printer, 2);
2727 /****************************************************************************
2728 Update the changeid time.
2729 This is SO NASTY as some drivers need this to change, others need it
2730 static. This value will change every second, and I must hope that this
2731 is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
2733 ****************************************************************************/
2735 static uint32 rev_changeid(void)
2739 get_process_uptime(&tv);
2742 /* Return changeid as msec since spooler restart */
2743 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
2746 * This setting seems to work well but is too untested
2747 * to replace the above calculation. Left in for experiementation
2748 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
2750 return tv.tv_sec * 10 + tv.tv_usec / 100000;
2755 * The function below are the high level ones.
2756 * only those ones must be called from the spoolss code.
2760 /****************************************************************************
2761 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2762 ****************************************************************************/
2764 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2768 dump_a_printer(printer, level);
2775 * Update the changestamp. Emperical tests show that the
2776 * ChangeID is always updated,but c_setprinter is
2777 * global spooler variable (not per printer).
2780 /* ChangeID **must** be increasing over the lifetime
2781 of client's spoolss service in order for the
2782 client's cache to show updates */
2784 printer.info_2->changeid = rev_changeid();
2787 * Because one day someone will ask:
2788 * NT->NT An admin connection to a remote
2789 * printer show changes imeediately in
2790 * the properities dialog
2792 * A non-admin connection will only show the
2793 * changes after viewing the properites page
2794 * 2 times. Seems to be related to a
2795 * race condition in the client between the spooler
2796 * updating the local cache and the Explorer.exe GUI
2797 * actually displaying the properties.
2799 * This is fixed in Win2k. admin/non-admin
2800 * connections both display changes immediately.
2805 result=update_a_printer_2(printer.info_2);
2809 result=WERR_UNKNOWN_LEVEL;
2816 /****************************************************************************
2817 Initialize printer devmode & data with previously saved driver init values.
2818 ****************************************************************************/
2820 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2824 TDB_DATA kbuf, dbuf;
2825 NT_PRINTER_PARAM *current;
2826 NT_PRINTER_INFO_LEVEL_2 info;
2829 * Delete any printer data 'specifics' already set. When called for driver
2830 * replace, there will generally be some, but during an add printer, there
2831 * should not be any (if there are delete them).
2833 while ( (current=info_ptr->specific) != NULL ) {
2834 info_ptr->specific=current->next;
2835 SAFE_FREE(current->data);
2841 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2844 kbuf.dsize = strlen(key)+1;
2846 dbuf = tdb_fetch(tdb_drivers, kbuf);
2849 * When changing to a driver that has no init info in the tdb, remove
2850 * the previous drivers init info and leave the new on blank.
2852 free_nt_devicemode(&info_ptr->devmode);
2857 * Get the saved DEVMODE..
2859 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2862 * The saved DEVMODE contains the devicename from the printer used during
2863 * the initialization save. Change it to reflect the new printer.
2865 ZERO_STRUCT(info.devmode->devicename);
2866 fstrcpy(info.devmode->devicename, info_ptr->printername);
2870 * NT/2k does not change out the entire DeviceMode of a printer
2871 * when changing the driver. Only the driverextra, private, &
2872 * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
2878 * Bind the saved DEVMODE to the new the printer.
2880 free_nt_devicemode(&info_ptr->devmode);
2881 info_ptr->devmode = info.devmode;
2883 /* copy the entire devmode if we currently don't have one */
2885 if (!info_ptr->devmode) {
2886 DEBUG(10,("set_driver_init_2: Current Devmode is NULL. Copying entire Device Mode\n"));
2887 info_ptr->devmode = info.devmode;
2890 /* only set the necessary fields */
2892 DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n",
2893 info.devmode->driverversion, info.devmode->driverextra));
2895 info_ptr->devmode->driverversion = info.devmode->driverversion;
2897 SAFE_FREE(info_ptr->devmode->private);
2898 info_ptr->devmode->private = NULL;
2900 if (info.devmode->driverversion)
2901 info_ptr->devmode->private = memdup(info.devmode->private, info.devmode->driverversion);
2903 free_nt_devicemode(&info.devmode);
2907 DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2908 info_ptr->printername, info_ptr->drivername));
2911 * Add the printer data 'specifics' to the new printer
2913 len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2915 SAFE_FREE(dbuf.dptr);
2920 /****************************************************************************
2921 Initialize printer devmode & data with previously saved driver init values.
2922 When a printer is created using AddPrinter, the drivername bound to the
2923 printer is used to lookup previously saved driver initialization info, which
2924 is bound to the new printer.
2925 ****************************************************************************/
2927 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2935 result=set_driver_init_2(printer->info_2);
2946 /****************************************************************************
2947 Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
2948 in the tdb. Note: this is different from the driver entry and the printer
2949 entry. There should be a single driver init entry for each driver regardless
2950 of whether it was installed from NT or 2K. Technically, they should be
2951 different, but they work out to the same struct.
2952 ****************************************************************************/
2954 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2958 int buflen, len, ret;
2959 TDB_DATA kbuf, dbuf;
2966 len += pack_devicemode(info->devmode, buf+len, buflen-len);
2968 len += pack_specifics(info->specific, buf+len, buflen-len);
2970 if (buflen != len) {
2973 tb = (char *)Realloc(buf, len);
2975 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2984 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
2987 kbuf.dsize = strlen(key)+1;
2991 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
2995 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
2999 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
3000 info->sharename, info->drivername));
3005 /****************************************************************************
3006 Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
3007 ****************************************************************************/
3009 uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
3013 dump_a_printer(printer, level);
3019 result=update_driver_init_2(printer.info_2);
3030 /****************************************************************************
3031 Convert the printer data value, a REG_BINARY array, into an initialization
3032 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
3033 got to keep the endians happy :).
3034 ****************************************************************************/
3036 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
3038 BOOL result = False;
3042 ZERO_STRUCT(devmode);
3044 prs_init(&ps, 0, ctx, UNMARSHALL);
3045 ps.data_p = (char *)param->data;
3046 ps.buffer_size = param->data_len;
3048 if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
3049 result = convert_devicemode("", &devmode, &nt_devmode);
3051 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
3056 /****************************************************************************
3057 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
3059 1. Use the driver's config DLL to this UNC printername and:
3060 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
3061 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
3062 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
3064 The last step triggers saving the "driver initialization" information for
3065 this printer into the tdb. Later, new printers that use this driver will
3066 have this initialization information bound to them. This simulates the
3067 driver initialization, as if it had run on the Samba server (as it would
3070 The Win32 client side code requirement sucks! But until we can run arbitrary
3071 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
3073 It would have been easier to use SetPrinter because all the UNMARSHALLING of
3074 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
3075 about it and you will realize why. JRR 010720
3076 ****************************************************************************/