2a898f017054bba45bf9baab134a7e51a9501c35
[bbaumbach/samba-autobuild/.git] / source3 / 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  Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d
31  since the methods use the object pointer as the talloc context for 
32  internal private data.
33
34  There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy()
35  pair of functions.  Simply TALLOC_ZERO_P() and TALLOC_FREE() the 
36  object.
37
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         if ( !keyname )
47                 return ctr->num_subkeys;
48
49         /* make sure the keyname is not already there */
50
51         if ( regsubkey_ctr_key_exists( ctr, keyname ) )
52                 return ctr->num_subkeys;
53                 
54         /* allocate a space for the char* in the array */
55                 
56         if (ctr->subkeys == NULL) {
57                 ctr->subkeys = TALLOC_P(ctr, char *);
58         } else {
59                 ctr->subkeys = TALLOC_REALLOC_ARRAY(ctr, ctr->subkeys, char *, ctr->num_subkeys+1);
60         }
61
62         if (!ctr->subkeys) {
63                 ctr->num_subkeys = 0;
64                 return 0;
65         }
66
67         /* allocate the string and save it in the array */
68         
69         ctr->subkeys[ctr->num_subkeys] = talloc_strdup( ctr, keyname );
70         ctr->num_subkeys++;
71         
72         return ctr->num_subkeys;
73 }
74  
75  /***********************************************************************
76  Add a new key to the array
77  **********************************************************************/
78
79 int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname )
80 {
81         int i;
82
83         if ( !keyname )
84                 return ctr->num_subkeys;
85
86         /* make sure the keyname is actually already there */
87
88         for ( i=0; i<ctr->num_subkeys; i++ ) {
89                 if ( strequal( ctr->subkeys[i], keyname ) )
90                         break;
91         }
92         
93         if ( i == ctr->num_subkeys )
94                 return ctr->num_subkeys;
95
96         /* update if we have any keys left */
97         ctr->num_subkeys--;
98         if ( i < ctr->num_subkeys )
99                 memmove( &ctr->subkeys[i], &ctr->subkeys[i+1], sizeof(char*) * (ctr->num_subkeys-i) );
100         
101         return ctr->num_subkeys;
102 }
103
104 /***********************************************************************
105  Check for the existance of a key
106  **********************************************************************/
107
108 BOOL regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname )
109 {
110         int     i;
111         
112         for ( i=0; i<ctr->num_subkeys; i++ ) {
113                 if ( strequal( ctr->subkeys[i],keyname ) )
114                         return True;
115         }
116         
117         return False;
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  * Utility functions for REGVAL_CTR
143  */
144
145 /***********************************************************************
146  How many keys does the container hold ?
147  **********************************************************************/
148
149 int regval_ctr_numvals( REGVAL_CTR *ctr )
150 {
151         return ctr->num_values;
152 }
153
154 /***********************************************************************
155  allocate memory for and duplicate a REGISTRY_VALUE.
156  This is malloc'd memory so the caller should free it when done
157  **********************************************************************/
158
159 REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
160 {
161         REGISTRY_VALUE  *copy = NULL;
162         
163         if ( !val )
164                 return NULL;
165         
166         if ( !(copy = SMB_MALLOC_P( REGISTRY_VALUE)) ) {
167                 DEBUG(0,("dup_registry_value: malloc() failed!\n"));
168                 return NULL;
169         }
170         
171         /* copy all the non-pointer initial data */
172         
173         memcpy( copy, val, sizeof(REGISTRY_VALUE) );
174         
175         copy->size = 0;
176         copy->data_p = NULL;
177         
178         if ( val->data_p && val->size ) 
179         {
180                 if ( !(copy->data_p = (uint8 *)memdup( val->data_p,
181                                                        val->size )) ) {
182                         DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
183                                 val->size));
184                         SAFE_FREE( copy );
185                 }
186                 copy->size = val->size;
187         }
188         
189         return copy;    
190 }
191
192 /**********************************************************************
193  free the memory allocated to a REGISTRY_VALUE 
194  *********************************************************************/
195  
196 void free_registry_value( REGISTRY_VALUE *val )
197 {
198         if ( !val )
199                 return;
200                 
201         SAFE_FREE( val->data_p );
202         SAFE_FREE( val );
203         
204         return;
205 }
206
207 /**********************************************************************
208  *********************************************************************/
209
210 uint8* regval_data_p( REGISTRY_VALUE *val )
211 {
212         return val->data_p;
213 }
214
215 /**********************************************************************
216  *********************************************************************/
217
218 uint32 regval_size( REGISTRY_VALUE *val )
219 {
220         return val->size;
221 }
222
223 /**********************************************************************
224  *********************************************************************/
225
226 char* regval_name( REGISTRY_VALUE *val )
227 {
228         return val->valuename;
229 }
230
231 /**********************************************************************
232  *********************************************************************/
233
234 uint32 regval_type( REGISTRY_VALUE *val )
235 {
236         return val->type;
237 }
238
239 /***********************************************************************
240  Retreive a pointer to a specific value.  Caller shoud dup the structure
241  since this memory will go away when the ctr is free()'d
242  **********************************************************************/
243
244 REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
245 {
246         if ( !(idx < ctr->num_values) )
247                 return NULL;
248                 
249         return ctr->values[idx];
250 }
251
252 /***********************************************************************
253  Check for the existance of a value
254  **********************************************************************/
255
256 BOOL regval_ctr_key_exists( REGVAL_CTR *ctr, const char *value )
257 {
258         int     i;
259         
260         for ( i=0; i<ctr->num_values; i++ ) {
261                 if ( strequal( ctr->values[i]->valuename, value) )
262                         return True;
263         }
264         
265         return False;
266 }
267 /***********************************************************************
268  Add a new registry value to the array
269  **********************************************************************/
270
271 int regval_ctr_addvalue( REGVAL_CTR *ctr, const char *name, uint16 type, 
272                          const char *data_p, size_t size )
273 {
274         if ( !name )
275                 return ctr->num_values;
276
277         /* Delete the current value (if it exists) and add the new one */
278
279         regval_ctr_delvalue( ctr, name );
280
281         /* allocate a slot in the array of pointers */
282                 
283         if (  ctr->num_values == 0 ) {
284                 ctr->values = TALLOC_P( ctr, REGISTRY_VALUE *);
285         } else {
286                 ctr->values = TALLOC_REALLOC_ARRAY( ctr, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
287         }
288
289         if (!ctr->values) {
290                 ctr->num_values = 0;
291                 return 0;
292         }
293
294         /* allocate a new value and store the pointer in the arrya */
295                 
296         ctr->values[ctr->num_values] = TALLOC_P( ctr, REGISTRY_VALUE);
297         if (!ctr->values[ctr->num_values]) {
298                 ctr->num_values = 0;
299                 return 0;
300         }
301
302         /* init the value */
303         
304         fstrcpy( ctr->values[ctr->num_values]->valuename, name );
305         ctr->values[ctr->num_values]->type = type;
306         ctr->values[ctr->num_values]->data_p = (uint8 *)TALLOC_MEMDUP(
307                 ctr, data_p, size );
308         ctr->values[ctr->num_values]->size = size;
309         ctr->num_values++;
310
311         return ctr->num_values;
312 }
313
314 /***********************************************************************
315  Add a new registry value to the array
316  **********************************************************************/
317
318 int regval_ctr_copyvalue( REGVAL_CTR *ctr, REGISTRY_VALUE *val )
319 {
320         if ( val ) {
321                 /* allocate a slot in the array of pointers */
322                 
323                 if (  ctr->num_values == 0 ) {
324                         ctr->values = TALLOC_P( ctr, REGISTRY_VALUE *);
325                 } else {
326                         ctr->values = TALLOC_REALLOC_ARRAY( ctr, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
327                 }
328
329                 if (!ctr->values) {
330                         ctr->num_values = 0;
331                         return 0;
332                 }
333
334                 /* allocate a new value and store the pointer in the arrya */
335                 
336                 ctr->values[ctr->num_values] = TALLOC_P( ctr, REGISTRY_VALUE);
337                 if (!ctr->values[ctr->num_values]) {
338                         ctr->num_values = 0;
339                         return 0;
340                 }
341
342                 /* init the value */
343         
344                 fstrcpy( ctr->values[ctr->num_values]->valuename, val->valuename );
345                 ctr->values[ctr->num_values]->type = val->type;
346                 ctr->values[ctr->num_values]->data_p = (uint8 *)TALLOC_MEMDUP(
347                         ctr, 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         for ( i=0; i<ctr->num_values; i++ ) {
365                 if ( strequal( ctr->values[i]->valuename, name ) )
366                         break;
367         }
368         
369         /* just return if we don't find it */
370         
371         if ( i == ctr->num_values )
372                 return ctr->num_values;
373         
374         /* If 'i' was not the last element, just shift everything down one */
375         ctr->num_values--;
376         if ( i < ctr->num_values )
377                 memmove( &ctr->values[i], &ctr->values[i+1], sizeof(REGISTRY_VALUE*)*(ctr->num_values-i) );
378         
379         return ctr->num_values;
380 }
381
382 /***********************************************************************
383  Retrieve single value from the registry container.
384  No need to free memory since it is talloc'd.
385  **********************************************************************/
386
387 REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, const char *name )
388 {
389         int     i;
390         
391         /* search for the value */
392         
393         for ( i=0; i<ctr->num_values; i++ ) {
394                 if ( strequal( ctr->values[i]->valuename, name ) )
395                         return ctr->values[i];
396         }
397         
398         return NULL;
399 }
400
401 /***********************************************************************
402  return the data_p as a uint32
403  **********************************************************************/
404
405 uint32 regval_dword( REGISTRY_VALUE *val )
406 {
407         uint32 data;
408         
409         data = IVAL( regval_data_p(val), 0 );
410         
411         return data;
412 }
413
414 /***********************************************************************
415  return the data_p as a character string
416  **********************************************************************/
417
418 char* regval_sz( REGISTRY_VALUE *val )
419 {
420         static pstring data;
421
422         rpcstr_pull( data, regval_data_p(val), sizeof(data), regval_size(val), 0 );
423         
424         return data;
425 }