2002-07-19 03:00:24 +04:00
/*
* Unix SMB / CIFS implementation .
2005-05-23 20:25:31 +04:00
* Virtual Windows Registry Layer
* Copyright ( C ) Gerald Carter 2002 - 2005
2002-07-19 03:00:24 +04:00
*
* 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 0213 9 , USA .
*/
/* Implementation of registry virtual views for printing information */
# include "includes.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
2005-06-30 07:29:48 +04:00
/* 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"
2005-06-30 21:46:06 +04:00
# define KEY_DRIVERS "HKLM / SYSTEM / CURRENTCONTROLSET / CONTROL / PRINT / ENVIRONMENTS / ... / DRIVERS"
# define KEY_PRINTPROC "HKLM / SYSTEM / CURRENTCONTROLSET / CONTROL / PRINT / ENVIRONMENTS / ... / PRINTPROC"
2005-06-30 07:29:48 +04:00
# 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 */
2005-06-30 06:59:29 +04:00
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 ) ;
} ;
#if 0 /* UNUSED */
2002-07-19 03:00:24 +04:00
/**********************************************************************
2005-06-30 21:46:06 +04:00
handle enumeration of subkeys below KEY_PRINTING \ Printers
2002-07-19 22:49:44 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 21:46:06 +04:00
static int print_subpath_printers ( char * key , REGSUBKEY_CTR * subkeys )
2002-07-19 22:49:44 +04:00
{
2005-06-30 21:46:06 +04:00
int n_services = lp_numservices ( ) ;
int snum ;
fstring sname ;
int i ;
int num_subkeys = 0 ;
char * keystr , * key2 = NULL ;
char * base , * new_path ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
fstring * subkey_names = NULL ;
2002-07-19 22:49:44 +04:00
2005-06-30 21:46:06 +04:00
DEBUG ( 10 , ( " print_subpath_printers: key=>[%s] \n " , key ? key : " NULL " ) ) ;
2002-07-24 10:42:09 +04:00
2005-06-30 21:46:06 +04:00
if ( ! key )
{
/* enumerate all printers */
for ( snum = 0 ; snum < n_services ; snum + + ) {
if ( ! ( lp_snum_ok ( snum ) & & lp_print_ok ( snum ) ) )
continue ;
2002-07-24 10:42:09 +04:00
2005-06-30 21:46:06 +04:00
/* don't report the [printers] share */
if ( strequal ( lp_servicename ( snum ) , PRINTERS_NAME ) )
continue ;
2005-05-23 20:25:31 +04:00
2005-06-30 21:46:06 +04:00
fstrcpy ( sname , lp_servicename ( snum ) ) ;
2005-05-23 20:25:31 +04:00
2005-06-30 21:46:06 +04:00
regsubkey_ctr_addkey ( subkeys , sname ) ;
2005-05-23 20:25:31 +04:00
}
2005-06-30 21:46:06 +04:00
num_subkeys = regsubkey_ctr_numkeys ( subkeys ) ;
goto done ;
2002-07-24 10:42:09 +04:00
}
2005-05-23 20:25:31 +04:00
2005-06-30 21:46:06 +04:00
/* get information for a specific printer */
2005-05-23 20:25:31 +04:00
2005-06-30 21:46:06 +04:00
key2 = SMB_STRDUP ( key ) ;
keystr = key2 ;
reg_split_path ( keystr , & base , & new_path ) ;
2005-05-23 20:25:31 +04:00
2005-06-30 21:46:06 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( NULL , & printer , 2 , base ) ) )
goto done ;
num_subkeys = get_printer_subkeys ( & printer - > info_2 - > data , new_path ? new_path : " " , & subkey_names ) ;
2005-05-23 20:25:31 +04:00
2005-06-30 21:46:06 +04:00
for ( i = 0 ; i < num_subkeys ; i + + )
regsubkey_ctr_addkey ( subkeys , subkey_names [ i ] ) ;
2005-05-23 20:25:31 +04:00
2005-06-30 21:46:06 +04:00
free_a_printer ( & printer , 2 ) ;
/* no other subkeys below here */
2002-07-24 10:42:09 +04:00
2005-06-30 21:46:06 +04:00
done :
SAFE_FREE ( key2 ) ;
SAFE_FREE ( subkey_names ) ;
2002-07-24 10:42:09 +04:00
2005-06-30 21:46:06 +04:00
return num_subkeys ;
2002-07-24 10:42:09 +04:00
}
/**********************************************************************
2005-06-30 21:46:06 +04:00
handle enumeration of values below KEY_PRINTING \ Printers
2002-07-24 10:42:09 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 21:46:06 +04:00
static int print_subpath_values_printers ( char * key , REGVAL_CTR * val )
2002-07-24 10:42:09 +04:00
{
2005-06-30 21:46:06 +04:00
int num_values = 0 ;
char * keystr , * key2 = NULL ;
char * base , * new_path ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
NT_PRINTER_INFO_LEVEL_2 * info2 ;
DEVICEMODE * devmode ;
prs_struct prs ;
uint32 offset ;
int snum ;
fstring printername ;
NT_PRINTER_DATA * p_data ;
int i , key_index ;
2005-05-23 20:25:31 +04:00
UNISTR2 data ;
2002-07-24 10:42:09 +04:00
2005-06-30 21:46:06 +04:00
/*
* Theres are tw cases to deal with here
* ( 1 ) enumeration of printer_info_2 values
* ( 2 ) enumeration of the PrinterDriverData subney
*/
if ( ! key ) {
/* top level key has no values */
goto done ;
}
2002-07-24 10:42:09 +04:00
2005-06-30 21:46:06 +04:00
key2 = SMB_STRDUP ( key ) ;
2002-07-24 10:42:09 +04:00
keystr = key2 ;
2005-06-30 21:46:06 +04:00
reg_split_path ( keystr , & base , & new_path ) ;
2002-07-24 10:42:09 +04:00
2005-06-30 21:46:06 +04:00
fstrcpy ( printername , base ) ;
2002-07-24 10:42:09 +04:00
2005-06-30 21:46:06 +04:00
if ( ! new_path ) {
char * p ;
uint32 printer_status = PRINTER_STATUS_OK ;
2005-05-23 20:25:31 +04:00
2002-07-24 12:58:03 +04:00
/* we are dealing with the printer itself */
2003-02-25 23:53:53 +03:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( NULL , & printer , 2 , printername ) ) )
2002-07-24 12:58:03 +04:00
goto done ;
info2 = printer - > info_2 ;
regval_ctr_addvalue ( val , " Attributes " , REG_DWORD , ( char * ) & info2 - > attributes , sizeof ( info2 - > attributes ) ) ;
regval_ctr_addvalue ( val , " Priority " , REG_DWORD , ( char * ) & info2 - > priority , sizeof ( info2 - > attributes ) ) ;
regval_ctr_addvalue ( val , " ChangeID " , REG_DWORD , ( char * ) & info2 - > changeid , sizeof ( info2 - > changeid ) ) ;
regval_ctr_addvalue ( val , " Default Priority " , REG_DWORD , ( char * ) & info2 - > default_priority , sizeof ( info2 - > default_priority ) ) ;
2005-06-22 22:03:38 +04:00
/* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */
regval_ctr_addvalue ( val , " Status " , REG_DWORD , ( char * ) & printer_status , sizeof ( info2 - > status ) ) ;
2002-07-24 12:58:03 +04:00
regval_ctr_addvalue ( val , " StartTime " , REG_DWORD , ( char * ) & info2 - > starttime , sizeof ( info2 - > starttime ) ) ;
regval_ctr_addvalue ( val , " UntilTime " , REG_DWORD , ( char * ) & info2 - > untiltime , sizeof ( info2 - > untiltime ) ) ;
2002-09-25 19:19:00 +04:00
2005-05-23 20:25:31 +04:00
/* 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 ( val , " Name " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , info2 - > location , UNI_STR_TERMINATE ) ;
2005-05-23 20:25:31 +04:00
regval_ctr_addvalue ( val , " Location " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , info2 - > comment , UNI_STR_TERMINATE ) ;
2005-05-23 20:25:31 +04:00
regval_ctr_addvalue ( val , " Description " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , info2 - > parameters , UNI_STR_TERMINATE ) ;
2005-05-23 20:25:31 +04:00
regval_ctr_addvalue ( val , " Parameters " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , info2 - > portname , UNI_STR_TERMINATE ) ;
2005-05-23 20:25:31 +04:00
regval_ctr_addvalue ( val , " Port " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , info2 - > sharename , UNI_STR_TERMINATE ) ;
2005-05-23 20:25:31 +04:00
regval_ctr_addvalue ( val , " Share Name " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , info2 - > drivername , UNI_STR_TERMINATE ) ;
2005-05-23 20:25:31 +04:00
regval_ctr_addvalue ( val , " Printer Driver " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , info2 - > sepfile , UNI_STR_TERMINATE ) ;
2005-05-23 20:25:31 +04:00
regval_ctr_addvalue ( val , " Separator File " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
init_unistr2 ( & data , " WinPrint " , UNI_STR_TERMINATE ) ;
2002-09-25 19:19:00 +04:00
regval_ctr_addvalue ( val , " Print Processor " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
init_unistr2 ( & data , " RAW " , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( val , " Datatype " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2002-07-24 12:58:03 +04:00
/* use a prs_struct for converting the devmode and security
2005-05-23 20:25:31 +04:00
descriptor to REG_BINARY */
2002-07-24 12:58:03 +04:00
prs_init ( & prs , MAX_PDU_FRAG_LEN , regval_ctr_getctx ( val ) , MARSHALL ) ;
/* stream the device mode */
snum = lp_servicenumber ( info2 - > sharename ) ;
if ( ( devmode = construct_dev_mode ( snum ) ) ! = NULL )
{
if ( spoolss_io_devmode ( " devmode " , & prs , 0 , devmode ) ) {
offset = prs_offset ( & prs ) ;
regval_ctr_addvalue ( val , " Default Devmode " , REG_BINARY , prs_data_p ( & prs ) , offset ) ;
}
}
prs_mem_clear ( & prs ) ;
prs_set_offset ( & prs , 0 ) ;
if ( info2 - > secdesc_buf & & info2 - > secdesc_buf - > len )
{
if ( sec_io_desc ( " sec_desc " , & info2 - > secdesc_buf - > sec , & prs , 0 ) ) {
offset = prs_offset ( & prs ) ;
regval_ctr_addvalue ( val , " Security " , REG_BINARY , prs_data_p ( & prs ) , offset ) ;
}
}
prs_mem_free ( & prs ) ;
num_values = regval_ctr_numvals ( val ) ;
2002-09-25 19:19:00 +04:00
2002-07-24 12:58:03 +04:00
goto done ;
2002-07-20 08:27:30 +04:00
}
2002-07-24 12:58:03 +04:00
2002-09-25 19:19:00 +04:00
/* now enumerate the key */
2003-02-25 23:53:53 +03:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( NULL , & printer , 2 , printername ) ) )
2002-07-24 12:58:03 +04:00
goto done ;
/* iterate over all printer data and fill the regval container */
2002-09-25 19:19:00 +04:00
p_data = & printer - > info_2 - > data ;
if ( ( key_index = lookup_printerkey ( p_data , new_path ) ) = = - 1 ) {
DEBUG ( 10 , ( " print_subpath_values_printer: Unknown keyname [%s] \n " , new_path ) ) ;
goto done ;
2002-07-20 08:27:30 +04:00
}
2002-07-24 12:58:03 +04:00
2002-09-25 19:19:00 +04:00
num_values = regval_ctr_numvals ( & p_data - > keys [ key_index ] . values ) ;
for ( i = 0 ; i < num_values ; i + + )
regval_ctr_copyvalue ( val , regval_ctr_specific_value ( & p_data - > keys [ key_index ] . values , i ) ) ;
2002-07-24 12:58:03 +04:00
done :
2002-09-25 19:19:00 +04:00
if ( printer )
free_a_printer ( & printer , 2 ) ;
2002-07-24 12:58:03 +04:00
SAFE_FREE ( key2 ) ;
2002-07-20 08:27:30 +04:00
2002-07-24 12:58:03 +04:00
return num_values ;
2002-07-19 22:49:44 +04:00
}
/**********************************************************************
Routine to handle enumeration of subkeys and values
below KEY_PRINTING ( depending on whether or not subkeys / val are
valid pointers .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-20 08:27:30 +04:00
static int handle_printing_subpath ( char * key , REGSUBKEY_CTR * subkeys , REGVAL_CTR * val )
2002-07-19 03:00:24 +04:00
{
int result = 0 ;
char * p , * base ;
int i ;
2002-07-19 22:49:44 +04:00
2002-07-20 08:27:30 +04:00
DEBUG ( 10 , ( " handle_printing_subpath: key=>[%s] \n " , key ) ) ;
2002-07-19 03:00:24 +04:00
/*
* break off the first part of the path
* topmost base * * must * * be one of the strings
* in top_level_keys [ ]
*/
2002-07-19 22:49:44 +04:00
reg_split_path ( key , & base , & p ) ;
2002-07-19 03:00:24 +04:00
for ( i = 0 ; i < MAX_TOP_LEVEL_KEYS ; i + + ) {
if ( StrCaseCmp ( top_level_keys [ i ] , base ) = = 0 )
break ;
}
2002-07-19 22:49:44 +04:00
DEBUG ( 10 , ( " handle_printing_subpath: base=>[%s], i==[%d] \n " , base , i ) ) ;
2002-07-20 08:27:30 +04:00
if ( ! ( i < MAX_TOP_LEVEL_KEYS ) )
2002-07-19 03:00:24 +04:00
return - 1 ;
2002-07-20 17:23:57 +04:00
2002-07-19 03:00:24 +04:00
/* Call routine to handle each top level key */
switch ( i )
{
case KEY_INDEX_ENVIR :
2002-07-19 22:49:44 +04:00
if ( subkeys )
2002-07-20 08:27:30 +04:00
print_subpath_environments ( p , subkeys ) ;
2002-07-24 10:42:09 +04:00
if ( val )
print_subpath_values_environments ( p , val ) ;
2002-07-19 03:00:24 +04:00
break ;
case KEY_INDEX_FORMS :
2002-07-20 17:23:57 +04:00
if ( subkeys )
print_subpath_forms ( p , subkeys ) ;
if ( val )
print_subpath_values_forms ( p , val ) ;
2002-07-19 03:00:24 +04:00
break ;
case KEY_INDEX_PRINTER :
2002-07-20 17:23:57 +04:00
if ( subkeys )
print_subpath_printers ( p , subkeys ) ;
2002-07-24 12:58:03 +04:00
if ( val )
print_subpath_values_printers ( p , val ) ;
2002-07-19 03:00:24 +04:00
break ;
/* default case for top level key that has no handler */
default :
break ;
}
return result ;
}
2005-06-29 20:35:32 +04:00
2002-07-19 03:00:24 +04:00
/**********************************************************************
Enumerate registry subkey names given a registry path .
Caller is responsible for freeing memory to * * subkeys
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-25 21:31:40 +04:00
static int printing_subkey_info ( const char * key , REGSUBKEY_CTR * subkey_ctr )
2002-07-19 03:00:24 +04:00
{
char * path ;
int num_subkeys = 0 ;
DEBUG ( 10 , ( " printing_subkey_info: key=>[%s] \n " , key ) ) ;
path = trim_reg_path ( key ) ;
/* check to see if we are dealing with the top level key */
2005-06-29 20:35:32 +04:00
if ( path ) {
2002-07-20 08:27:30 +04:00
num_subkeys = handle_printing_subpath ( path , subkey_ctr , NULL ) ;
2005-06-29 20:35:32 +04:00
SAFE_FREE ( path ) ;
return num_subkeys ;
}
2002-07-19 03:00:24 +04:00
2005-06-29 20:35:32 +04:00
/* handle top level keys here */
if ( strequal ( KEY_PRINTING , key ) ) {
regsubkey_ctr_addkey ( subkey_ctr , " Environments " ) ;
regsubkey_ctr_addkey ( subkey_ctr , " Forms " ) ;
}
else if ( strequal ( KEY_PRINTING_2K , key ) ) {
regsubkey_ctr_addkey ( subkey_ctr , " Printers " ) ;
}
2002-07-19 03:00:24 +04:00
return num_subkeys ;
}
2005-06-30 06:59:29 +04:00
# endif /* UNUSED */
2005-06-30 21:46:06 +04:00
2005-06-30 07:29:48 +04:00
/**********************************************************************
move to next non - delimter character
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * remaining_path ( const char * key )
{
static pstring new_path ;
char * p ;
2005-06-30 21:46:06 +04:00
if ( ! key | | ! * key )
return NULL ;
pstrcpy ( new_path , key ) ;
normalize_reg_path ( new_path ) ;
p = strchr ( new_path , ' / ' ) ;
if ( p )
p + + ;
else
p = new_path ;
return p ;
}
/***********************************************************************
simple function to prune a pathname down to the basename of a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * dos_basename ( char * path )
{
char * p ;
p = strrchr ( path , ' \\ ' ) ;
if ( p )
p + + ;
else
p = path ;
return p ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int key_forms_fetch_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
return 0 ;
}
static BOOL key_forms_store_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
return True ;
}
static int key_forms_fetch_values ( const char * key , REGVAL_CTR * values )
{
int num_values = 0 ;
uint32 data [ 8 ] ;
int form_index = 1 ;
int i ;
DEBUG ( 10 , ( " print_values_forms: key=>[%s] \n " , key ? key : " NULL " ) ) ;
nt_forms_struct * forms_list = NULL ;
nt_forms_struct * form = NULL ;
if ( ( num_values = get_ntforms ( & forms_list ) ) = = 0 )
return 0 ;
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 */
if ( ( num_values = get_builtin_ntforms ( & forms_list ) ) = = 0 )
return 0 ;
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 ) ;
}
static BOOL key_forms_store_values ( const char * key , REGVAL_CTR * values )
{
return True ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int key_printer_fetch_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
return 0 ;
}
static BOOL key_printer_store_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
return True ;
}
static int key_printer_fetch_values ( const char * key , REGVAL_CTR * values )
{
return 0 ;
}
static BOOL key_printer_store_values ( const char * key , REGVAL_CTR * values )
{
return True ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define ENVIRONMENT_DRIVERS 1
# define ENVIRONMENT_PRINTPROC 2
static int key_driver_fetch_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
const char * environments [ ] = {
" Windows 4.0 " ,
" Windows NT x86 " ,
" Windows NT R4000 " ,
" Windows NT Alpha_AXP " ,
" Windows NT PowerPC " ,
" Windows IA64 " ,
" Windows x64 " ,
NULL } ;
fstring * drivers = NULL ;
int i , env_index , num_drivers ;
char * keystr , * base , * subkeypath ;
pstring key2 ;
int num_subkeys = - 1 ;
int env_subkey_type = 0 ;
int version ;
DEBUG ( 10 , ( " print_subpath_environments: key=>[%s] \n " , key ? key : " NULL " ) ) ;
/* list all possible architectures */
if ( ! key ) {
for ( num_subkeys = 0 ; environments [ num_subkeys ] ; num_subkeys + + )
regsubkey_ctr_addkey ( subkeys , environments [ num_subkeys ] ) ;
return num_subkeys ;
}
/* we are dealing with a subkey of "Environments */
pstrcpy ( key2 , key ) ;
keystr = key2 ;
reg_split_path ( keystr , & base , & subkeypath ) ;
/* sanity check */
for ( env_index = 0 ; environments [ env_index ] ; env_index + + ) {
if ( strequal ( environments [ env_index ] , base ) )
break ;
}
if ( ! environments [ env_index ] )
return - 1 ;
/* ...\Print\Environements\...\ */
if ( ! subkeypath ) {
regsubkey_ctr_addkey ( subkeys , " Drivers " ) ;
regsubkey_ctr_addkey ( subkeys , " Print Processors " ) ;
return 2 ;
}
/* more of the key path to process */
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
/* ...\Print\Environements\...\Drivers\ */
if ( strequal ( base , " Drivers " ) )
env_subkey_type = ENVIRONMENT_DRIVERS ;
else if ( strequal ( base , " Print Processors " ) )
env_subkey_type = ENVIRONMENT_PRINTPROC ;
else
/* invalid path */
return - 1 ;
if ( ! subkeypath ) {
switch ( env_subkey_type ) {
case ENVIRONMENT_DRIVERS :
switch ( env_index ) {
case 0 : /* Win9x */
regsubkey_ctr_addkey ( subkeys , " Version-0 " ) ;
break ;
default : /* Windows NT based systems */
regsubkey_ctr_addkey ( subkeys , " Version-2 " ) ;
regsubkey_ctr_addkey ( subkeys , " Version-3 " ) ;
break ;
}
return regsubkey_ctr_numkeys ( subkeys ) ;
case ENVIRONMENT_PRINTPROC :
if ( env_index = = 1 | | env_index = = 5 | | env_index = = 6 )
regsubkey_ctr_addkey ( subkeys , " winprint " ) ;
return regsubkey_ctr_numkeys ( subkeys ) ;
}
}
/* we finally get to enumerate the drivers */
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
/* get thr print processors key out of the way */
if ( env_subkey_type = = ENVIRONMENT_PRINTPROC ) {
if ( ! strequal ( base , " winprint " ) )
return - 1 ;
return ! subkeypath ? 0 : - 1 ;
}
/* only dealing with drivers from here on out */
version = atoi ( & base [ strlen ( base ) - 1 ] ) ;
switch ( env_index ) {
case 0 :
if ( version ! = 0 )
return - 1 ;
break ;
default :
if ( version ! = 2 & & version ! = 3 )
return - 1 ;
break ;
}
if ( ! subkeypath ) {
num_drivers = get_ntdrivers ( & drivers , environments [ env_index ] , version ) ;
for ( i = 0 ; i < num_drivers ; i + + )
regsubkey_ctr_addkey ( subkeys , drivers [ i ] ) ;
return regsubkey_ctr_numkeys ( subkeys ) ;
}
/* if anything else left, just say if has no subkeys */
DEBUG ( 1 , ( " print_subpath_environments: unhandled key [%s] (subkey == %s \n " ,
key , subkeypath ) ) ;
return 0 ;
}
static BOOL key_driver_store_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
return True ;
}
static int key_driver_fetch_values ( const char * key , REGVAL_CTR * values )
{
char * keystr , * base , * subkeypath ;
pstring key2 ;
fstring arch_environment ;
fstring driver ;
int version ;
NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr ;
NT_PRINTER_DRIVER_INFO_LEVEL_3 * info3 ;
WERROR w_result ;
char * buffer = NULL ;
char * buffer2 = NULL ;
int buffer_size = 0 ;
int i , length ;
char * filename ;
UNISTR2 data ;
int env_subkey_type = 0 ;
DEBUG ( 8 , ( " print_subpath_values_environments: Enter key => [%s] \n " , key ? key : " NULL " ) ) ;
if ( ! key )
return 0 ;
/* The only keys below KEY_PRINTING\Environments is the
specific printer driver info */
/* environment */
2005-06-30 07:29:48 +04:00
2005-06-30 21:46:06 +04:00
pstrcpy ( key2 , key ) ;
keystr = key2 ;
reg_split_path ( keystr , & base , & subkeypath ) ;
if ( ! subkeypath )
return 0 ;
fstrcpy ( arch_environment , base ) ;
2005-06-30 07:29:48 +04:00
2005-06-30 21:46:06 +04:00
/* Driver */
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
if ( strequal ( base , " Drivers " ) )
env_subkey_type = ENVIRONMENT_DRIVERS ;
else if ( strequal ( base , " Print Processors " ) )
env_subkey_type = ENVIRONMENT_PRINTPROC ;
2005-06-30 07:29:48 +04:00
else
2005-06-30 21:46:06 +04:00
/* invalid path */
return - 1 ;
if ( ! subkeypath )
return 0 ;
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
/* for now bail out if we are seeing anything other than the drivers key */
if ( env_subkey_type = = ENVIRONMENT_PRINTPROC )
return 0 ;
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
version = atoi ( & base [ strlen ( base ) - 1 ] ) ;
2002-07-19 22:49:44 +04:00
2005-06-30 21:46:06 +04:00
/* printer driver name */
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
/* don't go any deeper for now */
if ( subkeypath )
return 0 ;
fstrcpy ( driver , base ) ;
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
w_result = get_a_printer_driver ( & driver_ctr , 3 , driver , arch_environment , version ) ;
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
if ( ! W_ERROR_IS_OK ( w_result ) )
return - 1 ;
/* build the values out of the driver information */
info3 = driver_ctr . info_3 ;
2002-07-19 03:00:24 +04:00
2005-06-30 21:46:06 +04:00
filename = dos_basename ( info3 - > driverpath ) ;
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Driver " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2002-07-19 03:00:24 +04:00
2005-06-30 21:46:06 +04:00
filename = dos_basename ( info3 - > configfile ) ;
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Configuration File " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
filename = dos_basename ( info3 - > datafile ) ;
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Data File " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
filename = dos_basename ( info3 - > helpfile ) ;
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Help File " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
init_unistr2 ( & data , info3 - > defaultdatatype , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Data Type " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
regval_ctr_addvalue ( values , " Version " , REG_DWORD , ( char * ) & info3 - > cversion , sizeof ( info3 - > cversion ) ) ;
if ( info3 - > dependentfiles ) {
/* place the list of dependent files in a single
character buffer , separating each file name by
a NULL */
for ( i = 0 ; strcmp ( info3 - > dependentfiles [ i ] , " " ) ; i + + ) {
/* strip the path to only the file's base name */
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
filename = dos_basename ( info3 - > dependentfiles [ i ] ) ;
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
length = strlen ( filename ) ;
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
buffer2 = SMB_REALLOC ( buffer , buffer_size + ( length + 1 ) * sizeof ( uint16 ) ) ;
if ( ! buffer2 )
break ;
buffer = buffer2 ;
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
memcpy ( buffer + buffer_size , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
buffer_size + = ( length + 1 ) * sizeof ( uint16 ) ;
}
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
/* terminated by double NULL. Add the final one here */
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
buffer2 = SMB_REALLOC ( buffer , buffer_size + 2 ) ;
if ( ! buffer2 ) {
SAFE_FREE ( buffer ) ;
buffer_size = 0 ;
} else {
buffer = buffer2 ;
buffer [ buffer_size + + ] = ' \0 ' ;
buffer [ buffer_size + + ] = ' \0 ' ;
}
2005-06-30 06:59:29 +04:00
}
2005-06-30 21:46:06 +04:00
regval_ctr_addvalue ( values , " Dependent Files " , REG_MULTI_SZ , buffer , buffer_size ) ;
free_a_printer_driver ( driver_ctr , 3 ) ;
SAFE_FREE ( buffer ) ;
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
DEBUG ( 8 , ( " print_subpath_values_environments: Exit \n " ) ) ;
2002-07-19 03:00:24 +04:00
2005-06-30 06:59:29 +04:00
return regval_ctr_numvals ( values ) ;
}
static BOOL key_driver_store_values ( const char * key , REGVAL_CTR * values )
{
return True ;
}
/**********************************************************************
2005-06-30 21:46:06 +04:00
Deal with the ' Print ' key the same whether it came from SYSTEM
or SOFTWARE
2005-06-30 06:59:29 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int key_print_fetch_keys ( const char * key , REGSUBKEY_CTR * subkeys )
2005-06-30 21:46:06 +04:00
{
int key_len = strlen ( key ) ;
/* no keys below 'Print' handled here */
if ( ( key_len ! = strlen ( KEY_CONTROL_PRINT ) ) & & ( key_len ! = strlen ( KEY_WINNT_PRINT ) ) )
return - 1 ;
2005-06-30 06:59:29 +04:00
2005-06-30 21:46:06 +04:00
regsubkey_ctr_addkey ( subkeys , " Environments " ) ;
regsubkey_ctr_addkey ( subkeys , " Monitors " ) ;
regsubkey_ctr_addkey ( subkeys , " Forms " ) ;
regsubkey_ctr_addkey ( subkeys , " Printers " ) ;
return regsubkey_ctr_numkeys ( subkeys ) ;
2005-06-30 06:59:29 +04:00
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int key_ports_fetch_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
2005-06-30 07:29:48 +04:00
char * p = remaining_path ( key + strlen ( KEY_PORTS ) ) ;
/* no keys below ports */
if ( p )
return - 1 ;
2005-06-30 06:59:29 +04:00
return 0 ;
}
static BOOL key_ports_store_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
return True ;
}
static int key_ports_fetch_values ( const char * key , REGVAL_CTR * values )
{
int numlines , i ;
char * * lines ;
UNISTR2 data ;
WERROR result ;
2005-06-30 07:29:48 +04:00
char * p = remaining_path ( key + strlen ( KEY_PORTS ) ) ;
/* no keys below ports */
if ( p )
return - 1 ;
2005-06-30 06:59:29 +04:00
if ( ! W_ERROR_IS_OK ( result = enumports_hook ( & numlines , & lines ) ) )
return - 1 ;
init_unistr2 ( & data , " " , UNI_STR_TERMINATE ) ;
for ( i = 0 ; i < numlines ; i + + )
regval_ctr_addvalue ( values , lines [ i ] , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
return regval_ctr_numvals ( values ) ;
}
static BOOL key_ports_store_values ( const char * key , REGVAL_CTR * values )
{
return True ;
}
/**********************************************************************
Structure to hold dispatch table of ops for various printer keys .
Make sure to always store deeper keys along the same path first so
we ge a more specific match .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct reg_dyn_tree print_registry [ ] = {
2005-06-30 21:46:06 +04:00
/* just pass the monitor onto the regostry tdb */
2005-06-30 07:29:48 +04:00
{ KEY_MONITORS ,
2005-06-30 21:46:06 +04:00
& regdb_fetch_keys ,
& regdb_store_keys ,
& regdb_fetch_values ,
& regdb_store_values } ,
2005-06-30 07:29:48 +04:00
{ KEY_FORMS ,
2005-06-30 06:59:29 +04:00
& key_forms_fetch_keys ,
& key_forms_store_keys ,
& key_forms_fetch_values ,
& key_forms_store_values } ,
2005-06-30 07:29:48 +04:00
{ KEY_CONTROL_PRINTERS ,
2005-06-30 06:59:29 +04:00
& key_printer_fetch_keys ,
& key_printer_store_keys ,
& key_printer_fetch_values ,
& key_printer_store_values } ,
2005-06-30 07:29:48 +04:00
{ KEY_ENVIRONMENTS ,
2005-06-30 06:59:29 +04:00
& key_driver_fetch_keys ,
& key_driver_store_keys ,
& key_driver_fetch_values ,
& key_driver_store_values } ,
2005-06-30 07:29:48 +04:00
{ KEY_CONTROL_PRINT ,
2005-06-30 06:59:29 +04:00
& key_print_fetch_keys ,
2005-06-30 21:46:06 +04:00
NULL ,
NULL ,
NULL } ,
2005-06-30 07:29:48 +04:00
{ KEY_WINNT_PRINTERS ,
2005-06-30 06:59:29 +04:00
& key_printer_fetch_keys ,
& key_printer_store_keys ,
& key_printer_fetch_values ,
& key_printer_store_values } ,
2005-06-30 07:29:48 +04:00
{ KEY_WINNT_PRINT ,
2005-06-30 06:59:29 +04:00
& key_print_fetch_keys ,
2005-06-30 21:46:06 +04:00
NULL ,
NULL ,
NULL } ,
2005-06-30 07:29:48 +04:00
{ KEY_PORTS ,
2005-06-30 06:59:29 +04:00
& key_ports_fetch_keys ,
& key_ports_store_keys ,
& key_ports_fetch_values ,
& key_ports_store_values } ,
{ NULL , NULL , NULL , NULL , NULL }
} ;
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int match_registry_path ( const char * key )
{
int i ;
pstring path ;
if ( ! key )
return - 1 ;
pstrcpy ( path , key ) ;
normalize_reg_path ( path ) ;
for ( i = 0 ; print_registry [ i ] . path ; i + + ) {
if ( strncmp ( path , print_registry [ i ] . path , strlen ( print_registry [ i ] . path ) ) = = 0 )
return i ;
}
return - 1 ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int regprint_fetch_reg_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
int i = match_registry_path ( key ) ;
if ( i = = - 1 )
return - 1 ;
2005-06-30 21:46:06 +04:00
if ( ! print_registry [ i ] . fetch_subkeys )
return - 1 ;
2005-06-30 06:59:29 +04:00
return print_registry [ i ] . fetch_subkeys ( key , subkeys ) ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL regprint_store_reg_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
int i = match_registry_path ( key ) ;
if ( i = = - 1 )
return False ;
2005-06-30 21:46:06 +04:00
if ( ! print_registry [ i ] . store_subkeys )
return False ;
2005-06-30 06:59:29 +04:00
return print_registry [ i ] . store_subkeys ( key , subkeys ) ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int regprint_fetch_reg_values ( const char * key , REGVAL_CTR * values )
{
int i = match_registry_path ( key ) ;
if ( i = = - 1 )
return - 1 ;
2005-06-30 21:46:06 +04:00
/* return 0 values by default since we know the key had
to exist because the client opened a handle */
if ( ! print_registry [ i ] . fetch_values )
return 0 ;
2005-06-30 06:59:29 +04:00
return print_registry [ i ] . fetch_values ( key , values ) ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL regprint_store_reg_values ( const char * key , REGVAL_CTR * values )
{
int i = match_registry_path ( key ) ;
if ( i = = - 1 )
return False ;
2005-06-30 21:46:06 +04:00
if ( ! print_registry [ i ] . store_values )
return False ;
2005-06-30 06:59:29 +04:00
return print_registry [ i ] . store_values ( key , values ) ;
}
2002-07-19 03:00:24 +04:00
/*
* Table of function pointers for accessing printing data
*/
REGISTRY_OPS printing_ops = {
2005-06-30 06:59:29 +04:00
regprint_fetch_reg_keys ,
regprint_fetch_reg_values ,
regprint_store_reg_keys ,
regprint_store_reg_values ,
2005-06-17 00:45:55 +04:00
NULL
2002-07-19 03:00:24 +04:00
} ;
2002-07-19 22:49:44 +04:00