/* Implementation of registry virtual views for printing information */
#include "includes.h"
+#include "registry.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
/* callbscks for fetch/store operations */
int ( *fetch_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
bool (*store_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
- int (*fetch_values) ( const char *path, REGVAL_CTR *values );
- bool (*store_values) ( const char *path, REGVAL_CTR *values );
+ int (*fetch_values) ( const char *path, struct regval_ctr *values );
+ bool (*store_values) ( const char *path, struct regval_ctr *values );
};
/*********************************************************************
/**********************************************************************
*********************************************************************/
-static int key_forms_fetch_values( const char *key, REGVAL_CTR *values )
+static int key_forms_fetch_values(const char *key, struct regval_ctr *values)
{
uint32 data[8];
int i, num_values, form_index = 1;
}
num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names );
-
+
for ( i=0; i<num_subkeys; i++ )
regsubkey_ctr_addkey( subkeys, subkey_names[i] );
-
+
free_a_printer( &printer, 2 );
-
+
/* no other subkeys below here */
done:
SAFE_FREE( subkey_names );
-
+
return num_subkeys;
}
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 );
int i, num_subkeys, num_existing_keys;
char *subkeyname;
fstring *existing_subkeys = NULL;
-
+
printers_key = strip_printers_prefix( key );
-
+
if ( !printers_key ) {
/* have to deal with some new or deleted printer */
return add_printers_by_registry( subkeys );
}
-
+
if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
return False;
}
-
+
/* lookup the printer */
-
+
if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername)) ) {
DEBUG(0,("key_printers_store_keys: Tried to store subkey for bad printername %s\n",
printername));
return False;
}
-
+
/* get the top level printer keys */
-
+
num_existing_keys = get_printer_subkeys( printer->info_2->data, "", &existing_subkeys );
-
+
for ( i=0; i<num_existing_keys; i++ ) {
-
+
/* remove the key if it has been deleted */
-
+
if ( !regsubkey_ctr_key_exists( subkeys, existing_subkeys[i] ) ) {
DEBUG(5,("key_printers_store_keys: deleting key %s\n",
existing_subkeys[i]));
}
}
}
-
+
/* write back to disk */
-
+
mod_a_printer( printer, 2 );
-
+
/* cleanup */
-
+
free_a_printer( &printer, 2 );
SAFE_FREE( existing_subkeys );
/**********************************************************************
*********************************************************************/
-static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values )
+static void fill_in_printer_values(NT_PRINTER_INFO_LEVEL_2 *info2, struct regval_ctr *values)
{
struct spoolss_DeviceMode *devmode;
- UNISTR2 data;
char *p;
uint32 printer_status = PRINTER_STATUS_OK;
-
+
regval_ctr_addvalue( values, "Attributes", REG_DWORD, (char*)&info2->attributes, sizeof(info2->attributes) );
regval_ctr_addvalue( values, "Priority", REG_DWORD, (char*)&info2->priority, sizeof(info2->attributes) );
regval_ctr_addvalue( values, "ChangeID", REG_DWORD, (char*)&info2->changeid, sizeof(info2->changeid) );
regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) );
-
+
/* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */
regval_ctr_addvalue( values, "Status", REG_DWORD, (char*)&printer_status, sizeof(info2->status) );
p = info2->printername;
else
p++;
- init_unistr2( &data, p, UNI_STR_TERMINATE);
- regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- init_unistr2( &data, info2->location, UNI_STR_TERMINATE);
- regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- init_unistr2( &data, info2->comment, UNI_STR_TERMINATE);
- regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE);
- regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- init_unistr2( &data, info2->portname, UNI_STR_TERMINATE);
- regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- 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) );
-
- 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) );
- 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) );
-
- init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE);
- regval_ctr_addvalue( values, "Print Processor", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
- init_unistr2( &data, "RAW", UNI_STR_TERMINATE);
- regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+ regval_ctr_addvalue_sz(values, "Name", p);
+ regval_ctr_addvalue_sz(values, "Location", info2->location);
+ regval_ctr_addvalue_sz(values, "Description", info2->comment);
+ regval_ctr_addvalue_sz(values, "Parameters", info2->parameters);
+ regval_ctr_addvalue_sz(values, "Port", info2->portname);
+ regval_ctr_addvalue_sz(values, "Share Name", info2->sharename);
+ regval_ctr_addvalue_sz(values, "Printer Driver", info2->drivername);
+ regval_ctr_addvalue_sz(values, "Separator File", info2->sepfile);
+ regval_ctr_addvalue_sz(values, "Print Processor", info2->printprocessor);
+ regval_ctr_addvalue_sz(values, "Datatype", info2->datatype);
/* stream the device mode */
- devmode = construct_dev_mode_new(values,info2->sharename);
+ devmode = construct_dev_mode(values,info2->sharename);
if (devmode) {
DATA_BLOB blob;
enum ndr_err_code ndr_err;
/**********************************************************************
*********************************************************************/
-static int key_printers_fetch_values( const char *key, REGVAL_CTR *values )
+static int key_printers_fetch_values(const char *key, struct regval_ctr *values)
{
int num_values;
char *printers_key;
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_DATA *p_data;
int i, key_index;
-
+
printers_key = strip_printers_prefix( key );
-
+
/* top level key values stored in the registry has no values */
-
+
if ( !printers_key ) {
/* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' key */
return regdb_fetch_values( KEY_WINNT_PRINTERS, values );
}
-
+
/* lookup the printer object */
-
+
if (!reg_split_path( printers_key, &printername, &printerdatakey )) {
return -1;
}
-
+
if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
goto done;
-
+
if ( !printerdatakey ) {
fill_in_printer_values( printer->info_2, values );
goto done;
}
-
+
/* iterate over all printer data keys and fill the regval container */
-
+
p_data = printer->info_2->data;
if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1 ) {
/* failure....should never happen if the client has a valid open handle first */
free_a_printer( &printer, 2 );
return -1;
}
-
+
num_values = regval_ctr_numvals( p_data->keys[key_index].values );
for ( i=0; i<num_values; i++ )
regval_ctr_copyvalue( values, regval_ctr_specific_value(p_data->keys[key_index].values, i) );
-
+
done:
if ( printer )
free_a_printer( &printer, 2 );
-
+
return regval_ctr_numvals( values );
}
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 )
+static void pull_reg_sz_fstring(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, fstring s)
+{
+ const char *str;
+ pull_reg_sz(mem_ctx, NULL, blob, &str);
+ fstrcpy(s, str);
+}
+
+static void convert_values_to_printer_info_2(TALLOC_CTX *mem_ctx,
+ NT_PRINTER_INFO_LEVEL_2 *printer2,
+ struct regval_ctr *values)
{
int num_values = regval_ctr_numvals( values );
uint32 value_index;
- REGISTRY_VALUE *val;
+ struct regval_blob *val;
int i;
-
+
for ( i=0; i<num_values; i++ ) {
+ DATA_BLOB blob;
val = regval_ctr_specific_value( values, i );
value_index = find_valuename_index( regval_name( val ) );
-
+
+ blob = data_blob_const(regval_data_p(val), regval_size(val));
+
switch( value_index ) {
case REG_IDX_ATTRIBUTES:
printer2->attributes = (uint32)(*regval_data_p(val));
printer2->untiltime = (uint32)(*regval_data_p(val));
break;
case REG_IDX_NAME:
- rpcstr_pull( printer2->printername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->printername);
break;
case REG_IDX_LOCATION:
- rpcstr_pull( printer2->location, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->location);
break;
case REG_IDX_DESCRIPTION:
- rpcstr_pull( printer2->comment, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->comment);
break;
case REG_IDX_PARAMETERS:
- rpcstr_pull( printer2->parameters, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->parameters);
break;
case REG_IDX_PORT:
- rpcstr_pull( printer2->portname, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->portname);
break;
case REG_IDX_SHARENAME:
- rpcstr_pull( printer2->sharename, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->sharename);
break;
case REG_IDX_DRIVER:
- rpcstr_pull( printer2->drivername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->drivername);
break;
case REG_IDX_SEP_FILE:
- rpcstr_pull( printer2->sepfile, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->sepfile);
break;
case REG_IDX_PRINTPROC:
- rpcstr_pull( printer2->printprocessor, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->printprocessor);
break;
case REG_IDX_DATATYPE:
- rpcstr_pull( printer2->datatype, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+ pull_reg_sz_fstring(mem_ctx, &blob, printer2->datatype);
break;
case REG_IDX_DEVMODE:
break;
regval_name( val ) ));
}
}
-
+
return;
}
/**********************************************************************
*********************************************************************/
-static bool key_printers_store_values( const char *key, REGVAL_CTR *values )
+static bool key_printers_store_values(const char *key, struct regval_ctr *values)
{
char *printers_key;
char *printername, *keyname;
NT_PRINTER_INFO_LEVEL *printer = NULL;
WERROR result;
-
+ TALLOC_CTX *mem_ctx = talloc_init("key_printers_store_values");
+
printers_key = strip_printers_prefix( key );
-
+
/* values in the top level key get stored in the registry */
if ( !printers_key ) {
/* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
return regdb_store_values( KEY_WINNT_PRINTERS, values );
}
-
+
if (!reg_split_path( printers_key, &printername, &keyname )) {
return False;
}
/* deal with setting values directly under the printername */
if ( !keyname ) {
- convert_values_to_printer_info_2( printer->info_2, values );
+ convert_values_to_printer_info_2(mem_ctx, printer->info_2, values );
}
else {
int num_values = regval_ctr_numvals( values );
int i;
- REGISTRY_VALUE *val;
-
+ struct regval_blob *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 );
DEBUG(0,("key_printers_store_values: failed to set printer data [%s]!\n",
keyname));
free_a_printer( &printer, 2 );
+ talloc_destroy(mem_ctx);
return False;
}
}
result = mod_a_printer( printer, 2 );
free_a_printer( &printer, 2 );
+ talloc_destroy(mem_ctx);
return W_ERROR_IS_OK(result);
}
/* if anything else left, just say if has no subkeys */
- DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s\n",
+ DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s)\n",
key, subkeypath ));
return 0;
/**********************************************************************
*********************************************************************/
-static void fill_in_driver_values( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, REGVAL_CTR *values )
+static void fill_in_driver_values(const struct spoolss_DriverInfo8 *r,
+ struct regval_ctr *values)
{
char *buffer = NULL;
int buffer_size = 0;
int i, length;
const char *filename;
- UNISTR2 data;
+ DATA_BLOB data;
- 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) );
+ filename = dos_basename(r->driver_path);
+ regval_ctr_addvalue_sz(values, "Driver", filename);
- 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(r->config_file);
+ regval_ctr_addvalue_sz(values, "Configuration File", filename);
- 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(r->data_file);
+ regval_ctr_addvalue_sz(values, "Data File", filename);
- 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) );
+ filename = dos_basename(r->help_file);
+ regval_ctr_addvalue_sz(values, "Help File", filename);
- 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_sz(values, "Datatype", r->default_datatype);
+ regval_ctr_addvalue_sz(values, "Monitor", r->monitor_name);
- regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&info3->cversion,
- sizeof(info3->cversion) );
+ regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&r->version,
+ sizeof(r->version) );
- if ( info3->dependentfiles ) {
+ if (r->dependent_files) {
/* 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++ ) {
+ for (i=0; r->dependent_files[i] && strcmp(r->dependent_files[i], ""); i++) {
/* strip the path to only the file's base name */
- filename = dos_basename( info3->dependentfiles[i] );
+ filename = dos_basename(r->dependent_files[i]);
length = strlen(filename);
break;
}
- init_unistr2( &data, filename, UNI_STR_TERMINATE);
- memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+ push_reg_sz(talloc_tos(), NULL, &data, filename);
+ memcpy( buffer+buffer_size, (char*)data.data, data.length);
buffer_size += (length + 1)*sizeof(uint16);
}
/**********************************************************************
*********************************************************************/
-static int driver_arch_fetch_values( char *key, REGVAL_CTR *values )
+static int driver_arch_fetch_values(char *key, struct regval_ctr *values)
{
char *keystr, *base, *subkeypath;
fstring arch_environment;
fstring driver;
int version;
- NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr;
+ struct spoolss_DriverInfo8 *driver_ctr;
WERROR w_result;
if (!reg_split_path( key, &base, &subkeypath )) {
fstrcpy( driver, base );
- w_result = get_a_printer_driver( &driver_ctr, 3, driver, arch_environment, version );
+ w_result = get_a_printer_driver(talloc_tos(), &driver_ctr, driver, arch_environment, version);
if ( !W_ERROR_IS_OK(w_result) )
return -1;
- fill_in_driver_values( driver_ctr.info_3, values );
+ fill_in_driver_values(driver_ctr, values);
- free_a_printer_driver( driver_ctr, 3 );
+ free_a_printer_driver(driver_ctr);
/* END PRINTER DRIVER NAME BLOCK */
/**********************************************************************
*********************************************************************/
-static int key_driver_fetch_values( const char *key, REGVAL_CTR *values )
+static int key_driver_fetch_values(const char *key, struct regval_ctr *values)
{
char *keystr = NULL;
char *subkey = NULL;
/**********************************************************************
*********************************************************************/
-static int regprint_fetch_reg_values( const char *key, REGVAL_CTR *values )
+static int regprint_fetch_reg_values(const char *key, struct regval_ctr *values)
{
int i = match_registry_path( key );
/**********************************************************************
*********************************************************************/
-static bool regprint_store_reg_values( const char *key, REGVAL_CTR *values )
+static bool regprint_store_reg_values(const char *key, struct regval_ctr *values)
{
int i = match_registry_path( key );
* Table of function pointers for accessing printing data
*/
-REGISTRY_OPS printing_ops = {
+struct registry_ops printing_ops = {
.fetch_subkeys = regprint_fetch_reg_keys,
.fetch_values = regprint_fetch_reg_values,
.store_subkeys = regprint_store_reg_keys,