registry/reg_printing.c

説明を見る。
00001 /* 
00002  *  Unix SMB/CIFS implementation.
00003  *  Virtual Windows Registry Layer
00004  *  Copyright (C) Gerald Carter                     2002-2005
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *  
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *  
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 /* Implementation of registry virtual views for printing information */
00022 
00023 #include "includes.h"
00024 
00025 #undef DBGC_CLASS
00026 #define DBGC_CLASS DBGC_RPC_SRV
00027 
00028 /* registrt paths used in the print_registry[] */
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 /* callback table for various registry paths below the ones we service in this module */
00040         
00041 struct reg_dyn_tree {
00042         /* full key path in normalized form */
00043         const char *path;
00044         
00045         /* callbscks for fetch/store operations */
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  ** Utility Functions
00055  *********************************************************************
00056  *********************************************************************/
00057 
00058 /***********************************************************************
00059  simple function to prune a pathname down to the basename of a file 
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  ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS"
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         /* no keys below Forms */
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         /* handle user defined forms */
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         /* handle built-on forms */
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  ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
00159  ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
00160  *********************************************************************
00161  *********************************************************************/
00162 
00163 /*********************************************************************
00164  strip off prefix for printers key.  DOes return a pointer to static 
00165  memory.
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         /* normalizing the path does not change length, just key delimiters and case */
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                 /* enumerate all printers */
00207                 
00208                 for (snum=0; snum<n_services; snum++) {
00209                         if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
00210                                 continue;
00211 
00212                         /* don't report the [printers] share */
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         /* get information for a specific printer */
00227         
00228         if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
00229                 return -1;
00230         }
00231 
00232         /* validate the printer name */
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         /* no other subkeys below here */
00255 
00256 done:   
00257         SAFE_FREE( subkey_names );
00258         
00259         return num_subkeys;
00260 }
00261 
00262 /**********************************************************************
00263  Take a list of names and call add_printer_hook() if necessary
00264  Note that we do this a little differently from Windows since the 
00265  keyname is the sharename and not the printer name.
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                 /* just verify a valied snum for now */
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                 /* have to deal with some new or deleted printer */
00316                 return add_printers_by_registry( subkeys );
00317         }
00318         
00319         if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
00320                 return False;
00321         }
00322         
00323         /* lookup the printer */
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         /* get the top level printer keys */
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                 /* remove the key if it has been deleted */
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                 /* add any missing printer keys */
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         /* write back to disk */
00361         
00362         mod_a_printer( printer, 2 );
00363         
00364         /* cleanup */
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         /* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */
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         /* strip the \\server\ from this string */
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         /* use a prs_struct for converting the devmode and security 
00434            descriptor to REG_BINARY */
00435         
00436         prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL);
00437 
00438         /* stream the device mode */
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         /* stream the printer security descriptor */
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         /* top level key values stored in the registry has no values */
00479         
00480         if ( !printers_key ) {
00481                 /* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' ket */
00482                 return regdb_fetch_values( KEY_WINNT_PRINTERS, values );
00483         }
00484         
00485         /* lookup the printer object */
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         /* iterate over all printer data keys and fill the regval container */
00500         
00501         p_data = printer->info_2->data;
00502         if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1  ) {
00503                 /* failure....should never happen if the client has a valid open handle first */
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                                 /* unsupported value...throw away */
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         /* values in the top level key get stored in the registry */
00674 
00675         if ( !printers_key ) {
00676                 /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
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         /* deal with setting values directly under the printername */
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                 /* deal with any subkeys */
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  ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS"
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         /* list all possible architectures */
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         /* we are dealing with a subkey of "Environments */
00761         
00762         pstrcpy( key2, keystr );
00763         keystr = key2;
00764         if (!reg_split_path( keystr, &base, &subkeypath )) {
00765                 return -1;
00766         }
00767         
00768         /* sanity check */
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         /* ...\Print\Environements\...\ */
00778         
00779         if ( !subkeypath ) {
00780                 regsubkey_ctr_addkey( subkeys, "Drivers" );
00781                 regsubkey_ctr_addkey( subkeys, "Print Processors" );
00782                                 
00783                 return 2;
00784         }
00785         
00786         /* more of the key path to process */
00787         
00788         keystr = subkeypath;
00789         if (!reg_split_path( keystr, &base, &subkeypath )) {
00790                 return -1;
00791         }
00792                 
00793         /* ...\Print\Environements\...\Drivers\ */
00794         
00795         if ( !subkeypath ) {
00796                 if ( strequal(base, "Drivers") ) {
00797                         switch ( env_index ) {
00798                                 case 0: /* Win9x */
00799                                         regsubkey_ctr_addkey( subkeys, "Version-0" );
00800                                         break;
00801                                 default: /* Windows NT based systems */
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;      /* bad path */
00815         }
00816         
00817         /* we finally get to enumerate the drivers */
00818         
00819         /* only one possible subkey below PrintProc key */
00820 
00821         if ( strequal(base, "Print Processors") ) {
00822                 keystr = subkeypath;
00823                 if (!reg_split_path( keystr, &base, &subkeypath )) {
00824                         return -1;
00825                 }
00826 
00827                 /* no subkeys below this point */
00828 
00829                 if ( subkeypath )
00830                         return -1;
00831 
00832                 /* only allow one keyname here -- 'winprint' */
00833 
00834                 return strequal( base, "winprint" ) ? 0 : -1;
00835         }
00836         
00837         /* only dealing with drivers from here on out */
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         /* if anything else left, just say if has no subkeys */
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                 /* place the list of dependent files in a single 
00915                    character buffer, separating each file name by
00916                    a NULL */
00917                    
00918                 for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ ) {
00919                         /* strip the path to only the file's base name */
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                 /* terminated by double NULL.  Add the final one here */
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         /* no values in 'Environments\Drivers\Windows NT x86' */
00971         
00972         if ( !subkeypath ) 
00973                 return 0;
00974                 
00975         /* We have the Architecture string and some subkey name:
00976            Currently we only support
00977            * Drivers
00978            * Print Processors
00979            Anything else is an error.
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         /* only Drivers key can be left */
00993                 
00994         if ( !strequal(base, "Drivers") )
00995                 return -1;
00996                         
00997         if ( !subkeypath )
00998                 return 0;
00999         
01000         /* We know that we have Architechure\Drivers with some subkey name
01001            The subkey name has to be Version-XX */
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         /* BEGIN PRINTER DRIVER NAME BLOCK */
01014         
01015         keystr = subkeypath;
01016         if (!reg_split_path( keystr, &base, &subkeypath )) {
01017                 return -1;
01018         }
01019         
01020         /* don't go any deeper for now */
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         /* END PRINTER DRIVER NAME BLOCK */
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         /* no values in the Environments key */
01052         
01053         if ( !(keystr = reg_remaining_path( key + strlen(KEY_ENVIRONMENTS) )) )
01054                 return 0;
01055         
01056         pstrcpy( subkey, keystr);
01057         
01058         /* pass off to handle subkeys */
01059         
01060         return driver_arch_fetch_values( subkey, values );
01061 }
01062 
01063 /*********************************************************************
01064  *********************************************************************
01065  ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT"
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         /* no keys below 'Print' handled here */
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  ** Structure to hold dispatch table of ops for various printer keys.
01089  ** Make sure to always store deeper keys along the same path first so 
01090  ** we ge a more specific match.
01091  *********************************************************************
01092  *********************************************************************/
01093 
01094 static struct reg_dyn_tree print_registry[] = {
01095 /* just pass the monitor onto the registry tdb */
01096 { KEY_MONITORS,
01097         &regdb_fetch_keys, 
01098         &regdb_store_keys,
01099         &regdb_fetch_values,
01100         &regdb_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         &regdb_fetch_keys, 
01128         &regdb_store_keys,
01129         &regdb_fetch_values,
01130         &regdb_store_values },
01131         
01132 { NULL, NULL, NULL, NULL, NULL }
01133 };
01134 
01135 
01136 /**********************************************************************
01137  *********************************************************************
01138  ** Main reg_printing interface functions
01139  *********************************************************************
01140  *********************************************************************/
01141 
01142 /***********************************************************************
01143  Lookup a key in the print_registry table, returning its index.
01144  -1 on failure
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         /* return 0 values by default since we know the key had 
01209            to exist because the client opened a handle */
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  * Table of function pointers for accessing printing data
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 

Sambaに対してSat Aug 29 21:23:15 2009に生成されました。  doxygen 1.4.7