00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025 #undef DBGC_CLASS
00026 #define DBGC_CLASS DBGC_RPC_SRV
00027
00028
00029
00030 #define KEY_MONITORS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/MONITORS"
00031 #define KEY_FORMS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS"
00032 #define KEY_CONTROL_PRINTERS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
00033 #define KEY_ENVIRONMENTS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS"
00034 #define KEY_CONTROL_PRINT "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT"
00035 #define KEY_WINNT_PRINTERS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
00036 #define KEY_WINNT_PRINT "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT"
00037 #define KEY_PORTS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PORTS"
00038
00039
00040
00041 struct reg_dyn_tree {
00042
00043 const char *path;
00044
00045
00046 int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys );
00047 BOOL (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys );
00048 int (*fetch_values) ( const char *path, REGVAL_CTR *values );
00049 BOOL (*store_values) ( const char *path, REGVAL_CTR *values );
00050 };
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static char* dos_basename ( char *path )
00063 {
00064 char *p;
00065
00066 if ( !(p = strrchr( path, '\\' )) )
00067 p = path;
00068 else
00069 p++;
00070
00071 return p;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 static int key_forms_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
00081 {
00082 char *p = reg_remaining_path( key + strlen(KEY_FORMS) );
00083
00084
00085
00086 if ( p )
00087 return -1;
00088
00089 return 0;
00090 }
00091
00092
00093
00094
00095 static int key_forms_fetch_values( const char *key, REGVAL_CTR *values )
00096 {
00097 uint32 data[8];
00098 int i, num_values, form_index = 1;
00099 nt_forms_struct *forms_list = NULL;
00100 nt_forms_struct *form;
00101
00102 DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" ));
00103
00104 num_values = get_ntforms( &forms_list );
00105
00106 DEBUG(10,("hive_forms_fetch_values: [%d] user defined forms returned\n",
00107 num_values));
00108
00109
00110
00111 for ( i=0; i<num_values; i++ ) {
00112 form = &forms_list[i];
00113
00114 data[0] = form->width;
00115 data[1] = form->length;
00116 data[2] = form->left;
00117 data[3] = form->top;
00118 data[4] = form->right;
00119 data[5] = form->bottom;
00120 data[6] = form_index++;
00121 data[7] = form->flag;
00122
00123 regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) );
00124 }
00125
00126 SAFE_FREE( forms_list );
00127 forms_list = NULL;
00128
00129
00130
00131 num_values = get_builtin_ntforms( &forms_list );
00132
00133 DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n",
00134 num_values));
00135
00136 for ( i=0; i<num_values; i++ ) {
00137 form = &forms_list[i];
00138
00139 data[0] = form->width;
00140 data[1] = form->length;
00141 data[2] = form->left;
00142 data[3] = form->top;
00143 data[4] = form->right;
00144 data[5] = form->bottom;
00145 data[6] = form_index++;
00146 data[7] = form->flag;
00147
00148 regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) );
00149 }
00150
00151 SAFE_FREE( forms_list );
00152
00153 return regval_ctr_numvals( values );
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 static char* strip_printers_prefix( const char *key )
00169 {
00170 char *subkeypath;
00171 pstring path;
00172
00173 pstrcpy( path, key );
00174 normalize_reg_path( path );
00175
00176
00177
00178 if ( strncmp( path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS) ) == 0 )
00179 subkeypath = reg_remaining_path( key + strlen(KEY_WINNT_PRINTERS) );
00180 else
00181 subkeypath = reg_remaining_path( key + strlen(KEY_CONTROL_PRINTERS) );
00182
00183 return subkeypath;
00184 }
00185
00186
00187
00188
00189 static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
00190 {
00191 int n_services = lp_numservices();
00192 int snum;
00193 fstring sname;
00194 int i;
00195 int num_subkeys = 0;
00196 char *printers_key;
00197 char *printername, *printerdatakey;
00198 NT_PRINTER_INFO_LEVEL *printer = NULL;
00199 fstring *subkey_names = NULL;
00200
00201 DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" ));
00202
00203 printers_key = strip_printers_prefix( key );
00204
00205 if ( !printers_key ) {
00206
00207
00208 for (snum=0; snum<n_services; snum++) {
00209 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
00210 continue;
00211
00212
00213
00214 if ( strequal( lp_servicename(snum), PRINTERS_NAME ) )
00215 continue;
00216
00217 fstrcpy( sname, lp_servicename(snum) );
00218
00219 regsubkey_ctr_addkey( subkeys, sname );
00220 }
00221
00222 num_subkeys = regsubkey_ctr_numkeys( subkeys );
00223 goto done;
00224 }
00225
00226
00227
00228 if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
00229 return -1;
00230 }
00231
00232
00233
00234 for (snum=0; snum<n_services; snum++) {
00235 if ( !lp_snum_ok(snum) || !lp_print_ok(snum) )
00236 continue;
00237 if (strequal( lp_servicename(snum), printername ) )
00238 break;
00239 }
00240
00241 if ( snum>=n_services
00242 || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
00243 {
00244 return -1;
00245 }
00246
00247 num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names );
00248
00249 for ( i=0; i<num_subkeys; i++ )
00250 regsubkey_ctr_addkey( subkeys, subkey_names[i] );
00251
00252 free_a_printer( &printer, 2 );
00253
00254
00255
00256 done:
00257 SAFE_FREE( subkey_names );
00258
00259 return num_subkeys;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268 static BOOL add_printers_by_registry( REGSUBKEY_CTR *subkeys )
00269 {
00270 int i, num_keys, snum;
00271 char *printername;
00272 NT_PRINTER_INFO_LEVEL_2 info2;
00273 NT_PRINTER_INFO_LEVEL printer;
00274
00275 ZERO_STRUCT( info2 );
00276 printer.info_2 = &info2;
00277
00278 num_keys = regsubkey_ctr_numkeys( subkeys );
00279
00280 become_root();
00281 for ( i=0; i<num_keys; i++ ) {
00282 printername = regsubkey_ctr_specific_key( subkeys, i );
00283 snum = find_service( printername );
00284
00285
00286 if ( snum == -1 ) {
00287 fstrcpy( info2.printername, printername );
00288 fstrcpy( info2.sharename, printername );
00289 if ( !add_printer_hook( NULL, &printer ) ) {
00290 DEBUG(0,("add_printers_by_registry: Failed to add printer [%s]\n",
00291 printername));
00292 }
00293 }
00294 }
00295 unbecome_root();
00296
00297 return True;
00298 }
00299
00300
00301
00302
00303 static BOOL key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
00304 {
00305 char *printers_key;
00306 char *printername, *printerdatakey;
00307 NT_PRINTER_INFO_LEVEL *printer = NULL;
00308 int i, num_subkeys, num_existing_keys;
00309 char *subkeyname;
00310 fstring *existing_subkeys = NULL;
00311
00312 printers_key = strip_printers_prefix( key );
00313
00314 if ( !printers_key ) {
00315
00316 return add_printers_by_registry( subkeys );
00317 }
00318
00319 if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
00320 return False;
00321 }
00322
00323
00324
00325 if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername)) ) {
00326 DEBUG(0,("key_printers_store_keys: Tried to store subkey for bad printername %s\n",
00327 printername));
00328 return False;
00329 }
00330
00331
00332
00333 num_existing_keys = get_printer_subkeys( printer->info_2->data, "", &existing_subkeys );
00334
00335 for ( i=0; i<num_existing_keys; i++ ) {
00336
00337
00338
00339 if ( !regsubkey_ctr_key_exists( subkeys, existing_subkeys[i] ) ) {
00340 DEBUG(5,("key_printers_store_keys: deleting key %s\n",
00341 existing_subkeys[i]));
00342 delete_printer_key( printer->info_2->data, existing_subkeys[i] );
00343 }
00344 }
00345
00346 num_subkeys = regsubkey_ctr_numkeys( subkeys );
00347 for ( i=0; i<num_subkeys; i++ ) {
00348 subkeyname = regsubkey_ctr_specific_key(subkeys, i);
00349
00350 if ( lookup_printerkey(printer->info_2->data, subkeyname) == -1 ) {
00351 DEBUG(5,("key_printers_store_keys: adding key %s\n",
00352 existing_subkeys[i]));
00353 if ( add_new_printer_key( printer->info_2->data, subkeyname ) == -1 ) {
00354 SAFE_FREE( existing_subkeys );
00355 return False;
00356 }
00357 }
00358 }
00359
00360
00361
00362 mod_a_printer( printer, 2 );
00363
00364
00365
00366 if ( printer )
00367 free_a_printer( &printer, 2 );
00368
00369 SAFE_FREE( existing_subkeys );
00370
00371 return True;
00372 }
00373
00374
00375
00376
00377 static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values )
00378 {
00379 DEVICEMODE *devmode;
00380 prs_struct prs;
00381 uint32 offset;
00382 UNISTR2 data;
00383 char *p;
00384 uint32 printer_status = PRINTER_STATUS_OK;
00385
00386 regval_ctr_addvalue( values, "Attributes", REG_DWORD, (char*)&info2->attributes, sizeof(info2->attributes) );
00387 regval_ctr_addvalue( values, "Priority", REG_DWORD, (char*)&info2->priority, sizeof(info2->attributes) );
00388 regval_ctr_addvalue( values, "ChangeID", REG_DWORD, (char*)&info2->changeid, sizeof(info2->changeid) );
00389 regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) );
00390
00391
00392 regval_ctr_addvalue( values, "Status", REG_DWORD, (char*)&printer_status, sizeof(info2->status) );
00393
00394 regval_ctr_addvalue( values, "StartTime", REG_DWORD, (char*)&info2->starttime, sizeof(info2->starttime) );
00395 regval_ctr_addvalue( values, "UntilTime", REG_DWORD, (char*)&info2->untiltime, sizeof(info2->untiltime) );
00396
00397
00398 if ( !(p = strrchr( info2->printername, '\\' ) ) )
00399 p = info2->printername;
00400 else
00401 p++;
00402 init_unistr2( &data, p, UNI_STR_TERMINATE);
00403 regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00404
00405 init_unistr2( &data, info2->location, UNI_STR_TERMINATE);
00406 regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00407
00408 init_unistr2( &data, info2->comment, UNI_STR_TERMINATE);
00409 regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00410
00411 init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE);
00412 regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00413
00414 init_unistr2( &data, info2->portname, UNI_STR_TERMINATE);
00415 regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00416
00417 init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE);
00418 regval_ctr_addvalue( values, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00419
00420 init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE);
00421 regval_ctr_addvalue( values, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00422
00423 init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE);
00424 regval_ctr_addvalue( values, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00425
00426 init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE);
00427 regval_ctr_addvalue( values, "Print Processor", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00428
00429 init_unistr2( &data, "RAW", UNI_STR_TERMINATE);
00430 regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00431
00432
00433
00434
00435
00436 prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL);
00437
00438
00439
00440 if ( (devmode = construct_dev_mode( info2->sharename )) != NULL ) {
00441 if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) {
00442 offset = prs_offset( &prs );
00443 regval_ctr_addvalue( values, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset );
00444 }
00445 }
00446
00447 prs_mem_clear( &prs );
00448 prs_set_offset( &prs, 0 );
00449
00450
00451
00452 if ( info2->secdesc_buf && info2->secdesc_buf->len ) {
00453 if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sec, &prs, 0 ) ) {
00454 offset = prs_offset( &prs );
00455 regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset );
00456 }
00457 }
00458
00459 prs_mem_free( &prs );
00460
00461 return;
00462 }
00463
00464
00465
00466
00467 static int key_printers_fetch_values( const char *key, REGVAL_CTR *values )
00468 {
00469 int num_values;
00470 char *printers_key;
00471 char *printername, *printerdatakey;
00472 NT_PRINTER_INFO_LEVEL *printer = NULL;
00473 NT_PRINTER_DATA *p_data;
00474 int i, key_index;
00475
00476 printers_key = strip_printers_prefix( key );
00477
00478
00479
00480 if ( !printers_key ) {
00481
00482 return regdb_fetch_values( KEY_WINNT_PRINTERS, values );
00483 }
00484
00485
00486
00487 if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
00488 return -1;
00489 }
00490
00491 if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
00492 goto done;
00493
00494 if ( !printerdatakey ) {
00495 fill_in_printer_values( printer->info_2, values );
00496 goto done;
00497 }
00498
00499
00500
00501 p_data = printer->info_2->data;
00502 if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1 ) {
00503
00504 DEBUG(10,("key_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey));
00505 if ( printer )
00506 free_a_printer( &printer, 2 );
00507 return -1;
00508 }
00509
00510 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
00511 for ( i=0; i<num_values; i++ )
00512 regval_ctr_copyvalue( values, regval_ctr_specific_value(p_data->keys[key_index].values, i) );
00513
00514
00515 done:
00516 if ( printer )
00517 free_a_printer( &printer, 2 );
00518
00519 return regval_ctr_numvals( values );
00520 }
00521
00522
00523
00524
00525 #define REG_IDX_ATTRIBUTES 1
00526 #define REG_IDX_PRIORITY 2
00527 #define REG_IDX_DEFAULT_PRIORITY 3
00528 #define REG_IDX_CHANGEID 4
00529 #define REG_IDX_STATUS 5
00530 #define REG_IDX_STARTTIME 6
00531 #define REG_IDX_NAME 7
00532 #define REG_IDX_LOCATION 8
00533 #define REG_IDX_DESCRIPTION 9
00534 #define REG_IDX_PARAMETERS 10
00535 #define REG_IDX_PORT 12
00536 #define REG_IDX_SHARENAME 13
00537 #define REG_IDX_DRIVER 14
00538 #define REG_IDX_SEP_FILE 15
00539 #define REG_IDX_PRINTPROC 16
00540 #define REG_IDX_DATATYPE 17
00541 #define REG_IDX_DEVMODE 18
00542 #define REG_IDX_SECDESC 19
00543 #define REG_IDX_UNTILTIME 20
00544
00545 struct {
00546 const char *name;
00547 int index;
00548 } printer_values_map[] = {
00549 { "Attributes", REG_IDX_ATTRIBUTES },
00550 { "Priority", REG_IDX_PRIORITY },
00551 { "Default Priority", REG_IDX_DEFAULT_PRIORITY },
00552 { "ChangeID", REG_IDX_CHANGEID },
00553 { "Status", REG_IDX_STATUS },
00554 { "StartTime", REG_IDX_STARTTIME },
00555 { "UntilTime", REG_IDX_UNTILTIME },
00556 { "Name", REG_IDX_NAME },
00557 { "Location", REG_IDX_LOCATION },
00558 { "Description", REG_IDX_DESCRIPTION },
00559 { "Parameters", REG_IDX_PARAMETERS },
00560 { "Port", REG_IDX_PORT },
00561 { "Share Name", REG_IDX_SHARENAME },
00562 { "Printer Driver", REG_IDX_DRIVER },
00563 { "Separator File", REG_IDX_SEP_FILE },
00564 { "Print Processor", REG_IDX_PRINTPROC },
00565 { "Datatype", REG_IDX_DATATYPE },
00566 { "Default Devmode", REG_IDX_DEVMODE },
00567 { "Security", REG_IDX_SECDESC },
00568 { NULL, -1 }
00569 };
00570
00571
00572 static int find_valuename_index( const char *valuename )
00573 {
00574 int i;
00575
00576 for ( i=0; printer_values_map[i].name; i++ ) {
00577 if ( strequal( valuename, printer_values_map[i].name ) )
00578 return printer_values_map[i].index;
00579 }
00580
00581 return -1;
00582 }
00583
00584
00585
00586
00587 static void convert_values_to_printer_info_2( NT_PRINTER_INFO_LEVEL_2 *printer2, REGVAL_CTR *values )
00588 {
00589 int num_values = regval_ctr_numvals( values );
00590 uint32 value_index;
00591 REGISTRY_VALUE *val;
00592 int i;
00593
00594 for ( i=0; i<num_values; i++ ) {
00595 val = regval_ctr_specific_value( values, i );
00596 value_index = find_valuename_index( regval_name( val ) );
00597
00598 switch( value_index ) {
00599 case REG_IDX_ATTRIBUTES:
00600 printer2->attributes = (uint32)(*regval_data_p(val));
00601 break;
00602 case REG_IDX_PRIORITY:
00603 printer2->priority = (uint32)(*regval_data_p(val));
00604 break;
00605 case REG_IDX_DEFAULT_PRIORITY:
00606 printer2->default_priority = (uint32)(*regval_data_p(val));
00607 break;
00608 case REG_IDX_CHANGEID:
00609 printer2->changeid = (uint32)(*regval_data_p(val));
00610 break;
00611 case REG_IDX_STARTTIME:
00612 printer2->starttime = (uint32)(*regval_data_p(val));
00613 break;
00614 case REG_IDX_UNTILTIME:
00615 printer2->untiltime = (uint32)(*regval_data_p(val));
00616 break;
00617 case REG_IDX_NAME:
00618 rpcstr_pull( printer2->printername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00619 break;
00620 case REG_IDX_LOCATION:
00621 rpcstr_pull( printer2->location, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00622 break;
00623 case REG_IDX_DESCRIPTION:
00624 rpcstr_pull( printer2->comment, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00625 break;
00626 case REG_IDX_PARAMETERS:
00627 rpcstr_pull( printer2->parameters, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00628 break;
00629 case REG_IDX_PORT:
00630 rpcstr_pull( printer2->portname, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00631 break;
00632 case REG_IDX_SHARENAME:
00633 rpcstr_pull( printer2->sharename, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00634 break;
00635 case REG_IDX_DRIVER:
00636 rpcstr_pull( printer2->drivername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00637 break;
00638 case REG_IDX_SEP_FILE:
00639 rpcstr_pull( printer2->sepfile, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00640 break;
00641 case REG_IDX_PRINTPROC:
00642 rpcstr_pull( printer2->printprocessor, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00643 break;
00644 case REG_IDX_DATATYPE:
00645 rpcstr_pull( printer2->datatype, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
00646 break;
00647 case REG_IDX_DEVMODE:
00648 break;
00649 case REG_IDX_SECDESC:
00650 break;
00651 default:
00652
00653 DEBUG(8,("convert_values_to_printer_info_2: Unsupported registry value [%s]\n",
00654 regval_name( val ) ));
00655 }
00656 }
00657
00658 return;
00659 }
00660
00661
00662
00663
00664 static BOOL key_printers_store_values( const char *key, REGVAL_CTR *values )
00665 {
00666 char *printers_key;
00667 char *printername, *keyname;
00668 NT_PRINTER_INFO_LEVEL *printer = NULL;
00669 WERROR result;
00670
00671 printers_key = strip_printers_prefix( key );
00672
00673
00674
00675 if ( !printers_key ) {
00676
00677 return regdb_store_values( KEY_WINNT_PRINTERS, values );
00678 }
00679
00680 if (!reg_split_path( printers_key, &printername, &keyname )) {
00681 return False;
00682 }
00683
00684 if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername) ) )
00685 return False;
00686
00687
00688
00689 if ( !keyname ) {
00690 convert_values_to_printer_info_2( printer->info_2, values );
00691 }
00692 else {
00693 int num_values = regval_ctr_numvals( values );
00694 int i;
00695 REGISTRY_VALUE *val;
00696
00697 delete_printer_key( printer->info_2->data, keyname );
00698
00699
00700 for ( i=0; i<num_values; i++ ) {
00701 val = regval_ctr_specific_value( values, i );
00702 result = set_printer_dataex( printer, keyname,
00703 regval_name( val ),
00704 regval_type( val ),
00705 regval_data_p( val ),
00706 regval_size( val ) );
00707 if ( !W_ERROR_IS_OK(result) ) {
00708 DEBUG(0,("key_printers_store_values: failed to set printer data [%s]!\n",
00709 keyname));
00710 free_a_printer( &printer, 2 );
00711 return False;
00712 }
00713 }
00714 }
00715
00716 result = mod_a_printer( printer, 2 );
00717
00718 free_a_printer( &printer, 2 );
00719
00720 return W_ERROR_IS_OK(result);
00721 }
00722
00723
00724
00725
00726
00727
00728
00729 static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
00730 {
00731 const char *environments[] = {
00732 "Windows 4.0",
00733 "Windows NT x86",
00734 "Windows NT R4000",
00735 "Windows NT Alpha_AXP",
00736 "Windows NT PowerPC",
00737 "Windows IA64",
00738 "Windows x64",
00739 NULL };
00740 fstring *drivers = NULL;
00741 int i, env_index, num_drivers;
00742 char *keystr, *base, *subkeypath;
00743 pstring key2;
00744 int num_subkeys = -1;
00745 int version;
00746
00747 DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" ));
00748
00749 keystr = reg_remaining_path( key + strlen(KEY_ENVIRONMENTS) );
00750
00751
00752
00753 if ( !keystr ) {
00754 for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ )
00755 regsubkey_ctr_addkey( subkeys, environments[num_subkeys] );
00756
00757 return num_subkeys;
00758 }
00759
00760
00761
00762 pstrcpy( key2, keystr );
00763 keystr = key2;
00764 if (!reg_split_path( keystr, &base, &subkeypath )) {
00765 return -1;
00766 }
00767
00768
00769
00770 for ( env_index=0; environments[env_index]; env_index++ ) {
00771 if ( strequal( environments[env_index], base ) )
00772 break;
00773 }
00774 if ( !environments[env_index] )
00775 return -1;
00776
00777
00778
00779 if ( !subkeypath ) {
00780 regsubkey_ctr_addkey( subkeys, "Drivers" );
00781 regsubkey_ctr_addkey( subkeys, "Print Processors" );
00782
00783 return 2;
00784 }
00785
00786
00787
00788 keystr = subkeypath;
00789 if (!reg_split_path( keystr, &base, &subkeypath )) {
00790 return -1;
00791 }
00792
00793
00794
00795 if ( !subkeypath ) {
00796 if ( strequal(base, "Drivers") ) {
00797 switch ( env_index ) {
00798 case 0:
00799 regsubkey_ctr_addkey( subkeys, "Version-0" );
00800 break;
00801 default:
00802 regsubkey_ctr_addkey( subkeys, "Version-2" );
00803 regsubkey_ctr_addkey( subkeys, "Version-3" );
00804 break;
00805 }
00806
00807 return regsubkey_ctr_numkeys( subkeys );
00808 } else if ( strequal(base, "Print Processors") ) {
00809 if ( env_index == 1 || env_index == 5 || env_index == 6 )
00810 regsubkey_ctr_addkey( subkeys, "winprint" );
00811
00812 return regsubkey_ctr_numkeys( subkeys );
00813 } else
00814 return -1;
00815 }
00816
00817
00818
00819
00820
00821 if ( strequal(base, "Print Processors") ) {
00822 keystr = subkeypath;
00823 if (!reg_split_path( keystr, &base, &subkeypath )) {
00824 return -1;
00825 }
00826
00827
00828
00829 if ( subkeypath )
00830 return -1;
00831
00832
00833
00834 return strequal( base, "winprint" ) ? 0 : -1;
00835 }
00836
00837
00838
00839 keystr = subkeypath;
00840 if (!reg_split_path( keystr, &base, &subkeypath )) {
00841 return -1;
00842 }
00843
00844 version = atoi(&base[strlen(base)-1]);
00845
00846 switch (env_index) {
00847 case 0:
00848 if ( version != 0 )
00849 return -1;
00850 break;
00851 default:
00852 if ( version != 2 && version != 3 )
00853 return -1;
00854 break;
00855 }
00856
00857
00858 if ( !subkeypath ) {
00859 num_drivers = get_ntdrivers( &drivers, environments[env_index], version );
00860 for ( i=0; i<num_drivers; i++ )
00861 regsubkey_ctr_addkey( subkeys, drivers[i] );
00862
00863 return regsubkey_ctr_numkeys( subkeys );
00864 }
00865
00866
00867
00868 DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s\n",
00869 key, subkeypath ));
00870
00871 return 0;
00872 }
00873
00874
00875
00876
00877
00878 static void fill_in_driver_values( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, REGVAL_CTR *values )
00879 {
00880 char *buffer = NULL;
00881 int buffer_size = 0;
00882 int i, length;
00883 char *filename;
00884 UNISTR2 data;
00885
00886 filename = dos_basename( info3->driverpath );
00887 init_unistr2( &data, filename, UNI_STR_TERMINATE);
00888 regval_ctr_addvalue( values, "Driver", REG_SZ, (char*)data.buffer,
00889 data.uni_str_len*sizeof(uint16) );
00890
00891 filename = dos_basename( info3->configfile );
00892 init_unistr2( &data, filename, UNI_STR_TERMINATE);
00893 regval_ctr_addvalue( values, "Configuration File", REG_SZ, (char*)data.buffer,
00894 data.uni_str_len*sizeof(uint16) );
00895
00896 filename = dos_basename( info3->datafile );
00897 init_unistr2( &data, filename, UNI_STR_TERMINATE);
00898 regval_ctr_addvalue( values, "Data File", REG_SZ, (char*)data.buffer,
00899 data.uni_str_len*sizeof(uint16) );
00900
00901 filename = dos_basename( info3->helpfile );
00902 init_unistr2( &data, filename, UNI_STR_TERMINATE);
00903 regval_ctr_addvalue( values, "Help File", REG_SZ, (char*)data.buffer,
00904 data.uni_str_len*sizeof(uint16) );
00905
00906 init_unistr2( &data, info3->defaultdatatype, UNI_STR_TERMINATE);
00907 regval_ctr_addvalue( values, "Data Type", REG_SZ, (char*)data.buffer,
00908 data.uni_str_len*sizeof(uint16) );
00909
00910 regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&info3->cversion,
00911 sizeof(info3->cversion) );
00912
00913 if ( info3->dependentfiles ) {
00914
00915
00916
00917
00918 for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ ) {
00919
00920
00921 filename = dos_basename( info3->dependentfiles[i] );
00922
00923 length = strlen(filename);
00924
00925 buffer = (char *)SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) );
00926 if ( !buffer ) {
00927 break;
00928 }
00929
00930 init_unistr2( &data, filename, UNI_STR_TERMINATE);
00931 memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
00932
00933 buffer_size += (length + 1)*sizeof(uint16);
00934 }
00935
00936
00937
00938 buffer = (char *)SMB_REALLOC( buffer, buffer_size + 2 );
00939 if ( !buffer ) {
00940 buffer_size = 0;
00941 } else {
00942 buffer[buffer_size++] = '\0';
00943 buffer[buffer_size++] = '\0';
00944 }
00945 }
00946
00947 regval_ctr_addvalue( values, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size );
00948
00949 SAFE_FREE( buffer );
00950
00951 return;
00952 }
00953
00954
00955
00956
00957 static int driver_arch_fetch_values( char *key, REGVAL_CTR *values )
00958 {
00959 char *keystr, *base, *subkeypath;
00960 fstring arch_environment;
00961 fstring driver;
00962 int version;
00963 NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr;
00964 WERROR w_result;
00965
00966 if (!reg_split_path( key, &base, &subkeypath )) {
00967 return -1;
00968 }
00969
00970
00971
00972 if ( !subkeypath )
00973 return 0;
00974
00975
00976
00977
00978
00979
00980
00981
00982 fstrcpy( arch_environment, base );
00983
00984 keystr = subkeypath;
00985 if (!reg_split_path( keystr, &base, &subkeypath )) {
00986 return -1;
00987 }
00988
00989 if ( strequal(base, "Print Processors") )
00990 return 0;
00991
00992
00993
00994 if ( !strequal(base, "Drivers") )
00995 return -1;
00996
00997 if ( !subkeypath )
00998 return 0;
00999
01000
01001
01002
01003 keystr = subkeypath;
01004 if (!reg_split_path( keystr, &base, &subkeypath )) {
01005 return -1;
01006 }
01007
01008 if ( !subkeypath )
01009 return 0;
01010
01011 version = atoi(&base[strlen(base)-1]);
01012
01013
01014
01015 keystr = subkeypath;
01016 if (!reg_split_path( keystr, &base, &subkeypath )) {
01017 return -1;
01018 }
01019
01020
01021
01022 fstrcpy( driver, base );
01023
01024 w_result = get_a_printer_driver( &driver_ctr, 3, driver, arch_environment, version );
01025
01026 if ( !W_ERROR_IS_OK(w_result) )
01027 return -1;
01028
01029 fill_in_driver_values( driver_ctr.info_3, values );
01030
01031 free_a_printer_driver( driver_ctr, 3 );
01032
01033
01034
01035
01036 DEBUG(8,("key_driver_fetch_values: Exit\n"));
01037
01038 return regval_ctr_numvals( values );
01039 }
01040
01041
01042
01043
01044 static int key_driver_fetch_values( const char *key, REGVAL_CTR *values )
01045 {
01046 char *keystr;
01047 pstring subkey;
01048
01049 DEBUG(8,("key_driver_fetch_values: Enter key => [%s]\n", key ? key : "NULL"));
01050
01051
01052
01053 if ( !(keystr = reg_remaining_path( key + strlen(KEY_ENVIRONMENTS) )) )
01054 return 0;
01055
01056 pstrcpy( subkey, keystr);
01057
01058
01059
01060 return driver_arch_fetch_values( subkey, values );
01061 }
01062
01063
01064
01065
01066
01067
01068
01069 static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
01070 {
01071 int key_len = strlen(key);
01072
01073
01074
01075 if ( (key_len != strlen(KEY_CONTROL_PRINT)) && (key_len != strlen(KEY_WINNT_PRINT)) )
01076 return -1;
01077
01078 regsubkey_ctr_addkey( subkeys, "Environments" );
01079 regsubkey_ctr_addkey( subkeys, "Monitors" );
01080 regsubkey_ctr_addkey( subkeys, "Forms" );
01081 regsubkey_ctr_addkey( subkeys, "Printers" );
01082
01083 return regsubkey_ctr_numkeys( subkeys );
01084 }
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 static struct reg_dyn_tree print_registry[] = {
01095
01096 { KEY_MONITORS,
01097 ®db_fetch_keys,
01098 ®db_store_keys,
01099 ®db_fetch_values,
01100 ®db_store_values },
01101 { KEY_FORMS,
01102 &key_forms_fetch_keys,
01103 NULL,
01104 &key_forms_fetch_values,
01105 NULL },
01106 { KEY_CONTROL_PRINTERS,
01107 &key_printers_fetch_keys,
01108 &key_printers_store_keys,
01109 &key_printers_fetch_values,
01110 &key_printers_store_values },
01111 { KEY_ENVIRONMENTS,
01112 &key_driver_fetch_keys,
01113 NULL,
01114 &key_driver_fetch_values,
01115 NULL },
01116 { KEY_CONTROL_PRINT,
01117 &key_print_fetch_keys,
01118 NULL,
01119 NULL,
01120 NULL },
01121 { KEY_WINNT_PRINTERS,
01122 &key_printers_fetch_keys,
01123 &key_printers_store_keys,
01124 &key_printers_fetch_values,
01125 &key_printers_store_values },
01126 { KEY_PORTS,
01127 ®db_fetch_keys,
01128 ®db_store_keys,
01129 ®db_fetch_values,
01130 ®db_store_values },
01131
01132 { NULL, NULL, NULL, NULL, NULL }
01133 };
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 static int match_registry_path( const char *key )
01148 {
01149 int i;
01150 pstring path;
01151
01152 if ( !key )
01153 return -1;
01154
01155 pstrcpy( path, key );
01156 normalize_reg_path( path );
01157
01158 for ( i=0; print_registry[i].path; i++ ) {
01159 if ( strncmp( path, print_registry[i].path, strlen(print_registry[i].path) ) == 0 )
01160 return i;
01161 }
01162
01163 return -1;
01164 }
01165
01166
01167
01168
01169 static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
01170 {
01171 int i = match_registry_path( key );
01172
01173 if ( i == -1 )
01174 return -1;
01175
01176 if ( !print_registry[i].fetch_subkeys )
01177 return -1;
01178
01179 return print_registry[i].fetch_subkeys( key, subkeys );
01180 }
01181
01182
01183
01184
01185 static BOOL regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
01186 {
01187 int i = match_registry_path( key );
01188
01189 if ( i == -1 )
01190 return False;
01191
01192 if ( !print_registry[i].store_subkeys )
01193 return False;
01194
01195 return print_registry[i].store_subkeys( key, subkeys );
01196 }
01197
01198
01199
01200
01201 static int regprint_fetch_reg_values( const char *key, REGVAL_CTR *values )
01202 {
01203 int i = match_registry_path( key );
01204
01205 if ( i == -1 )
01206 return -1;
01207
01208
01209
01210
01211 if ( !print_registry[i].fetch_values )
01212 return 0;
01213
01214 return print_registry[i].fetch_values( key, values );
01215 }
01216
01217
01218
01219
01220 static BOOL regprint_store_reg_values( const char *key, REGVAL_CTR *values )
01221 {
01222 int i = match_registry_path( key );
01223
01224 if ( i == -1 )
01225 return False;
01226
01227 if ( !print_registry[i].store_values )
01228 return False;
01229
01230 return print_registry[i].store_values( key, values );
01231 }
01232
01233
01234
01235
01236
01237 REGISTRY_OPS printing_ops = {
01238 regprint_fetch_reg_keys,
01239 regprint_fetch_reg_values,
01240 regprint_store_reg_keys,
01241 regprint_store_reg_values,
01242 NULL
01243 };
01244
01245