582a696529f1341bd2214e85cc5ed02ee59c87cd
[tprouty/samba.git] / source / registry / reg_objects.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  Virtual Windows Registry Layer
4  *  Copyright (C) Gerald Carter                     2002-2005
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 /* Implementation of registry frontend view functions. */
22
23 #include "includes.h"
24
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_SRV
27
28
29 /***********************************************************************
30  Init the talloc context held by a REGSUBKEY_CTR structure
31  This now zero's the structure
32  **********************************************************************/
33
34 void regsubkey_ctr_init( REGSUBKEY_CTR *ctr )
35 {
36         ZERO_STRUCTP( ctr );
37         ctr->ctx = talloc_init("regsubkey_ctr_init for ctr %p", ctr);
38 }
39
40 /***********************************************************************
41  Add a new key to the array
42  **********************************************************************/
43
44 int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname )
45 {
46         char **pp;
47
48         if ( !keyname )
49                 return ctr->num_subkeys;
50
51         /* make sure the keyname is not already there */
52
53         if ( regsubkey_ctr_key_exists( ctr, keyname ) )
54                 return ctr->num_subkeys;
55                 
56         /* allocate a space for the char* in the array */
57                 
58         if (  ctr->subkeys == 0 )
59                 ctr->subkeys = TALLOC_P( ctr->ctx, char *);
60         else {
61                 pp = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->subkeys, char *, ctr->num_subkeys+1);
62                 if ( pp )
63                         ctr->subkeys = pp;
64         }
65
66         /* allocate the string and save it in the array */
67         
68         ctr->subkeys[ctr->num_subkeys] = talloc_strdup( ctr->ctx, keyname );
69         ctr->num_subkeys++;
70         
71         return ctr->num_subkeys;
72 }
73  
74  /***********************************************************************
75  Add a new key to the array
76  **********************************************************************/
77
78 int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname )
79 {
80         int i;
81
82         if ( !keyname )
83                 return ctr->num_subkeys;
84
85         /* make sure the keyname is actually already there */
86
87         for ( i=0; i<ctr->num_subkeys; i++ ) {
88                 if ( strequal( ctr->subkeys[i], keyname ) )
89                         break;
90         }
91         
92         if ( i == ctr->num_subkeys )
93                 return ctr->num_subkeys;
94
95         /* update if we have any keys left */
96         ctr->num_subkeys--;
97         if ( ctr->num_subkeys )
98                 memmove( &ctr->subkeys[i], &ctr->subkeys[i+1], sizeof(char*) * (ctr->num_subkeys-i) );
99         
100         return ctr->num_subkeys;
101 }
102
103 /***********************************************************************
104  Check for the existance of a key
105  **********************************************************************/
106
107 BOOL regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname )
108 {
109         int     i;
110         
111         for ( i=0; i<ctr->num_subkeys; i++ ) {
112                 if ( strequal( ctr->subkeys[i],keyname ) )
113                         return True;
114         }
115         
116         return False;
117
118 }
119
120 /***********************************************************************
121  How many keys does the container hold ?
122  **********************************************************************/
123
124 int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr )
125 {
126         return ctr->num_subkeys;
127 }
128
129 /***********************************************************************
130  Retreive a specific key string
131  **********************************************************************/
132
133 char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index )
134 {
135         if ( ! (key_index < ctr->num_subkeys) )
136                 return NULL;
137                 
138         return ctr->subkeys[key_index];
139 }
140
141 /***********************************************************************
142  free memory held by a REGSUBKEY_CTR structure
143  **********************************************************************/
144
145 void regsubkey_ctr_destroy( REGSUBKEY_CTR *ctr )
146 {
147         if ( ctr ) {
148                 talloc_destroy( ctr->ctx );     
149                 ZERO_STRUCTP( ctr );
150         }
151 }
152
153
154 /*
155  * Utility functions for REGVAL_CTR
156  */
157
158 /***********************************************************************
159  Init the talloc context held by a REGSUBKEY_CTR structure
160  This now zero's the structure
161  **********************************************************************/
162
163 void regval_ctr_init( REGVAL_CTR *ctr )
164 {
165         ZERO_STRUCTP( ctr );
166         ctr->ctx = talloc_init("regval_ctr_init for ctr %p", ctr);
167 }
168
169 /***********************************************************************
170  How many keys does the container hold ?
171  **********************************************************************/
172
173 int regval_ctr_numvals( REGVAL_CTR *ctr )
174 {
175         return ctr->num_values;
176 }
177
178 /***********************************************************************
179  allocate memory for and duplicate a REGISTRY_VALUE.
180  This is malloc'd memory so the caller should free it when done
181  **********************************************************************/
182
183 REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
184 {
185         REGISTRY_VALUE  *copy = NULL;
186         
187         if ( !val )
188                 return NULL;
189         
190         if ( !(copy = SMB_MALLOC_P( REGISTRY_VALUE)) ) {
191                 DEBUG(0,("dup_registry_value: malloc() failed!\n"));
192                 return NULL;
193         }
194         
195         /* copy all the non-pointer initial data */
196         
197         memcpy( copy, val, sizeof(REGISTRY_VALUE) );
198         if ( val->data_p ) 
199         {
200                 if ( !(copy->data_p = memdup( val->data_p, val->size )) ) {
201                         DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
202                                 val->size));
203                         SAFE_FREE( copy );
204                 }
205         }
206         
207         return copy;    
208 }
209
210 /**********************************************************************
211  free the memory allocated to a REGISTRY_VALUE 
212  *********************************************************************/
213  
214 void free_registry_value( REGISTRY_VALUE *val )
215 {
216         if ( !val )
217                 return;
218                 
219         SAFE_FREE( val->data_p );
220         SAFE_FREE( val );
221         
222         return;
223 }
224
225 /**********************************************************************
226  *********************************************************************/
227
228 uint8* regval_data_p( REGISTRY_VALUE *val )
229 {
230         return val->data_p;
231 }
232
233 /**********************************************************************
234  *********************************************************************/
235
236 int regval_size( REGISTRY_VALUE *val )
237 {
238         return val->size;
239 }
240
241 /**********************************************************************
242  *********************************************************************/
243
244 char* regval_name( REGISTRY_VALUE *val )
245 {
246         return val->valuename;
247 }
248
249 /**********************************************************************
250  *********************************************************************/
251
252 uint32 regval_type( REGISTRY_VALUE *val )
253 {
254         return val->type;
255 }
256
257 /***********************************************************************
258  Retreive a pointer to a specific value.  Caller shoud dup the structure
259  since this memory may go away with a regval_ctr_destroy()
260  **********************************************************************/
261
262 REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
263 {
264         if ( !(idx < ctr->num_values) )
265                 return NULL;
266                 
267         return ctr->values[idx];
268 }
269
270 /***********************************************************************
271  Retrive the TALLOC_CTX associated with a REGISTRY_VALUE 
272  **********************************************************************/
273
274 TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val )
275 {
276         if ( !val )
277                 return NULL;
278
279         return val->ctx;
280 }
281
282 /***********************************************************************
283  Add a new registry value to the array
284  **********************************************************************/
285
286 int regval_ctr_addvalue( REGVAL_CTR *ctr, const char *name, uint16 type, 
287                          const char *data_p, size_t size )
288 {
289         REGISTRY_VALUE **ppreg;
290         
291         if ( !name )
292                 return ctr->num_values;
293
294         /* allocate a slot in the array of pointers */
295                 
296         if (  ctr->num_values == 0 )
297                 ctr->values = TALLOC_P( ctr->ctx, REGISTRY_VALUE *);
298         else {
299                 ppreg = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
300                 if ( ppreg )
301                         ctr->values = ppreg;
302         }
303
304         /* allocate a new value and store the pointer in the arrya */
305                 
306         ctr->values[ctr->num_values] = TALLOC_P( ctr->ctx, REGISTRY_VALUE);
307
308         /* init the value */
309         
310         fstrcpy( ctr->values[ctr->num_values]->valuename, name );
311         ctr->values[ctr->num_values]->type = type;
312         ctr->values[ctr->num_values]->data_p = TALLOC_MEMDUP( ctr->ctx, data_p, size );
313         ctr->values[ctr->num_values]->size = size;
314         ctr->num_values++;
315
316         return ctr->num_values;
317 }
318
319 /***********************************************************************
320  Add a new registry value to the array
321  **********************************************************************/
322
323 int regval_ctr_copyvalue( REGVAL_CTR *ctr, REGISTRY_VALUE *val )
324 {
325         REGISTRY_VALUE **ppreg;
326         
327         if ( val )
328         {
329                 /* allocate a slot in the array of pointers */
330                 
331                 if (  ctr->num_values == 0 )
332                         ctr->values = TALLOC_P( ctr->ctx, REGISTRY_VALUE *);
333                 else {
334                         ppreg = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
335                         if ( ppreg )
336                                 ctr->values = ppreg;
337                 }
338
339                 /* allocate a new value and store the pointer in the arrya */
340                 
341                 ctr->values[ctr->num_values] = TALLOC_P( ctr->ctx, REGISTRY_VALUE);
342
343                 /* init the value */
344         
345                 fstrcpy( ctr->values[ctr->num_values]->valuename, val->valuename );
346                 ctr->values[ctr->num_values]->type = val->type;
347                 ctr->values[ctr->num_values]->data_p = TALLOC_MEMDUP( ctr->ctx, val->data_p, val->size );
348                 ctr->values[ctr->num_values]->size = val->size;
349                 ctr->num_values++;
350         }
351
352         return ctr->num_values;
353 }
354
355 /***********************************************************************
356  Delete a single value from the registry container.
357  No need to free memory since it is talloc'd.
358  **********************************************************************/
359
360 int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name )
361 {
362         int     i;
363         
364         /* search for the value */
365         if (!(ctr->num_values))
366                 return 0;
367         
368         for ( i=0; i<ctr->num_values; i++ ) {
369                 if ( strcmp( ctr->values[i]->valuename, name ) == 0)
370                         break;
371         }
372         
373         /* just return if we don't find it */
374         
375         if ( i == ctr->num_values )
376                 return ctr->num_values;
377         
378         /* just shift everything down one */
379         
380         for ( /* use previous i */; i<(ctr->num_values-1); i++ )
381                 memcpy( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE) );
382                 
383         /* paranoia */
384         
385         ZERO_STRUCTP( ctr->values[i] );
386         
387         ctr->num_values--;
388         
389         return ctr->num_values;
390 }
391
392 /***********************************************************************
393  Retrieve single value from the registry container.
394  No need to free memory since it is talloc'd.
395  **********************************************************************/
396
397 REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, const char *name )
398 {
399         int     i;
400         
401         /* search for the value */
402         
403         for ( i=0; i<ctr->num_values; i++ ) {
404                 if ( strequal( ctr->values[i]->valuename, name ) )
405                         return ctr->values[i];
406         }
407         
408         return NULL;
409 }
410
411 /***********************************************************************
412  free memory held by a REGVAL_CTR structure
413  **********************************************************************/
414
415 void regval_ctr_destroy( REGVAL_CTR *ctr )
416 {
417         if ( ctr ) {
418                 talloc_destroy( ctr->ctx );
419                 ZERO_STRUCTP( ctr );
420         }
421 }
422
423