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"
# 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 ) ;
} ;
2005-07-01 23:15:07 +04:00
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * Utility Functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-19 03:00:24 +04:00
/**********************************************************************
2005-06-30 23:43:53 +04:00
move to next non - delimter character
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * remaining_path ( const char * key )
{
static pstring new_path ;
char * p ;
if ( ! key | | ! * key )
return NULL ;
pstrcpy ( new_path , key ) ;
/* normalize_reg_path( new_path ); */
if ( ! ( p = strchr ( new_path , ' \\ ' ) ) )
{
if ( ! ( p = strchr ( new_path , ' / ' ) ) )
p = new_path ;
else
p + + ;
}
else
p + + ;
return p ;
}
/***********************************************************************
simple function to prune a pathname down to the basename of a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-19 22:49:44 +04:00
2005-06-30 23:43:53 +04:00
static char * dos_basename ( char * path )
{
char * p ;
if ( ! ( p = strrchr ( path , ' \\ ' ) ) )
p = path ;
else
p + + ;
return p ;
}
2005-07-01 23:15:07 +04:00
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * " HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2005-06-30 23:43:53 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int key_forms_fetch_keys ( const char * key , REGSUBKEY_CTR * subkeys )
{
char * p = remaining_path ( key + strlen ( KEY_FORMS ) ) ;
/* no keys below Forms */
if ( p )
return - 1 ;
return 0 ;
}
2005-07-01 23:15:07 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 23:43:53 +04:00
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 ) ;
}
2005-07-01 23:15:07 +04:00
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * " HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS "
* * " HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2005-06-30 23:43:53 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-02 02:24:00 +04:00
/*********************************************************************
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 = remaining_path ( key + strlen ( KEY_WINNT_PRINTERS ) ) ;
else
subkeypath = remaining_path ( key + strlen ( KEY_CONTROL_PRINTERS ) ) ;
return subkeypath ;
}
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-02 05:23:21 +04:00
static int key_printers_fetch_keys ( const 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 ;
2005-07-02 02:24:00 +04:00
char * printers_key ;
2005-07-02 05:23:21 +04:00
char * printername , * printerdatakey ;
2005-06-30 21:46:06 +04:00
NT_PRINTER_INFO_LEVEL * printer = NULL ;
fstring * subkey_names = NULL ;
2005-07-11 22:27:22 +04:00
fstring sharename ;
2002-07-19 22:49:44 +04:00
2005-07-02 05:23:21 +04:00
DEBUG ( 10 , ( " key_printers_fetch_keys: key=>[%s] \n " , key ? key : " NULL " ) ) ;
2002-07-24 10:42:09 +04:00
2005-07-02 02:24:00 +04:00
printers_key = strip_printers_prefix ( key ) ;
2005-06-30 23:43:53 +04:00
2005-07-02 02:24:00 +04:00
if ( ! printers_key ) {
2005-06-30 21:46:06 +04:00
/* 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-07-02 05:23:21 +04:00
reg_split_path ( printers_key , & printername , & printerdatakey ) ;
2005-05-23 20:25:31 +04:00
2005-07-11 22:27:22 +04:00
if ( find_service ( sharename ) = = - 1
| | ! W_ERROR_IS_OK ( get_a_printer ( NULL , & printer , 2 , sharename ) ) )
{
return - 1 ;
}
2005-06-30 21:46:06 +04:00
2005-07-02 05:23:21 +04:00
num_subkeys = get_printer_subkeys ( & printer - > info_2 - > data , printerdatakey ? printerdatakey : " " , & 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 ( 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-07-01 23:15:07 +04:00
/**********************************************************************
2005-07-11 22:27:22 +04:00
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 .
2005-07-01 23:15:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-02 05:23:21 +04:00
static BOOL add_printers_by_registry ( REGSUBKEY_CTR * subkeys )
{
2005-07-11 22:27:22 +04:00
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 ) ;
2005-07-11 22:37:15 +04:00
fstrcpy ( info2 . sharename , printername ) ;
2005-07-11 22:27:22 +04:00
if ( ! add_printer_hook ( NULL , & printer ) ) {
DEBUG ( 0 , ( " add_printers_by_registry: Failed to add printer [%s] \n " ,
printername ) ) ;
}
}
}
unbecome_root ( ) ;
return True ;
2005-07-02 05:23:21 +04:00
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL key_printers_store_keys ( const char * key , REGSUBKEY_CTR * subkeys )
2005-06-30 23:43:53 +04:00
{
2005-07-02 02:24:00 +04:00
char * printers_key ;
2005-07-02 05:23:21 +04:00
char * printername , * printerdatakey ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2005-07-03 06:05:01 +04:00
int i , num_subkeys , num_existing_keys ;
2005-07-02 05:23:21 +04:00
char * subkeyname ;
2005-07-03 06:05:01 +04:00
fstring * existing_subkeys = NULL ;
2005-07-02 02:24:00 +04:00
printers_key = strip_printers_prefix ( key ) ;
if ( ! printers_key ) {
/* have to deal with some new or deleted printer */
2005-07-02 05:23:21 +04:00
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 ) ) ;
2005-07-02 02:24:00 +04:00
return False ;
}
2005-07-03 06:05:01 +04:00
/* 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 ] ) ;
}
}
2005-07-02 02:24:00 +04:00
2005-07-02 05:23:21 +04:00
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 ) {
2005-07-03 06:05:01 +04:00
DEBUG ( 5 , ( " key_printers_store_keys: adding key %s \n " ,
existing_subkeys [ i ] ) ) ;
2005-07-02 05:23:21 +04:00
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 ;
2005-06-30 23:43:53 +04:00
}
2005-07-01 23:15:07 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void fill_in_printer_values ( NT_PRINTER_INFO_LEVEL_2 * info2 , REGVAL_CTR * values )
2002-07-24 10:42:09 +04:00
{
2005-06-30 21:46:06 +04:00
DEVICEMODE * devmode ;
prs_struct prs ;
uint32 offset ;
2005-05-23 20:25:31 +04:00
UNISTR2 data ;
2005-07-01 23:15:07 +04:00
char * p ;
uint32 printer_status = PRINTER_STATUS_OK ;
int snum ;
2002-07-24 10:42:09 +04:00
2005-07-01 23:15:07 +04:00
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 ) ) ;
2002-07-24 10:42:09 +04:00
2005-07-01 23:15:07 +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 ( values , " Status " , REG_DWORD , ( char * ) & printer_status , sizeof ( info2 - > status ) ) ;
2005-06-22 22:03:38 +04:00
2005-07-01 23:15:07 +04:00
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 ) ) ;
2002-09-25 19:19:00 +04:00
2005-07-01 23:15:07 +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 ( values , " Name " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2005-07-01 23:15:07 +04:00
init_unistr2 ( & data , info2 - > location , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Location " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2005-07-01 23:15:07 +04:00
init_unistr2 ( & data , info2 - > comment , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Description " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2005-07-01 23:15:07 +04:00
init_unistr2 ( & data , info2 - > parameters , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Parameters " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2005-07-01 23:15:07 +04:00
init_unistr2 ( & data , info2 - > portname , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Port " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2005-07-01 23:15:07 +04:00
init_unistr2 ( & data , info2 - > sharename , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Share Name " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2005-07-01 23:15:07 +04:00
init_unistr2 ( & data , info2 - > drivername , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Printer Driver " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2005-07-01 23:15:07 +04:00
init_unistr2 ( & data , info2 - > sepfile , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Separator File " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2005-07-01 23:15:07 +04:00
init_unistr2 ( & data , " WinPrint " , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Print Processor " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2005-07-01 23:15:07 +04:00
init_unistr2 ( & data , " RAW " , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( values , " Datatype " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2005-05-23 20:25:31 +04:00
2002-07-24 12:58:03 +04:00
2005-07-01 23:15:07 +04:00
/* use a prs_struct for converting the devmode and security
descriptor to REG_BINARY */
prs_init ( & prs , MAX_PDU_FRAG_LEN , regval_ctr_getctx ( values ) , MARSHALL ) ;
2002-07-24 12:58:03 +04:00
2005-07-01 23:15:07 +04:00
/* stream the device mode */
2002-07-24 12:58:03 +04:00
2005-07-01 23:15:07 +04:00
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 ( values , " Default Devmode " , REG_BINARY , prs_data_p ( & prs ) , offset ) ;
2002-07-24 12:58:03 +04:00
}
2005-07-01 23:15:07 +04:00
}
2002-07-24 12:58:03 +04:00
2005-07-01 23:15:07 +04:00
prs_mem_clear ( & prs ) ;
prs_set_offset ( & prs , 0 ) ;
2002-07-24 12:58:03 +04:00
2005-07-01 23:15:07 +04:00
/* stream the printer security descriptor */
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 ( values , " Security " , REG_BINARY , prs_data_p ( & prs ) , offset ) ;
2002-07-24 12:58:03 +04:00
}
2005-07-01 23:15:07 +04:00
}
2002-07-24 12:58:03 +04:00
2005-07-01 23:15:07 +04:00
prs_mem_free ( & prs ) ;
return ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-02 05:23:21 +04:00
static int key_printers_fetch_values ( const char * key , REGVAL_CTR * values )
2005-07-01 23:15:07 +04:00
{
int num_values ;
2005-07-02 02:24:00 +04:00
char * printers_key ;
2005-07-01 23:15:07 +04:00
char * printername , * printerdatakey ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
NT_PRINTER_DATA * p_data ;
int i , key_index ;
2005-07-02 02:24:00 +04:00
printers_key = strip_printers_prefix ( key ) ;
2005-07-01 23:15:07 +04:00
2005-07-02 02:24:00 +04:00
/* top level key values stored in the registry has no values */
2005-07-01 23:15:07 +04:00
2005-07-02 02:24:00 +04:00
if ( ! printers_key ) {
/* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' ket */
return regdb_fetch_values ( KEY_WINNT_PRINTERS , values ) ;
}
2005-07-01 23:15:07 +04:00
/* lookup the printer object */
2005-07-02 02:24:00 +04:00
reg_split_path ( printers_key , & printername , & printerdatakey ) ;
2005-07-01 23:15:07 +04:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( NULL , & printer , 2 , printername ) ) )
2002-07-24 12:58:03 +04:00
goto done ;
2005-07-01 23:15:07 +04:00
if ( ! printerdatakey ) {
fill_in_printer_values ( printer - > info_2 , values ) ;
goto done ;
2002-07-20 08:27:30 +04:00
}
2002-07-24 12:58:03 +04:00
2005-07-02 02:24:00 +04:00
/* iterate over all printer data keys and fill the regval container */
2002-07-24 12:58:03 +04:00
2002-09-25 19:19:00 +04:00
p_data = & printer - > info_2 - > data ;
2005-07-01 23:15:07 +04:00
if ( ( key_index = lookup_printerkey ( p_data , printerdatakey ) ) = = - 1 ) {
2005-07-02 02:24:00 +04:00
/* failure....should never happen if the client has a valid open handle first */
2005-07-02 05:23:21 +04:00
DEBUG ( 10 , ( " key_printers_fetch_values: Unknown keyname [%s] \n " , printerdatakey ) ) ;
2005-07-02 02:24:00 +04:00
if ( printer )
free_a_printer ( & printer , 2 ) ;
return - 1 ;
2002-07-20 08:27:30 +04:00
}
2002-07-24 12:58:03 +04:00
2005-07-01 23:15:07 +04:00
num_values = regval_ctr_numvals ( & p_data - > keys [ key_index ] . values ) ;
2002-09-25 19:19:00 +04:00
for ( i = 0 ; i < num_values ; i + + )
2005-06-30 23:43:53 +04:00
regval_ctr_copyvalue ( values , regval_ctr_specific_value ( & p_data - > keys [ key_index ] . values , i ) ) ;
2002-09-25 19:19:00 +04:00
2002-07-24 12:58:03 +04:00
done :
2002-09-25 19:19:00 +04:00
if ( printer )
free_a_printer ( & printer , 2 ) ;
2005-07-01 23:15:07 +04:00
return regval_ctr_numvals ( values ) ;
2002-07-19 22:49:44 +04:00
}
2005-07-11 20:55:10 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define REG_IDX_ATTRIBUTES 1
# define REG_IDX_PRIORITY 2
# define REG_IDX_DEFAULT_PRIORITY 3
# define REG_IDX_CHANGEID 4
# define REG_IDX_STATUS 5
# define REG_IDX_STARTTIME 6
# define REG_IDX_NAME 7
# define REG_IDX_LOCATION 8
# define REG_IDX_DESCRIPTION 9
# define REG_IDX_PARAMETERS 10
# define REG_IDX_PORT 12
# define REG_IDX_SHARENAME 13
# define REG_IDX_DRIVER 14
# define REG_IDX_SEP_FILE 15
# define REG_IDX_PRINTPROC 16
# define REG_IDX_DATATYPE 17
# define REG_IDX_DEVMODE 18
# define REG_IDX_SECDESC 19
# define REG_IDX_UNTILTIME 20
struct {
const char * name ;
int index ;
} printer_values_map [ ] = {
{ " Attributes " , REG_IDX_ATTRIBUTES } ,
{ " Priority " , REG_IDX_PRIORITY } ,
{ " Default Priority " , REG_IDX_DEFAULT_PRIORITY } ,
{ " ChangeID " , REG_IDX_CHANGEID } ,
{ " Status " , REG_IDX_STATUS } ,
{ " StartTime " , REG_IDX_STARTTIME } ,
{ " UntilTime " , REG_IDX_UNTILTIME } ,
{ " Name " , REG_IDX_NAME } ,
{ " Location " , REG_IDX_LOCATION } ,
2005-07-11 22:27:22 +04:00
{ " Descrioption " , REG_IDX_DESCRIPTION } ,
2005-07-11 20:55:10 +04:00
{ " Parameters " , REG_IDX_PARAMETERS } ,
{ " Port " , REG_IDX_PORT } ,
{ " Share Name " , REG_IDX_SHARENAME } ,
{ " Printer Driver " , REG_IDX_DRIVER } ,
{ " Separator File " , REG_IDX_SEP_FILE } ,
{ " Print Processor " , REG_IDX_PRINTPROC } ,
{ " Datatype " , REG_IDX_DATATYPE } ,
{ " Default Devmode " , REG_IDX_DEVMODE } ,
{ " Security " , REG_IDX_SECDESC } ,
{ NULL , - 1 }
} ;
static int find_valuename_index ( const char * valuename )
{
int i ;
for ( i = 0 ; printer_values_map [ i ] . name ; i + + ) {
if ( strequal ( valuename , printer_values_map [ i ] . name ) )
return printer_values_map [ i ] . index ;
}
return - 1 ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void convert_values_to_printer_info_2 ( NT_PRINTER_INFO_LEVEL_2 * printer2 , REGVAL_CTR * values )
{
int num_values = regval_ctr_numvals ( values ) ;
uint32 value_index ;
2005-07-11 21:17:50 +04:00
REGISTRY_VALUE * val ;
2005-07-11 20:55:10 +04:00
int i ;
for ( i = 0 ; i < num_values ; i + + ) {
2005-07-11 21:17:50 +04:00
val = regval_ctr_specific_value ( values , i ) ;
value_index = find_valuename_index ( regval_name ( val ) ) ;
2005-07-11 20:55:10 +04:00
switch ( value_index ) {
case REG_IDX_ATTRIBUTES :
2005-07-11 21:17:50 +04:00
printer2 - > attributes = ( uint32 ) ( * regval_data_p ( val ) ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_PRIORITY :
2005-07-11 21:17:50 +04:00
printer2 - > priority = ( uint32 ) ( * regval_data_p ( val ) ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_DEFAULT_PRIORITY :
2005-07-11 21:17:50 +04:00
printer2 - > default_priority = ( uint32 ) ( * regval_data_p ( val ) ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_CHANGEID :
2005-07-11 21:17:50 +04:00
printer2 - > changeid = ( uint32 ) ( * regval_data_p ( val ) ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_STARTTIME :
2005-07-11 21:17:50 +04:00
printer2 - > starttime = ( uint32 ) ( * regval_data_p ( val ) ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_UNTILTIME :
2005-07-11 21:17:50 +04:00
printer2 - > untiltime = ( uint32 ) ( * regval_data_p ( val ) ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_NAME :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > printername , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_LOCATION :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > location , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_DESCRIPTION :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > comment , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_PARAMETERS :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > parameters , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_PORT :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > portname , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_SHARENAME :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > sharename , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_DRIVER :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > drivername , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_SEP_FILE :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > sepfile , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_PRINTPROC :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > printprocessor , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_DATATYPE :
2005-07-11 21:17:50 +04:00
rpcstr_pull ( printer2 - > datatype , regval_data_p ( val ) , sizeof ( fstring ) , regval_size ( val ) , 0 ) ;
2005-07-11 20:55:10 +04:00
break ;
case REG_IDX_DEVMODE :
break ;
case REG_IDX_SECDESC :
break ;
default :
2005-07-11 21:17:50 +04:00
/* unsupported value...throw away */
DEBUG ( 8 , ( " convert_values_to_printer_info_2: Unsupported registry value [%s] \n " ,
regval_name ( val ) ) ) ;
2005-07-11 20:55:10 +04:00
}
}
return ;
}
2005-07-01 23:15:07 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-02 05:23:21 +04:00
static BOOL key_printers_store_values ( const char * key , REGVAL_CTR * values )
2005-06-30 21:46:06 +04:00
{
2005-07-02 02:24:00 +04:00
char * printers_key ;
2005-07-11 20:55:10 +04:00
char * printername , * keyname ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
WERROR result ;
2005-07-02 02:24:00 +04:00
printers_key = strip_printers_prefix ( key ) ;
/* values in the top level key get stored in the registry */
if ( ! printers_key ) {
2005-07-11 20:55:10 +04:00
/* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
2005-07-02 02:24:00 +04:00
return regdb_store_values ( KEY_WINNT_PRINTERS , values ) ;
}
2005-07-11 20:55:10 +04:00
reg_split_path ( printers_key , & printername , & keyname ) ;
if ( ! W_ERROR_IS_OK ( get_a_printer ( NULL , & printer , 2 , printername ) ) )
return False ;
/* deal with setting values directly under the printername */
if ( ! keyname ) {
convert_values_to_printer_info_2 ( printer - > info_2 , values ) ;
}
else {
int num_values = regval_ctr_numvals ( values ) ;
int i ;
REGISTRY_VALUE * val ;
delete_printer_key ( & printer - > info_2 - > data , keyname ) ;
/* deal with any subkeys */
for ( i = 0 ; i < num_values ; i + + ) {
val = regval_ctr_specific_value ( values , i ) ;
result = set_printer_dataex ( printer , keyname ,
regval_name ( val ) ,
regval_type ( val ) ,
regval_data_p ( val ) ,
regval_size ( val ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " key_printers_store_values: failed to set printer data [%s]! \n " ,
keyname ) ) ;
free_a_printer ( & printer , 2 ) ;
return False ;
}
}
}
result = mod_a_printer ( printer , 2 ) ;
free_a_printer ( & printer , 2 ) ;
return W_ERROR_IS_OK ( result ) ;
2005-06-30 21:46:06 +04:00
}
2005-07-01 23:15:07 +04:00
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * " HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2005-06-30 21:46:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 version ;
2005-06-30 23:43:53 +04:00
DEBUG ( 10 , ( " key_driver_fetch_keys key=>[%s] \n " , key ? key : " NULL " ) ) ;
keystr = remaining_path ( key + strlen ( KEY_ENVIRONMENTS ) ) ;
2005-06-30 21:46:06 +04:00
/* list all possible architectures */
2005-06-30 23:43:53 +04:00
if ( ! keystr ) {
2005-06-30 21:46:06 +04:00
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 */
2005-06-30 23:43:53 +04:00
pstrcpy ( key2 , keystr ) ;
2005-06-30 21:46:06 +04:00
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 ( ! subkeypath ) {
2005-07-01 23:15:07 +04:00
if ( strequal ( base , " Drivers " ) ) {
2005-06-30 21:46:06 +04:00
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 ) ;
2005-07-01 23:15:07 +04:00
} else if ( strequal ( base , " Print Processors " ) ) {
2005-06-30 21:46:06 +04:00
if ( env_index = = 1 | | env_index = = 5 | | env_index = = 6 )
regsubkey_ctr_addkey ( subkeys , " winprint " ) ;
return regsubkey_ctr_numkeys ( subkeys ) ;
2005-07-01 23:15:07 +04:00
} else
return - 1 ; /* bad path */
2005-06-30 21:46:06 +04:00
}
/* we finally get to enumerate the drivers */
2005-07-01 23:15:07 +04:00
/* only one possible subkey below PrintProc key */
if ( strequal ( base , " Print Processors " ) ) {
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
/* no subkeys below this point */
2005-06-30 21:46:06 +04:00
2005-07-01 23:15:07 +04:00
if ( subkeypath )
2005-06-30 21:46:06 +04:00
return - 1 ;
2005-07-01 23:15:07 +04:00
/* only allow one keyname here -- 'winprint' */
return strequal ( base , " winprint " ) ? 0 : - 1 ;
2005-06-30 21:46:06 +04:00
}
/* only dealing with drivers from here on out */
2005-07-01 23:15:07 +04:00
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
2005-06-30 21:46:06 +04:00
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 */
2005-06-30 23:43:53 +04:00
DEBUG ( 1 , ( " key_driver_fetch_keys unhandled key [%s] (subkey == %s \n " ,
2005-06-30 21:46:06 +04:00
key , subkeypath ) ) ;
return 0 ;
}
2005-06-30 06:59:29 +04:00
2005-07-01 23:15:07 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 06:59:29 +04:00
2005-07-01 23:15:07 +04:00
static void fill_in_driver_values ( NT_PRINTER_DRIVER_INFO_LEVEL_3 * info3 , REGVAL_CTR * values )
{
char * buffer = NULL ;
char * buffer2 = NULL ;
int buffer_size = 0 ;
int i , length ;
char * filename ;
UNISTR2 data ;
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 ) ;
2005-07-01 23:15:07 +04:00
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 ) ;
2005-07-01 23:15:07 +04:00
regval_ctr_addvalue ( values , " Configuration File " , REG_SZ , ( char * ) data . buffer ,
data . uni_str_len * sizeof ( uint16 ) ) ;
2005-06-30 21:46:06 +04:00
filename = dos_basename ( info3 - > datafile ) ;
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
2005-07-01 23:15:07 +04:00
regval_ctr_addvalue ( values , " Data File " , REG_SZ , ( char * ) data . buffer ,
data . uni_str_len * sizeof ( uint16 ) ) ;
2005-06-30 21:46:06 +04:00
filename = dos_basename ( info3 - > helpfile ) ;
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
2005-07-01 23:15:07 +04:00
regval_ctr_addvalue ( values , " Help File " , REG_SZ , ( char * ) data . buffer ,
data . uni_str_len * sizeof ( uint16 ) ) ;
2005-06-30 21:46:06 +04:00
init_unistr2 ( & data , info3 - > defaultdatatype , UNI_STR_TERMINATE ) ;
2005-07-01 23:15:07 +04:00
regval_ctr_addvalue ( values , " Data Type " , REG_SZ , ( char * ) data . buffer ,
data . uni_str_len * sizeof ( uint16 ) ) ;
2005-06-30 21:46:06 +04:00
2005-07-01 23:15:07 +04:00
regval_ctr_addvalue ( values , " Version " , REG_DWORD , ( char * ) & info3 - > cversion ,
sizeof ( info3 - > cversion ) ) ;
2005-06-30 21:46:06 +04:00
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 ) ;
2005-07-01 23:15:07 +04:00
SAFE_FREE ( buffer ) ;
2005-06-30 21:46:06 +04:00
2005-07-01 23:15:07 +04:00
return ;
}
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int driver_arch_fetch_values ( char * key , REGVAL_CTR * values )
{
char * keystr , * base , * subkeypath ;
fstring arch_environment ;
fstring driver ;
int version ;
NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr ;
WERROR w_result ;
reg_split_path ( key , & base , & subkeypath ) ;
2005-06-30 21:46:06 +04:00
2005-07-01 23:15:07 +04:00
/* no values in 'Environments\Drivers\Windows NT x86' */
if ( ! subkeypath )
return 0 ;
/* We have the Architecture string and some subkey name:
Currently we only support
* Drivers
* Print Processors
Anything else is an error .
*/
fstrcpy ( arch_environment , base ) ;
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
if ( strequal ( base , " Print Processors " ) )
return 0 ;
/* only Drivers key can be left */
if ( ! strequal ( base , " Drivers " ) )
return - 1 ;
if ( ! subkeypath )
return 0 ;
/* We know that we have Architechure\Drivers with some subkey name
The subkey name has to be Version - XX */
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
if ( ! subkeypath )
return 0 ;
version = atoi ( & base [ strlen ( base ) - 1 ] ) ;
/* BEGIN PRINTER DRIVER NAME BLOCK */
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
/* don't go any deeper for now */
fstrcpy ( driver , base ) ;
w_result = get_a_printer_driver ( & driver_ctr , 3 , driver , arch_environment , version ) ;
if ( ! W_ERROR_IS_OK ( w_result ) )
return - 1 ;
2005-06-30 06:59:29 +04:00
2005-07-01 23:15:07 +04:00
fill_in_driver_values ( driver_ctr . info_3 , values ) ;
free_a_printer_driver ( driver_ctr , 3 ) ;
/* END PRINTER DRIVER NAME BLOCK */
2005-07-01 00:16:16 +04:00
DEBUG ( 8 , ( " key_driver_fetch_values: Exit \n " ) ) ;
2002-07-19 03:00:24 +04:00
2005-06-30 06:59:29 +04:00
return regval_ctr_numvals ( values ) ;
}
2005-07-01 23:15:07 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int key_driver_fetch_values ( const char * key , REGVAL_CTR * values )
2005-06-30 06:59:29 +04:00
{
2005-07-01 23:15:07 +04:00
char * keystr ;
pstring subkey ;
DEBUG ( 8 , ( " key_driver_fetch_values: Enter key => [%s] \n " , key ? key : " NULL " ) ) ;
/* no values in the Environments key */
if ( ! ( keystr = remaining_path ( key + strlen ( KEY_ENVIRONMENTS ) ) ) )
return 0 ;
pstrcpy ( subkey , keystr ) ;
/* pass off to handle subkeys */
return driver_arch_fetch_values ( subkey , values ) ;
2005-06-30 06:59:29 +04:00
}
2005-07-01 23:15:07 +04:00
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * " HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
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
}
/**********************************************************************
2005-07-01 23:15:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * 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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2005-06-30 06:59:29 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct reg_dyn_tree print_registry [ ] = {
2005-06-30 23:43:53 +04:00
/* just pass the monitor onto the registry 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 ,
2005-06-30 23:43:53 +04:00
NULL ,
2005-06-30 06:59:29 +04:00
& key_forms_fetch_values ,
2005-06-30 23:43:53 +04:00
NULL } ,
2005-06-30 07:29:48 +04:00
{ KEY_CONTROL_PRINTERS ,
2005-07-02 05:23:21 +04:00
& key_printers_fetch_keys ,
& key_printers_store_keys ,
& key_printers_fetch_values ,
& key_printers_store_values } ,
2005-06-30 07:29:48 +04:00
{ KEY_ENVIRONMENTS ,
2005-06-30 06:59:29 +04:00
& key_driver_fetch_keys ,
2005-07-01 23:15:07 +04:00
NULL ,
2005-06-30 06:59:29 +04:00
& key_driver_fetch_values ,
2005-07-01 23:15:07 +04:00
NULL } ,
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-07-02 05:23:21 +04:00
& key_printers_fetch_keys ,
& key_printers_store_keys ,
& key_printers_fetch_values ,
& key_printers_store_values } ,
2005-06-30 07:29:48 +04:00
{ KEY_PORTS ,
2005-07-01 23:15:07 +04:00
& regdb_fetch_keys ,
& regdb_store_keys ,
& regdb_fetch_values ,
& regdb_store_values } ,
2005-06-30 06:59:29 +04:00
{ NULL , NULL , NULL , NULL , NULL }
} ;
/**********************************************************************
2005-07-01 23:15:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * Main reg_printing interface functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2005-06-30 06:59:29 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-01 23:15:07 +04:00
/***********************************************************************
Lookup a key in the print_registry table , returning its index .
- 1 on failure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 06:59:29 +04:00
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 ;
}
2005-07-01 23:15:07 +04:00
/***********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 06:59:29 +04:00
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