2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 extern DOM_SID global_sid_World;
27 static TDB_CONTEXT *tdb_forms; /* used for forms files */
28 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
29 static TDB_CONTEXT *tdb_printers; /* used for printers files */
31 #define FORMS_PREFIX "FORMS/"
32 #define DRIVERS_PREFIX "DRIVERS/"
33 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
34 #define PRINTERS_PREFIX "PRINTERS/"
35 #define SECDESC_PREFIX "SECDESC/"
37 #define NTDRIVERS_DATABASE_VERSION_1 1
38 #define NTDRIVERS_DATABASE_VERSION_2 2
40 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_2
42 /* Map generic permissions to printer object specific permissions */
44 struct generic_mapping printer_generic_mapping = {
51 /* We need one default form to support our default printer. Msoft adds the
52 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
53 array index). Letter is always first, so (for the current code) additions
54 always put things in the correct order. */
55 static nt_forms_struct default_forms[] = {
56 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
57 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
58 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
59 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
60 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
61 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
62 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
63 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
64 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
65 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
66 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
67 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
68 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
69 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
70 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
71 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
72 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
73 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
74 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
75 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
76 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
77 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
78 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
79 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
80 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
81 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
82 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
83 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
84 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
85 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
86 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
87 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
88 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
89 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
90 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
91 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
92 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
93 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
94 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
95 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
96 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
97 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
98 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
99 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
100 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
101 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
102 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
103 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
104 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
105 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
106 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
107 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
108 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
109 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
110 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
111 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
112 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
113 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
114 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
115 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
116 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
117 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
118 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
119 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
120 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
121 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
122 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
123 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
124 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
125 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
126 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
127 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
128 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
129 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
130 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
131 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
132 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
133 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
134 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
135 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
136 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
137 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
138 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
139 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
140 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
141 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
142 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
143 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
144 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
145 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
146 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
147 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
148 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
149 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
150 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
151 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
152 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
153 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
154 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
155 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
156 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
157 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
158 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
159 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
160 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
161 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
162 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
163 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
164 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
165 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
166 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
167 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
168 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
169 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
170 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
171 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
172 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
173 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
176 static BOOL upgrade_to_version_2(void)
178 TDB_DATA kbuf, newkey, dbuf;
180 DEBUG(0,("upgrade_to_version_2: upgrading print tdb's to version 2\n"));
182 for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
183 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
185 dbuf = tdb_fetch(tdb_drivers, kbuf);
187 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
188 DEBUG(0,("upgrade_to_version_2:moving form\n"));
189 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
190 DEBUG(0,("upgrade_to_version_2: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
193 if (tdb_delete(tdb_drivers, kbuf) != 0) {
194 DEBUG(0,("upgrade_to_version_2: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
199 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
200 DEBUG(0,("upgrade_to_version_2:moving printer\n"));
201 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
202 DEBUG(0,("upgrade_to_version_2: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
205 if (tdb_delete(tdb_drivers, kbuf) != 0) {
206 DEBUG(0,("upgrade_to_version_2: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
211 if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
212 DEBUG(0,("upgrade_to_version_2:moving secdesc\n"));
213 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
214 DEBUG(0,("upgrade_to_version_2: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
217 if (tdb_delete(tdb_drivers, kbuf) != 0) {
218 DEBUG(0,("upgrade_to_version_2: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
223 SAFE_FREE(dbuf.dptr);
229 /****************************************************************************
230 open the NT printing tdb
231 ****************************************************************************/
232 BOOL nt_printing_init(void)
234 static pid_t local_pid;
235 char *vstring = "INFO/version";
237 if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
240 tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
242 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
243 lock_path("ntdrivers.tdb"), strerror(errno) ));
247 tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
249 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
250 lock_path("ntprinters.tdb"), strerror(errno) ));
254 tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
256 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
257 lock_path("ntforms.tdb"), strerror(errno) ));
261 local_pid = sys_getpid();
263 /* handle a Samba upgrade */
264 tdb_lock_bystring(tdb_drivers, vstring);
265 if (tdb_fetch_int(tdb_drivers, vstring) != NTDRIVERS_DATABASE_VERSION) {
267 if (tdb_fetch_int(tdb_drivers, vstring) == NTDRIVERS_DATABASE_VERSION_1) {
268 if (!upgrade_to_version_2())
271 tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
273 tdb_store_int(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
275 tdb_unlock_bystring(tdb_drivers, vstring);
280 /****************************************************************************
281 get builtin form struct list
282 ****************************************************************************/
283 int get_builtin_ntforms(nt_forms_struct **list)
285 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
286 return sizeof(default_forms) / sizeof(default_forms[0]);
289 /****************************************************************************
290 get a builtin form struct
291 ****************************************************************************/
293 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
297 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
298 DEBUGADD(6,("Looking for builtin form %s \n", form_name));
299 count = sizeof(default_forms) / sizeof(default_forms[0]);
300 for (i=0;i<count;i++) {
301 if (strequal(form_name,default_forms[i].name)) {
302 DEBUGADD(6,("Found builtin form %s \n", form_name));
303 memcpy(form,&default_forms[i],sizeof(*form));
311 /****************************************************************************
312 get a form struct list
313 ****************************************************************************/
314 int get_ntforms(nt_forms_struct **list)
316 TDB_DATA kbuf, newkey, dbuf;
318 nt_forms_struct form;
323 for (kbuf = tdb_firstkey(tdb_forms);
325 newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
326 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
328 dbuf = tdb_fetch(tdb_forms, kbuf);
329 if (!dbuf.dptr) continue;
331 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
332 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
333 &i, &form.flag, &form.width, &form.length, &form.left,
334 &form.top, &form.right, &form.bottom);
335 SAFE_FREE(dbuf.dptr);
336 if (ret != dbuf.dsize) continue;
338 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
340 DEBUG(0,("get_ntforms: Realloc fail.\n"));
352 /****************************************************************************
353 write a form struct list
354 ****************************************************************************/
355 int write_ntforms(nt_forms_struct **list, int number)
362 for (i=0;i<number;i++) {
363 /* save index, so list is rebuilt in correct order */
364 len = tdb_pack(buf, sizeof(buf), "dddddddd",
365 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
366 (*list)[i].left, (*list)[i].top, (*list)[i].right,
368 if (len > sizeof(buf)) break;
369 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
370 kbuf.dsize = strlen(key)+1;
374 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
380 /****************************************************************************
381 add a form struct at the end of the list
382 ****************************************************************************/
383 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
391 * NT tries to add forms even when
392 * they are already in the base
393 * only update the values if already present
398 unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
399 for (n=0; n<*count; n++) {
400 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
401 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
408 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
409 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
413 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
417 (*list)[n].flag=form->flags;
418 (*list)[n].width=form->size_x;
419 (*list)[n].length=form->size_y;
420 (*list)[n].left=form->left;
421 (*list)[n].top=form->top;
422 (*list)[n].right=form->right;
423 (*list)[n].bottom=form->bottom;
428 /****************************************************************************
429 delete a named form struct
430 ****************************************************************************/
431 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
440 unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
442 for (n=0; n<*count; n++) {
443 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
444 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
450 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
451 *ret = WERR_INVALID_PARAM;
455 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
456 kbuf.dsize = strlen(key)+1;
458 if (tdb_delete(tdb_forms, kbuf) != 0) {
466 /****************************************************************************
468 ****************************************************************************/
469 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
473 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
475 DEBUG(106, ("[%s]\n", form_name));
476 for (n=0; n<count; n++)
478 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
479 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
483 if (n==count) return;
485 (*list)[n].flag=form->flags;
486 (*list)[n].width=form->size_x;
487 (*list)[n].length=form->size_y;
488 (*list)[n].left=form->left;
489 (*list)[n].top=form->top;
490 (*list)[n].right=form->right;
491 (*list)[n].bottom=form->bottom;
494 /****************************************************************************
495 get the nt drivers list
497 traverse the database and look-up the matching names
498 ****************************************************************************/
499 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
505 TDB_DATA kbuf, newkey;
507 get_short_archi(short_archi, architecture);
508 slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
510 for (kbuf = tdb_firstkey(tdb_drivers);
512 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
513 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
515 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
516 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
521 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
528 /****************************************************************************
529 function to do the mapping between the long architecture name and
531 ****************************************************************************/
532 BOOL get_short_archi(char *short_archi, char *long_archi)
539 struct table archi_table[]=
541 {"Windows 4.0", "WIN40" },
542 {"Windows NT x86", "W32X86" },
543 {"Windows NT R4000", "W32MIPS" },
544 {"Windows NT Alpha_AXP", "W32ALPHA" },
545 {"Windows NT PowerPC", "W32PPC" },
551 DEBUG(107,("Getting architecture dependant directory\n"));
554 } while ( (archi_table[i].long_archi!=NULL ) &&
555 StrCaseCmp(long_archi, archi_table[i].long_archi) );
557 if (archi_table[i].long_archi==NULL) {
558 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
562 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
564 DEBUGADD(108,("index: [%d]\n", i));
565 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
566 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
571 /****************************************************************************
572 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
573 There are two case to be covered here: PE (Portable Executable) and NE (New
574 Executable) files. Both files support the same INFO structure, but PE files
575 store the signature in unicode, and NE files store it as !unicode.
576 ****************************************************************************/
577 static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
584 if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
585 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
586 fname, PE_HEADER_SIZE));
590 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
591 if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
592 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
594 goto no_version_info;
597 /* Is this really a DOS header? */
598 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
599 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
600 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
601 goto no_version_info;
604 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
605 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
606 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
608 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
609 goto no_version_info;
612 if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
613 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
615 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
616 goto no_version_info;
619 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
620 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
622 int section_table_bytes;
624 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
625 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
626 fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
627 /* At this point, we assume the file is in error. It still could be somthing
628 * else besides a PE file, but it unlikely at this point.
633 /* get the section table */
634 num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
635 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
637 if ((buf=malloc(section_table_bytes)) == NULL) {
638 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
639 fname, section_table_bytes));
643 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
644 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
649 /* Iterate the section table looking for the resource section ".rsrc" */
650 for (i = 0; i < num_sections; i++) {
651 int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
653 if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
654 int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
655 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
658 if ((buf=malloc(section_bytes)) == NULL) {
659 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
660 fname, section_bytes));
664 /* Seek to the start of the .rsrc section info */
665 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
666 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
671 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
672 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
677 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
678 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
679 if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
680 /* Align to next long address */
681 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
683 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
684 *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
685 *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
687 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
688 fname, *major, *minor,
689 (*major>>16)&0xffff, *major&0xffff,
690 (*minor>>16)&0xffff, *minor&0xffff));
699 /* Version info not found, fall back to origin date/time */
700 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
704 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
705 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
706 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
707 fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
708 /* At this point, we assume the file is in error. It still could be somthing
709 * else besides a NE file, but it unlikely at this point. */
713 /* Allocate a bit more space to speed up things */
715 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
716 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
717 fname, PE_HEADER_SIZE));
721 /* This is a HACK! I got tired of trying to sort through the messy
722 * 'NE' file format. If anyone wants to clean this up please have at
723 * it, but this works. 'NE' files will eventually fade away. JRR */
724 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
725 /* Cover case that should not occur in a well formed 'NE' .dll file */
726 if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
728 for(i=0; i<byte_count; i++) {
729 /* Fast skip past data that can't possibly match */
730 if (buf[i] != 'V') continue;
732 /* Potential match data crosses buf boundry, move it to beginning
733 * of buf, and fill the buf with as much as it will hold. */
734 if (i>byte_count-VS_VERSION_INFO_SIZE) {
737 memcpy(buf, &buf[i], byte_count-i);
738 if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
739 (byte_count-i))) < 0) {
741 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
746 byte_count = bc + (byte_count - i);
747 if (byte_count<VS_VERSION_INFO_SIZE) break;
752 /* Check that the full signature string and the magic number that
753 * follows exist (not a perfect solution, but the chances that this
754 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
755 * twice, as it is simpler to read the code. */
756 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
757 /* Compute skip alignment to next long address */
758 int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
759 sizeof(VS_SIGNATURE)) & 3;
760 if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
762 *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
763 *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
764 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
765 fname, *major, *minor,
766 (*major>>16)&0xffff, *major&0xffff,
767 (*minor>>16)&0xffff, *minor&0xffff));
774 /* Version info not found, fall back to origin date/time */
775 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
780 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
781 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
782 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
793 /****************************************************************************
794 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
795 share one or more files. During the MS installation process files are checked
796 to insure that only a newer version of a shared file is installed over an
797 older version. There are several possibilities for this comparison. If there
798 is no previous version, the new one is newer (obviously). If either file is
799 missing the version info structure, compare the creation date (on Unix use
800 the modification date). Otherwise chose the numerically larger version number.
801 ****************************************************************************/
802 static int file_version_is_newer(connection_struct *conn, fstring new_file,
805 BOOL use_version = True;
810 time_t new_create_time;
814 time_t old_create_time;
818 files_struct *fsp = NULL;
820 SMB_STRUCT_STAT stat_buf;
824 ZERO_STRUCT(stat_buf);
825 new_create_time = (time_t)0;
826 old_create_time = (time_t)0;
828 /* Get file version info (if available) for previous file (if it exists) */
829 pstrcpy(filepath, old_file);
831 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
833 fsp = open_file_shared(conn, filepath, &stat_buf,
834 SET_OPEN_MODE(DOS_OPEN_RDONLY),
835 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
836 0, 0, &access_mode, &action);
838 /* Old file not found, so by definition new file is in fact newer */
839 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
844 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
845 if (ret == -1) goto error_exit;
848 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
851 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
852 old_create_time = st.st_mtime;
853 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
856 close_file(fsp, True);
858 /* Get file version info (if available) for new file */
859 pstrcpy(filepath, new_file);
860 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
862 fsp = open_file_shared(conn, filepath, &stat_buf,
863 SET_OPEN_MODE(DOS_OPEN_RDONLY),
864 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
865 0, 0, &access_mode, &action);
867 /* New file not found, this shouldn't occur if the caller did its job */
868 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
873 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
874 if (ret == -1) goto error_exit;
877 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
880 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
881 new_create_time = st.st_mtime;
882 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
885 close_file(fsp, True);
888 /* Compare versions and choose the larger version number */
889 if (new_major > old_major ||
890 (new_major == old_major && new_minor > old_minor)) {
892 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
896 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
901 /* Compare modification time/dates and choose the newest time/date */
902 if (new_create_time > old_create_time) {
903 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
907 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
914 close_file(fsp, True);
918 /****************************************************************************
919 Determine the correct cVersion associated with an architecture and driver
920 ****************************************************************************/
921 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
922 struct current_user *user, WERROR *perr)
930 files_struct *fsp = NULL;
933 connection_struct *conn;
937 *perr = WERR_INVALID_PARAM;
939 /* If architecture is Windows 95/98/ME, the version is always 0. */
940 if (strcmp(architecture, "WIN40") == 0) {
941 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
946 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
947 /* Null password is ok - we are already an authenticated user... */
948 null_pw = data_blob(NULL, 0);
951 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
955 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
956 *perr = ntstatus_to_werror(nt_status);
960 /* We are temporarily becoming the connection user. */
961 if (!become_user(conn, conn->vuid)) {
962 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
963 *perr = WERR_ACCESS_DENIED;
967 /* Open the driver file (Portable Executable format) and determine the
968 * deriver the cversion. */
969 slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
971 unix_convert(driverpath,conn,NULL,&bad_path,&st);
973 fsp = open_file_shared(conn, driverpath, &st,
974 SET_OPEN_MODE(DOS_OPEN_RDONLY),
975 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
976 0, 0, &access_mode, &action);
978 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
980 *perr = WERR_ACCESS_DENIED;
986 int ret = get_file_version(fsp, driverpath, &major, &minor);
987 if (ret == -1) goto error_exit;
990 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
995 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
996 * for more details. Version in this case is not just the version of the
997 * file, but the version in the sense of kernal mode (2) vs. user mode
998 * (3) drivers. Other bits of the version fields are the version info.
1001 cversion = major & 0x0000ffff;
1003 case 2: /* WinNT drivers */
1004 case 3: /* Win2K drivers */
1008 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
1009 driverpath, cversion));
1013 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
1014 driverpath, major, minor));
1017 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1018 driverpath, cversion));
1020 close_file(fsp, True);
1021 close_cnum(conn, user->vuid);
1029 close_file(fsp, True);
1031 close_cnum(conn, user->vuid);
1036 /****************************************************************************
1037 ****************************************************************************/
1038 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1039 struct current_user *user)
1041 fstring architecture;
1047 /* clean up the driver name.
1048 * we can get .\driver.dll
1049 * or worse c:\windows\system\driver.dll !
1051 /* using an intermediate string to not have overlaping memcpy()'s */
1052 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1053 fstrcpy(new_name, p+1);
1054 fstrcpy(driver->driverpath, new_name);
1057 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1058 fstrcpy(new_name, p+1);
1059 fstrcpy(driver->datafile, new_name);
1062 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1063 fstrcpy(new_name, p+1);
1064 fstrcpy(driver->configfile, new_name);
1067 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1068 fstrcpy(new_name, p+1);
1069 fstrcpy(driver->helpfile, new_name);
1072 if (driver->dependentfiles) {
1073 for (i=0; *driver->dependentfiles[i]; i++) {
1074 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1075 fstrcpy(new_name, p+1);
1076 fstrcpy(driver->dependentfiles[i], new_name);
1081 get_short_archi(architecture, driver->environment);
1083 /* jfm:7/16/2000 the client always sends the cversion=0.
1084 * The server should check which version the driver is by reading
1085 * the PE header of driver->driverpath.
1087 * For Windows 95/98 the version is 0 (so the value sent is correct)
1088 * For Windows NT (the architecture doesn't matter)
1089 * NT 3.1: cversion=0
1090 * NT 3.5/3.51: cversion=1
1094 if ((driver->cversion = get_correct_cversion( architecture,
1095 driver->driverpath, user, &err)) == -1)
1101 /****************************************************************************
1102 ****************************************************************************/
1103 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1104 struct current_user *user)
1106 fstring architecture;
1112 /* clean up the driver name.
1113 * we can get .\driver.dll
1114 * or worse c:\windows\system\driver.dll !
1116 /* using an intermediate string to not have overlaping memcpy()'s */
1117 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1118 fstrcpy(new_name, p+1);
1119 fstrcpy(driver->driverpath, new_name);
1122 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1123 fstrcpy(new_name, p+1);
1124 fstrcpy(driver->datafile, new_name);
1127 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1128 fstrcpy(new_name, p+1);
1129 fstrcpy(driver->configfile, new_name);
1132 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1133 fstrcpy(new_name, p+1);
1134 fstrcpy(driver->helpfile, new_name);
1137 if (driver->dependentfiles) {
1138 for (i=0; *driver->dependentfiles[i]; i++) {
1139 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1140 fstrcpy(new_name, p+1);
1141 fstrcpy(driver->dependentfiles[i], new_name);
1146 get_short_archi(architecture, driver->environment);
1148 /* jfm:7/16/2000 the client always sends the cversion=0.
1149 * The server should check which version the driver is by reading
1150 * the PE header of driver->driverpath.
1152 * For Windows 95/98 the version is 0 (so the value sent is correct)
1153 * For Windows NT (the architecture doesn't matter)
1154 * NT 3.1: cversion=0
1155 * NT 3.5/3.51: cversion=1
1159 if ((driver->version = get_correct_cversion(architecture,
1160 driver->driverpath, user, &err)) == -1)
1166 /****************************************************************************
1167 ****************************************************************************/
1168 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1169 uint32 level, struct current_user *user)
1174 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1175 driver=driver_abstract.info_3;
1176 return clean_up_driver_struct_level_3(driver, user);
1180 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1181 driver=driver_abstract.info_6;
1182 return clean_up_driver_struct_level_6(driver, user);
1185 return WERR_INVALID_PARAM;
1189 /****************************************************************************
1190 This function sucks and should be replaced. JRA.
1191 ****************************************************************************/
1193 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1195 dst->cversion = src->version;
1197 fstrcpy( dst->name, src->name);
1198 fstrcpy( dst->environment, src->environment);
1199 fstrcpy( dst->driverpath, src->driverpath);
1200 fstrcpy( dst->datafile, src->datafile);
1201 fstrcpy( dst->configfile, src->configfile);
1202 fstrcpy( dst->helpfile, src->helpfile);
1203 fstrcpy( dst->monitorname, src->monitorname);
1204 fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1205 dst->dependentfiles = src->dependentfiles;
1208 #if 0 /* Debugging function */
1210 static char* ffmt(unsigned char *c){
1212 static char ffmt_str[17];
1214 for (i=0; i<16; i++) {
1215 if ((c[i] < ' ') || (c[i] > '~'))
1226 /****************************************************************************
1227 ****************************************************************************/
1228 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
1229 struct current_user *user, WERROR *perr)
1231 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1232 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1233 fstring architecture;
1238 connection_struct *conn;
1246 driver=driver_abstract.info_3;
1247 else if (level==6) {
1248 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1249 driver = &converted_driver;
1251 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1255 get_short_archi(architecture, driver->environment);
1257 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
1258 /* Null password is ok - we are already an authenticated user... */
1259 null_pw = data_blob(NULL, 0);
1260 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1263 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1264 *perr = ntstatus_to_werror(nt_status);
1269 * Save who we are - we are temporarily becoming the connection user.
1274 if (!become_user(conn, conn->vuid)) {
1275 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1281 * make the directories version and version\driver_name
1282 * under the architecture directory.
1284 DEBUG(5,("Creating first directory\n"));
1285 slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1286 mkdir_internal(conn, new_dir);
1288 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1289 * listed for this driver which has already been moved, skip it (note:
1290 * drivers may list the same file name several times. Then check if the
1291 * file already exists in archi\cversion\, if so, check that the version
1292 * info (or time stamps if version info is unavailable) is newer (or the
1293 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1294 * Otherwise, delete the file.
1296 * If a file is not moved to archi\cversion\ because of an error, all the
1297 * rest of the 'unmoved' driver files are removed from archi\. If one or
1298 * more of the driver's files was already moved to archi\cversion\, it
1299 * potentially leaves the driver in a partially updated state. Version
1300 * trauma will most likely occur if an client attempts to use any printer
1301 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1302 * done is appropriate... later JRR
1305 DEBUG(5,("Moving files now !\n"));
1307 if (driver->driverpath && strlen(driver->driverpath)) {
1308 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
1309 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
1310 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1312 status = rename_internals(conn, new_name, old_name, True);
1313 if (!NT_STATUS_IS_OK(status)) {
1314 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1315 new_name, old_name));
1316 *perr = ntstatus_to_werror(status);
1317 unlink_internals(conn, 0, new_name);
1322 unlink_internals(conn, 0, new_name);
1325 if (driver->datafile && strlen(driver->datafile)) {
1326 if (!strequal(driver->datafile, driver->driverpath)) {
1327 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
1328 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
1329 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1331 status = rename_internals(conn, new_name, old_name, True);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1334 new_name, old_name));
1335 *perr = ntstatus_to_werror(status);
1336 unlink_internals(conn, 0, new_name);
1341 unlink_internals(conn, 0, new_name);
1345 if (driver->configfile && strlen(driver->configfile)) {
1346 if (!strequal(driver->configfile, driver->driverpath) &&
1347 !strequal(driver->configfile, driver->datafile)) {
1348 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
1349 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
1350 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1352 status = rename_internals(conn, new_name, old_name, True);
1353 if (!NT_STATUS_IS_OK(status)) {
1354 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1355 new_name, old_name));
1356 *perr = ntstatus_to_werror(status);
1357 unlink_internals(conn, 0, new_name);
1362 unlink_internals(conn, 0, new_name);
1366 if (driver->helpfile && strlen(driver->helpfile)) {
1367 if (!strequal(driver->helpfile, driver->driverpath) &&
1368 !strequal(driver->helpfile, driver->datafile) &&
1369 !strequal(driver->helpfile, driver->configfile)) {
1370 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
1371 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
1372 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1374 status = rename_internals(conn, new_name, old_name, True);
1375 if (!NT_STATUS_IS_OK(status)) {
1376 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1377 new_name, old_name));
1378 *perr = ntstatus_to_werror(status);
1379 unlink_internals(conn, 0, new_name);
1384 unlink_internals(conn, 0, new_name);
1388 if (driver->dependentfiles) {
1389 for (i=0; *driver->dependentfiles[i]; i++) {
1390 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1391 !strequal(driver->dependentfiles[i], driver->datafile) &&
1392 !strequal(driver->dependentfiles[i], driver->configfile) &&
1393 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1395 for (j=0; j < i; j++) {
1396 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1401 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
1402 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
1403 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1405 status = rename_internals(conn, new_name, old_name, True);
1406 if (!NT_STATUS_IS_OK(status)) {
1407 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1408 new_name, old_name));
1409 *perr = ntstatus_to_werror(status);
1410 unlink_internals(conn, 0, new_name);
1415 unlink_internals(conn, 0, new_name);
1421 close_cnum(conn, user->vuid);
1424 return ver == -1 ? False : True;
1427 /****************************************************************************
1428 ****************************************************************************/
1429 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1432 fstring architecture;
1438 TDB_DATA kbuf, dbuf;
1440 get_short_archi(architecture, driver->environment);
1442 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1443 * \\server is added in the rpc server layer.
1444 * It does make sense to NOT store the server's name in the printer TDB.
1447 slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1449 /* .inf files do not always list a file for each of the four standard files.
1450 * Don't prepend a path to a null filename, or client claims:
1451 * "The server on which the printer resides does not have a suitable
1452 * <printer driver name> printer driver installed. Click OK if you
1453 * wish to install the driver on your local machine."
1455 if (strlen(driver->driverpath)) {
1456 fstrcpy(temp_name, driver->driverpath);
1457 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1460 if (strlen(driver->datafile)) {
1461 fstrcpy(temp_name, driver->datafile);
1462 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1465 if (strlen(driver->configfile)) {
1466 fstrcpy(temp_name, driver->configfile);
1467 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1470 if (strlen(driver->helpfile)) {
1471 fstrcpy(temp_name, driver->helpfile);
1472 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1475 if (driver->dependentfiles) {
1476 for (i=0; *driver->dependentfiles[i]; i++) {
1477 fstrcpy(temp_name, driver->dependentfiles[i]);
1478 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1482 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1484 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1491 len += tdb_pack(buf+len, buflen-len, "dffffffff",
1494 driver->environment,
1499 driver->monitorname,
1500 driver->defaultdatatype);
1502 if (driver->dependentfiles) {
1503 for (i=0; *driver->dependentfiles[i]; i++) {
1504 len += tdb_pack(buf+len, buflen-len, "f",
1505 driver->dependentfiles[i]);
1509 if (len != buflen) {
1512 tb = (char *)Realloc(buf, len);
1514 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1525 kbuf.dsize = strlen(key)+1;
1529 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1533 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1539 /****************************************************************************
1540 ****************************************************************************/
1541 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1543 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1546 info3.cversion = driver->version;
1547 fstrcpy(info3.name,driver->name);
1548 fstrcpy(info3.environment,driver->environment);
1549 fstrcpy(info3.driverpath,driver->driverpath);
1550 fstrcpy(info3.datafile,driver->datafile);
1551 fstrcpy(info3.configfile,driver->configfile);
1552 fstrcpy(info3.helpfile,driver->helpfile);
1553 fstrcpy(info3.monitorname,driver->monitorname);
1554 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1555 info3.dependentfiles = driver->dependentfiles;
1557 return add_a_printer_driver_3(&info3);
1561 /****************************************************************************
1562 ****************************************************************************/
1563 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1565 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1569 fstrcpy(info.name, in_prt);
1570 fstrcpy(info.defaultdatatype, "RAW");
1572 fstrcpy(info.driverpath, "");
1573 fstrcpy(info.datafile, "");
1574 fstrcpy(info.configfile, "");
1575 fstrcpy(info.helpfile, "");
1577 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1580 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1581 fstrcpy(info.dependentfiles[0], "");
1583 *info_ptr = memdup(&info, sizeof(info));
1588 /****************************************************************************
1589 ****************************************************************************/
1590 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1592 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1593 TDB_DATA kbuf, dbuf;
1594 fstring architecture;
1599 ZERO_STRUCT(driver);
1601 get_short_archi(architecture, in_arch);
1603 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1605 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1608 kbuf.dsize = strlen(key)+1;
1610 dbuf = tdb_fetch(tdb_drivers, kbuf);
1612 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1614 if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1616 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1625 driver.defaultdatatype);
1628 while (len < dbuf.dsize) {
1631 tddfs = (fstring *)Realloc(driver.dependentfiles,
1632 sizeof(fstring)*(i+2));
1633 if (tddfs == NULL) {
1634 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1637 else driver.dependentfiles = tddfs;
1639 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1640 &driver.dependentfiles[i]);
1643 if (driver.dependentfiles != NULL)
1644 fstrcpy(driver.dependentfiles[i], "");
1646 SAFE_FREE(dbuf.dptr);
1648 if (len != dbuf.dsize) {
1649 SAFE_FREE(driver.dependentfiles);
1651 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1654 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1659 /****************************************************************************
1660 ****************************************************************************/
1661 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1663 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1669 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1670 DEBUG(10,("driver key: [%s]\n", key));
1673 kbuf.dsize = strlen(key)+1;
1674 if (!tdb_exists(tdb_drivers, kbuf)) return False;
1677 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1679 DEBUGADD(10,("info3->name [%s]\n", info3->name));
1680 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
1681 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
1682 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
1683 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1684 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1685 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
1687 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
1688 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
1689 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
1691 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1692 trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1693 pstrcat(line, info3->configfile);
1695 trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1696 pstrcat(line, info3->datafile);
1698 trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1699 pstrcat(line, info3->helpfile);
1701 trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1702 pstrcat(line, info3->monitorname);
1704 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
1707 for (i=0; info3->dependentfiles &&
1708 *info3->dependentfiles[i]; i++) {
1709 if (i) pstrcat(line, ","); /* don't end in a "," */
1710 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1711 pstrcat(line, info3->dependentfiles[i]);
1719 /****************************************************************************
1720 debugging function, dump at level 6 the struct in the logs
1721 ****************************************************************************/
1722 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1725 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1728 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1734 if (driver.info_3 == NULL)
1737 info3=driver.info_3;
1739 DEBUGADD(106,("version:[%d]\n", info3->cversion));
1740 DEBUGADD(106,("name:[%s]\n", info3->name));
1741 DEBUGADD(106,("environment:[%s]\n", info3->environment));
1742 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
1743 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
1744 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
1745 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
1746 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
1747 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1749 for (i=0; info3->dependentfiles &&
1750 *info3->dependentfiles[i]; i++) {
1751 DEBUGADD(106,("dependentfile:[%s]\n",
1752 info3->dependentfiles[i]));
1759 DEBUGADD(1,("Level not implemented\n"));
1767 /****************************************************************************
1768 ****************************************************************************/
1769 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1773 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1775 if (!nt_devmode) return len;
1777 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1778 nt_devmode->devicename,
1779 nt_devmode->formname,
1781 nt_devmode->specversion,
1782 nt_devmode->driverversion,
1784 nt_devmode->driverextra,
1785 nt_devmode->orientation,
1786 nt_devmode->papersize,
1787 nt_devmode->paperlength,
1788 nt_devmode->paperwidth,
1791 nt_devmode->defaultsource,
1792 nt_devmode->printquality,
1795 nt_devmode->yresolution,
1796 nt_devmode->ttoption,
1797 nt_devmode->collate,
1798 nt_devmode->logpixels,
1801 nt_devmode->bitsperpel,
1802 nt_devmode->pelswidth,
1803 nt_devmode->pelsheight,
1804 nt_devmode->displayflags,
1805 nt_devmode->displayfrequency,
1806 nt_devmode->icmmethod,
1807 nt_devmode->icmintent,
1808 nt_devmode->mediatype,
1809 nt_devmode->dithertype,
1810 nt_devmode->reserved1,
1811 nt_devmode->reserved2,
1812 nt_devmode->panningwidth,
1813 nt_devmode->panningheight,
1814 nt_devmode->private);
1817 if (nt_devmode->private) {
1818 len += tdb_pack(buf+len, buflen-len, "B",
1819 nt_devmode->driverextra,
1820 nt_devmode->private);
1823 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1828 /****************************************************************************
1829 ****************************************************************************/
1830 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1834 while (param != NULL) {
1835 len += tdb_pack(buf+len, buflen-len, "pfdB",
1844 len += tdb_pack(buf+len, buflen-len, "p", param);
1850 /****************************************************************************
1851 delete a printer - this just deletes the printer info file, any open
1852 handles are not affected
1853 ****************************************************************************/
1854 uint32 del_a_printer(char *sharename)
1859 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1862 kbuf.dsize=strlen(key)+1;
1864 tdb_delete(tdb_printers, kbuf);
1868 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
1869 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1870 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1871 /****************************************************************************
1872 ****************************************************************************/
1873 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1879 TDB_DATA kbuf, dbuf;
1882 * in addprinter: no servername and the printer is the name
1883 * in setprinter: servername is \\server
1884 * and printer is \\server\\printer
1886 * Samba manages only local printers.
1887 * we currently don't support things like path=\\other_server\printer
1890 if (info->servername[0]!='\0') {
1891 trim_string(info->printername, info->servername, NULL);
1892 trim_string(info->printername, "\\", NULL);
1893 info->servername[0]='\0';
1897 * JFM: one day I'll forget.
1898 * below that's info->portname because that's the SAMBA sharename
1899 * and I made NT 'thinks' it's the portname
1900 * the info->sharename is the thing you can name when you add a printer
1901 * that's the short-name when you create shared printer for 95/98
1902 * So I've made a limitation in SAMBA: you can only have 1 printer model
1903 * behind a SAMBA share.
1911 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1914 info->default_priority,
1931 info->printprocessor,
1935 len += pack_devicemode(info->devmode, buf+len, buflen-len);
1937 len += pack_specifics(info->specific, buf+len, buflen-len);
1939 if (buflen != len) {
1942 tb = (char *)Realloc(buf, len);
1944 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
1954 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
1957 kbuf.dsize = strlen(key)+1;
1961 ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
1964 if (!W_ERROR_IS_OK(ret))
1965 DEBUG(8, ("error updating printer to tdb on disk\n"));
1969 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1970 info->sharename, info->drivername, info->portname, len));
1976 /****************************************************************************
1977 ****************************************************************************/
1978 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
1980 NT_PRINTER_PARAM *current;
1982 DEBUG(108,("add_a_specific_param\n"));
1984 (*param)->next=NULL;
1986 if (info_2->specific == NULL)
1988 info_2->specific=*param;
1992 current=info_2->specific;
1993 while (current->next != NULL) {
1994 current=current->next;
1996 current->next=*param;
2002 /****************************************************************************
2003 ****************************************************************************/
2004 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2006 NT_PRINTER_PARAM *current;
2007 NT_PRINTER_PARAM *previous;
2009 current=info_2->specific;
2012 if (current==NULL) return (False);
2014 if ( !strcmp(current->value, param->value) &&
2015 (strlen(current->value)==strlen(param->value)) ) {
2016 DEBUG(109,("deleting first value\n"));
2017 info_2->specific=current->next;
2018 SAFE_FREE(current->data);
2020 DEBUG(109,("deleted first value\n"));
2024 current=previous->next;
2026 while ( current!=NULL ) {
2027 if (!strcmp(current->value, param->value) &&
2028 strlen(current->value)==strlen(param->value) ) {
2029 DEBUG(109,("deleting current value\n"));
2030 previous->next=current->next;
2031 SAFE_FREE(current->data);
2033 DEBUG(109,("deleted current value\n"));
2037 previous=previous->next;
2038 current=current->next;
2043 /****************************************************************************
2044 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2045 ****************************************************************************/
2046 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2048 NT_PRINTER_PARAM *param = *param_ptr;
2053 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2055 SAFE_FREE(param->data);
2056 SAFE_FREE(*param_ptr);
2059 /****************************************************************************
2060 Malloc and return an NT devicemode.
2061 ****************************************************************************/
2063 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2066 * should I init this ones ???
2067 nt_devmode->devicename
2071 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2073 if (nt_devmode == NULL) {
2074 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2078 ZERO_STRUCTP(nt_devmode);
2080 safe_strcpy(adevice, default_devicename, sizeof(adevice));
2081 fstrcpy(nt_devmode->devicename, adevice);
2083 fstrcpy(nt_devmode->formname, "Letter");
2085 nt_devmode->specversion = 0x0401;
2086 nt_devmode->driverversion = 0x0400;
2087 nt_devmode->size = 0x00DC;
2088 nt_devmode->driverextra = 0x0000;
2089 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
2090 DEFAULTSOURCE | COPIES | SCALE |
2091 PAPERSIZE | ORIENTATION;
2092 nt_devmode->orientation = 1;
2093 nt_devmode->papersize = PAPER_LETTER;
2094 nt_devmode->paperlength = 0;
2095 nt_devmode->paperwidth = 0;
2096 nt_devmode->scale = 0x64;
2097 nt_devmode->copies = 1;
2098 nt_devmode->defaultsource = BIN_FORMSOURCE;
2099 nt_devmode->printquality = RES_HIGH; /* 0x0258 */
2100 nt_devmode->color = COLOR_MONOCHROME;
2101 nt_devmode->duplex = DUP_SIMPLEX;
2102 nt_devmode->yresolution = 0;
2103 nt_devmode->ttoption = TT_SUBDEV;
2104 nt_devmode->collate = COLLATE_FALSE;
2105 nt_devmode->icmmethod = 0;
2106 nt_devmode->icmintent = 0;
2107 nt_devmode->mediatype = 0;
2108 nt_devmode->dithertype = 0;
2110 /* non utilisés par un driver d'imprimante */
2111 nt_devmode->logpixels = 0;
2112 nt_devmode->bitsperpel = 0;
2113 nt_devmode->pelswidth = 0;
2114 nt_devmode->pelsheight = 0;
2115 nt_devmode->displayflags = 0;
2116 nt_devmode->displayfrequency = 0;
2117 nt_devmode->reserved1 = 0;
2118 nt_devmode->reserved2 = 0;
2119 nt_devmode->panningwidth = 0;
2120 nt_devmode->panningheight = 0;
2122 nt_devmode->private = NULL;
2126 /****************************************************************************
2127 Deepcopy an NT devicemode.
2128 ****************************************************************************/
2130 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2132 NT_DEVICEMODE *new_nt_devicemode = NULL;
2134 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2135 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2139 new_nt_devicemode->private = NULL;
2140 if (nt_devicemode->private != NULL) {
2141 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2142 SAFE_FREE(new_nt_devicemode);
2143 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2148 return new_nt_devicemode;
2151 /****************************************************************************
2152 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2153 ****************************************************************************/
2155 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2157 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2159 if(nt_devmode == NULL)
2162 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2164 SAFE_FREE(nt_devmode->private);
2165 SAFE_FREE(*devmode_ptr);
2168 /****************************************************************************
2169 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2170 ****************************************************************************/
2171 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2173 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2174 NT_PRINTER_PARAM *param_ptr;
2179 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2181 free_nt_devicemode(&info->devmode);
2183 for(param_ptr = info->specific; param_ptr; ) {
2184 NT_PRINTER_PARAM *tofree = param_ptr;
2186 param_ptr = param_ptr->next;
2187 free_nt_printer_param(&tofree);
2190 SAFE_FREE(*info_ptr);
2194 /****************************************************************************
2195 ****************************************************************************/
2196 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2200 NT_DEVICEMODE devmode;
2202 ZERO_STRUCT(devmode);
2204 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2206 if (!*nt_devmode) return len;
2208 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2212 &devmode.specversion,
2213 &devmode.driverversion,
2215 &devmode.driverextra,
2216 &devmode.orientation,
2218 &devmode.paperlength,
2219 &devmode.paperwidth,
2222 &devmode.defaultsource,
2223 &devmode.printquality,
2226 &devmode.yresolution,
2232 &devmode.bitsperpel,
2234 &devmode.pelsheight,
2235 &devmode.displayflags,
2236 &devmode.displayfrequency,
2240 &devmode.dithertype,
2243 &devmode.panningwidth,
2244 &devmode.panningheight,
2247 if (devmode.private) {
2248 /* the len in tdb_unpack is an int value and
2249 * devmode.driverextra is only a short
2251 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2252 devmode.driverextra=(uint16)extra_len;
2254 /* check to catch an invalid TDB entry so we don't segfault */
2255 if (devmode.driverextra == 0) {
2256 devmode.private = NULL;
2260 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2262 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2263 if (devmode.private)
2264 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2269 /****************************************************************************
2270 ****************************************************************************/
2271 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2274 NT_PRINTER_PARAM param, *p;
2279 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2282 len += tdb_unpack(buf+len, buflen-len, "fdB",
2288 *list = memdup(¶m, sizeof(param));
2290 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2296 static void map_to_os2_driver(fstring drivername)
2298 static BOOL initialised=False;
2299 static fstring last_from,last_to;
2300 char *mapfile = lp_os2_driver_map();
2301 char **lines = NULL;
2305 if (!strlen(drivername))
2312 *last_from = *last_to = 0;
2316 if (strequal(drivername,last_from)) {
2317 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2318 fstrcpy(drivername,last_to);
2322 lines = file_lines_load(mapfile, &numlines);
2323 if (numlines == 0) {
2324 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2328 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2330 for( i = 0; i < numlines; i++) {
2331 char *nt_name = lines[i];
2332 char *os2_name = strchr(nt_name,'=');
2339 while (isspace(*nt_name))
2342 if (!*nt_name || strchr("#;",*nt_name))
2346 int l = strlen(nt_name);
2347 while (l && isspace(nt_name[l-1])) {
2353 while (isspace(*os2_name))
2357 int l = strlen(os2_name);
2358 while (l && isspace(os2_name[l-1])) {
2364 if (strequal(nt_name,drivername)) {
2365 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2366 fstrcpy(last_from,drivername);
2367 fstrcpy(last_to,os2_name);
2368 fstrcpy(drivername,os2_name);
2369 file_lines_free(lines);
2374 file_lines_free(lines);
2377 /****************************************************************************
2378 get a default printer info 2 struct
2379 ****************************************************************************/
2380 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2382 extern pstring global_myname;
2383 extern fstring local_machine;
2385 NT_PRINTER_INFO_LEVEL_2 info;
2386 char *sub_name = *local_machine ? local_machine : global_myname;
2390 snum = lp_servicenumber(sharename);
2392 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", sub_name);
2393 slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
2394 sub_name, sharename);
2395 fstrcpy(info.sharename, sharename);
2396 fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2397 fstrcpy(info.drivername, lp_printerdriver(snum));
2399 /* by setting the driver name to an empty string, a local NT admin
2400 can now run the **local** APW to install a local printer driver
2401 for a Samba shared printer in 2.2. Without this, drivers **must** be
2402 installed on the Samba server for NT clients --jerry */
2403 #if 0 /* JERRY --do not uncomment-- */
2404 if (!*info.drivername)
2405 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2409 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2411 pstrcpy(info.comment, "");
2412 fstrcpy(info.printprocessor, "winprint");
2413 fstrcpy(info.datatype, "RAW");
2415 info.attributes = PRINTER_ATTRIBUTE_SHARED \
2416 | PRINTER_ATTRIBUTE_LOCAL \
2417 | PRINTER_ATTRIBUTE_RAW_ONLY \
2418 | PRINTER_ATTRIBUTE_QUEUED ; /* attributes */
2420 info.starttime = 0; /* Minutes since 12:00am GMT */
2421 info.untiltime = 0; /* Minutes since 12:00am GMT */
2423 info.default_priority = 1;
2424 info.setuptime = (uint32)time(NULL) - 86400; /* minus 1 day */
2427 * I changed this as I think it is better to have a generic
2428 * DEVMODE than to crash Win2k explorer.exe --jerry
2429 * See the HP Deskjet 990c Win2k drivers for an example.
2432 #if 0 /* JRA - NO NOT CHANGE ! */
2433 info.devmode = NULL;
2436 * We should not return a default devicemode, as this causes
2437 * Win2K to not send the correct one on PCL drivers. It needs to
2438 * see a null devicemode so it can then overwrite the devicemode
2439 * on OpenPrinterEx. Yes this *is* insane :-). JRA.
2441 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2445 /* This will get the current RPC talloc context, but we should be
2446 passing this as a parameter... fixme... JRA ! */
2448 if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2451 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2453 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2462 free_nt_devicemode(&info.devmode);
2463 return WERR_ACCESS_DENIED;
2466 /****************************************************************************
2467 ****************************************************************************/
2468 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2470 extern pstring global_myname;
2471 extern fstring local_machine;
2473 char *sub_name = *local_machine ? local_machine : global_myname;
2474 NT_PRINTER_INFO_LEVEL_2 info;
2476 TDB_DATA kbuf, dbuf;
2477 fstring printername;
2481 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2484 kbuf.dsize = strlen(key)+1;
2486 dbuf = tdb_fetch(tdb_printers, kbuf);
2488 return get_a_printer_2_default(info_ptr, sharename);
2490 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2493 &info.default_priority,
2510 info.printprocessor,
2514 /* Samba has to have shared raw drivers. */
2515 info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
2517 /* Restore the stripped strings. */
2518 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", sub_name);
2519 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", sub_name,
2521 fstrcpy(info.printername, printername);
2523 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2526 * Some client drivers freak out if there is a NULL devmode
2527 * (probably the driver is not checking before accessing
2528 * the devmode pointer) --jerry
2532 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2534 info.devmode = construct_nt_devicemode(printername);
2537 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2539 /* This will get the current RPC talloc context, but we should be
2540 passing this as a parameter... fixme... JRA ! */
2542 nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2544 /* Fix for OS/2 drivers. */
2546 if (get_remote_arch() == RA_OS2)
2547 map_to_os2_driver(info.drivername);
2549 SAFE_FREE(dbuf.dptr);
2550 *info_ptr=memdup(&info, sizeof(info));
2552 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2553 sharename, info.printername, info.drivername));
2558 /****************************************************************************
2559 debugging function, dump at level 6 the struct in the logs
2560 ****************************************************************************/
2561 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2564 NT_PRINTER_INFO_LEVEL_2 *info2;
2566 DEBUG(106,("Dumping printer at level [%d]\n", level));
2572 if (printer.info_2 == NULL)
2576 info2=printer.info_2;
2578 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2579 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2580 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2581 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2582 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2583 DEBUGADD(106,("status:[%d]\n", info2->status));
2584 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2585 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2586 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2587 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2588 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2590 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2591 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2592 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2593 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2594 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2595 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2596 DEBUGADD(106,("location:[%s]\n", info2->location));
2597 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2598 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2599 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2600 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2606 DEBUGADD(1,("Level not implemented\n"));
2614 /****************************************************************************
2615 Get the parameters we can substitute in an NT print job.
2616 ****************************************************************************/
2618 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2620 NT_PRINTER_INFO_LEVEL *printer = NULL;
2622 **printername = **sharename = **portname = '\0';
2624 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2627 fstrcpy(*printername, printer->info_2->printername);
2628 fstrcpy(*sharename, printer->info_2->sharename);
2629 fstrcpy(*portname, printer->info_2->portname);
2631 free_a_printer(&printer, 2);
2635 * The function below are the high level ones.
2636 * only those ones must be called from the spoolss code.
2640 /****************************************************************************
2641 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2642 ****************************************************************************/
2644 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2648 dump_a_printer(printer, level);
2655 * Update the changestamp. Emperical tests show that the
2656 * ChangeID is always updated,but c_setprinter is only
2657 * incremented on a SetPrinter() call.
2660 time_t time_unix = time(NULL);
2662 /* ChangeID **must** be increasing over the lifetime
2663 of client's spoolss service in order for the
2664 client's cache to show updates */
2666 printer.info_2->changeid = time_unix * 100;
2669 * Because one day someone will ask:
2670 * NT->NT An admin connection to a remote
2671 * printer show changes imeediately in
2672 * the properities dialog
2674 * A non-admin connection will only show the
2675 * changes after viewing the properites page
2676 * 2 times. Seems to be related to a
2677 * race condition in the client between the spooler
2678 * updating the local cache and the Explorer.exe GUI
2679 * actually displaying the properties.
2681 * This is fixed in Win2k. admin/non-admin
2682 * connections both display changes immediately.
2687 result=update_a_printer_2(printer.info_2);
2691 result=WERR_UNKNOWN_LEVEL;
2698 /****************************************************************************
2699 Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
2700 We split this out from mod_a_printer as it updates the id's and timestamps.
2701 ****************************************************************************/
2703 WERROR add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2707 dump_a_printer(printer, level);
2714 * Update the changestamp. See comments in mod_a_printer()
2718 time_t time_unix = time(NULL);
2720 printer.info_2->changeid = time_unix * 100;
2721 printer.info_2->c_setprinter++;
2723 result=update_a_printer_2(printer.info_2);
2727 result=WERR_UNKNOWN_LEVEL;
2734 /****************************************************************************
2735 Initialize printer devmode & data with previously saved driver init values.
2736 ****************************************************************************/
2737 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2741 TDB_DATA kbuf, dbuf;
2742 NT_PRINTER_PARAM *current;
2743 NT_PRINTER_INFO_LEVEL_2 info;
2747 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2750 kbuf.dsize = strlen(key)+1;
2752 dbuf = tdb_fetch(tdb_drivers, kbuf);
2757 * Get the saved DEVMODE..
2759 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2762 * The saved DEVMODE contains the devicename from the printer used during
2763 * the initialization save. Change it to reflect the new printer.
2765 ZERO_STRUCT(info.devmode->devicename);
2766 fstrcpy(info.devmode->devicename, info_ptr->printername);
2769 * Bind the saved DEVMODE to the new the printer.
2771 free_nt_devicemode(&info_ptr->devmode);
2772 info_ptr->devmode = info.devmode;
2774 DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2775 info_ptr->printername, info_ptr->drivername));
2778 * There should not be any printer data 'specifics' already set during the
2779 * add printer operation, if there are delete them.
2781 while ( (current=info_ptr->specific) != NULL ) {
2782 info_ptr->specific=current->next;
2783 SAFE_FREE(current->data);
2788 * Add the printer data 'specifics' to the new printer
2790 len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2792 SAFE_FREE(dbuf.dptr);
2797 /****************************************************************************
2798 Initialize printer devmode & data with previously saved driver init values.
2799 When a printer is created using AddPrinter, the drivername bound to the
2800 printer is used to lookup previously saved driver initialization info, which
2801 is bound to the new printer.
2802 ****************************************************************************/
2804 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2812 result=set_driver_init_2(printer->info_2);
2823 /****************************************************************************
2824 Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
2825 in the tdb. Note: this is different from the driver entry and the printer
2826 entry. There should be a single driver init entry for each driver regardless
2827 of whether it was installed from NT or 2K. Technically, they should be
2828 different, but they work out to the same struct.
2829 ****************************************************************************/
2830 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2834 int buflen, len, ret;
2835 TDB_DATA kbuf, dbuf;
2842 len += pack_devicemode(info->devmode, buf+len, buflen-len);
2844 len += pack_specifics(info->specific, buf+len, buflen-len);
2846 if (buflen != len) {
2849 tb = (char *)Realloc(buf, len);
2851 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2860 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
2863 kbuf.dsize = strlen(key)+1;
2867 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
2871 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
2875 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
2876 info->sharename, info->drivername));
2881 /****************************************************************************
2882 Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
2883 ****************************************************************************/
2885 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2889 dump_a_printer(printer, level);
2895 result=update_driver_init_2(printer.info_2);
2906 /****************************************************************************
2907 Convert the printer data value, a REG_BINARY array, into an initialization
2908 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
2909 got to keep the endians happy :).
2910 ****************************************************************************/
2912 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
2914 BOOL result = False;
2918 ZERO_STRUCT(devmode);
2920 prs_init(&ps, 0, ctx, UNMARSHALL);
2921 ps.data_p = (char *)param->data;
2922 ps.buffer_size = param->data_len;
2924 if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
2925 result = convert_devicemode("", &devmode, &nt_devmode);
2927 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
2932 /****************************************************************************
2933 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
2935 1. Use the driver's config DLL to this UNC printername and:
2936 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
2937 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
2938 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
2940 The last step triggers saving the "driver initialization" information for
2941 this printer into the tdb. Later, new printers that use this driver will
2942 have this initialization information bound to them. This simulates the
2943 driver initialization, as if it had run on the Samba server (as it would
2946 The Win32 client side code requirement sucks! But until we can run arbitrary
2947 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
2949 It would have been easier to use SetPrinter because all the UNMARSHALLING of
2950 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
2951 about it and you will realize why. JRR 010720
2952 ****************************************************************************/
2954 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
2956 WERROR status = WERR_OK;
2957 TALLOC_CTX *ctx = NULL;
2958 NT_DEVICEMODE *nt_devmode = NULL;
2959 NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
2962 * Set devmode on printer info, so entire printer initialization can be
2965 if ((ctx = talloc_init()) == NULL)
2968 if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
2969 status = WERR_NOMEM;
2973 ZERO_STRUCTP(nt_devmode);
2976 * The DEVMODE is held in the 'data' component of the param in raw binary.
2977 * Convert it to to a devmode structure
2979 if (!convert_driver_init(param, ctx, nt_devmode)) {
2980 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
2981 status = WERR_INVALID_PARAM;
2986 * Pack up and add (or update) the DEVMODE and any current printer data to
2987 * a 'driver init' element in the tdb
2990 printer->info_2->devmode = nt_devmode;
2991 if (update_driver_init(*printer, 2)!=0) {
2992 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
2993 status = WERR_NOMEM;
2998 * If driver initialization info was successfully saved, set the current
2999 * printer to match it. This allows initialization of the current printer
3000 * as well as the driver.
3002 status = mod_a_printer(*printer, 2);
3003 if (!W_ERROR_IS_OK(status)) {
3004 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
3005 printer->info_2->printername));
3009 talloc_destroy(ctx);
3011 SAFE_FREE(nt_devmode->private);
3012 SAFE_FREE(nt_devmode);
3013 printer->info_2->devmode = tmp_devmode;
3018 /****************************************************************************
3019 Update the driver init info (DEVMODE and specifics) for a printer
3020 ****************************************************************************/
3022 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
3024 WERROR status = WERR_OK;
3030 status=save_driver_init_2(printer, param);
3034 status=WERR_UNKNOWN_LEVEL;
3041 /****************************************************************************
3042 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3043 ****************************************************************************/
3045 WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
3048 NT_PRINTER_INFO_LEVEL *printer = NULL;
3052 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
3058 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3059 DEBUG(0,("get_a_printer: malloc fail.\n"));
3062 ZERO_STRUCTP(printer);
3063 result=get_a_printer_2(&printer->info_2, sharename);
3064 if (W_ERROR_IS_OK(result)) {
3065 dump_a_printer(*printer, level);
3066 *pp_printer = printer;
3073 result=WERR_UNKNOWN_LEVEL;