~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/registry/reg_backend_printing.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Unix SMB/CIFS implementation.
 
3
 *  Virtual Windows Registry Layer
 
4
 *  Copyright (C) Gerald Carter                     2002-2005
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 3 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
/* Implementation of registry virtual views for printing information */
 
21
 
 
22
#include "includes.h"
 
23
 
 
24
#undef DBGC_CLASS
 
25
#define DBGC_CLASS DBGC_REGISTRY
 
26
 
 
27
/* registrt paths used in the print_registry[] */
 
28
 
 
29
#define KEY_MONITORS            "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/MONITORS"
 
30
#define KEY_FORMS               "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS"
 
31
#define KEY_CONTROL_PRINTERS    "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
 
32
#define KEY_ENVIRONMENTS        "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS"
 
33
#define KEY_CONTROL_PRINT       "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT"
 
34
#define KEY_WINNT_PRINTERS      "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
 
35
#define KEY_WINNT_PRINT         "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT"
 
36
#define KEY_PORTS               "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PORTS"
 
37
 
 
38
/* callback table for various registry paths below the ones we service in this module */
 
39
 
 
40
struct reg_dyn_tree {
 
41
        /* full key path in normalized form */
 
42
        const char *path;
 
43
 
 
44
        /* callbscks for fetch/store operations */
 
45
        int ( *fetch_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
 
46
        bool (*store_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
 
47
        int  (*fetch_values)  ( const char *path, REGVAL_CTR *values );
 
48
        bool (*store_values)  ( const char *path, REGVAL_CTR *values );
 
49
};
 
50
 
 
51
/*********************************************************************
 
52
 *********************************************************************
 
53
 ** Utility Functions
 
54
 *********************************************************************
 
55
 *********************************************************************/
 
56
 
 
57
/***********************************************************************
 
58
 simple function to prune a pathname down to the basename of a file
 
59
 **********************************************************************/
 
60
 
 
61
static const char *dos_basename(const char *path)
 
62
{
 
63
        const char *p;
 
64
 
 
65
        if (!(p = strrchr( path, '\\'))) {
 
66
                p = path;
 
67
        } else {
 
68
                p++;
 
69
        }
 
70
 
 
71
        return p;
 
72
}
 
73
 
 
74
/*********************************************************************
 
75
 *********************************************************************
 
76
 ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS"
 
77
 *********************************************************************
 
78
 *********************************************************************/
 
79
 
 
80
static int key_forms_fetch_keys(const char *key, struct regsubkey_ctr *subkeys)
 
81
{
 
82
        char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS));
 
83
 
 
84
        /* no keys below Forms */
 
85
 
 
86
        if (p) {
 
87
                return -1;
 
88
        }
 
89
 
 
90
        return 0;
 
91
}
 
92
 
 
93
/**********************************************************************
 
94
 *********************************************************************/
 
95
 
 
96
static int key_forms_fetch_values( const char *key, REGVAL_CTR *values )
 
97
{
 
98
        uint32          data[8];
 
99
        int             i, num_values, form_index = 1;
 
100
        nt_forms_struct *forms_list = NULL;
 
101
        nt_forms_struct *form;
 
102
 
 
103
        DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" ));
 
104
 
 
105
        num_values = get_ntforms( &forms_list );
 
106
 
 
107
        DEBUG(10,("hive_forms_fetch_values: [%d] user defined forms returned\n",
 
108
                num_values));
 
109
 
 
110
        /* handle user defined forms */
 
111
 
 
112
        for ( i=0; i<num_values; i++ ) {
 
113
                form = &forms_list[i];
 
114
 
 
115
                data[0] = form->width;
 
116
                data[1] = form->length;
 
117
                data[2] = form->left;
 
118
                data[3] = form->top;
 
119
                data[4] = form->right;
 
120
                data[5] = form->bottom;
 
121
                data[6] = form_index++;
 
122
                data[7] = form->flag;
 
123
 
 
124
                regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) );       
 
125
        }
 
126
 
 
127
        SAFE_FREE( forms_list );
 
128
        forms_list = NULL;
 
129
 
 
130
        /* handle built-on forms */
 
131
 
 
132
        num_values = get_builtin_ntforms( &forms_list );
 
133
 
 
134
        DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n",
 
135
                num_values));
 
136
 
 
137
        for ( i=0; i<num_values; i++ ) {
 
138
                form = &forms_list[i];
 
139
 
 
140
                data[0] = form->width;
 
141
                data[1] = form->length;
 
142
                data[2] = form->left;
 
143
                data[3] = form->top;
 
144
                data[4] = form->right;
 
145
                data[5] = form->bottom;
 
146
                data[6] = form_index++;
 
147
                data[7] = form->flag;
 
148
 
 
149
                regval_ctr_addvalue(values, form->name, REG_BINARY, (char*)data, sizeof(data) );
 
150
        }
 
151
 
 
152
        SAFE_FREE(forms_list);
 
153
 
 
154
        return regval_ctr_numvals(values);
 
155
}
 
156
 
 
157
/*********************************************************************
 
158
 *********************************************************************
 
159
 ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
 
160
 ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
 
161
 *********************************************************************
 
162
 *********************************************************************/
 
163
 
 
164
/*********************************************************************
 
165
 strip off prefix for printers key.  DOes return a pointer to static
 
166
 memory.
 
167
 *********************************************************************/
 
168
 
 
169
static char *strip_printers_prefix(const char *key)
 
170
{
 
171
        char *subkeypath = NULL;
 
172
        char *path = NULL;
 
173
        TALLOC_CTX *ctx = talloc_tos();
 
174
 
 
175
        path = talloc_strdup(ctx, key);
 
176
        if (!path) {
 
177
                return NULL;
 
178
        }
 
179
        path = normalize_reg_path(ctx, path);
 
180
        if (!path) {
 
181
                return NULL;
 
182
        }
 
183
 
 
184
        /* normalizing the path does not change length, just key delimiters and case */
 
185
 
 
186
        if (strncmp(path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS)) == 0) {
 
187
                subkeypath = reg_remaining_path(ctx, key + strlen(KEY_WINNT_PRINTERS));
 
188
        } else {
 
189
                subkeypath = reg_remaining_path(ctx, key + strlen(KEY_CONTROL_PRINTERS));
 
190
        }
 
191
 
 
192
        TALLOC_FREE(path);
 
193
        return subkeypath;
 
194
}
 
195
 
 
196
/*********************************************************************
 
197
 *********************************************************************/
 
198
 
 
199
static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
 
200
{
 
201
        int n_services = lp_numservices();
 
202
        int snum;
 
203
        fstring sname;
 
204
        int i;
 
205
        int num_subkeys = 0;
 
206
        char *printers_key;
 
207
        char *printername, *printerdatakey;
 
208
        NT_PRINTER_INFO_LEVEL *printer = NULL;
 
209
        fstring *subkey_names = NULL;
 
210
 
 
211
        DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" ));
 
212
 
 
213
        printers_key = strip_printers_prefix( key );
 
214
 
 
215
        if ( !printers_key ) {
 
216
                /* enumerate all printers */
 
217
 
 
218
                for (snum=0; snum<n_services; snum++) {
 
219
                        if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
 
220
                                continue;
 
221
 
 
222
                        /* don't report the [printers] share */
 
223
 
 
224
                        if ( strequal( lp_servicename(snum), PRINTERS_NAME ) )
 
225
                                continue;
 
226
 
 
227
                        fstrcpy( sname, lp_servicename(snum) );
 
228
 
 
229
                        regsubkey_ctr_addkey( subkeys, sname );
 
230
                }
 
231
 
 
232
                num_subkeys = regsubkey_ctr_numkeys( subkeys );
 
233
                goto done;
 
234
        }
 
235
 
 
236
        /* get information for a specific printer */
 
237
 
 
238
        if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
 
239
                return -1;
 
240
        }
 
241
 
 
242
        /* validate the printer name */
 
243
 
 
244
        for (snum=0; snum<n_services; snum++) {
 
245
                if ( !lp_snum_ok(snum) || !lp_print_ok(snum) )
 
246
                        continue;
 
247
                if (strequal( lp_servicename(snum), printername ) )
 
248
                        break;
 
249
        }
 
250
 
 
251
        if ( snum>=n_services
 
252
                || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) 
 
253
        {
 
254
                return -1;
 
255
        }
 
256
 
 
257
        num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names );
 
258
        
 
259
        for ( i=0; i<num_subkeys; i++ )
 
260
                regsubkey_ctr_addkey( subkeys, subkey_names[i] );
 
261
        
 
262
        free_a_printer( &printer, 2 );
 
263
                        
 
264
        /* no other subkeys below here */
 
265
 
 
266
done:   
 
267
        SAFE_FREE( subkey_names );
 
268
        
 
269
        return num_subkeys;
 
270
}
 
271
 
 
272
/**********************************************************************
 
273
 Take a list of names and call add_printer_hook() if necessary
 
274
 Note that we do this a little differently from Windows since the 
 
275
 keyname is the sharename and not the printer name.
 
276
 *********************************************************************/
 
277
 
 
278
static bool add_printers_by_registry( struct regsubkey_ctr *subkeys )
 
279
{
 
280
        int i, num_keys, snum;
 
281
        char *printername;
 
282
        NT_PRINTER_INFO_LEVEL_2 info2;
 
283
        NT_PRINTER_INFO_LEVEL printer;
 
284
        
 
285
        ZERO_STRUCT( info2 );
 
286
        printer.info_2 = &info2;
 
287
        
 
288
        num_keys = regsubkey_ctr_numkeys( subkeys );
 
289
        
 
290
        become_root();
 
291
        for ( i=0; i<num_keys; i++ ) {
 
292
                printername = regsubkey_ctr_specific_key( subkeys, i );
 
293
                snum = find_service( printername );
 
294
                
 
295
                /* just verify a valied snum for now */
 
296
                if ( snum == -1 ) {
 
297
                        fstrcpy( info2.printername, printername );
 
298
                        fstrcpy( info2.sharename, printername );
 
299
                        if ( !add_printer_hook(talloc_tos(), NULL, &printer ) ) {
 
300
                                DEBUG(0,("add_printers_by_registry: Failed to add printer [%s]\n",
 
301
                                        printername));
 
302
                        }       
 
303
                }
 
304
        }
 
305
        unbecome_root();
 
306
 
 
307
        return True;
 
308
}
 
309
 
 
310
/**********************************************************************
 
311
 *********************************************************************/
 
312
 
 
313
static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys )
 
314
{
 
315
        char *printers_key;
 
316
        char *printername, *printerdatakey;
 
317
        NT_PRINTER_INFO_LEVEL *printer = NULL;
 
318
        int i, num_subkeys, num_existing_keys;
 
319
        char *subkeyname;
 
320
        fstring *existing_subkeys = NULL;
 
321
        
 
322
        printers_key = strip_printers_prefix( key );
 
323
        
 
324
        if ( !printers_key ) {
 
325
                /* have to deal with some new or deleted printer */
 
326
                return add_printers_by_registry( subkeys );
 
327
        }
 
328
        
 
329
        if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
 
330
                return False;
 
331
        }
 
332
        
 
333
        /* lookup the printer */
 
334
        
 
335
        if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername)) ) {
 
336
                DEBUG(0,("key_printers_store_keys: Tried to store subkey for bad printername %s\n", 
 
337
                        printername));
 
338
                return False;
 
339
        }
 
340
        
 
341
        /* get the top level printer keys */
 
342
        
 
343
        num_existing_keys = get_printer_subkeys( printer->info_2->data, "", &existing_subkeys );
 
344
        
 
345
        for ( i=0; i<num_existing_keys; i++ ) {
 
346
        
 
347
                /* remove the key if it has been deleted */
 
348
                
 
349
                if ( !regsubkey_ctr_key_exists( subkeys, existing_subkeys[i] ) ) {
 
350
                        DEBUG(5,("key_printers_store_keys: deleting key %s\n", 
 
351
                                existing_subkeys[i]));
 
352
                        delete_printer_key( printer->info_2->data, existing_subkeys[i] );
 
353
                }
 
354
        }
 
355
 
 
356
        num_subkeys = regsubkey_ctr_numkeys( subkeys );
 
357
        for ( i=0; i<num_subkeys; i++ ) {
 
358
                subkeyname = regsubkey_ctr_specific_key(subkeys, i);
 
359
                /* add any missing printer keys */
 
360
                if ( lookup_printerkey(printer->info_2->data, subkeyname) == -1 ) {
 
361
                        DEBUG(5,("key_printers_store_keys: adding key %s\n", 
 
362
                                existing_subkeys[i]));
 
363
                        if ( add_new_printer_key( printer->info_2->data, subkeyname ) == -1 ) {
 
364
                                SAFE_FREE( existing_subkeys );
 
365
                                return False;
 
366
                        }
 
367
                }
 
368
        }
 
369
        
 
370
        /* write back to disk */
 
371
        
 
372
        mod_a_printer( printer, 2 );
 
373
        
 
374
        /* cleanup */
 
375
        
 
376
        free_a_printer( &printer, 2 );
 
377
 
 
378
        SAFE_FREE( existing_subkeys );
 
379
 
 
380
        return True;
 
381
}
 
382
 
 
383
/**********************************************************************
 
384
 *********************************************************************/
 
385
 
 
386
static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values )
 
387
{
 
388
        struct spoolss_DeviceMode *devmode;
 
389
        UNISTR2         data;
 
390
        char            *p;
 
391
        uint32 printer_status = PRINTER_STATUS_OK;
 
392
        
 
393
        regval_ctr_addvalue( values, "Attributes",       REG_DWORD, (char*)&info2->attributes,       sizeof(info2->attributes) );
 
394
        regval_ctr_addvalue( values, "Priority",         REG_DWORD, (char*)&info2->priority,         sizeof(info2->attributes) );
 
395
        regval_ctr_addvalue( values, "ChangeID",         REG_DWORD, (char*)&info2->changeid,         sizeof(info2->changeid) );
 
396
        regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) );
 
397
        
 
398
        /* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */
 
399
        regval_ctr_addvalue( values, "Status",           REG_DWORD, (char*)&printer_status,          sizeof(info2->status) );
 
400
 
 
401
        regval_ctr_addvalue( values, "StartTime",        REG_DWORD, (char*)&info2->starttime,        sizeof(info2->starttime) );
 
402
        regval_ctr_addvalue( values, "UntilTime",        REG_DWORD, (char*)&info2->untiltime,        sizeof(info2->untiltime) );
 
403
 
 
404
        /* strip the \\server\ from this string */
 
405
        if ( !(p = strrchr( info2->printername, '\\' ) ) )
 
406
                p = info2->printername;
 
407
        else
 
408
                p++;
 
409
        init_unistr2( &data, p, UNI_STR_TERMINATE);
 
410
        regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
411
 
 
412
        init_unistr2( &data, info2->location, UNI_STR_TERMINATE);
 
413
        regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
414
 
 
415
        init_unistr2( &data, info2->comment, UNI_STR_TERMINATE);
 
416
        regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
417
 
 
418
        init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE);
 
419
        regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
420
 
 
421
        init_unistr2( &data, info2->portname, UNI_STR_TERMINATE);
 
422
        regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
423
 
 
424
        init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE);
 
425
        regval_ctr_addvalue( values, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
426
 
 
427
        init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE);
 
428
        regval_ctr_addvalue( values, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
429
 
 
430
        init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE);
 
431
        regval_ctr_addvalue( values, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
432
 
 
433
        init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE);
 
434
        regval_ctr_addvalue( values, "Print Processor",  REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
435
 
 
436
        init_unistr2( &data, "RAW", UNI_STR_TERMINATE);
 
437
        regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
438
 
 
439
        /* stream the device mode */
 
440
 
 
441
        devmode = construct_dev_mode(values,info2->sharename);
 
442
        if (devmode) {
 
443
                DATA_BLOB blob;
 
444
                enum ndr_err_code ndr_err;
 
445
 
 
446
                ndr_err = ndr_push_struct_blob(&blob, values, NULL, devmode,
 
447
                                (ndr_push_flags_fn_t)ndr_push_spoolss_DeviceMode);
 
448
 
 
449
                if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
450
                        regval_ctr_addvalue(values, "Default Devmode", REG_BINARY,
 
451
                                            (const char *)blob.data, blob.length);
 
452
                }
 
453
        }
 
454
 
 
455
        /* stream the printer security descriptor */
 
456
 
 
457
        if (info2->secdesc_buf &&
 
458
            info2->secdesc_buf->sd &&
 
459
            info2->secdesc_buf->sd_size)
 
460
        {
 
461
                NTSTATUS status;
 
462
                DATA_BLOB blob;
 
463
 
 
464
                status = marshall_sec_desc(values, info2->secdesc_buf->sd,
 
465
                                           &blob.data, &blob.length);
 
466
                if (NT_STATUS_IS_OK(status)) {
 
467
                        regval_ctr_addvalue(values, "Security", REG_BINARY,
 
468
                                            (const char *)blob.data, blob.length);
 
469
                }
 
470
        }
 
471
 
 
472
        return;
 
473
}
 
474
 
 
475
/**********************************************************************
 
476
 *********************************************************************/
 
477
 
 
478
static int key_printers_fetch_values( const char *key, REGVAL_CTR *values )
 
479
{
 
480
        int             num_values;
 
481
        char            *printers_key;
 
482
        char            *printername, *printerdatakey;
 
483
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
 
484
        NT_PRINTER_DATA *p_data;
 
485
        int             i, key_index;
 
486
        
 
487
        printers_key = strip_printers_prefix( key );    
 
488
        
 
489
        /* top level key values stored in the registry has no values */
 
490
        
 
491
        if ( !printers_key ) {
 
492
                /* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' key */
 
493
                return regdb_fetch_values( KEY_WINNT_PRINTERS, values );
 
494
        }
 
495
        
 
496
        /* lookup the printer object */
 
497
        
 
498
        if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
 
499
                return -1;
 
500
        }
 
501
        
 
502
        if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
 
503
                goto done;
 
504
                
 
505
        if ( !printerdatakey ) {
 
506
                fill_in_printer_values( printer->info_2, values );
 
507
                goto done;
 
508
        }
 
509
                
 
510
        /* iterate over all printer data keys and fill the regval container */
 
511
        
 
512
        p_data = printer->info_2->data;
 
513
        if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1  ) {
 
514
                /* failure....should never happen if the client has a valid open handle first */
 
515
                DEBUG(10,("key_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey));
 
516
                free_a_printer( &printer, 2 );
 
517
                return -1;
 
518
        }
 
519
        
 
520
        num_values = regval_ctr_numvals( p_data->keys[key_index].values );      
 
521
        for ( i=0; i<num_values; i++ )
 
522
                regval_ctr_copyvalue( values, regval_ctr_specific_value(p_data->keys[key_index].values, i) );
 
523
                        
 
524
 
 
525
done:
 
526
        if ( printer )
 
527
                free_a_printer( &printer, 2 );
 
528
                
 
529
        return regval_ctr_numvals( values );
 
530
}
 
531
 
 
532
/**********************************************************************
 
533
 *********************************************************************/
 
534
 
 
535
#define REG_IDX_ATTRIBUTES              1
 
536
#define REG_IDX_PRIORITY                2
 
537
#define REG_IDX_DEFAULT_PRIORITY        3
 
538
#define REG_IDX_CHANGEID                4
 
539
#define REG_IDX_STATUS                  5
 
540
#define REG_IDX_STARTTIME               6
 
541
#define REG_IDX_NAME                    7
 
542
#define REG_IDX_LOCATION                8
 
543
#define REG_IDX_DESCRIPTION             9
 
544
#define REG_IDX_PARAMETERS              10
 
545
#define REG_IDX_PORT                    12
 
546
#define REG_IDX_SHARENAME               13
 
547
#define REG_IDX_DRIVER                  14
 
548
#define REG_IDX_SEP_FILE                15
 
549
#define REG_IDX_PRINTPROC               16
 
550
#define REG_IDX_DATATYPE                17
 
551
#define REG_IDX_DEVMODE                 18
 
552
#define REG_IDX_SECDESC                 19
 
553
#define REG_IDX_UNTILTIME               20
 
554
 
 
555
struct {
 
556
        const char *name;
 
557
        int index;      
 
558
} printer_values_map[] = {
 
559
        { "Attributes",         REG_IDX_ATTRIBUTES },
 
560
        { "Priority",           REG_IDX_PRIORITY },
 
561
        { "Default Priority",   REG_IDX_DEFAULT_PRIORITY },
 
562
        { "ChangeID",           REG_IDX_CHANGEID },
 
563
        { "Status",             REG_IDX_STATUS },
 
564
        { "StartTime",          REG_IDX_STARTTIME },
 
565
        { "UntilTime",          REG_IDX_UNTILTIME },
 
566
        { "Name",               REG_IDX_NAME },
 
567
        { "Location",           REG_IDX_LOCATION },
 
568
        { "Description",        REG_IDX_DESCRIPTION },
 
569
        { "Parameters",         REG_IDX_PARAMETERS },
 
570
        { "Port",               REG_IDX_PORT },
 
571
        { "Share Name",         REG_IDX_SHARENAME },
 
572
        { "Printer Driver",     REG_IDX_DRIVER },
 
573
        { "Separator File",     REG_IDX_SEP_FILE },
 
574
        { "Print Processor",    REG_IDX_PRINTPROC },
 
575
        { "Datatype",           REG_IDX_DATATYPE },
 
576
        { "Default Devmode",    REG_IDX_DEVMODE },
 
577
        { "Security",           REG_IDX_SECDESC },
 
578
        { NULL, -1 }
 
579
};
 
580
 
 
581
 
 
582
static int find_valuename_index( const char *valuename )
 
583
{
 
584
        int i;
 
585
        
 
586
        for ( i=0; printer_values_map[i].name; i++ ) {
 
587
                if ( strequal( valuename, printer_values_map[i].name ) )
 
588
                        return printer_values_map[i].index;
 
589
        }
 
590
        
 
591
        return -1;
 
592
}
 
593
 
 
594
/**********************************************************************
 
595
 *********************************************************************/
 
596
 
 
597
static void convert_values_to_printer_info_2( NT_PRINTER_INFO_LEVEL_2 *printer2, REGVAL_CTR *values )
 
598
{
 
599
        int num_values = regval_ctr_numvals( values );
 
600
        uint32 value_index;
 
601
        REGISTRY_VALUE *val;
 
602
        int i;
 
603
        
 
604
        for ( i=0; i<num_values; i++ ) {
 
605
                val = regval_ctr_specific_value( values, i );
 
606
                value_index = find_valuename_index( regval_name( val ) );
 
607
                
 
608
                switch( value_index ) {
 
609
                        case REG_IDX_ATTRIBUTES:
 
610
                                printer2->attributes = (uint32)(*regval_data_p(val));
 
611
                                break;
 
612
                        case REG_IDX_PRIORITY:
 
613
                                printer2->priority = (uint32)(*regval_data_p(val));
 
614
                                break;
 
615
                        case REG_IDX_DEFAULT_PRIORITY:
 
616
                                printer2->default_priority = (uint32)(*regval_data_p(val));
 
617
                                break;
 
618
                        case REG_IDX_CHANGEID:
 
619
                                printer2->changeid = (uint32)(*regval_data_p(val));
 
620
                                break;
 
621
                        case REG_IDX_STARTTIME:
 
622
                                printer2->starttime = (uint32)(*regval_data_p(val));
 
623
                                break;
 
624
                        case REG_IDX_UNTILTIME:
 
625
                                printer2->untiltime = (uint32)(*regval_data_p(val));
 
626
                                break;
 
627
                        case REG_IDX_NAME:
 
628
                                rpcstr_pull( printer2->printername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
629
                                break;
 
630
                        case REG_IDX_LOCATION:
 
631
                                rpcstr_pull( printer2->location, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
632
                                break;
 
633
                        case REG_IDX_DESCRIPTION:
 
634
                                rpcstr_pull( printer2->comment, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
635
                                break;
 
636
                        case REG_IDX_PARAMETERS:
 
637
                                rpcstr_pull( printer2->parameters, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
638
                                break;
 
639
                        case REG_IDX_PORT:
 
640
                                rpcstr_pull( printer2->portname, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
641
                                break;
 
642
                        case REG_IDX_SHARENAME:
 
643
                                rpcstr_pull( printer2->sharename, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
644
                                break;
 
645
                        case REG_IDX_DRIVER:
 
646
                                rpcstr_pull( printer2->drivername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
647
                                break;
 
648
                        case REG_IDX_SEP_FILE:
 
649
                                rpcstr_pull( printer2->sepfile, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
650
                                break;
 
651
                        case REG_IDX_PRINTPROC:
 
652
                                rpcstr_pull( printer2->printprocessor, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
653
                                break;
 
654
                        case REG_IDX_DATATYPE:
 
655
                                rpcstr_pull( printer2->datatype, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
 
656
                                break;
 
657
                        case REG_IDX_DEVMODE:
 
658
                                break;
 
659
                        case REG_IDX_SECDESC:
 
660
                                break;          
 
661
                        default:
 
662
                                /* unsupported value...throw away */
 
663
                                DEBUG(8,("convert_values_to_printer_info_2: Unsupported registry value [%s]\n", 
 
664
                                        regval_name( val ) ));
 
665
                }
 
666
        }
 
667
        
 
668
        return;
 
669
}       
 
670
 
 
671
/**********************************************************************
 
672
 *********************************************************************/
 
673
 
 
674
static bool key_printers_store_values( const char *key, REGVAL_CTR *values )
 
675
{
 
676
        char *printers_key;
 
677
        char *printername, *keyname;
 
678
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
 
679
        WERROR result;
 
680
        
 
681
        printers_key = strip_printers_prefix( key );
 
682
        
 
683
        /* values in the top level key get stored in the registry */
 
684
 
 
685
        if ( !printers_key ) {
 
686
                /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
 
687
                return regdb_store_values( KEY_WINNT_PRINTERS, values );
 
688
        }
 
689
        
 
690
        if (!reg_split_path( printers_key, &printername, &keyname )) {
 
691
                return False;
 
692
        }
 
693
 
 
694
        if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername) ) )
 
695
                return False;
 
696
 
 
697
        /* deal with setting values directly under the printername */
 
698
 
 
699
        if ( !keyname ) {
 
700
                convert_values_to_printer_info_2( printer->info_2, values );
 
701
        }
 
702
        else {
 
703
                int num_values = regval_ctr_numvals( values );
 
704
                int i;
 
705
                REGISTRY_VALUE *val;
 
706
                
 
707
                delete_printer_key( printer->info_2->data, keyname );
 
708
                
 
709
                /* deal with any subkeys */
 
710
                for ( i=0; i<num_values; i++ ) {
 
711
                        val = regval_ctr_specific_value( values, i );
 
712
                        result = set_printer_dataex( printer, keyname, 
 
713
                                regval_name( val ),
 
714
                                regval_type( val ),
 
715
                                regval_data_p( val ),
 
716
                                regval_size( val ) );
 
717
                        if ( !W_ERROR_IS_OK(result) ) {
 
718
                                DEBUG(0,("key_printers_store_values: failed to set printer data [%s]!\n",
 
719
                                        keyname));
 
720
                                free_a_printer( &printer, 2 );
 
721
                                return False;
 
722
                        }
 
723
                }
 
724
        }
 
725
 
 
726
        result = mod_a_printer( printer, 2 );
 
727
 
 
728
        free_a_printer( &printer, 2 );
 
729
 
 
730
        return W_ERROR_IS_OK(result);
 
731
}
 
732
 
 
733
/*********************************************************************
 
734
 *********************************************************************
 
735
 ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS"
 
736
 *********************************************************************
 
737
 *********************************************************************/
 
738
 
 
739
static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
 
740
{
 
741
        const char *environments[] = {
 
742
                "Windows 4.0",
 
743
                "Windows NT x86",
 
744
                "Windows NT R4000",
 
745
                "Windows NT Alpha_AXP",
 
746
                "Windows NT PowerPC",
 
747
                "Windows IA64",
 
748
                "Windows x64",
 
749
                NULL };
 
750
        fstring *drivers = NULL;
 
751
        int i, env_index, num_drivers;
 
752
        char *keystr, *base, *subkeypath;
 
753
        char *key2 = NULL;
 
754
        int num_subkeys = -1;
 
755
        int version;
 
756
        TALLOC_CTX *ctx = talloc_tos();
 
757
 
 
758
        DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" ));
 
759
 
 
760
        keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS) );
 
761
 
 
762
        /* list all possible architectures */
 
763
 
 
764
        if ( !keystr ) {
 
765
                for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ )
 
766
                        regsubkey_ctr_addkey( subkeys,  environments[num_subkeys] );
 
767
 
 
768
                return num_subkeys;
 
769
        }
 
770
 
 
771
        /* we are dealing with a subkey of "Environments */
 
772
        key2 = talloc_strdup(ctx, keystr);
 
773
        if (!key2) {
 
774
                return -1;
 
775
        }
 
776
        keystr = key2;
 
777
        if (!reg_split_path(keystr, &base, &subkeypath )) {
 
778
                return -1;
 
779
        }
 
780
 
 
781
        /* sanity check */
 
782
 
 
783
        for ( env_index=0; environments[env_index]; env_index++ ) {
 
784
                if ( strequal( environments[env_index], base ) )
 
785
                        break;
 
786
        }
 
787
        if ( !environments[env_index] )
 
788
                return -1;
 
789
 
 
790
        /* ...\Print\Environements\...\ */
 
791
 
 
792
        if ( !subkeypath ) {
 
793
                regsubkey_ctr_addkey( subkeys, "Drivers" );
 
794
                regsubkey_ctr_addkey( subkeys, "Print Processors" );
 
795
 
 
796
                return 2;
 
797
        }
 
798
 
 
799
        /* more of the key path to process */
 
800
 
 
801
        keystr = subkeypath;
 
802
        if (!reg_split_path( keystr, &base, &subkeypath )) {
 
803
                return -1;
 
804
        }
 
805
 
 
806
        /* ...\Print\Environements\...\Drivers\ */
 
807
 
 
808
        if ( !subkeypath ) {
 
809
                if ( strequal(base, "Drivers") ) {
 
810
                        switch ( env_index ) {
 
811
                                case 0: /* Win9x */
 
812
                                        regsubkey_ctr_addkey( subkeys, "Version-0" );
 
813
                                        break;
 
814
                                default: /* Windows NT based systems */
 
815
                                        regsubkey_ctr_addkey( subkeys, "Version-2" );
 
816
                                        regsubkey_ctr_addkey( subkeys, "Version-3" );
 
817
                                        break;
 
818
                        }
 
819
 
 
820
                        return regsubkey_ctr_numkeys( subkeys );
 
821
                } else if ( strequal(base, "Print Processors") ) {
 
822
                        if ( env_index == 1 || env_index == 5 || env_index == 6 )
 
823
 
 
824
 
 
825
                        return regsubkey_ctr_numkeys( subkeys );
 
826
                } else
 
827
                        return -1;      /* bad path */
 
828
        }
 
829
 
 
830
        /* we finally get to enumerate the drivers */
 
831
 
 
832
        /* only one possible subkey below PrintProc key */
 
833
 
 
834
        if ( strequal(base, "Print Processors") ) {
 
835
                keystr = subkeypath;
 
836
                if (!reg_split_path( keystr, &base, &subkeypath )) {
 
837
                        return -1;
 
838
                }
 
839
 
 
840
                /* no subkeys below this point */
 
841
 
 
842
                if ( subkeypath )
 
843
                        return -1;
 
844
 
 
845
                /* only allow one keyname here -- 'winprint' */
 
846
 
 
847
                return strequal( base, "winprint" ) ? 0 : -1;
 
848
        }
 
849
 
 
850
        /* only dealing with drivers from here on out */
 
851
 
 
852
        keystr = subkeypath;
 
853
        if (!reg_split_path( keystr, &base, &subkeypath )) {
 
854
                return -1;
 
855
        }
 
856
 
 
857
        version = atoi(&base[strlen(base)-1]);
 
858
 
 
859
        switch (env_index) {
 
860
        case 0:
 
861
                if ( version != 0 )
 
862
                        return -1;
 
863
                break;
 
864
        default:
 
865
                if ( version != 2 && version != 3 )
 
866
                        return -1;
 
867
                break;
 
868
        }
 
869
 
 
870
 
 
871
        if ( !subkeypath ) {
 
872
                num_drivers = get_ntdrivers( &drivers, environments[env_index], version );
 
873
                for ( i=0; i<num_drivers; i++ )
 
874
                        regsubkey_ctr_addkey( subkeys, drivers[i] );
 
875
 
 
876
                return regsubkey_ctr_numkeys( subkeys );
 
877
        }
 
878
 
 
879
        /* if anything else left, just say if has no subkeys */
 
880
 
 
881
        DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s)\n",
 
882
                key, subkeypath ));
 
883
 
 
884
        return 0;
 
885
}
 
886
 
 
887
 
 
888
/**********************************************************************
 
889
 *********************************************************************/
 
890
 
 
891
static void fill_in_driver_values( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, REGVAL_CTR *values )
 
892
{
 
893
        char *buffer = NULL;
 
894
        int buffer_size = 0;
 
895
        int i, length;
 
896
        const char *filename;
 
897
        UNISTR2 data;
 
898
 
 
899
        filename = dos_basename( info3->driverpath );
 
900
        init_unistr2( &data, filename, UNI_STR_TERMINATE);
 
901
        regval_ctr_addvalue( values, "Driver", REG_SZ, (char*)data.buffer,
 
902
                data.uni_str_len*sizeof(uint16) );
 
903
 
 
904
        filename = dos_basename( info3->configfile );
 
905
        init_unistr2( &data, filename, UNI_STR_TERMINATE);
 
906
        regval_ctr_addvalue( values, "Configuration File", REG_SZ, (char*)data.buffer, 
 
907
                data.uni_str_len*sizeof(uint16) );
 
908
 
 
909
        filename = dos_basename( info3->datafile );
 
910
        init_unistr2( &data, filename, UNI_STR_TERMINATE);
 
911
        regval_ctr_addvalue( values, "Data File", REG_SZ, (char*)data.buffer,
 
912
                data.uni_str_len*sizeof(uint16) );
 
913
 
 
914
        filename = dos_basename( info3->helpfile );
 
915
        init_unistr2( &data, filename, UNI_STR_TERMINATE);
 
916
        regval_ctr_addvalue( values, "Help File", REG_SZ, (char*)data.buffer,
 
917
                data.uni_str_len*sizeof(uint16) );
 
918
 
 
919
        init_unistr2( &data, info3->defaultdatatype, UNI_STR_TERMINATE);
 
920
        regval_ctr_addvalue( values, "Data Type", REG_SZ, (char*)data.buffer,
 
921
                data.uni_str_len*sizeof(uint16) );
 
922
 
 
923
        regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&info3->cversion, 
 
924
                sizeof(info3->cversion) );
 
925
 
 
926
        if ( info3->dependentfiles ) {
 
927
                /* place the list of dependent files in a single
 
928
                   character buffer, separating each file name by
 
929
                   a NULL */
 
930
 
 
931
                for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ ) {
 
932
                        /* strip the path to only the file's base name */
 
933
 
 
934
                        filename = dos_basename( info3->dependentfiles[i] );
 
935
 
 
936
                        length = strlen(filename);
 
937
 
 
938
                        buffer = (char *)SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) );
 
939
                        if ( !buffer ) {
 
940
                                break;
 
941
                        }
 
942
 
 
943
                        init_unistr2( &data, filename, UNI_STR_TERMINATE);
 
944
                        memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
945
 
 
946
                        buffer_size += (length + 1)*sizeof(uint16);
 
947
                }
 
948
 
 
949
                /* terminated by double NULL.  Add the final one here */
 
950
 
 
951
                buffer = (char *)SMB_REALLOC( buffer, buffer_size + 2 );
 
952
                if ( !buffer ) {
 
953
                        buffer_size = 0;
 
954
                } else {
 
955
                        buffer[buffer_size++] = '\0';
 
956
                        buffer[buffer_size++] = '\0';
 
957
                }
 
958
        }
 
959
 
 
960
        regval_ctr_addvalue( values, "Dependent Files",    REG_MULTI_SZ, buffer, buffer_size );
 
961
 
 
962
        SAFE_FREE( buffer );
 
963
 
 
964
        return;
 
965
}
 
966
 
 
967
/**********************************************************************
 
968
 *********************************************************************/
 
969
 
 
970
static int driver_arch_fetch_values( char *key, REGVAL_CTR *values )
 
971
{
 
972
        char            *keystr, *base, *subkeypath;
 
973
        fstring         arch_environment;
 
974
        fstring         driver;
 
975
        int             version;
 
976
        NT_PRINTER_DRIVER_INFO_LEVEL    driver_ctr;
 
977
        WERROR          w_result;
 
978
 
 
979
        if (!reg_split_path( key, &base, &subkeypath )) {
 
980
                return -1;
 
981
        }
 
982
 
 
983
        /* no values in 'Environments\Drivers\Windows NT x86' */
 
984
 
 
985
        if ( !subkeypath )
 
986
                return 0;
 
987
 
 
988
        /* We have the Architecture string and some subkey name:
 
989
           Currently we only support
 
990
           * Drivers
 
991
           * Print Processors
 
992
           Anything else is an error.
 
993
           */
 
994
 
 
995
        fstrcpy( arch_environment, base );
 
996
 
 
997
        keystr = subkeypath;
 
998
        if (!reg_split_path( keystr, &base, &subkeypath )) {
 
999
                return -1;
 
1000
        }
 
1001
 
 
1002
        if ( strequal(base, "Print Processors") )
 
1003
                return 0;
 
1004
 
 
1005
        /* only Drivers key can be left */
 
1006
 
 
1007
        if ( !strequal(base, "Drivers") )
 
1008
                return -1;
 
1009
 
 
1010
        if ( !subkeypath )
 
1011
                return 0;
 
1012
 
 
1013
        /* We know that we have Architechure\Drivers with some subkey name
 
1014
           The subkey name has to be Version-XX */
 
1015
 
 
1016
        keystr = subkeypath;
 
1017
        if (!reg_split_path( keystr, &base, &subkeypath )) {
 
1018
                return -1;
 
1019
        }
 
1020
 
 
1021
        if ( !subkeypath )
 
1022
                return 0;
 
1023
 
 
1024
        version = atoi(&base[strlen(base)-1]);
 
1025
 
 
1026
        /* BEGIN PRINTER DRIVER NAME BLOCK */
 
1027
 
 
1028
        keystr = subkeypath;
 
1029
        if (!reg_split_path( keystr, &base, &subkeypath )) {
 
1030
                return -1;
 
1031
        }
 
1032
 
 
1033
        /* don't go any deeper for now */
 
1034
 
 
1035
        fstrcpy( driver, base );
 
1036
 
 
1037
        w_result = get_a_printer_driver( &driver_ctr, 3, driver, arch_environment, version );
 
1038
 
 
1039
        if ( !W_ERROR_IS_OK(w_result) )
 
1040
                return -1;
 
1041
 
 
1042
        fill_in_driver_values( driver_ctr.info_3, values );
 
1043
 
 
1044
        free_a_printer_driver( driver_ctr, 3 );
 
1045
 
 
1046
        /* END PRINTER DRIVER NAME BLOCK */
 
1047
 
 
1048
 
 
1049
        DEBUG(8,("key_driver_fetch_values: Exit\n"));
 
1050
 
 
1051
        return regval_ctr_numvals( values );
 
1052
}
 
1053
 
 
1054
/**********************************************************************
 
1055
 *********************************************************************/
 
1056
 
 
1057
static int key_driver_fetch_values( const char *key, REGVAL_CTR *values )
 
1058
{
 
1059
        char *keystr = NULL;
 
1060
        char *subkey = NULL;
 
1061
        TALLOC_CTX *ctx = talloc_tos();
 
1062
 
 
1063
        DEBUG(8,("key_driver_fetch_values: Enter key => [%s]\n", key ? key : "NULL"));
 
1064
 
 
1065
        /* no values in the Environments key */
 
1066
 
 
1067
        if (!(keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS))))
 
1068
                return 0;
 
1069
 
 
1070
        subkey = talloc_strdup(ctx, keystr);
 
1071
        if (!subkey) {
 
1072
                return 0;
 
1073
        }
 
1074
 
 
1075
        /* pass off to handle subkeys */
 
1076
 
 
1077
        return driver_arch_fetch_values( subkey, values );
 
1078
}
 
1079
 
 
1080
/*********************************************************************
 
1081
 *********************************************************************
 
1082
 ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT"
 
1083
 *********************************************************************
 
1084
 *********************************************************************/
 
1085
 
 
1086
static int key_print_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
 
1087
{
 
1088
        int key_len = strlen(key);
 
1089
 
 
1090
        /* no keys below 'Print' handled here */
 
1091
 
 
1092
        if ( (key_len != strlen(KEY_CONTROL_PRINT)) && (key_len != strlen(KEY_WINNT_PRINT)) )
 
1093
                return -1;
 
1094
 
 
1095
        regsubkey_ctr_addkey( subkeys, "Environments" );
 
1096
        regsubkey_ctr_addkey( subkeys, "Monitors" );
 
1097
        regsubkey_ctr_addkey( subkeys, "Forms" );
 
1098
        regsubkey_ctr_addkey( subkeys, "Printers" );
 
1099
 
 
1100
        return regsubkey_ctr_numkeys( subkeys );
 
1101
}
 
1102
 
 
1103
/**********************************************************************
 
1104
 *********************************************************************
 
1105
 ** Structure to hold dispatch table of ops for various printer keys.
 
1106
 ** Make sure to always store deeper keys along the same path first so
 
1107
 ** we ge a more specific match.
 
1108
 *********************************************************************
 
1109
 *********************************************************************/
 
1110
 
 
1111
static struct reg_dyn_tree print_registry[] = {
 
1112
/* just pass the monitor onto the registry tdb */
 
1113
{ KEY_MONITORS,
 
1114
        &regdb_fetch_keys,
 
1115
        &regdb_store_keys,
 
1116
        &regdb_fetch_values,
 
1117
        &regdb_store_values },
 
1118
{ KEY_FORMS,
 
1119
        &key_forms_fetch_keys,
 
1120
        NULL,
 
1121
        &key_forms_fetch_values,
 
1122
        NULL },
 
1123
{ KEY_CONTROL_PRINTERS,
 
1124
        &key_printers_fetch_keys,
 
1125
        &key_printers_store_keys,
 
1126
        &key_printers_fetch_values,
 
1127
        &key_printers_store_values },
 
1128
{ KEY_ENVIRONMENTS,
 
1129
        &key_driver_fetch_keys,
 
1130
        NULL,
 
1131
        &key_driver_fetch_values,
 
1132
        NULL },
 
1133
{ KEY_CONTROL_PRINT,
 
1134
        &key_print_fetch_keys,
 
1135
        NULL,
 
1136
        NULL,
 
1137
        NULL },
 
1138
{ KEY_WINNT_PRINTERS,
 
1139
        &key_printers_fetch_keys,
 
1140
        &key_printers_store_keys,
 
1141
        &key_printers_fetch_values,
 
1142
        &key_printers_store_values },
 
1143
{ KEY_PORTS,
 
1144
        &regdb_fetch_keys,
 
1145
        &regdb_store_keys,
 
1146
        &regdb_fetch_values,
 
1147
        &regdb_store_values },
 
1148
 
 
1149
{ NULL, NULL, NULL, NULL, NULL }
 
1150
};
 
1151
 
 
1152
 
 
1153
/**********************************************************************
 
1154
 *********************************************************************
 
1155
 ** Main reg_printing interface functions
 
1156
 *********************************************************************
 
1157
 *********************************************************************/
 
1158
 
 
1159
/***********************************************************************
 
1160
 Lookup a key in the print_registry table, returning its index.
 
1161
 -1 on failure
 
1162
 **********************************************************************/
 
1163
 
 
1164
static int match_registry_path(const char *key)
 
1165
{
 
1166
        int i;
 
1167
        char *path = NULL;
 
1168
        TALLOC_CTX *ctx = talloc_tos();
 
1169
 
 
1170
        if ( !key )
 
1171
                return -1;
 
1172
 
 
1173
        path = talloc_strdup(ctx, key);
 
1174
        if (!path) {
 
1175
                return -1;
 
1176
        }
 
1177
        path = normalize_reg_path(ctx, path);
 
1178
        if (!path) {
 
1179
                return -1;
 
1180
        }
 
1181
 
 
1182
        for ( i=0; print_registry[i].path; i++ ) {
 
1183
                if (strncmp( path, print_registry[i].path, strlen(print_registry[i].path) ) == 0 )
 
1184
                        return i;
 
1185
        }
 
1186
 
 
1187
        return -1;
 
1188
}
 
1189
 
 
1190
/***********************************************************************
 
1191
 **********************************************************************/
 
1192
 
 
1193
static int regprint_fetch_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
 
1194
{
 
1195
        int i = match_registry_path( key );
 
1196
 
 
1197
        if ( i == -1 )
 
1198
                return -1;
 
1199
 
 
1200
        if ( !print_registry[i].fetch_subkeys )
 
1201
                return -1;
 
1202
 
 
1203
        return print_registry[i].fetch_subkeys( key, subkeys );
 
1204
}
 
1205
 
 
1206
/**********************************************************************
 
1207
 *********************************************************************/
 
1208
 
 
1209
static bool regprint_store_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
 
1210
{
 
1211
        int i = match_registry_path( key );
 
1212
 
 
1213
        if ( i == -1 )
 
1214
                return False;
 
1215
 
 
1216
        if ( !print_registry[i].store_subkeys )
 
1217
                return False;
 
1218
 
 
1219
        return print_registry[i].store_subkeys( key, subkeys );
 
1220
}
 
1221
 
 
1222
/**********************************************************************
 
1223
 *********************************************************************/
 
1224
 
 
1225
static int regprint_fetch_reg_values( const char *key, REGVAL_CTR *values )
 
1226
{
 
1227
        int i = match_registry_path( key );
 
1228
 
 
1229
        if ( i == -1 )
 
1230
                return -1;
 
1231
 
 
1232
        /* return 0 values by default since we know the key had
 
1233
           to exist because the client opened a handle */
 
1234
 
 
1235
        if ( !print_registry[i].fetch_values )
 
1236
                return 0;
 
1237
 
 
1238
        return print_registry[i].fetch_values( key, values );
 
1239
}
 
1240
 
 
1241
/**********************************************************************
 
1242
 *********************************************************************/
 
1243
 
 
1244
static bool regprint_store_reg_values( const char *key, REGVAL_CTR *values )
 
1245
{
 
1246
        int i = match_registry_path( key );
 
1247
 
 
1248
        if ( i == -1 )
 
1249
                return False;
 
1250
 
 
1251
        if ( !print_registry[i].store_values )
 
1252
                return False;
 
1253
 
 
1254
        return print_registry[i].store_values( key, values );
 
1255
}
 
1256
 
 
1257
/*
 
1258
 * Table of function pointers for accessing printing data
 
1259
 */
 
1260
 
 
1261
REGISTRY_OPS printing_ops = {
 
1262
        .fetch_subkeys = regprint_fetch_reg_keys,
 
1263
        .fetch_values = regprint_fetch_reg_values,
 
1264
        .store_subkeys = regprint_store_reg_keys,
 
1265
        .store_values = regprint_store_reg_values,
 
1266
};