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
# define MAX_TOP_LEVEL_KEYS 3
/* some symbolic indexes into the top_level_keys */
# define KEY_INDEX_ENVIR 0
# define KEY_INDEX_FORMS 1
# define KEY_INDEX_PRINTER 2
2003-03-05 04:34:34 +03:00
static const char * top_level_keys [ MAX_TOP_LEVEL_KEYS ] = {
2002-07-19 03:00:24 +04:00
" Environments " ,
" Forms " ,
" Printers "
} ;
2005-05-23 20:25:31 +04:00
2002-07-20 17:23:57 +04:00
2002-07-19 03:00:24 +04:00
/**********************************************************************
It is safe to assume that every registry path passed into on of
the exported functions here begins with KEY_PRINTING else
these functions would have never been called . This is a small utility
function to strip the beginning of the path and make a copy that the
caller can modify . Note that the caller is responsible for releasing
the memory allocated here .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * trim_reg_path ( char * path )
{
char * p ;
2005-05-23 20:25:31 +04:00
uint16 key_len = strlen ( path ) ;
uint16 base_key_len ;
2005-05-24 11:55:02 +04:00
int key_printing_len = strlen ( KEY_PRINTING ) ;
int key_printing2k_len = strlen ( KEY_PRINTING_2K ) ;
int key_printing_ports_len = strlen ( KEY_PRINTING_PORTS ) ;
2005-05-23 20:25:31 +04:00
2002-07-19 22:49:44 +04:00
/*
* sanity check . . . this really should never be True .
* It is only here to prevent us from accessing outside
* the path buffer in the extreme case .
*/
2005-05-23 20:25:31 +04:00
if ( ( key_len < key_printing_len )
& & ( key_len < key_printing2k_len )
& & ( key_len < key_printing_ports_len ) )
{
2002-07-19 22:49:44 +04:00
DEBUG ( 0 , ( " trim_reg_path: Registry path too short! [%s] \n " , path ) ) ;
2005-05-23 20:25:31 +04:00
return NULL ;
}
base_key_len = 0 ;
if ( StrnCaseCmp ( KEY_PRINTING , path , key_printing_len ) = = 0 ) {
base_key_len = key_printing_len ;
}
else if ( StrnCaseCmp ( KEY_PRINTING_2K , path , key_printing2k_len ) = = 0 ) {
base_key_len = key_printing2k_len ;
}
else if ( StrnCaseCmp ( KEY_PRINTING_PORTS , path , key_printing2k_len ) = = 0 ) {
base_key_len = key_printing_ports_len ;
}
else {
DEBUG ( 0 , ( " trim_reg_path: invalid path [%s] \n " , path ) ) ;
2002-07-19 22:49:44 +04:00
return NULL ;
}
2005-05-23 20:25:31 +04:00
p = path + base_key_len ;
2002-07-19 03:00:24 +04:00
2002-07-19 22:49:44 +04:00
if ( * p = = ' \\ ' )
p + + ;
2002-07-19 03:00:24 +04:00
if ( * p )
2004-12-07 21:25:53 +03:00
return SMB_STRDUP ( p ) ;
2002-07-19 03:00:24 +04:00
else
return NULL ;
}
2005-05-23 20:25:31 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int fill_ports_values ( REGVAL_CTR * values )
{
int numlines , i ;
char * * lines ;
UNISTR2 data ;
WERROR result ;
result = enumports_hook ( & numlines , & lines ) ;
if ( ! W_ERROR_IS_OK ( result ) )
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 numlines ;
}
2002-07-19 03:00:24 +04:00
/**********************************************************************
2002-07-19 22:49:44 +04:00
handle enumeration of subkeys below KEY_PRINTING \ Environments
2005-05-23 20:25:31 +04:00
Environments \ $ ARCH \ Print Processors
Environments \ $ ARCH \ Drivers \ { 0 , 2 , 3 }
2002-07-19 22:49:44 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-05-23 20:25:31 +04:00
# define ENVIRONMENT_DRIVERS 1
# define ENVIRONMENT_PRINTPROC 2
2002-07-20 08:27:30 +04:00
static int print_subpath_environments ( char * key , REGSUBKEY_CTR * subkeys )
2002-07-19 22:49:44 +04:00
{
2003-01-03 11:28:12 +03:00
const char * environments [ ] = {
2002-07-24 10:42:09 +04:00
" Windows 4.0 " ,
" Windows NT x86 " ,
" Windows NT R4000 " ,
" Windows NT Alpha_AXP " ,
" Windows NT PowerPC " ,
2004-10-05 02:13:57 +04:00
" Windows IA64 " ,
" Windows x64 " ,
2002-07-24 10:42:09 +04:00
NULL } ;
fstring * drivers = NULL ;
int i , env_index , num_drivers ;
2005-05-23 20:25:31 +04:00
char * keystr , * base , * subkeypath ;
pstring key2 ;
2002-07-24 10:42:09 +04:00
int num_subkeys = - 1 ;
2005-05-23 20:25:31 +04:00
int env_subkey_type = 0 ;
int version ;
2002-07-24 10:42:09 +04:00
2002-07-19 22:49:44 +04:00
DEBUG ( 10 , ( " print_subpath_environments: key=>[%s] \n " , key ? key : " NULL " ) ) ;
2005-05-23 20:25:31 +04:00
/* list all possible architectures */
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
if ( ! key ) {
for ( num_subkeys = 0 ; environments [ num_subkeys ] ; num_subkeys + + )
regsubkey_ctr_addkey ( subkeys , environments [ num_subkeys ] ) ;
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
return num_subkeys ;
2002-07-24 10:42:09 +04:00
}
/* we are dealing with a subkey of "Environments */
2005-05-23 20:25:31 +04:00
pstrcpy ( key2 , key ) ;
2002-07-24 10:42:09 +04:00
keystr = key2 ;
2005-05-23 20:25:31 +04:00
reg_split_path ( keystr , & base , & subkeypath ) ;
2002-07-24 10:42:09 +04:00
/* sanity check */
for ( env_index = 0 ; environments [ env_index ] ; env_index + + ) {
2005-05-23 20:25:31 +04:00
if ( strequal ( environments [ env_index ] , base ) )
2002-07-24 10:42:09 +04:00
break ;
}
2005-05-23 20:25:31 +04:00
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 ) ;
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
/* ...\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 */
2002-07-24 10:42:09 +04:00
return - 1 ;
2005-05-23 20:25:31 +04:00
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 ;
}
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
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 ) ;
}
2002-07-24 10:42:09 +04:00
}
/* we finally get to enumerate the drivers */
2005-05-23 20:25:31 +04:00
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 ;
}
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
/* 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 ) ;
2002-07-24 10:42:09 +04:00
for ( i = 0 ; i < num_drivers ; i + + )
regsubkey_ctr_addkey ( subkeys , drivers [ i ] ) ;
2005-05-23 20:25:31 +04:00
return regsubkey_ctr_numkeys ( subkeys ) ;
}
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
/* 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 ;
2002-07-24 10:42:09 +04:00
}
/***********************************************************************
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 ;
}
/**********************************************************************
handle enumeration of values below
KEY_PRINTING \ Environments \ < arch > \ < version > \ < drivername >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int print_subpath_values_environments ( char * key , REGVAL_CTR * val )
{
2005-05-23 20:25:31 +04:00
char * keystr , * base , * subkeypath ;
pstring key2 ;
fstring arch_environment ;
2002-07-24 10:42:09 +04:00
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 ;
2005-05-23 20:25:31 +04:00
UNISTR2 data ;
int env_subkey_type = 0 ;
2002-07-24 10:42:09 +04:00
DEBUG ( 8 , ( " print_subpath_values_environments: Enter key => [%s] \n " , key ? key : " NULL " ) ) ;
2002-07-19 22:49:44 +04:00
if ( ! key )
2002-07-24 10:42:09 +04:00
return 0 ;
2005-05-23 20:25:31 +04:00
/* The only keys below KEY_PRINTING\Environments is the
specific printer driver info */
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
/* environment */
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
pstrcpy ( key2 , key ) ;
2002-07-24 10:42:09 +04:00
keystr = key2 ;
2005-05-23 20:25:31 +04:00
reg_split_path ( keystr , & base , & subkeypath ) ;
if ( ! subkeypath )
2002-07-24 10:42:09 +04:00
return 0 ;
2005-05-23 20:25:31 +04:00
fstrcpy ( arch_environment , base ) ;
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
/* Driver */
2002-07-24 10:42:09 +04:00
2005-05-23 20:25:31 +04:00
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 ;
else
/* invalid path */
return - 1 ;
if ( ! subkeypath )
2002-07-24 10:42:09 +04:00
return 0 ;
2005-05-23 20:25:31 +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-24 10:42:09 +04:00
/* printer driver name */
2005-05-23 20:25:31 +04:00
keystr = subkeypath ;
reg_split_path ( keystr , & base , & subkeypath ) ;
/* don't go any deeper for now */
if ( subkeypath )
2002-07-24 10:42:09 +04:00
return 0 ;
fstrcpy ( driver , base ) ;
2005-05-23 20:25:31 +04:00
w_result = get_a_printer_driver ( & driver_ctr , 3 , driver , arch_environment , version ) ;
2002-07-24 10:42:09 +04:00
if ( ! W_ERROR_IS_OK ( w_result ) )
return - 1 ;
/* build the values out of the driver information */
info3 = driver_ctr . info_3 ;
filename = dos_basename ( info3 - > driverpath ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
2002-09-25 19:19:00 +04:00
regval_ctr_addvalue ( val , " Driver " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2002-07-24 10:42:09 +04:00
filename = dos_basename ( info3 - > configfile ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
2002-09-25 19:19:00 +04:00
regval_ctr_addvalue ( val , " Configuration File " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2002-07-24 10:42:09 +04:00
filename = dos_basename ( info3 - > datafile ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
2002-09-25 19:19:00 +04:00
regval_ctr_addvalue ( val , " Data File " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2002-07-24 10:42:09 +04:00
filename = dos_basename ( info3 - > helpfile ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
2002-09-25 19:19:00 +04:00
regval_ctr_addvalue ( val , " Help File " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , info3 - > defaultdatatype , UNI_STR_TERMINATE ) ;
2002-09-25 19:19:00 +04:00
regval_ctr_addvalue ( val , " Data Type " , REG_SZ , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2002-07-24 10:42:09 +04:00
regval_ctr_addvalue ( val , " Version " , REG_DWORD , ( char * ) & info3 - > cversion , sizeof ( info3 - > cversion ) ) ;
2003-09-26 01:26:16 +04:00
if ( info3 - > dependentfiles ) {
2002-07-24 10:42:09 +04:00
/* place the list of dependent files in a single
character buffer , separating each file name by
a NULL */
2003-09-26 01:26:16 +04:00
for ( i = 0 ; strcmp ( info3 - > dependentfiles [ i ] , " " ) ; i + + ) {
2002-07-24 10:42:09 +04:00
/* strip the path to only the file's base name */
filename = dos_basename ( info3 - > dependentfiles [ i ] ) ;
length = strlen ( filename ) ;
2004-12-07 21:25:53 +03:00
buffer2 = SMB_REALLOC ( buffer , buffer_size + ( length + 1 ) * sizeof ( uint16 ) ) ;
2002-07-24 10:42:09 +04:00
if ( ! buffer2 )
break ;
buffer = buffer2 ;
2002-09-25 19:19:00 +04:00
2003-09-26 01:26:16 +04:00
init_unistr2 ( & data , filename , UNI_STR_TERMINATE ) ;
2002-09-25 19:19:00 +04:00
memcpy ( buffer + buffer_size , ( char * ) data . buffer , data . uni_str_len * sizeof ( uint16 ) ) ;
2002-07-24 10:42:09 +04:00
2002-09-25 19:19:00 +04:00
buffer_size + = ( length + 1 ) * sizeof ( uint16 ) ;
2002-07-24 10:42:09 +04:00
}
/* terminated by double NULL. Add the final one here */
2004-12-07 21:25:53 +03:00
buffer2 = SMB_REALLOC ( buffer , buffer_size + 2 ) ;
2002-07-24 10:42:09 +04:00
if ( ! buffer2 ) {
SAFE_FREE ( buffer ) ;
buffer_size = 0 ;
2003-09-26 01:26:16 +04:00
} else {
2002-07-24 10:42:09 +04:00
buffer = buffer2 ;
buffer [ buffer_size + + ] = ' \0 ' ;
2002-09-25 19:19:00 +04:00
buffer [ buffer_size + + ] = ' \0 ' ;
2002-07-24 10:42:09 +04:00
}
2002-07-19 22:49:44 +04:00
}
2002-07-24 10:42:09 +04:00
regval_ctr_addvalue ( val , " Dependent Files " , REG_MULTI_SZ , buffer , buffer_size ) ;
2002-07-19 22:49:44 +04:00
2002-07-24 10:42:09 +04:00
free_a_printer_driver ( driver_ctr , 3 ) ;
2002-09-25 19:19:00 +04:00
2002-07-24 10:42:09 +04:00
SAFE_FREE ( buffer ) ;
DEBUG ( 8 , ( " print_subpath_values_environments: Exit \n " ) ) ;
return regval_ctr_numvals ( val ) ;
2002-07-19 22:49:44 +04:00
}
2002-07-24 10:42:09 +04:00
2002-07-19 22:49:44 +04:00
/**********************************************************************
handle enumeration of subkeys below KEY_PRINTING \ Forms
2002-07-20 17:23:57 +04:00
Really just a stub function , but left here in case it needs to
be expanded later on
2002-07-19 03:00:24 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-20 08:27:30 +04:00
static int print_subpath_forms ( char * key , REGSUBKEY_CTR * subkeys )
2002-07-19 22:49:44 +04:00
{
DEBUG ( 10 , ( " print_subpath_forms: key=>[%s] \n " , key ? key : " NULL " ) ) ;
2002-07-20 17:23:57 +04:00
/* there are no subkeys */
if ( key )
return - 1 ;
2002-07-19 22:49:44 +04:00
return 0 ;
}
/**********************************************************************
handle enumeration of values below KEY_PRINTING \ Forms
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-20 17:23:57 +04:00
static int print_subpath_values_forms ( char * key , REGVAL_CTR * val )
2002-07-19 22:49:44 +04:00
{
2002-07-20 17:23:57 +04:00
int num_values = 0 ;
2002-07-23 09:07:40 +04:00
uint32 data [ 8 ] ;
int form_index = 1 ;
2002-07-19 22:49:44 +04:00
DEBUG ( 10 , ( " print_values_forms: key=>[%s] \n " , key ? key : " NULL " ) ) ;
/* handle ..\Forms\ */
if ( ! key )
{
2002-07-20 17:23:57 +04:00
nt_forms_struct * forms_list = NULL ;
nt_forms_struct * form = NULL ;
2002-07-19 22:49:44 +04:00
int i ;
2002-07-20 17:23:57 +04:00
if ( ( num_values = get_ntforms ( & forms_list ) ) = = 0 )
2002-07-19 22:49:44 +04:00
return 0 ;
2002-07-20 17:23:57 +04:00
DEBUG ( 10 , ( " print_subpath_values_forms: [%d] user defined forms returned \n " ,
num_values ) ) ;
/* handle user defined forms */
for ( i = 0 ; i < num_values ; i + + )
{
form = & forms_list [ i ] ;
2002-07-23 09:07:40 +04:00
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 ;
2002-07-20 17:23:57 +04:00
regval_ctr_addvalue ( val , form - > name , REG_BINARY , ( char * ) data , sizeof ( data ) ) ;
2002-07-19 22:49:44 +04:00
}
2002-07-20 17:23:57 +04:00
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 ) ) ;
2002-07-19 22:49:44 +04:00
for ( i = 0 ; i < num_values ; i + + )
{
2002-07-20 17:23:57 +04:00
form = & forms_list [ i ] ;
2002-07-19 22:49:44 +04:00
2002-07-23 09:07:40 +04:00
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 ;
2002-07-20 17:23:57 +04:00
regval_ctr_addvalue ( val , form - > name , REG_BINARY , ( char * ) data , sizeof ( data ) ) ;
2002-07-19 22:49:44 +04:00
}
2002-07-20 17:23:57 +04:00
SAFE_FREE ( forms_list ) ;
2002-07-19 22:49:44 +04:00
}
return num_values ;
}
/**********************************************************************
handle enumeration of subkeys below KEY_PRINTING \ Printers
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-20 08:27:30 +04:00
static int print_subpath_printers ( char * key , REGSUBKEY_CTR * subkeys )
2002-07-19 22:49:44 +04:00
{
2002-07-20 17:23:57 +04:00
int n_services = lp_numservices ( ) ;
2002-07-20 08:27:30 +04:00
int snum ;
fstring sname ;
2002-09-25 19:19:00 +04:00
int i ;
2002-07-24 12:58:03 +04:00
int num_subkeys = 0 ;
char * keystr , * key2 = NULL ;
char * base , * new_path ;
NT_PRINTER_INFO_LEVEL * printer = NULL ;
2002-09-25 19:19:00 +04:00
fstring * subkey_names = NULL ;
2002-07-20 08:27:30 +04:00
2002-07-19 22:49:44 +04:00
DEBUG ( 10 , ( " print_subpath_printers: key=>[%s] \n " , key ? key : " NULL " ) ) ;
2002-07-20 08:27:30 +04:00
if ( ! key )
{
/* enumerate all printers */
for ( snum = 0 ; snum < n_services ; snum + + ) {
if ( ! ( lp_snum_ok ( snum ) & & lp_print_ok ( snum ) ) )
continue ;
2005-05-23 20:25:31 +04:00
/* don't report the [printers] share */
if ( strequal ( lp_servicename ( snum ) , PRINTERS_NAME ) )
continue ;
2002-07-20 08:27:30 +04:00
fstrcpy ( sname , lp_servicename ( snum ) ) ;
regsubkey_ctr_addkey ( subkeys , sname ) ;
}
2002-07-24 12:58:03 +04:00
num_subkeys = regsubkey_ctr_numkeys ( subkeys ) ;
goto done ;
}
/* get information for a specific printer */
2004-12-07 21:25:53 +03:00
key2 = SMB_STRDUP ( key ) ;
2002-07-24 12:58:03 +04:00
keystr = key2 ;
reg_split_path ( keystr , & base , & new_path ) ;
2002-09-25 19:19:00 +04:00
2003-02-25 23:53:53 +03:00
if ( ! W_ERROR_IS_OK ( get_a_printer ( NULL , & printer , 2 , base ) ) )
2002-09-25 19:19:00 +04:00
goto done ;
num_subkeys = get_printer_subkeys ( & printer - > info_2 - > data , new_path ? new_path : " " , & subkey_names ) ;
2002-07-24 12:58:03 +04:00
2002-09-25 19:19:00 +04:00
for ( i = 0 ; i < num_subkeys ; i + + )
regsubkey_ctr_addkey ( subkeys , subkey_names [ i ] ) ;
2002-07-24 12:58:03 +04:00
2002-09-25 19:19:00 +04:00
free_a_printer ( & printer , 2 ) ;
2002-07-24 12:58:03 +04:00
/* no other subkeys below here */
done :
SAFE_FREE ( key2 ) ;
2002-09-25 19:19:00 +04:00
SAFE_FREE ( subkey_names ) ;
2002-07-24 12:58:03 +04:00
return num_subkeys ;
}
/**********************************************************************
handle enumeration of values below KEY_PRINTING \ Printers
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int print_subpath_values_printers ( char * key , REGVAL_CTR * val )
{
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 ;
2002-09-25 19:19:00 +04:00
fstring printername ;
NT_PRINTER_DATA * p_data ;
int i , key_index ;
UNISTR2 data ;
2002-07-24 12:58:03 +04:00
/*
2002-09-25 19:19:00 +04:00
* Theres are tw cases to deal with here
2002-07-24 12:58:03 +04:00
* ( 1 ) enumeration of printer_info_2 values
* ( 2 ) enumeration of the PrinterDriverData subney
*/
if ( ! key ) {
/* top level key has no values */
goto done ;
}
2004-12-07 21:25:53 +03:00
key2 = SMB_STRDUP ( key ) ;
2002-07-24 12:58:03 +04:00
keystr = key2 ;
reg_split_path ( keystr , & base , & new_path ) ;
fstrcpy ( printername , base ) ;
2005-05-23 20:25:31 +04:00
if ( ! new_path ) {
char * p ;
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 ) ) ;
regval_ctr_addvalue ( val , " Status " , REG_DWORD , ( char * ) & info2 - > status , sizeof ( info2 - > status ) ) ;
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 ;
}
/**********************************************************************
Enumerate registry subkey names given a registry path .
Caller is responsible for freeing memory to * * subkeys
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-05-23 20:25:31 +04:00
static int printing_subkey_info ( char * key , REGSUBKEY_CTR * subkey_ctr )
2002-07-19 03:00:24 +04:00
{
char * path ;
BOOL top_level = False ;
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 */
if ( ! path )
top_level = True ;
if ( top_level ) {
2005-05-23 20:25:31 +04:00
/* check between the two 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
}
else
2002-07-20 08:27:30 +04:00
num_subkeys = handle_printing_subpath ( path , subkey_ctr , NULL ) ;
2002-07-19 03:00:24 +04:00
SAFE_FREE ( path ) ;
2002-07-19 22:49:44 +04:00
2002-07-19 03:00:24 +04:00
return num_subkeys ;
}
/**********************************************************************
2002-07-19 22:49:44 +04:00
Enumerate registry values given a registry path .
Caller is responsible for freeing memory
2002-07-19 03:00:24 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-19 22:49:44 +04:00
2005-05-23 20:25:31 +04:00
static int printing_value_info ( char * key , REGVAL_CTR * val )
2002-07-19 03:00:24 +04:00
{
char * path ;
BOOL top_level = False ;
2002-07-19 22:49:44 +04:00
int num_values = 0 ;
2002-07-19 03:00:24 +04:00
2002-07-19 22:49:44 +04:00
DEBUG ( 10 , ( " printing_value_info: key=>[%s] \n " , key ) ) ;
2002-07-19 03:00:24 +04:00
path = trim_reg_path ( key ) ;
/* check to see if we are dealing with the top level key */
if ( ! path )
top_level = True ;
2002-07-19 22:49:44 +04:00
/* fill in values from the getprinterdata_printer_server() */
2005-05-23 20:25:31 +04:00
if ( top_level ) {
if ( strequal ( key , KEY_PRINTING_PORTS ) )
num_values = fill_ports_values ( val ) ;
} else
2002-07-20 08:27:30 +04:00
num_values = handle_printing_subpath ( path , NULL , val ) ;
2002-07-19 22:49:44 +04:00
2002-07-19 03:00:24 +04:00
2002-07-19 22:49:44 +04:00
return num_values ;
2002-07-19 03:00:24 +04:00
}
/**********************************************************************
Stub function which always returns failure since we don ' t want
people storing printing information directly via regostry calls
( for now at least )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-05-23 20:25:31 +04:00
static BOOL printing_store_subkey ( char * key , REGSUBKEY_CTR * subkeys )
2002-07-19 03:00:24 +04:00
{
2005-06-09 02:10:34 +04:00
return True ;
2002-07-19 03:00:24 +04:00
}
/**********************************************************************
Stub function which always returns failure since we don ' t want
people storing printing information directly via regostry calls
( for now at least )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-05-23 20:25:31 +04:00
static BOOL printing_store_value ( char * key , REGVAL_CTR * val )
2002-07-19 03:00:24 +04:00
{
2005-06-09 02:10:34 +04:00
return True ;
2002-07-19 03:00:24 +04:00
}
/*
* Table of function pointers for accessing printing data
*/
REGISTRY_OPS printing_ops = {
printing_subkey_info ,
printing_value_info ,
printing_store_subkey ,
printing_store_value
} ;
2002-07-19 22:49:44 +04:00