?? reg_printing.c
字號:
/* * Unix SMB/CIFS implementation. * Virtual Windows Registry Layer * Copyright (C) Gerald Carter 2002-2005 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* Implementation of registry virtual views for printing information */#include "includes.h"#undef DBGC_CLASS#define DBGC_CLASS DBGC_RPC_SRV/* registrt paths used in the print_registry[] */#define KEY_MONITORS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/MONITORS"#define KEY_FORMS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS"#define KEY_CONTROL_PRINTERS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"#define KEY_ENVIRONMENTS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS"#define KEY_CONTROL_PRINT "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT"#define KEY_WINNT_PRINTERS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"#define KEY_WINNT_PRINT "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT"#define KEY_PORTS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PORTS"/* callback table for various registry paths below the ones we service in this module */ struct reg_dyn_tree { /* full key path in normalized form */ const char *path; /* callbscks for fetch/store operations */ int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); BOOL (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); int (*fetch_values) ( const char *path, REGVAL_CTR *values ); BOOL (*store_values) ( const char *path, REGVAL_CTR *values );};/********************************************************************* ********************************************************************* ** Utility Functions ********************************************************************* *********************************************************************//*********************************************************************** simple function to prune a pathname down to the basename of a file **********************************************************************/ static char* dos_basename ( char *path ){ char *p; if ( !(p = strrchr( path, '\\' )) ) p = path; else p++; return p;}/********************************************************************* ********************************************************************* ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS" ********************************************************************* *********************************************************************/static int key_forms_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ){ char *p = reg_remaining_path( key + strlen(KEY_FORMS) ); /* no keys below Forms */ if ( p ) return -1; return 0;}/********************************************************************** *********************************************************************/static int key_forms_fetch_values( const char *key, REGVAL_CTR *values ){ uint32 data[8]; int i, num_values, form_index = 1; nt_forms_struct *forms_list = NULL; nt_forms_struct *form; DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" )); num_values = get_ntforms( &forms_list ); DEBUG(10,("hive_forms_fetch_values: [%d] user defined forms returned\n", num_values)); /* handle user defined forms */ for ( i=0; i<num_values; i++ ) { form = &forms_list[i]; data[0] = form->width; data[1] = form->length; data[2] = form->left; data[3] = form->top; data[4] = form->right; data[5] = form->bottom; data[6] = form_index++; data[7] = form->flag; regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) ); } SAFE_FREE( forms_list ); forms_list = NULL; /* handle built-on forms */ num_values = get_builtin_ntforms( &forms_list ); DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n", num_values)); for ( i=0; i<num_values; i++ ) { form = &forms_list[i]; data[0] = form->width; data[1] = form->length; data[2] = form->left; data[3] = form->top; data[4] = form->right; data[5] = form->bottom; data[6] = form_index++; data[7] = form->flag; regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) ); } SAFE_FREE( forms_list ); return regval_ctr_numvals( values );}/********************************************************************* ********************************************************************* ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS" ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS" ********************************************************************* *********************************************************************//********************************************************************* strip off prefix for printers key. DOes return a pointer to static memory. *********************************************************************/static char* strip_printers_prefix( const char *key ){ char *subkeypath; pstring path; pstrcpy( path, key ); normalize_reg_path( path ); /* normalizing the path does not change length, just key delimiters and case */ if ( strncmp( path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS) ) == 0 ) subkeypath = reg_remaining_path( key + strlen(KEY_WINNT_PRINTERS) ); else subkeypath = reg_remaining_path( key + strlen(KEY_CONTROL_PRINTERS) ); return subkeypath;}/********************************************************************* *********************************************************************/ static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ){ int n_services = lp_numservices(); int snum; fstring sname; int i; int num_subkeys = 0; char *printers_key; char *printername, *printerdatakey; NT_PRINTER_INFO_LEVEL *printer = NULL; fstring *subkey_names = NULL; DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" )); printers_key = strip_printers_prefix( key ); if ( !printers_key ) { /* enumerate all printers */ for (snum=0; snum<n_services; snum++) { if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) ) continue; /* don't report the [printers] share */ if ( strequal( lp_servicename(snum), PRINTERS_NAME ) ) continue; fstrcpy( sname, lp_servicename(snum) ); regsubkey_ctr_addkey( subkeys, sname ); } num_subkeys = regsubkey_ctr_numkeys( subkeys ); goto done; } /* get information for a specific printer */ reg_split_path( printers_key, &printername, &printerdatakey ); /* validate the printer name */ for (snum=0; snum<n_services; snum++) { if ( !lp_snum_ok(snum) || !lp_print_ok(snum) ) continue; if (strequal( lp_servicename(snum), printername ) ) break; } if ( snum>=n_services || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) { return -1; } num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names ); for ( i=0; i<num_subkeys; i++ ) regsubkey_ctr_addkey( subkeys, subkey_names[i] ); free_a_printer( &printer, 2 ); /* no other subkeys below here */done: SAFE_FREE( subkey_names ); return num_subkeys;}/********************************************************************** Take a list of names and call add_printer_hook() if necessary Note that we do this a little differently from Windows since the keyname is the sharename and not the printer name. *********************************************************************/static BOOL add_printers_by_registry( REGSUBKEY_CTR *subkeys ){ int i, num_keys, snum; char *printername; NT_PRINTER_INFO_LEVEL_2 info2; NT_PRINTER_INFO_LEVEL printer; ZERO_STRUCT( info2 ); printer.info_2 = &info2; num_keys = regsubkey_ctr_numkeys( subkeys ); become_root(); for ( i=0; i<num_keys; i++ ) { printername = regsubkey_ctr_specific_key( subkeys, i ); snum = find_service( printername ); /* just verify a valied snum for now */ if ( snum == -1 ) { fstrcpy( info2.printername, printername ); fstrcpy( info2.sharename, printername ); if ( !add_printer_hook( NULL, &printer ) ) { DEBUG(0,("add_printers_by_registry: Failed to add printer [%s]\n", printername)); } } } unbecome_root(); return True;}/********************************************************************** *********************************************************************/static BOOL key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys ){ char *printers_key; char *printername, *printerdatakey; NT_PRINTER_INFO_LEVEL *printer = NULL; int i, num_subkeys, num_existing_keys; char *subkeyname; fstring *existing_subkeys = NULL; printers_key = strip_printers_prefix( key ); if ( !printers_key ) { /* have to deal with some new or deleted printer */ return add_printers_by_registry( subkeys ); } reg_split_path( printers_key, &printername, &printerdatakey ); /* lookup the printer */ if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername)) ) { DEBUG(0,("key_printers_store_keys: Tried to store subkey for bad printername %s\n", printername)); return False; } /* get the top level printer keys */ num_existing_keys = get_printer_subkeys( printer->info_2->data, "", &existing_subkeys ); for ( i=0; i<num_existing_keys; i++ ) { /* remove the key if it has been deleted */ if ( !regsubkey_ctr_key_exists( subkeys, existing_subkeys[i] ) ) { DEBUG(5,("key_printers_store_keys: deleting key %s\n", existing_subkeys[i])); delete_printer_key( printer->info_2->data, existing_subkeys[i] ); } } num_subkeys = regsubkey_ctr_numkeys( subkeys ); for ( i=0; i<num_subkeys; i++ ) { subkeyname = regsubkey_ctr_specific_key(subkeys, i); /* add any missing printer keys */ if ( lookup_printerkey(printer->info_2->data, subkeyname) == -1 ) { DEBUG(5,("key_printers_store_keys: adding key %s\n", existing_subkeys[i])); if ( add_new_printer_key( printer->info_2->data, subkeyname ) == -1 ) return False; } } /* write back to disk */ mod_a_printer( printer, 2 ); /* cleanup */ if ( printer ) free_a_printer( &printer, 2 ); return True;}/********************************************************************** *********************************************************************/static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values ){ DEVICEMODE *devmode; prs_struct prs; uint32 offset; UNISTR2 data; char *p; uint32 printer_status = PRINTER_STATUS_OK; int snum; regval_ctr_addvalue( values, "Attributes", REG_DWORD, (char*)&info2->attributes, sizeof(info2->attributes) ); regval_ctr_addvalue( values, "Priority", REG_DWORD, (char*)&info2->priority, sizeof(info2->attributes) ); regval_ctr_addvalue( values, "ChangeID", REG_DWORD, (char*)&info2->changeid, sizeof(info2->changeid) ); regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) ); /* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */ regval_ctr_addvalue( values, "Status", REG_DWORD, (char*)&printer_status, sizeof(info2->status) ); regval_ctr_addvalue( values, "StartTime", REG_DWORD, (char*)&info2->starttime, sizeof(info2->starttime) ); regval_ctr_addvalue( values, "UntilTime", REG_DWORD, (char*)&info2->untiltime, sizeof(info2->untiltime) ); /* strip the \\server\ from this string */ if ( !(p = strrchr( info2->printername, '\\' ) ) ) p = info2->printername; else p++; init_unistr2( &data, p, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->location, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->comment, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->portname, UNI_STR_TERMINATE);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -