1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r9739: conver the reg_objects (REGSUBKEY_CTR & REGVAL_CTR) to use

the new talloc() features:

 Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d
 since the methods use the object pointer as the talloc context for
 internal private data.

 There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy()
 pair of functions.  Simply TALLOC_ZERO_P() and TALLOC_FREE() the
 object.

Also had to convert the printer_info_2->NT_PRINTER_DATA field
to be talloc()'d as well.  This is just a stop on the road to
cleaning up the printer memory management.
(This used to be commit ef721333ab)
This commit is contained in:
Gerald Carter 2005-08-29 14:55:40 +00:00 committed by Gerald (Jerry) Carter
parent 77670a2ec3
commit 44707ad2e0
17 changed files with 482 additions and 770 deletions

View File

@ -245,7 +245,7 @@ typedef struct nt_printer_driver_info_level
typedef struct {
char *name;
REGVAL_CTR values;
REGVAL_CTR *values;
} NT_PRINTER_KEY;
/* container for all printer data */
@ -320,7 +320,7 @@ typedef struct nt_printer_info_level_2
fstring printprocessor;
fstring datatype;
fstring parameters;
NT_PRINTER_DATA data;
NT_PRINTER_DATA *data;
SEC_DESC_BUF *secdesc_buf;
uint32 changeid;
uint32 c_setprinter;

View File

@ -34,7 +34,6 @@ typedef struct {
/* container for registry values */
typedef struct {
TALLOC_CTX *ctx;
uint32 num_values;
REGISTRY_VALUE **values;
} REGVAL_CTR;
@ -42,7 +41,6 @@ typedef struct {
/* container for registry subkey names */
typedef struct {
TALLOC_CTX *ctx;
uint32 num_subkeys;
char **subkeys;
} REGSUBKEY_CTR;

View File

@ -292,6 +292,7 @@ copy an IP address from one buffer to another
#define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__)
#define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type)
#define talloc_destroy(ctx) talloc_free(ctx)
#define TALLOC_FREE(ctx) do { if ((ctx) != NULL) {talloc_free(ctx); ctx=NULL;} } while(0)
/* only define PARANOID_MALLOC_CHECKER with --enable-developer and not compiling
the smbmount utils */

View File

@ -265,8 +265,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
{
WERROR result;
char *printername, *servername;
REGVAL_CTR dsdriver_ctr, dsspooler_ctr;
BOOL got_dsdriver = False, got_dsspooler = False;
REGVAL_CTR *dsdriver_ctr, *dsspooler_ctr;
uint32 i;
POLICY_HND pol;
@ -286,36 +285,44 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
return result;
}
result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, &dsdriver_ctr);
if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
if (!W_ERROR_IS_OK(result)) {
DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
printername, dos_errstr(result)));
} else {
uint32 num_values = regval_ctr_numvals( dsdriver_ctr );
/* Have the data we need now, so start building */
got_dsdriver = True;
for (i=0; i < dsdriver_ctr.num_values; i++)
map_regval_to_ads(mem_ctx, mods,
dsdriver_ctr.values[i]);
for (i=0; i < num_values; i++) {
map_regval_to_ads(mem_ctx, mods, dsdriver_ctr->values[i]);
}
}
result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, &dsspooler_ctr);
if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
if (!W_ERROR_IS_OK(result)) {
DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
printername, dos_errstr(result)));
} else {
got_dsspooler = True;
for (i=0; i < dsspooler_ctr.num_values; i++)
map_regval_to_ads(mem_ctx, mods,
dsspooler_ctr.values[i]);
uint32 num_values = regval_ctr_numvals( dsspooler_ctr );
for (i=0; i<num_values; i++) {
map_regval_to_ads(mem_ctx, mods, dsspooler_ctr->values[i]);
}
}
ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
if (got_dsdriver) regval_ctr_destroy(&dsdriver_ctr);
if (got_dsspooler) regval_ctr_destroy(&dsspooler_ctr);
TALLOC_FREE( dsdriver_ctr );
TALLOC_FREE( dsspooler_ctr );
cli_spoolss_close_printer(cli, mem_ctx, &pol);
return result;
@ -328,9 +335,9 @@ BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
uint32 key,val;
for (key=0; key < data->num_keys; key++) {
REGVAL_CTR ctr = data->keys[key].values;
for (val=0; val < ctr.num_values; val++)
map_regval_to_ads(mem_ctx, mods, ctr.values[val]);
REGVAL_CTR *ctr = data->keys[key].values;
for (val=0; val < ctr->num_values; val++)
map_regval_to_ads(mem_ctx, mods, ctr->values[val]);
}
return True;
}

View File

@ -616,15 +616,6 @@ BOOL nt_printing_init(void)
message_register( MSG_PRINTERDATA_INIT_RESET, reset_all_printerdata );
#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
/*
* register callback to handle invalidating the printer cache
* between smbd processes.
*/
message_register( MSG_PRINTER_MOD, receive_printer_mod_msg);
#endif
/* of course, none of the message callbacks matter if you don't
tell messages.c that you interested in receiving PRINT_GENERAL
msgs. This is done in claim_connection() */
@ -2260,7 +2251,7 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
/* loop over all keys */
for ( i=0; i<data->num_keys; i++ ) {
val_ctr = &data->keys[i].values;
val_ctr = data->keys[i].values;
num_values = regval_ctr_numvals( val_ctr );
/* pack the keyname followed by a empty value */
@ -2288,6 +2279,8 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
regval_type(val),
regval_size(val),
regval_data_p(val) );
DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val)));
}
}
@ -2402,7 +2395,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
len += pack_devicemode(info->devmode, buf+len, buflen-len);
len += pack_values( &info->data, buf+len, buflen-len );
len += pack_values( info->data, buf+len, buflen-len );
if (buflen != len) {
char *tb;
@ -2550,31 +2543,17 @@ void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
/****************************************************************************
Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
****************************************************************************/
static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
{
NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
NT_PRINTER_DATA *data;
int i;
if ( !info )
return;
DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
free_nt_devicemode(&info->devmode);
/* clean up all registry keys */
data = &info->data;
for ( i=0; i<data->num_keys; i++ ) {
SAFE_FREE( data->keys[i].name );
regval_ctr_destroy( &data->keys[i].values );
}
SAFE_FREE( data->keys );
/* finally the top level structure */
SAFE_FREE( *info_ptr );
TALLOC_FREE( *info_ptr );
}
@ -2662,12 +2641,12 @@ int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
NT_PRINTER_KEY *d;
int key_index;
if ( !data || !name )
if ( !name || !data )
return -1;
/* allocate another slot in the NT_PRINTER_KEY array */
if ( !(d = SMB_REALLOC_ARRAY( data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
return -1;
}
@ -2678,11 +2657,13 @@ int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
/* initialze new key */
data->keys[key_index].name = talloc_strdup( data, name );
if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, REGVAL_CTR )) )
return -1;
data->num_keys++;
data->keys[key_index].name = SMB_STRDUP( name );
regval_ctr_init( &data->keys[key_index].values );
DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
return key_index;
@ -2695,16 +2676,14 @@ int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
{
int i;
NT_PRINTER_KEY *printer_key;
for ( i=0; i<data->num_keys; i++ ) {
if ( strequal( data->keys[i].name, name ) ) {
/* cleanup memory */
printer_key = &data->keys[i];
SAFE_FREE( printer_key->name );
regval_ctr_destroy( &printer_key->values );
TALLOC_FREE( data->keys[i].name );
TALLOC_FREE( data->keys[i].values );
/* if not the end of the array, move remaining elements down one slot */
@ -2923,9 +2902,9 @@ static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
const char *ascii_str;
int i;
if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
ctr = &info2->data.keys[i].values;
if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
ctr = info2->data->keys[i].values;
map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
@ -2984,9 +2963,9 @@ static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
REGVAL_CTR *ctr=NULL;
/* find the DsSpooler key */
if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
ctr = &info2->data.keys[i].values;
if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
ctr = info2->data->keys[i].values;
regval_ctr_delvalue(ctr, "objectGUID");
regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY,
@ -3054,8 +3033,7 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
ctx = talloc_init("nt_printer_publish_ads");
mods = ads_init_mods(ctx);
get_local_printer_publishing_data(ctx, &mods,
&printer->info_2->data);
get_local_printer_publishing_data(ctx, &mods, printer->info_2->data);
ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
printer->info_2->sharename);
@ -3238,10 +3216,10 @@ BOOL is_printer_published(Printer_entry *print_hnd, int snum,
if (!W_ERROR_IS_OK(win_rc) ||
!(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) ||
((i = lookup_printerkey(&printer->info_2->data,
SPOOL_DSSPOOLER_KEY)) < 0) ||
!(ctr = &printer->info_2->data.keys[i].values) ||
!(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) {
((i = lookup_printerkey(printer->info_2->data, SPOOL_DSSPOOLER_KEY)) < 0) ||
!(ctr = printer->info_2->data->keys[i].values) ||
!(guid_val = regval_ctr_getvalue(ctr, "objectGUID")))
{
free_a_printer(&printer, 2);
return False;
}
@ -3281,7 +3259,7 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
int removed_keys = 0;
int empty_slot;
data = &p2->data;
data = p2->data;
empty_slot = data->num_keys;
if ( !key )
@ -3290,20 +3268,12 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
/* remove all keys */
if ( !strlen(key) ) {
for ( i=0; i<data->num_keys; i++ ) {
DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
data->keys[i].name));
SAFE_FREE( data->keys[i].name );
regval_ctr_destroy( &data->keys[i].values );
}
TALLOC_FREE( data );
DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
p2->printername ));
SAFE_FREE( data->keys );
ZERO_STRUCTP( data );
return WERR_OK;
}
@ -3314,9 +3284,9 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
data->keys[i].name));
SAFE_FREE( data->keys[i].name );
regval_ctr_destroy( &data->keys[i].values );
TALLOC_FREE( data->keys[i].name );
TALLOC_FREE( data->keys[i].values );
/* mark the slot as empty */
ZERO_STRUCTP( &data->keys[i] );
@ -3379,16 +3349,16 @@ WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const
/* find the printer key first */
key_index = lookup_printerkey( &p2->data, key );
key_index = lookup_printerkey( p2->data, key );
if ( key_index == -1 )
return WERR_OK;
/* make sure the value exists so we can return the correct error code */
if ( !regval_ctr_getvalue( &p2->data.keys[key_index].values, value ) )
if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) )
return WERR_BADFILE;
regval_ctr_delvalue( &p2->data.keys[key_index].values, value );
regval_ctr_delvalue( p2->data->keys[key_index].values, value );
DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
key, value ));
@ -3412,14 +3382,14 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const cha
/* find the printer key first */
key_index = lookup_printerkey( &p2->data, key );
key_index = lookup_printerkey( p2->data, key );
if ( key_index == -1 )
key_index = add_new_printer_key( &p2->data, key );
key_index = add_new_printer_key( p2->data, key );
if ( key_index == -1 )
return WERR_NOMEM;
regval_ctr_addvalue( &p2->data.keys[key_index].values, value,
regval_ctr_addvalue( p2->data->keys[key_index].values, value,
type, (const char *)data, real_len );
DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
@ -3435,13 +3405,13 @@ REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key,
{
int key_index;
if ( (key_index = lookup_printerkey( &p2->data, key )) == -1 )
if ( (key_index = lookup_printerkey( p2->data, key )) == -1 )
return NULL;
DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
key, value ));
return regval_ctr_getvalue( &p2->data.keys[key_index].values, value );
return regval_ctr_getvalue( p2->data->keys[key_index].values, value );
}
/****************************************************************************
@ -3458,7 +3428,7 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
uint8 *data_p;
REGISTRY_VALUE *regval_p;
int key_index;
/* add the "PrinterDriverData" key first for performance reasons */
add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
@ -3526,7 +3496,7 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
/* add the new value */
regval_ctr_addvalue( &printer_data->keys[key_index].values, valuename, type, (const char *)data_p, size );
regval_ctr_addvalue( printer_data->keys[key_index].values, valuename, type, (const char *)data_p, size );
SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
@ -3623,44 +3593,41 @@ static void map_to_os2_driver(fstring drivername)
/****************************************************************************
Get a default printer info 2 struct.
****************************************************************************/
static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *servername, const char* sharename)
static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, const char *servername, const char* sharename)
{
int snum;
NT_PRINTER_INFO_LEVEL_2 info;
ZERO_STRUCT(info);
snum = lp_servicenumber(sharename);
slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", servername);
slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
servername, sharename);
fstrcpy(info.sharename, sharename);
fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
fstrcpy(info->sharename, sharename);
fstrcpy(info->portname, SAMBA_PRINTER_PORT_NAME);
/* by setting the driver name to an empty string, a local NT admin
can now run the **local** APW to install a local printer driver
for a Samba shared printer in 2.2. Without this, drivers **must** be
installed on the Samba server for NT clients --jerry */
#if 0 /* JERRY --do not uncomment-- */
if (!*info.drivername)
fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
if (!*info->drivername)
fstrcpy(info->drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
#endif
DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername));
pstrcpy(info.comment, "");
fstrcpy(info.printprocessor, "winprint");
fstrcpy(info.datatype, "RAW");
pstrcpy(info->comment, "");
fstrcpy(info->printprocessor, "winprint");
fstrcpy(info->datatype, "RAW");
info.attributes = PRINTER_ATTRIBUTE_SAMBA;
info->attributes = PRINTER_ATTRIBUTE_SAMBA;
info.starttime = 0; /* Minutes since 12:00am GMT */
info.untiltime = 0; /* Minutes since 12:00am GMT */
info.priority = 1;
info.default_priority = 1;
info.setuptime = (uint32)time(NULL);
info->starttime = 0; /* Minutes since 12:00am GMT */
info->untiltime = 0; /* Minutes since 12:00am GMT */
info->priority = 1;
info->default_priority = 1;
info->setuptime = (uint32)time(NULL);
/*
* I changed this as I think it is better to have a generic
@ -3673,91 +3640,80 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const
*/
if (lp_default_devmode(snum)) {
if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
if ((info->devmode = construct_nt_devicemode(info->printername)) == NULL)
goto fail;
}
else {
info.devmode = NULL;
info->devmode = NULL;
}
/* This will get the current RPC talloc context, but we should be
passing this as a parameter... fixme... JRA ! */
if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
if (!nt_printing_getsec(info, sharename, &info->secdesc_buf))
goto fail;
*info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
if (! *info_ptr) {
DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
goto fail;
}
return WERR_OK;
fail:
if (info.devmode)
free_nt_devicemode(&info.devmode);
fail:
if (info->devmode)
free_nt_devicemode(&info->devmode);
return WERR_ACCESS_DENIED;
}
/****************************************************************************
****************************************************************************/
static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *servername, const char *sharename)
static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, const char *servername, const char *sharename)
{
NT_PRINTER_INFO_LEVEL_2 info;
int len = 0;
int snum = lp_servicenumber(sharename);
TDB_DATA kbuf, dbuf;
fstring printername;
char adevice[MAXDEVICENAME];
ZERO_STRUCT(info);
kbuf = make_printer_tdbkey( sharename );
dbuf = tdb_fetch(tdb_printers, kbuf);
if (!dbuf.dptr)
return get_a_printer_2_default(info_ptr, servername, sharename);
return get_a_printer_2_default(info, servername, sharename);
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
&info.attributes,
&info.priority,
&info.default_priority,
&info.starttime,
&info.untiltime,
&info.status,
&info.cjobs,
&info.averageppm,
&info.changeid,
&info.c_setprinter,
&info.setuptime,
info.servername,
info.printername,
info.sharename,
info.portname,
info.drivername,
info.comment,
info.location,
info.sepfile,
info.printprocessor,
info.datatype,
info.parameters);
&info->attributes,
&info->priority,
&info->default_priority,
&info->starttime,
&info->untiltime,
&info->status,
&info->cjobs,
&info->averageppm,
&info->changeid,
&info->c_setprinter,
&info->setuptime,
info->servername,
info->printername,
info->sharename,
info->portname,
info->drivername,
info->comment,
info->location,
info->sepfile,
info->printprocessor,
info->datatype,
info->parameters);
/* Samba has to have shared raw drivers. */
info.attributes |= PRINTER_ATTRIBUTE_SAMBA;
info.attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
/* Restore the stripped strings. */
slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", servername);
slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
if ( lp_force_printername(snum) )
slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename );
else
slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info.printername);
slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info->printername);
fstrcpy(info.printername, printername);
fstrcpy(info->printername, printername);
len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
len += unpack_devicemode(&info->devmode,dbuf.dptr+len, dbuf.dsize-len);
/*
* Some client drivers freak out if there is a NULL devmode
@ -3767,34 +3723,37 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *se
* See comments in get_a_printer_2_default()
*/
if (lp_default_devmode(snum) && !info.devmode) {
if (lp_default_devmode(snum) && !info->devmode) {
DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
printername));
info.devmode = construct_nt_devicemode(printername);
info->devmode = construct_nt_devicemode(printername);
}
slprintf( adevice, sizeof(adevice), "%s", info.printername );
if (info.devmode) {
fstrcpy(info.devmode->devicename, adevice);
slprintf( adevice, sizeof(adevice), "%s", info->printername );
if (info->devmode) {
fstrcpy(info->devmode->devicename, adevice);
}
len += unpack_values( &info.data, dbuf.dptr+len, dbuf.dsize-len );
if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) {
DEBUG(0,("unpack_values: talloc() failed!\n"));
return WERR_NOMEM;
}
len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len );
/* This will get the current RPC talloc context, but we should be
passing this as a parameter... fixme... JRA ! */
nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
nt_printing_getsec(info, sharename, &info->secdesc_buf);
/* Fix for OS/2 drivers. */
if (get_remote_arch() == RA_OS2)
map_to_os2_driver(info.drivername);
map_to_os2_driver(info->drivername);
SAFE_FREE(dbuf.dptr);
*info_ptr=memdup(&info, sizeof(info));
DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
sharename, info.printername, info.drivername));
sharename, info->printername, info->drivername));
return WERR_OK;
}
@ -3881,29 +3840,6 @@ static uint32 rev_changeid(void)
#endif
}
#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
/********************************************************************
Send a message to all smbds about the printer that just changed
********************************************************************/
static BOOL send_printer_mod_msg( char* printername )
{
int len = strlen(printername);
if (!len)
return False;
DEBUG(10,("send_printer_mod_msg: Sending message about printer change [%s]\n",
printername));
/* spam everyone that we just changed this printer */
message_send_all( conn_tdb_ctx(), MSG_PRINTER_MOD, printername, len+1, False, NULL );
return True;
}
#endif
/*
* The function below are the high level ones.
@ -3921,21 +3857,6 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
dump_a_printer(printer, level);
#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
/*
* invalidate cache for all open handles to this printer.
* cache for a given handle will be updated on the next
* get_a_printer()
*/
invalidate_printer_hnd_cache( printer->info_2->sharename );
/* messages between smbds can only be sent as root */
become_root();
send_printer_mod_msg( printer->info_2->sharename );
unbecome_root();
#endif
switch (level) {
case 2:
{
@ -4002,7 +3923,8 @@ static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
* should not be any (if there are delete them).
*/
delete_all_printer_data( info_ptr, "" );
if ( info_ptr->data )
delete_all_printer_data( info_ptr, "" );
slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
@ -4056,8 +3978,13 @@ static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername));
/* Add the printer data 'values' to the new printer */
if ( !(info_ptr->data = TALLOC_ZERO_P( info_ptr, NT_PRINTER_DATA )) ) {
DEBUG(0,("set_driver_init_2: talloc() failed!\n"));
return False;
}
len += unpack_values( &info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
len += unpack_values( info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
SAFE_FREE(dbuf.dptr);
@ -4136,7 +4063,7 @@ static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
len = 0;
len += pack_devicemode(info->devmode, buf+len, buflen-len);
len += pack_values( &info->data, buf+len, buflen-len );
len += pack_values( info->data, buf+len, buflen-len );
if (buflen < len) {
char *tb;
@ -4337,74 +4264,6 @@ WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *dat
return status;
}
#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
/****************************************************************************
Deep copy a NT_PRINTER_DATA
****************************************************************************/
static NTSTATUS copy_printer_data( NT_PRINTER_DATA *dst, NT_PRINTER_DATA *src )
{
int i, j, num_vals, new_key_index;
REGVAL_CTR *src_key, *dst_key;
if ( !dst || !src )
return NT_STATUS_NO_MEMORY;
for ( i=0; i<src->num_keys; i++ ) {
/* create a new instance of the printerkey in the destination
printer_data object */
new_key_index = add_new_printer_key( dst, src->keys[i].name );
dst_key = &dst->keys[new_key_index].values;
src_key = &src->keys[i].values;
num_vals = regval_ctr_numvals( src_key );
/* dup the printer entire printer key */
for ( j=0; j<num_vals; j++ ) {
regval_ctr_copyvalue( dst_key, regval_ctr_specific_value(src_key, j) );
}
}
return NT_STATUS_OK;
}
/****************************************************************************
Deep copy a NT_PRINTER_INFO_LEVEL_2 structure using malloc()'d memeory
Caller must free.
****************************************************************************/
NT_PRINTER_INFO_LEVEL_2* dup_printer_2( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 *printer )
{
NT_PRINTER_INFO_LEVEL_2 *copy;
if ( !printer )
return NULL;
if ( !(copy = SMB_MALLOC_P(NT_PRINTER_INFO_LEVEL_2)) )
return NULL;
memcpy( copy, printer, sizeof(NT_PRINTER_INFO_LEVEL_2) );
/* malloc()'d members copied here */
copy->devmode = dup_nt_devicemode( printer->devmode );
ZERO_STRUCT( copy->data );
copy_printer_data( &copy->data, &printer->data );
/* this is talloc()'d; very ugly that we have a structure that
is half malloc()'d and half talloc()'d but that is the way
that the PRINTER_INFO stuff is written right now. --jerry */
copy->secdesc_buf = dup_sec_desc_buf( ctx, printer->secdesc_buf );
return copy;
}
#endif
/****************************************************************************
Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
@ -4423,20 +4282,22 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print
const char *sharename)
{
WERROR result;
NT_PRINTER_INFO_LEVEL *printer = NULL;
fstring servername;
*pp_printer = NULL;
DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
DEBUG(0,("get_a_printer: talloc() fail.\n"));
return WERR_NOMEM;
}
switch (level) {
case 2:
if ((printer = SMB_MALLOC_P(NT_PRINTER_INFO_LEVEL)) == NULL) {
DEBUG(0,("get_a_printer: malloc fail.\n"));
if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) {
DEBUG(0,("get_a_printer: talloc() fail.\n"));
TALLOC_FREE( *pp_printer );
return WERR_NOMEM;
}
ZERO_STRUCTP(printer);
if ( print_hnd )
fstrcpy( servername, print_hnd->servername );
@ -4445,90 +4306,28 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print
standard_sub_basic( "", servername, sizeof(servername)-1 );
}
#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
/*
* check for cache first. A Printer handle cannot changed
* to another printer object so we only check that the printer
* is actually for a printer and that the printer_info pointer
* is valid
*/
if ( print_hnd
&& (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)
&& print_hnd->printer_info )
{
/* get_talloc_ctx() works here because we need a short
lived talloc context */
if ( !(printer->info_2 = dup_printer_2(get_talloc_ctx(), print_hnd->printer_info->info_2)) )
{
DEBUG(0,("get_a_printer: unable to copy cached printer info!\n"));
SAFE_FREE(printer);
return WERR_NOMEM;
}
DEBUG(10,("get_a_printer: using cached copy of printer_info_2\n"));
*pp_printer = printer;
result = WERR_OK;
break;
}
/* no cache for this handle; see if we can match one from another handle.
Make sure to use a short lived talloc ctx */
if ( print_hnd )
result = find_printer_in_print_hnd_cache(get_talloc_ctx(), &printer->info_2, servername, sharename);
/* fail to disk if we don't have it with any open handle */
if ( !print_hnd || !W_ERROR_IS_OK(result) )
result = get_a_printer_2(&printer->info_2, servername, sharename );
#else
result = get_a_printer_2(&printer->info_2, servername, sharename );
#endif
result = get_a_printer_2( (*pp_printer)->info_2, servername, sharename );
/* we have a new printer now. Save it with this handle */
if ( W_ERROR_IS_OK(result) ) {
dump_a_printer(printer, level);
#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
/* save a copy in cache */
if ( print_hnd && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)) {
if ( !print_hnd->printer_info )
print_hnd->printer_info = SMB_MALLOC_P(NT_PRINTER_INFO_LEVEL);
if ( print_hnd->printer_info ) {
/* make sure to use the handle's talloc ctx here since
the printer_2 object must last until the handle is closed */
print_hnd->printer_info->info_2 = dup_printer_2(print_hnd->ctx, printer->info_2);
/* don't fail the lookup just because the cache update failed */
if ( !print_hnd->printer_info->info_2 )
DEBUG(0,("get_a_printer: unable to copy new printer info!\n"));
}
}
#endif
*pp_printer = printer;
if ( !W_ERROR_IS_OK(result) ) {
TALLOC_FREE( *pp_printer );
DEBUG(10,("get_a_printer: [%s] level %u returning %s\n",
sharename, (unsigned int)level, dos_errstr(result)));
return result;
}
else
SAFE_FREE(printer);
dump_a_printer( *pp_printer, level);
break;
default:
result=WERR_UNKNOWN_LEVEL;
break;
TALLOC_FREE( *pp_printer );
return WERR_UNKNOWN_LEVEL;
}
DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, dos_errstr(result)));
return result;
return WERR_OK;
}
/****************************************************************************
@ -4537,30 +4336,25 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print
uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
{
uint32 result;
NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
DEBUG(104,("freeing a printer at level [%d]\n", level));
if (printer == NULL)
if ( !printer )
return 0;
switch (level) {
case 2:
if (printer->info_2 != NULL) {
if ( printer->info_2 )
free_nt_printer_info_level_2(&printer->info_2);
result=0;
} else
result=4;
break;
default:
result=1;
break;
DEBUG(0,("free_a_printer: unknown level! [%d]\n", level ));
return 1;
}
SAFE_FREE(*pp_printer);
return result;
TALLOC_FREE(*pp_printer);
return 0;
}
/****************************************************************************

View File

@ -31,7 +31,7 @@ static TDB_CONTEXT *tdb_reg;
/* List the deepest path into the registry. All part components will be created.*/
/* If you want to have a part of the path controlled by the tdb abd part by
/* If you want to have a part of the path controlled by the tdb and part by
a virtual registry db (e.g. printing), then you have to list the deepest path.
For example,"HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Print"
allows the reg_db backend to handle everything up to
@ -89,12 +89,20 @@ static BOOL init_registry_data( void )
{
pstring path, base, remaining;
fstring keyname, subkeyname;
REGSUBKEY_CTR subkeys;
REGVAL_CTR values;
REGSUBKEY_CTR *subkeys;
REGVAL_CTR *values;
uint32 *ctx;
int i;
const char *p, *p2;
UNISTR2 data;
/* create a new top level talloc ctx */
if ( !(ctx = TALLOC_P( NULL, uint32 )) ) {
DEBUG(0,("init_registry_data: top level talloc() failure!\n"));
return False;
}
/* loop over all of the predefined paths and add each component */
for ( i=0; builtin_registry_paths[i] != NULL; i++ ) {
@ -131,27 +139,33 @@ static BOOL init_registry_data( void )
we are about to update the record. We just want any
subkeys already present */
regsubkey_ctr_init( &subkeys );
regdb_fetch_keys( base, &subkeys );
if ( !(subkeys = TALLOC_ZERO_P( ctx, REGSUBKEY_CTR )) ) {
DEBUG(0,("talloc() failure!\n"));
return False;
}
regdb_fetch_keys( base, subkeys );
if ( *subkeyname )
regsubkey_ctr_addkey( &subkeys, subkeyname );
if ( !regdb_store_keys( base, &subkeys ))
regsubkey_ctr_addkey( subkeys, subkeyname );
if ( !regdb_store_keys( base, subkeys ))
return False;
regsubkey_ctr_destroy( &subkeys );
TALLOC_FREE( subkeys );
}
}
/* loop over all of the predefined values and add each component */
for ( i=0; builtin_registry_values[i].path != NULL; i++ ) {
regval_ctr_init( &values );
regdb_fetch_values( builtin_registry_values[i].path, &values );
if ( !(values = TALLOC_ZERO_P( ctx, REGVAL_CTR )) ) {
DEBUG(0,("talloc() failure!\n"));
return False;
}
regdb_fetch_values( builtin_registry_values[i].path, values );
switch( builtin_registry_values[i].type ) {
case REG_DWORD:
regval_ctr_addvalue( &values,
regval_ctr_addvalue( values,
builtin_registry_values[i].valuename,
REG_DWORD,
(char*)&builtin_registry_values[i].data.dw_value,
@ -160,7 +174,7 @@ static BOOL init_registry_data( void )
case REG_SZ:
init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE);
regval_ctr_addvalue( &values,
regval_ctr_addvalue( values,
builtin_registry_values[i].valuename,
REG_SZ,
(char*)data.buffer,
@ -171,9 +185,9 @@ static BOOL init_registry_data( void )
DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n",
builtin_registry_values[i].type));
}
regdb_store_values( builtin_registry_values[i].path, &values );
regdb_store_values( builtin_registry_values[i].path, values );
regval_ctr_destroy( &values );
TALLOC_FREE( values );
}
return True;
@ -297,13 +311,17 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr )
{
int num_subkeys, i;
pstring path;
REGSUBKEY_CTR subkeys, old_subkeys;
REGSUBKEY_CTR *subkeys, *old_subkeys;
char *oldkeyname;
/* fetch a list of the old subkeys so we can determine if any were deleted */
regsubkey_ctr_init( &old_subkeys );
regdb_fetch_keys( key, &old_subkeys );
if ( !(old_subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) {
DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
return False;
}
regdb_fetch_keys( key, old_subkeys );
/* store the subkey list for the parent */
@ -314,9 +332,9 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr )
/* now delete removed keys */
num_subkeys = regsubkey_ctr_numkeys( &old_subkeys );
num_subkeys = regsubkey_ctr_numkeys( old_subkeys );
for ( i=0; i<num_subkeys; i++ ) {
oldkeyname = regsubkey_ctr_specific_key( &old_subkeys, i );
oldkeyname = regsubkey_ctr_specific_key( old_subkeys, i );
if ( !regsubkey_ctr_key_exists( ctr, oldkeyname ) ) {
pstr_sprintf( path, "%s%c%s", key, '/', oldkeyname );
normalize_reg_path( path );
@ -324,23 +342,29 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr )
}
}
regsubkey_ctr_destroy( &old_subkeys );
TALLOC_FREE( old_subkeys );
/* now create records for any subkeys that don't already exist */
num_subkeys = regsubkey_ctr_numkeys( ctr );
for ( i=0; i<num_subkeys; i++ ) {
pstr_sprintf( path, "%s%c%s", key, '/', regsubkey_ctr_specific_key( ctr, i ) );
regsubkey_ctr_init( &subkeys );
if ( regdb_fetch_keys( path, &subkeys ) == -1 ) {
if ( !(subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) {
DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
return False;
}
if ( regdb_fetch_keys( path, subkeys ) == -1 ) {
/* create a record with 0 subkeys */
if ( !regdb_store_keys_internal( path, &subkeys ) ) {
if ( !regdb_store_keys_internal( path, subkeys ) ) {
DEBUG(0,("regdb_store_keys: Failed to store new record for key [%s}\n", path ));
regsubkey_ctr_destroy( &subkeys );
TALLOC_FREE( subkeys );
return False;
}
}
regsubkey_ctr_destroy( &subkeys );
TALLOC_FREE( subkeys );
}
return True;

View File

@ -38,7 +38,9 @@ REGISTRY_HOOK reg_hooks[] = {
{ KEY_PRINTING, &printing_ops },
{ KEY_PRINTING_2K, &printing_ops },
{ KEY_PRINTING_PORTS, &printing_ops },
#if 0
{ KEY_EVENTLOG, &eventlog_ops },
#endif
{ KEY_SHARES, &shares_reg_ops },
#endif
{ NULL, NULL }
@ -124,9 +126,8 @@ int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
{
static REGSUBKEY_CTR ctr;
static REGSUBKEY_CTR *ctr = NULL;
static pstring save_path;
static BOOL ctr_init = False;
char *s;
*subkey = NULL;
@ -135,32 +136,39 @@ BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index
DEBUG(8,("fetch_reg_keys_specific: Looking for key [%d] of [%s]\n", key_index, key->name));
if ( !ctr_init ) {
if ( !ctr ) {
DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
regsubkey_ctr_init( &ctr );
if ( !(ctr = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
DEBUG(0,("fetch_reg_keys_specific: talloc() failed!\n"));
return False;
}
pstrcpy( save_path, key->name );
if ( fetch_reg_keys( key, &ctr) == -1 )
if ( fetch_reg_keys( key, ctr) == -1 )
return False;
ctr_init = True;
}
/* clear the cache when key_index == 0 or the path has changed */
else if ( !key_index || StrCaseCmp( save_path, key->name) ) {
DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name));
regsubkey_ctr_destroy( &ctr );
regsubkey_ctr_init( &ctr );
TALLOC_FREE( ctr );
if ( !(ctr = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
DEBUG(0,("fetch_reg_keys_specific: talloc() failed!\n"));
return False;
}
pstrcpy( save_path, key->name );
if ( fetch_reg_keys( key, &ctr) == -1 )
if ( fetch_reg_keys( key, ctr) == -1 )
return False;
}
if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
if ( !(s = regsubkey_ctr_specific_key( ctr, key_index )) )
return False;
*subkey = SMB_STRDUP( s );
@ -198,42 +206,46 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 val_index )
{
static REGVAL_CTR ctr;
static REGVAL_CTR *ctr = NULL;
static pstring save_path;
static BOOL ctr_init = False;
REGISTRY_VALUE *v;
*val = NULL;
/* simple caching for performance; very basic heuristic */
if ( !ctr_init ) {
if ( !ctr ) {
DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key->name));
regval_ctr_init( &ctr );
if ( !(ctr = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
DEBUG(0,("fetch_reg_values_specific: talloc() failed!\n"));
return False;
}
pstrcpy( save_path, key->name );
if ( fetch_reg_values( key, &ctr) == -1 )
if ( fetch_reg_values( key, ctr) == -1 )
return False;
ctr_init = True;
}
/* clear the cache when val_index == 0 or the path has changed */
else if ( !val_index || !strequal(save_path, key->name) ) {
DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name));
regval_ctr_destroy( &ctr );
regval_ctr_init( &ctr );
TALLOC_FREE( ctr );
if ( !(ctr = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
DEBUG(0,("fetch_reg_values_specific: talloc() failed!\n"));
return False;
}
pstrcpy( save_path, key->name );
if ( fetch_reg_values( key, &ctr) == -1 )
if ( fetch_reg_values( key, ctr) == -1 )
return False;
}
if ( !(v = regval_ctr_specific_value( &ctr, val_index )) )
if ( !(v = regval_ctr_specific_value( ctr, val_index )) )
return False;
*val = dup_registry_value( v );

View File

@ -25,18 +25,18 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
/**********************************************************************
Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d
since the methods use the object pointer as the talloc context for
internal private data.
There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy()
pair of functions. Simply TALLOC_ZERO_P() and TALLOC_FREE() the
object.
/***********************************************************************
Init the talloc context held by a REGSUBKEY_CTR structure
This now zero's the structure
**********************************************************************/
void regsubkey_ctr_init( REGSUBKEY_CTR *ctr )
{
ZERO_STRUCTP( ctr );
ctr->ctx = talloc_init("regsubkey_ctr_init for ctr %p", ctr);
}
/***********************************************************************
Add a new key to the array
**********************************************************************/
@ -56,16 +56,16 @@ int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname )
/* allocate a space for the char* in the array */
if ( ctr->subkeys == 0 )
ctr->subkeys = TALLOC_P( ctr->ctx, char *);
ctr->subkeys = TALLOC_P( ctr, char *);
else {
pp = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->subkeys, char *, ctr->num_subkeys+1);
pp = TALLOC_REALLOC_ARRAY( ctr, ctr->subkeys, char *, ctr->num_subkeys+1);
if ( pp )
ctr->subkeys = pp;
}
/* allocate the string and save it in the array */
ctr->subkeys[ctr->num_subkeys] = talloc_strdup( ctr->ctx, keyname );
ctr->subkeys[ctr->num_subkeys] = talloc_strdup( ctr, keyname );
ctr->num_subkeys++;
return ctr->num_subkeys;
@ -137,34 +137,10 @@ char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index )
return ctr->subkeys[key_index];
}
/***********************************************************************
free memory held by a REGSUBKEY_CTR structure
**********************************************************************/
void regsubkey_ctr_destroy( REGSUBKEY_CTR *ctr )
{
if ( ctr ) {
talloc_destroy( ctr->ctx );
ZERO_STRUCTP( ctr );
}
}
/*
* Utility functions for REGVAL_CTR
*/
/***********************************************************************
Init the talloc context held by a REGSUBKEY_CTR structure
This now zero's the structure
**********************************************************************/
void regval_ctr_init( REGVAL_CTR *ctr )
{
ZERO_STRUCTP( ctr );
ctr->ctx = talloc_init("regval_ctr_init for ctr %p", ctr);
}
/***********************************************************************
How many keys does the container hold ?
**********************************************************************/
@ -271,17 +247,6 @@ REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
return ctr->values[idx];
}
/***********************************************************************
Retrive the TALLOC_CTX associated with a REGISTRY_VALUE
**********************************************************************/
TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val )
{
if ( !val )
return NULL;
return val->ctx; }
/***********************************************************************
Check for the existance of a value
**********************************************************************/
@ -316,22 +281,22 @@ int regval_ctr_addvalue( REGVAL_CTR *ctr, const char *name, uint16 type,
/* allocate a slot in the array of pointers */
if ( ctr->num_values == 0 )
ctr->values = TALLOC_P( ctr->ctx, REGISTRY_VALUE *);
ctr->values = TALLOC_P( ctr, REGISTRY_VALUE *);
else {
ppreg = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
ppreg = TALLOC_REALLOC_ARRAY( ctr, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
if ( ppreg )
ctr->values = ppreg;
}
/* allocate a new value and store the pointer in the arrya */
ctr->values[ctr->num_values] = TALLOC_P( ctr->ctx, REGISTRY_VALUE);
ctr->values[ctr->num_values] = TALLOC_P( ctr, REGISTRY_VALUE);
/* init the value */
fstrcpy( ctr->values[ctr->num_values]->valuename, name );
ctr->values[ctr->num_values]->type = type;
ctr->values[ctr->num_values]->data_p = TALLOC_MEMDUP( ctr->ctx, data_p, size );
ctr->values[ctr->num_values]->data_p = TALLOC_MEMDUP( ctr, data_p, size );
ctr->values[ctr->num_values]->size = size;
ctr->num_values++;
@ -351,22 +316,22 @@ int regval_ctr_copyvalue( REGVAL_CTR *ctr, REGISTRY_VALUE *val )
/* allocate a slot in the array of pointers */
if ( ctr->num_values == 0 )
ctr->values = TALLOC_P( ctr->ctx, REGISTRY_VALUE *);
ctr->values = TALLOC_P( ctr, REGISTRY_VALUE *);
else {
ppreg = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
ppreg = TALLOC_REALLOC_ARRAY( ctr, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
if ( ppreg )
ctr->values = ppreg;
}
/* allocate a new value and store the pointer in the arrya */
ctr->values[ctr->num_values] = TALLOC_P( ctr->ctx, REGISTRY_VALUE);
ctr->values[ctr->num_values] = TALLOC_P( ctr, REGISTRY_VALUE);
/* init the value */
fstrcpy( ctr->values[ctr->num_values]->valuename, val->valuename );
ctr->values[ctr->num_values]->type = val->type;
ctr->values[ctr->num_values]->data_p = TALLOC_MEMDUP( ctr->ctx, val->data_p, val->size );
ctr->values[ctr->num_values]->data_p = TALLOC_MEMDUP( ctr, val->data_p, val->size );
ctr->values[ctr->num_values]->size = val->size;
ctr->num_values++;
}
@ -420,16 +385,3 @@ REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, const char *name )
return NULL;
}
/***********************************************************************
free memory held by a REGVAL_CTR structure
**********************************************************************/
void regval_ctr_destroy( REGVAL_CTR *ctr )
{
if ( ctr ) {
talloc_destroy( ctr->ctx );
ZERO_STRUCTP( ctr );
}
}

View File

@ -261,7 +261,7 @@ static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
return -1;
}
num_subkeys = get_printer_subkeys( &printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names );
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] );
@ -345,7 +345,7 @@ static BOOL key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
/* get the top level printer keys */
num_existing_keys = get_printer_subkeys( &printer->info_2->data, "", &existing_subkeys );
num_existing_keys = get_printer_subkeys( printer->info_2->data, "", &existing_subkeys );
for ( i=0; i<num_existing_keys; i++ ) {
@ -354,7 +354,7 @@ static BOOL key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
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] );
delete_printer_key( printer->info_2->data, existing_subkeys[i] );
}
}
@ -362,10 +362,10 @@ static BOOL key_printers_store_keys( const char *key, REGSUBKEY_CTR *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 ) {
if ( lookup_printerkey(printer->info_2->data, subkeyname) == -1 ) {
DEBUG(5,("key_printers_store_keys: adding key %s\n",
existing_subkeys[i]));
if ( add_new_printer_key( &printer->info_2->data, subkeyname ) == -1 )
if ( add_new_printer_key( printer->info_2->data, subkeyname ) == -1 )
return False;
}
}
@ -445,7 +445,7 @@ static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *
/* 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);
prs_init( &prs, MAX_PDU_FRAG_LEN, values, MARSHALL);
/* stream the device mode */
@ -508,7 +508,7 @@ static int key_printers_fetch_values( const char *key, REGVAL_CTR *values )
/* iterate over all printer data keys and fill the regval container */
p_data = &printer->info_2->data;
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 */
DEBUG(10,("key_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey));
@ -517,9 +517,9 @@ static int key_printers_fetch_values( const char *key, REGVAL_CTR *values )
return -1;
}
num_values = regval_ctr_numvals( &p_data->keys[key_index].values );
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) );
regval_ctr_copyvalue( values, regval_ctr_specific_value(p_data->keys[key_index].values, i) );
done:
@ -702,7 +702,7 @@ static BOOL key_printers_store_values( const char *key, REGVAL_CTR *values )
int i;
REGISTRY_VALUE *val;
delete_printer_key( &printer->info_2->data, keyname );
delete_printer_key( printer->info_2->data, keyname );
/* deal with any subkeys */
for ( i=0; i<num_values; i++ ) {

View File

@ -1651,8 +1651,6 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (!W_ERROR_IS_OK(out.status))
return out.status;
regval_ctr_init(ctr);
for (i = 0; i < out.returned; i++) {
PRINTER_ENUM_VALUES *v = &out.ctr.values[i];
fstring name;

View File

@ -5356,32 +5356,10 @@ error:
}
BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
NT_PRINTER_INFO_LEVEL_2 **asc)
NT_PRINTER_INFO_LEVEL_2 *d)
{
NT_PRINTER_INFO_LEVEL_2 *d;
time_t time_unix;
DEBUG(7,("Converting from UNICODE to ASCII\n"));
time_unix=time(NULL);
if (*asc==NULL) {
DEBUGADD(8,("allocating memory\n"));
*asc=SMB_MALLOC_P(NT_PRINTER_INFO_LEVEL_2);
if(*asc == NULL)
return False;
ZERO_STRUCTP(*asc);
/* we allocate memory iff called from
* addprinter(ex) so we can do one time stuff here.
*/
(*asc)->setuptime=time_unix;
}
DEBUGADD(8,("start converting\n"));
d=*asc;
d->attributes=uni->attributes;
d->priority=uni->priority;
d->default_priority=uni->default_priority;

View File

@ -125,7 +125,7 @@ static WERROR open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *
{
REGISTRY_KEY *regkey = NULL;
WERROR result = WERR_OK;
REGSUBKEY_CTR subkeys;
REGSUBKEY_CTR *subkeys = NULL;
pstring subkeyname2;
int subkey_len;
@ -167,21 +167,25 @@ static WERROR open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *
if ( !(regkey->hook = reghook_cache_find( regkey->name )) ) {
DEBUG(0,("open_registry_key: Failed to assigned a REGISTRY_HOOK to [%s]\n",
regkey->name ));
return WERR_BADFILE;
result = WERR_BADFILE;
goto done;
}
/* check if the path really exists; failed is indicated by -1 */
/* if the subkey count failed, bail out */
regsubkey_ctr_init( &subkeys );
if ( fetch_reg_keys( regkey, &subkeys ) == -1 ) {
if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) {
result = WERR_NOMEM;
goto done;
}
if ( fetch_reg_keys( regkey, subkeys ) == -1 ) {
result = WERR_BADFILE;
goto done;
}
if ( !create_policy_hnd( p, hnd, free_regkey_info, regkey ) ) {
result = WERR_BADFILE;
result = WERR_BADFILE;
goto done;
}
@ -192,7 +196,7 @@ static WERROR open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *
done:
/* clean up */
regsubkey_ctr_destroy( &subkeys );
TALLOC_FREE( subkeys );
if ( ! NT_STATUS_IS_OK(result) )
SAFE_FREE( regkey );
@ -229,31 +233,32 @@ static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *m
{
int num_subkeys, i;
uint32 max_len;
REGSUBKEY_CTR subkeys;
REGSUBKEY_CTR *subkeys;
uint32 len;
if ( !key )
return False;
regsubkey_ctr_init( &subkeys );
if ( fetch_reg_keys( key, &subkeys ) == -1 )
if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) )
return False;
if ( fetch_reg_keys( key, subkeys ) == -1 )
return False;
/* find the longest string */
max_len = 0;
num_subkeys = regsubkey_ctr_numkeys( &subkeys );
num_subkeys = regsubkey_ctr_numkeys( subkeys );
for ( i=0; i<num_subkeys; i++ ) {
len = strlen( regsubkey_ctr_specific_key(&subkeys, i) );
len = strlen( regsubkey_ctr_specific_key(subkeys, i) );
max_len = MAX(max_len, len);
}
*maxnum = num_subkeys;
*maxlen = max_len*2;
regsubkey_ctr_destroy( &subkeys );
TALLOC_FREE( subkeys );
return True;
}
@ -265,7 +270,7 @@ static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *m
static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
uint32 *maxlen, uint32 *maxsize )
{
REGVAL_CTR values;
REGVAL_CTR *values;
REGISTRY_VALUE *val;
uint32 sizemax, lenmax;
int i, num_values;
@ -273,29 +278,30 @@ static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
if ( !key )
return False;
regval_ctr_init( &values );
if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) )
return False;
if ( fetch_reg_values( key, &values ) == -1 )
if ( fetch_reg_values( key, values ) == -1 )
return False;
lenmax = sizemax = 0;
num_values = regval_ctr_numvals( &values );
num_values = regval_ctr_numvals( values );
val = regval_ctr_specific_value( &values, 0 );
val = regval_ctr_specific_value( values, 0 );
for ( i=0; i<num_values && val; i++ )
{
lenmax = MAX(lenmax, val->valuename ? strlen(val->valuename)+1 : 0 );
sizemax = MAX(sizemax, val->size );
val = regval_ctr_specific_value( &values, i );
val = regval_ctr_specific_value( values, i );
}
*maxnum = num_values;
*maxlen = lenmax;
*maxsize = sizemax;
regval_ctr_destroy( &values );
TALLOC_FREE( values );
return True;
}
@ -400,7 +406,7 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
/* check granted access first; what is the correct mask here? */
if ( !(parent->access_granted & (SEC_RIGHTS_ENUM_SUBKEYS|SEC_RIGHTS_CREATE_SUBKEY)) )
if ( !(parent->access_granted & (SEC_RIGHTS_ENUM_SUBKEYS|SEC_RIGHTS_CREATE_SUBKEY|SEC_RIGHTS_QUERY_VALUE|SEC_RIGHTS_SET_VALUE)) )
return WERR_ACCESS_DENIED;
/* open the key first to get the appropriate REGISTRY_HOOK
@ -435,7 +441,7 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL
fstring name;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
REGISTRY_VALUE *val = NULL;
REGVAL_CTR regvals;
REGVAL_CTR *regvals;
int i;
if ( !regkey )
@ -447,7 +453,8 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL
DEBUG(5,("reg_info: looking up value: [%s]\n", name));
regval_ctr_init( &regvals );
if ( !(regvals = TALLOC_P( p->mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ )
{
@ -463,7 +470,7 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL
init_reg_r_query_value(q_u->ptr_buf, r_u, val, status);
regval_ctr_destroy( &regvals );
TALLOC_FREE( regvals );
free_registry_value( val );
return status;
@ -774,8 +781,8 @@ static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
{
REGF_NK_REC *subkey;
REGISTRY_KEY registry_key;
REGVAL_CTR values;
REGSUBKEY_CTR subkeys;
REGVAL_CTR *values;
REGSUBKEY_CTR *subkeys;
int i;
pstring path;
WERROR result = WERR_OK;
@ -791,13 +798,16 @@ static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
/* now start parsing the values and subkeys */
regsubkey_ctr_init( &subkeys );
regval_ctr_init( &values );
if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
return WERR_NOMEM;
if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
return WERR_NOMEM;
/* copy values into the REGVAL_CTR */
for ( i=0; i<key->num_values; i++ ) {
regval_ctr_addvalue( &values, key->values[i].valuename, key->values[i].type,
regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type,
key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) );
}
@ -805,20 +815,19 @@ static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
key->subkey_index = 0;
while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
regsubkey_ctr_addkey( &subkeys, subkey->keyname );
regsubkey_ctr_addkey( subkeys, subkey->keyname );
}
/* write this key and values out */
if ( !store_reg_values( &registry_key, &values )
|| !store_reg_keys( &registry_key, &subkeys ) )
if ( !store_reg_values( &registry_key, values )
|| !store_reg_keys( &registry_key, subkeys ) )
{
DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
result = WERR_REG_IO_FAILURE;
}
regval_ctr_destroy( &values );
regsubkey_ctr_destroy( &subkeys );
TALLOC_FREE( subkeys );
if ( !W_ERROR_IS_OK(result) )
return result;
@ -904,8 +913,8 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
REGF_NK_REC *parent, SEC_DESC *sec_desc )
{
REGF_NK_REC *key;
REGVAL_CTR values;
REGSUBKEY_CTR subkeys;
REGVAL_CTR *values;
REGSUBKEY_CTR *subkeys;
int i, num_subkeys;
pstring key_tmp;
char *keyname, *parentpath;
@ -939,24 +948,27 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
/* lookup the values and subkeys */
regsubkey_ctr_init( &subkeys );
regval_ctr_init( &values );
fetch_reg_keys( &registry_key, &subkeys );
fetch_reg_values( &registry_key, &values );
if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
return WERR_NOMEM;
if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
return WERR_NOMEM;
fetch_reg_keys( &registry_key, subkeys );
fetch_reg_values( &registry_key, values );
/* write out this key */
if ( !(key = regfio_write_key( regfile, keyname, &values, &subkeys, sec_desc, parent )) ) {
if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) {
result = WERR_CAN_NOT_COMPLETE;
goto done;
}
/* write each one of the subkeys out */
num_subkeys = regsubkey_ctr_numkeys( &subkeys );
num_subkeys = regsubkey_ctr_numkeys( subkeys );
for ( i=0; i<num_subkeys; i++ ) {
subkeyname = regsubkey_ctr_specific_key( &subkeys, i );
subkeyname = regsubkey_ctr_specific_key( subkeys, i );
pstr_sprintf( subkeypath, "%s\\%s", keypath, subkeyname );
result = reg_write_tree( regfile, subkeypath, key, sec_desc );
if ( !W_ERROR_IS_OK(result) )
@ -966,8 +978,7 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath ));
done:
regval_ctr_destroy( &values );
regsubkey_ctr_destroy( &subkeys );
TALLOC_FREE( subkeys );
return result;
}
@ -1079,7 +1090,7 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT
REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->handle);
REGISTRY_KEY *newparent;
POLICY_HND newparent_handle;
REGSUBKEY_CTR subkeys;
REGSUBKEY_CTR *subkeys;
BOOL write_result;
pstring name;
WERROR result;
@ -1138,19 +1149,22 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT
goto done;
}
regsubkey_ctr_init( &subkeys );
if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) {
result = WERR_NOMEM;
goto done;
}
/* (4) lookup the current keys and add the new one */
fetch_reg_keys( newparent, &subkeys );
regsubkey_ctr_addkey( &subkeys, name );
fetch_reg_keys( newparent, subkeys );
regsubkey_ctr_addkey( subkeys, name );
/* now write to the registry backend */
write_result = store_reg_keys( newparent, &subkeys );
regsubkey_ctr_destroy( &subkeys );
write_result = store_reg_keys( newparent, subkeys );
TALLOC_FREE( subkeys );
if ( !write_result )
return WERR_REG_IO_FAILURE;
@ -1177,7 +1191,7 @@ done:
WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r_u)
{
REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle);
REGVAL_CTR values;
REGVAL_CTR *values;
BOOL write_result;
fstring valuename;
@ -1198,19 +1212,20 @@ WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r
DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n", key->name, valuename));
regval_ctr_init( &values );
if ( !(values = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
/* lookup the current values and add the new one */
fetch_reg_values( key, &values );
fetch_reg_values( key, values );
regval_ctr_addvalue( &values, valuename, q_u->type, q_u->value.buffer, q_u->value.buf_len );
regval_ctr_addvalue( values, valuename, q_u->type, q_u->value.buffer, q_u->value.buf_len );
/* now write to the registry backend */
write_result = store_reg_values( key, &values );
write_result = store_reg_values( key, values );
regval_ctr_destroy( &values );
TALLOC_FREE( values );
if ( !write_result )
return WERR_REG_IO_FAILURE;
@ -1226,7 +1241,7 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY
REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->handle);
REGISTRY_KEY *newparent;
POLICY_HND newparent_handle;
REGSUBKEY_CTR subkeys;
REGSUBKEY_CTR *subkeys;
BOOL write_result;
pstring name;
WERROR result;
@ -1285,19 +1300,22 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY
goto done;
}
regsubkey_ctr_init( &subkeys );
if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) {
result = WERR_NOMEM;
goto done;
}
/* lookup the current keys and delete the new one */
fetch_reg_keys( newparent, &subkeys );
fetch_reg_keys( newparent, subkeys );
regsubkey_ctr_delkey( &subkeys, name );
regsubkey_ctr_delkey( subkeys, name );
/* now write to the registry backend */
write_result = store_reg_keys( newparent, &subkeys );
write_result = store_reg_keys( newparent, subkeys );
regsubkey_ctr_destroy( &subkeys );
TALLOC_FREE( subkeys );
result = write_result ? WERR_OK : WERR_REG_IO_FAILURE;
@ -1317,7 +1335,7 @@ done:
WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE_VALUE *r_u)
{
REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle);
REGVAL_CTR values;
REGVAL_CTR *values;
BOOL write_result;
fstring valuename;
@ -1336,19 +1354,20 @@ WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE
DEBUG(8,("_reg_delete_value: Setting value for [%s:%s]\n", key->name, valuename));
regval_ctr_init( &values );
if ( !(values = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
/* lookup the current values and add the new one */
fetch_reg_values( key, &values );
fetch_reg_values( key, values );
regval_ctr_delvalue( &values, valuename );
regval_ctr_delvalue( values, valuename );
/* now write to the registry backend */
write_result = store_reg_values( key, &values );
write_result = store_reg_values( key, values );
regval_ctr_destroy( &values );
TALLOC_FREE( values );
if ( !write_result )
return WERR_REG_IO_FAILURE;

View File

@ -274,62 +274,6 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd
return find_printer;
}
#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
/****************************************************************************
look for a printer object cached on an open printer handle
****************************************************************************/
WERROR find_printer_in_print_hnd_cache( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 **info2,
const char *servername, const char *printername )
{
Printer_entry *p;
DEBUG(10,("find_printer_in_print_hnd_cache: printer [\\\\%s\\%s]\n",
servername, printername));
for ( p=printers_list; p; p=p->next )
{
if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER
&& p->printer_info
&& strequal( p->sharename, printername )
&& strequal( p->servername, servername ) )
{
DEBUG(10,("Found printer\n"));
*info2 = dup_printer_2( ctx, p->printer_info->info_2 );
if ( *info2 )
return WERR_OK;
}
}
return WERR_INVALID_PRINTER_NAME;
}
/****************************************************************************
destroy any cached printer_info_2 structures on open handles
****************************************************************************/
void invalidate_printer_hnd_cache( char *printername )
{
Printer_entry *p;
DEBUG(10,("invalidate_printer_hnd_cache: printer [%s]\n", printername));
for ( p=printers_list; p; p=p->next )
{
if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER
&& p->printer_info
&& StrCaseCmp(p->sharename, printername)==0)
{
DEBUG(10,("invalidating printer_info cache for handl:\n"));
free_a_printer( &p->printer_info, 2 );
p->printer_info = NULL;
}
}
return;
}
#endif
/****************************************************************************
Close printer index by handle.
****************************************************************************/
@ -1216,24 +1160,6 @@ static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, siz
return;
}
#ifdef ENABLE_PRINT_HND_OBJECT_CACHE
/********************************************************************
callback to MSG_PRINTER_CHANGED. When a printer is changed by
one smbd, all of processes must clear their printer cache immediately.
********************************************************************/
void receive_printer_mod_msg(int msg_type, pid_t src, void *buf, size_t len)
{
fstring printername;
fstrcpy( printername, buf );
DEBUG(10,("receive_printer_mod_msg: Printer change [%s]\n", printername ));
invalidate_printer_hnd_cache( printername );
}
#endif
/********************************************************************
Send a message to ourself about new driver being installed
so we can upgrade the information for each printer bound to this
@ -1804,7 +1730,10 @@ static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
switch (level) {
case 2:
ret = uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
/* printer->info_2 is already a valid printer */
ret = uni_2_asc_printer_info_2(uni->info_2, printer->info_2);
printer->info_2->setuptime = time(NULL);
break;
default:
break;
@ -2272,8 +2201,8 @@ static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char
WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
uint32 type, uint8 *data, int real_len )
{
delete_printer_data( printer->info_2, key, value );
/* the registry objects enforce uniqueness based on value name */
return add_printer_data( printer->info_2, key, value, type, data, real_len );
}
@ -4234,22 +4163,19 @@ static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *p
printer->cjobs = count; /* jobs */
printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
if((printer->devmode = construct_dev_mode(snum)) == NULL) {
if ( !(printer->devmode = construct_dev_mode(snum)) )
DEBUG(8, ("Returning NULL Devicemode!\n"));
}
if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
/* steal the printer info sec_desc structure. [badly done]. */
printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen memory. */
ntprinter->info_2->secdesc_buf->len = 0; /* Stolen memory. */
ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen memory. */
}
else {
printer->secdesc = NULL;
printer->secdesc = NULL;
if ( ntprinter->info_2->secdesc_buf
&& ntprinter->info_2->secdesc_buf->len != 0 )
{
printer->secdesc = dup_sec_desc( get_talloc_ctx(), ntprinter->info_2->secdesc_buf->sec );
}
free_a_printer(&ntprinter, 2);
return True;
}
@ -4274,32 +4200,12 @@ static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **
ZERO_STRUCTP(printer);
printer->flags = 4; /* These are the components of the SD we are returning. */
/* These are the components of the SD we are returning. */
printer->flags = 0x4;
if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
/* steal the printer info sec_desc structure. [badly done]. */
printer->secdesc = ntprinter->info_2->secdesc_buf->sec;
#if 0
/*
* Set the flags for the components we are returning.
*/
if (printer->secdesc->owner_sid)
printer->flags |= OWNER_SECURITY_INFORMATION;
if (printer->secdesc->grp_sid)
printer->flags |= GROUP_SECURITY_INFORMATION;
if (printer->secdesc->dacl)
printer->flags |= DACL_SECURITY_INFORMATION;
if (printer->secdesc->sacl)
printer->flags |= SACL_SECURITY_INFORMATION;
#endif
ntprinter->info_2->secdesc_buf->sec = NULL; /* Stolen the malloced memory. */
ntprinter->info_2->secdesc_buf->len = 0; /* Stolen the malloced memory. */
ntprinter->info_2->secdesc_buf->max_len = 0; /* Stolen the malloced memory. */
printer->secdesc = dup_sec_desc( get_talloc_ctx(), ntprinter->info_2->secdesc_buf->sec );
}
free_a_printer(&ntprinter, 2);
@ -4582,16 +4488,20 @@ static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint3
if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
if (construct_printer_info_2(NULL, &current_prt, snum)) {
if((tp=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) == NULL) {
if (construct_printer_info_2(NULL, &current_prt, snum))
{
if ( !(tp=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
SAFE_FREE(printers);
*returned = 0;
return WERR_NOMEM;
}
else printers = tp;
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
printers = tp;
memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_2));
(*returned)++;
}
}
@ -4617,9 +4527,10 @@ static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint3
out:
/* clear memory */
for (i=0; i<*returned; i++) {
for (i=0; i<*returned; i++)
free_devmode(printers[i].devmode);
}
SAFE_FREE(printers);
if ( !W_ERROR_IS_OK(result) )
@ -7905,8 +7816,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
int i, key_index, num_values;
int name_length;
ZERO_STRUCT( printer );
*out_type = 0;
*out_max_data_len = 0;
@ -7927,7 +7836,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
if (!W_ERROR_IS_OK(result))
return result;
p_data = &printer->info_2->data;
p_data = printer->info_2->data;
key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
result = WERR_OK;
@ -7945,11 +7854,11 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
biggest_valuesize = 0;
biggest_datasize = 0;
num_values = regval_ctr_numvals( &p_data->keys[key_index].values );
num_values = regval_ctr_numvals( p_data->keys[key_index].values );
for ( i=0; i<num_values; i++ )
{
val = regval_ctr_specific_value( &p_data->keys[key_index].values, i );
val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
name_length = strlen(val->valuename);
if ( strlen(val->valuename) > biggest_valuesize )
@ -7979,7 +7888,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
*/
if ( key_index != -1 )
val = regval_ctr_specific_value( &p_data->keys[key_index].values, idx );
val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
if ( !val )
{
@ -8937,7 +8846,7 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u,
goto done;
}
if ( lookup_printerkey( &printer->info_2->data, keyname ) == -1 ) {
if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname ));
free_a_printer( &printer, 2 );
status = WERR_BADFILE;
@ -9158,7 +9067,7 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO
/* get the list of subkey names */
unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 );
data = &printer->info_2->data;
data = printer->info_2->data;
num_keys = get_printer_subkeys( data, key, &keynames );
@ -9301,7 +9210,7 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
/* now look for a match on the key name */
p_data = &printer->info_2->data;
p_data = printer->info_2->data;
unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
@ -9316,7 +9225,7 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
/* allocate the memory for the array of pointers -- if necessary */
num_entries = regval_ctr_numvals( &p_data->keys[key_index].values );
num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
if ( num_entries )
{
if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
@ -9339,7 +9248,7 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
{
/* lookup the registry value */
val = regval_ctr_specific_value( &p_data->keys[key_index].values, i );
val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
/* copy the data */

View File

@ -2293,7 +2293,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
fstring servername, user;
const char *keyname = NULL;
POLICY_HND hnd;
REGVAL_CTR ctr;
REGVAL_CTR *ctr = NULL;
if (argc != 3) {
printf("Usage: %s printername <keyname>\n", argv[0]);
@ -2322,16 +2322,19 @@ static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
/* Enumerate subkeys */
result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, &ctr);
if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr);
if (!W_ERROR_IS_OK(result))
goto done;
for (i=0; i < ctr.num_values; i++) {
display_reg_value(*(ctr.values[i]));
for (i=0; i < ctr->num_values; i++) {
display_reg_value(*(ctr->values[i]));
}
regval_ctr_destroy(&ctr);
TALLOC_FREE( ctr );
done:
if (got_hnd)

View File

@ -2159,7 +2159,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
BOOL got_dst_spoolss_pipe = False;
POLICY_HND hnd_src, hnd_dst;
PRINTER_INFO_CTR ctr_enum, ctr_dst, ctr_dst_publish;
REGVAL_CTR reg_ctr;
REGVAL_CTR *reg_ctr;
struct cli_state *cli_dst = NULL;
char *devicename = NULL, *unc_name = NULL, *url = NULL;
fstring longname;
@ -2351,13 +2351,16 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
curkey += strlen(subkey) + 1;
if ( !(reg_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
return NT_STATUS_NO_MEMORY;
/* enumerate all src subkeys */
if (!net_spoolss_enumprinterdataex(cli, mem_ctx, 0,
&hnd_src, subkey,
&reg_ctr))
reg_ctr))
goto done;
for (j=0; j < reg_ctr.num_values; j++) {
for (j=0; j < reg_ctr->num_values; j++) {
REGISTRY_VALUE value;
UNISTR2 data;
@ -2365,20 +2368,20 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
/* although samba replies with sane data in most cases we
should try to avoid writing wrong registry data */
if (strequal(reg_ctr.values[j]->valuename, SPOOL_REG_PORTNAME) ||
strequal(reg_ctr.values[j]->valuename, SPOOL_REG_UNCNAME) ||
strequal(reg_ctr.values[j]->valuename, SPOOL_REG_URL) ||
strequal(reg_ctr.values[j]->valuename, SPOOL_REG_SHORTSERVERNAME) ||
strequal(reg_ctr.values[j]->valuename, SPOOL_REG_SERVERNAME)) {
if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_PORTNAME) ||
strequal(reg_ctr->values[j]->valuename, SPOOL_REG_UNCNAME) ||
strequal(reg_ctr->values[j]->valuename, SPOOL_REG_URL) ||
strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SHORTSERVERNAME) ||
strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SERVERNAME)) {
if (strequal(reg_ctr.values[j]->valuename, SPOOL_REG_PORTNAME)) {
if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_PORTNAME)) {
/* although windows uses a multi-sz, we use a sz */
init_unistr2(&data, SAMBA_PRINTER_PORT_NAME, UNI_STR_TERMINATE);
fstrcpy(value.valuename, SPOOL_REG_PORTNAME);
}
if (strequal(reg_ctr.values[j]->valuename, SPOOL_REG_UNCNAME)) {
if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_UNCNAME)) {
if (asprintf(&unc_name, "\\\\%s\\%s", longname, sharename) < 0) {
nt_status = NT_STATUS_NO_MEMORY;
@ -2388,7 +2391,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
fstrcpy(value.valuename, SPOOL_REG_UNCNAME);
}
if (strequal(reg_ctr.values[j]->valuename, SPOOL_REG_URL)) {
if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_URL)) {
continue;
@ -2403,13 +2406,13 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
#endif
}
if (strequal(reg_ctr.values[j]->valuename, SPOOL_REG_SERVERNAME)) {
if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SERVERNAME)) {
init_unistr2(&data, longname, UNI_STR_TERMINATE);
fstrcpy(value.valuename, SPOOL_REG_SERVERNAME);
}
if (strequal(reg_ctr.values[j]->valuename, SPOOL_REG_SHORTSERVERNAME)) {
if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SHORTSERVERNAME)) {
init_unistr2(&data, global_myname(), UNI_STR_TERMINATE);
fstrcpy(value.valuename, SPOOL_REG_SHORTSERVERNAME);
@ -2430,21 +2433,21 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
} else {
if (opt_verbose)
display_reg_value(subkey, *(reg_ctr.values[j]));
display_reg_value(subkey, *(reg_ctr->values[j]));
/* here we have to set all subkeys on the dst server */
if (!net_spoolss_setprinterdataex(cli_dst, mem_ctx, &hnd_dst,
subkey, reg_ctr.values[j]))
subkey, reg_ctr->values[j]))
goto done;
}
DEBUGADD(1,("\tSetPrinterDataEx of key [%s\\%s] succeeded\n",
subkey, reg_ctr.values[j]->valuename));
subkey, reg_ctr->values[j]->valuename));
}
regval_ctr_destroy(&reg_ctr);
TALLOC_FREE( reg_ctr );
}
safe_free(keylist);

View File

@ -331,28 +331,35 @@ static BOOL write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
const char *parentpath )
{
REGF_NK_REC *key, *subkey;
REGVAL_CTR values;
REGSUBKEY_CTR subkeys;
REGVAL_CTR *values;
REGSUBKEY_CTR *subkeys;
int i;
pstring path;
regsubkey_ctr_init( &subkeys );
regval_ctr_init( &values );
if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
DEBUG(0,("write_registry_tree: talloc() failed!\n"));
return False;
}
if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
DEBUG(0,("write_registry_tree: talloc() failed!\n"));
return False;
}
/* copy values into the REGVAL_CTR */
for ( i=0; i<nk->num_values; i++ ) {
regval_ctr_addvalue( &values, nk->values[i].valuename, nk->values[i].type,
regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
}
/* copy subkeys into the REGSUBKEY_CTR */
while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
regsubkey_ctr_addkey( &subkeys, subkey->keyname );
regsubkey_ctr_addkey( subkeys, subkey->keyname );
}
key = regfio_write_key( outfile, nk->keyname, &values, &subkeys, nk->sec_desc->sec_desc, parent );
key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
/* write each one of the subkeys out */
@ -362,8 +369,7 @@ static BOOL write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
write_registry_tree( infile, subkey, key, outfile, path );
}
regval_ctr_destroy( &values );
regsubkey_ctr_destroy( &subkeys );
TALLOC_FREE( subkeys );
d_printf("[%s]\n", path );

View File

@ -67,8 +67,8 @@ static BOOL copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
{
REGF_NK_REC *key, *subkey;
SEC_DESC *new_sd;
REGVAL_CTR values;
REGSUBKEY_CTR subkeys;
REGVAL_CTR *values;
REGSUBKEY_CTR *subkeys;
int i;
pstring path;
@ -82,23 +82,30 @@ static BOOL copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
if ( swap_sid_in_acl( new_sd, &old_sid, &new_sid ) )
DEBUG(2,("Updating ACL for %s\n", nk->keyname ));
regsubkey_ctr_init( &subkeys );
regval_ctr_init( &values );
if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
return False;
}
if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
return False;
}
/* copy values into the REGVAL_CTR */
for ( i=0; i<nk->num_values; i++ ) {
regval_ctr_addvalue( &values, nk->values[i].valuename, nk->values[i].type,
regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
}
/* copy subkeys into the REGSUBKEY_CTR */
while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
regsubkey_ctr_addkey( &subkeys, subkey->keyname );
regsubkey_ctr_addkey( subkeys, subkey->keyname );
}
key = regfio_write_key( outfile, nk->keyname, &values, &subkeys, new_sd, parent );
key = regfio_write_key( outfile, nk->keyname, values, subkeys, new_sd, parent );
/* write each one of the subkeys out */
@ -110,8 +117,9 @@ static BOOL copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
return False;
}
regval_ctr_destroy( &values );
regsubkey_ctr_destroy( &subkeys );
/* values is a talloc()'d child of subkeys here so just throw it all away */
TALLOC_FREE( subkeys );
DEBUG(1,("[%s]\n", path));