Merged msacm and msacm32 dlls.
[wine] / server / registry.c
1 /*
2  * Server-side registry management
3  *
4  * Copyright (C) 1999 Alexandre Julliard
5  */
6
7 /* To do:
8  * - behavior with deleted keys
9  * - values larger than request buffer
10  * - symbolic links
11  */
12
13 #include <assert.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <limits.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <pwd.h>
23 #include "object.h"
24 #include "handle.h"
25 #include "request.h"
26 #include "unicode.h"
27
28 #include "winbase.h"
29 #include "winreg.h"
30 #include "winnt.h" /* registry definitions */
31
32
33 /* a registry key */
34 struct key
35 {
36     struct object     obj;         /* object header */
37     WCHAR            *name;        /* key name */
38     WCHAR            *class;       /* key class */
39     struct key       *parent;      /* parent key */
40     int               last_subkey; /* last in use subkey */
41     int               nb_subkeys;  /* count of allocated subkeys */
42     struct key      **subkeys;     /* subkeys array */
43     int               last_value;  /* last in use value */
44     int               nb_values;   /* count of allocated values in array */
45     struct key_value *values;      /* values array */
46     short             flags;       /* flags */
47     short             level;       /* saving level */
48     time_t            modif;       /* last modification time */
49 };
50
51 /* key flags */
52 #define KEY_VOLATILE 0x0001  /* key is volatile (not saved to disk) */
53 #define KEY_DELETED  0x0002  /* key has been deleted */
54 #define KEY_ROOT     0x0004  /* key is a root key */
55
56 /* a key value */
57 struct key_value
58 {
59     WCHAR            *name;    /* value name */
60     int               type;    /* value type */
61     size_t            len;     /* value data length in bytes */
62     void             *data;    /* pointer to value data */
63 };
64
65 #define MIN_SUBKEYS  8   /* min. number of allocated subkeys per key */
66 #define MIN_VALUES   8   /* min. number of allocated values per key */
67
68
69 /* the root keys */
70 #define HKEY_ROOT_FIRST   HKEY_CLASSES_ROOT
71 #define HKEY_ROOT_LAST    HKEY_DYN_DATA
72 #define NB_ROOT_KEYS      (HKEY_ROOT_LAST - HKEY_ROOT_FIRST + 1)
73 #define IS_ROOT_HKEY(h)   (((h) >= HKEY_ROOT_FIRST) && ((h) <= HKEY_ROOT_LAST))
74 static struct key *root_keys[NB_ROOT_KEYS];
75
76
77 /* keys saving level */
78 /* current_level is the level that is put into all newly created or modified keys */
79 /* saving_level is the minimum level that a key needs in order to get saved */
80 static int current_level;
81 static int saving_level;
82
83 static struct timeval next_save_time;           /* absolute time of next periodic save */
84 static int save_period;                         /* delay between periodic saves (ms) */
85 static struct timeout_user *save_timeout_user;  /* saving timer */
86
87 /* information about where to save a registry branch */
88 struct save_branch_info
89 {
90     struct key  *key;
91     char        *path;
92 };
93
94 #define MAX_SAVE_BRANCH_INFO 8
95 static int save_branch_count;
96 static struct save_branch_info save_branch_info[MAX_SAVE_BRANCH_INFO];
97
98
99 /* information about a file being loaded */
100 struct file_load_info
101 {
102     FILE *file;    /* input file */
103     char *buffer;  /* line buffer */
104     int   len;     /* buffer length */
105     int   line;    /* current input line */
106     char *tmp;     /* temp buffer to use while parsing input */
107     int   tmplen;  /* length of temp buffer */
108 };
109
110
111 static void key_dump( struct object *obj, int verbose );
112 static void key_destroy( struct object *obj );
113
114 static const struct object_ops key_ops =
115 {
116     sizeof(struct key),      /* size */
117     key_dump,                /* dump */
118     no_add_queue,            /* add_queue */
119     NULL,                    /* remove_queue */
120     NULL,                    /* signaled */
121     NULL,                    /* satisfied */
122     NULL,                    /* get_poll_events */
123     NULL,                    /* poll_event */
124     no_read_fd,              /* get_read_fd */
125     no_write_fd,             /* get_write_fd */
126     no_flush,                /* flush */
127     no_get_file_info,        /* get_file_info */
128     key_destroy              /* destroy */
129 };
130
131
132 /*
133  * The registry text file format v2 used by this code is similar to the one
134  * used by REGEDIT import/export functionality, with the following differences:
135  * - strings and key names can contain \x escapes for Unicode
136  * - key names use escapes too in order to support Unicode
137  * - the modification time optionally follows the key name
138  * - REG_EXPAND_SZ and REG_MULTI_SZ are saved as strings instead of hex
139  */
140
141 static inline char to_hex( char ch )
142 {
143     if (isdigit(ch)) return ch - '0';
144     return tolower(ch) - 'a' + 10;
145 }
146
147 /* dump the full path of a key */
148 static void dump_path( struct key *key, struct key *base, FILE *f )
149 {
150     if (key->parent && key != base)
151     {
152         dump_path( key->parent, base, f );
153         fprintf( f, "\\\\" );
154     }
155     dump_strW( key->name, strlenW(key->name), f, "[]" );
156 }
157
158 /* dump a value to a text file */
159 static void dump_value( struct key_value *value, FILE *f )
160 {
161     int i, count;
162
163     if (value->name[0])
164     {
165         fputc( '\"', f );
166         count = 1 + dump_strW( value->name, strlenW(value->name), f, "\"\"" );
167         count += fprintf( f, "\"=" );
168     }
169     else count = fprintf( f, "@=" );
170
171     switch(value->type)
172     {
173     case REG_SZ:
174     case REG_EXPAND_SZ:
175     case REG_MULTI_SZ:
176         if (value->type != REG_SZ) fprintf( f, "str(%d):", value->type );
177         fputc( '\"', f );
178         if (value->data) dump_strW( (WCHAR *)value->data, value->len / sizeof(WCHAR), f, "\"\"" );
179         fputc( '\"', f );
180         break;
181     case REG_DWORD:
182         if (value->len == sizeof(DWORD))
183         {
184             DWORD dw;
185             memcpy( &dw, value->data, sizeof(DWORD) );
186             fprintf( f, "dword:%08lx", dw );
187             break;
188         }
189         /* else fall through */
190     default:
191         if (value->type == REG_BINARY) count += fprintf( f, "hex:" );
192         else count += fprintf( f, "hex(%x):", value->type );
193         for (i = 0; i < value->len; i++)
194         {
195             count += fprintf( f, "%02x", *((unsigned char *)value->data + i) );
196             if (i < value->len-1)
197             {
198                 fputc( ',', f );
199                 if (++count > 76)
200                 {
201                     fprintf( f, "\\\n  " );
202                     count = 2;
203                 }
204             }
205         }
206         break;
207     }
208     fputc( '\n', f );
209 }
210
211 /* save a registry and all its subkeys to a text file */
212 static void save_subkeys( struct key *key, struct key *base, FILE *f )
213 {
214     int i;
215
216     if (key->flags & KEY_VOLATILE) return;
217     /* save key if it has the proper level, and has either some values or no subkeys */
218     /* keys with no values but subkeys are saved implicitly by saving the subkeys */
219     if ((key->level >= saving_level) && ((key->last_value >= 0) || (key->last_subkey == -1)))
220     {
221         fprintf( f, "\n[" );
222         dump_path( key, base, f );
223         fprintf( f, "] %ld\n", key->modif );
224         for (i = 0; i <= key->last_value; i++) dump_value( &key->values[i], f );
225     }
226     for (i = 0; i <= key->last_subkey; i++) save_subkeys( key->subkeys[i], base, f );
227 }
228
229 static void dump_operation( struct key *key, struct key_value *value, const char *op )
230 {
231     fprintf( stderr, "%s key ", op );
232     if (key) dump_path( key, NULL, stderr );
233     else fprintf( stderr, "ERROR" );
234     if (value)
235     {
236         fprintf( stderr, " value ");
237         dump_value( value, stderr );
238     }
239     else fprintf( stderr, "\n" );
240 }
241
242 static void key_dump( struct object *obj, int verbose )
243 {
244     struct key *key = (struct key *)obj;
245     assert( obj->ops == &key_ops );
246     fprintf( stderr, "Key flags=%x ", key->flags );
247     dump_path( key, NULL, stderr );
248     fprintf( stderr, "\n" );
249 }
250
251 static void key_destroy( struct object *obj )
252 {
253     int i;
254     struct key *key = (struct key *)obj;
255     assert( obj->ops == &key_ops );
256
257     if (key->name) free( key->name );
258     if (key->class) free( key->class );
259     for (i = 0; i <= key->last_value; i++)
260     {
261         free( key->values[i].name );
262         if (key->values[i].data) free( key->values[i].data );
263     }
264     for (i = 0; i <= key->last_subkey; i++)
265     {
266         key->subkeys[i]->parent = NULL;
267         release_object( key->subkeys[i] );
268     }
269 }
270
271 /* duplicate a key path from the request buffer */
272 /* returns a pointer to a static buffer, so only useable once per request */
273 static WCHAR *copy_path( const path_t path )
274 {
275     static WCHAR buffer[MAX_PATH+1];
276     WCHAR *p = buffer;
277
278     while (p < buffer + sizeof(buffer) - 1) if (!(*p++ = *path++)) break;
279     *p = 0;
280     return buffer;
281 }
282
283 /* return the next token in a given path */
284 /* returns a pointer to a static buffer, so only useable once per request */
285 static WCHAR *get_path_token( const WCHAR *initpath, size_t maxlen )
286 {
287     static const WCHAR *path;
288     static const WCHAR *end;
289     static WCHAR buffer[MAX_PATH+1];
290     WCHAR *p = buffer;
291
292     if (initpath)
293     {
294         path = initpath;
295         end  = path + maxlen / sizeof(WCHAR);
296     }
297     while ((path < end) && (*path == '\\')) path++;
298     while ((path < end) && (p < buffer + sizeof(buffer) - 1))
299     {
300         WCHAR ch = *path;
301         if (!ch || (ch == '\\')) break;
302         *p++ = ch;
303         path++;
304     }
305     *p = 0;
306     return buffer;
307 }
308
309 /* duplicate a Unicode string from the request buffer */
310 static WCHAR *req_strdupW( const void *req, const WCHAR *str )
311 {
312     WCHAR *name;
313     size_t len = get_req_strlenW( req, str );
314     if ((name = mem_alloc( (len + 1) * sizeof(WCHAR) )) != NULL)
315     {
316         memcpy( name, str, len * sizeof(WCHAR) );
317         name[len] = 0;
318     }
319     return name;
320 }
321
322 /* allocate a key object */
323 static struct key *alloc_key( const WCHAR *name, time_t modif )
324 {
325     struct key *key;
326     if ((key = (struct key *)alloc_object( &key_ops, -1 )))
327     {
328         key->class       = NULL;
329         key->flags       = 0;
330         key->last_subkey = -1;
331         key->nb_subkeys  = 0;
332         key->subkeys     = NULL;
333         key->nb_values   = 0;
334         key->last_value  = -1;
335         key->values      = NULL;
336         key->level       = current_level;
337         key->modif       = modif;
338         key->parent      = NULL;
339         if (!(key->name = strdupW( name )))
340         {
341             release_object( key );
342             key = NULL;
343         }
344     }
345     return key;
346 }
347
348 /* update key modification time */
349 static void touch_key( struct key *key )
350 {
351     key->modif = time(NULL);
352     key->level = max( key->level, current_level );
353 }
354
355 /* try to grow the array of subkeys; return 1 if OK, 0 on error */
356 static int grow_subkeys( struct key *key )
357 {
358     struct key **new_subkeys;
359     int nb_subkeys;
360
361     if (key->nb_subkeys)
362     {
363         nb_subkeys = key->nb_subkeys + (key->nb_subkeys / 2);  /* grow by 50% */
364         if (!(new_subkeys = realloc( key->subkeys, nb_subkeys * sizeof(*new_subkeys) )))
365         {
366             set_error( STATUS_NO_MEMORY );
367             return 0;
368         }
369     }
370     else
371     {
372         nb_subkeys = MIN_VALUES;
373         if (!(new_subkeys = mem_alloc( nb_subkeys * sizeof(*new_subkeys) ))) return 0;
374     }
375     key->subkeys    = new_subkeys;
376     key->nb_subkeys = nb_subkeys;
377     return 1;
378 }
379
380 /* allocate a subkey for a given key, and return its index */
381 static struct key *alloc_subkey( struct key *parent, const WCHAR *name, int index, time_t modif )
382 {
383     struct key *key;
384     int i;
385
386     if (parent->last_subkey + 1 == parent->nb_subkeys)
387     {
388         /* need to grow the array */
389         if (!grow_subkeys( parent )) return NULL;
390     }
391     if ((key = alloc_key( name, modif )) != NULL)
392     {
393         key->parent = parent;
394         for (i = ++parent->last_subkey; i > index; i--)
395             parent->subkeys[i] = parent->subkeys[i-1];
396         parent->subkeys[index] = key;
397     }
398     return key;
399 }
400
401 /* free a subkey of a given key */
402 static void free_subkey( struct key *parent, int index )
403 {
404     struct key *key;
405     int i, nb_subkeys;
406
407     assert( index >= 0 );
408     assert( index <= parent->last_subkey );
409
410     key = parent->subkeys[index];
411     for (i = index; i < parent->last_subkey; i++) parent->subkeys[i] = parent->subkeys[i + 1];
412     parent->last_subkey--;
413     key->flags |= KEY_DELETED;
414     key->parent = NULL;
415     release_object( key );
416     
417     /* try to shrink the array */
418     nb_subkeys = key->nb_subkeys;
419     if (nb_subkeys > MIN_SUBKEYS && key->last_subkey < nb_subkeys / 2)
420     {
421         struct key **new_subkeys;
422         nb_subkeys -= nb_subkeys / 3;  /* shrink by 33% */
423         if (nb_subkeys < MIN_SUBKEYS) nb_subkeys = MIN_SUBKEYS;
424         if (!(new_subkeys = realloc( key->subkeys, nb_subkeys * sizeof(*new_subkeys) ))) return;
425         key->subkeys = new_subkeys;
426         key->nb_subkeys = nb_subkeys;
427     }
428 }
429
430 /* find the named child of a given key and return its index */
431 static struct key *find_subkey( struct key *key, const WCHAR *name, int *index )
432 {
433     int i, min, max, res;
434
435     min = 0;
436     max = key->last_subkey;
437     while (min <= max)
438     {
439         i = (min + max) / 2;
440         if (!(res = strcmpiW( key->subkeys[i]->name, name )))
441         {
442             *index = i;
443             return key->subkeys[i];
444         }
445         if (res > 0) max = i - 1;
446         else min = i + 1;
447     }
448     *index = min;  /* this is where we should insert it */
449     return NULL;
450 }
451
452 /* open a subkey */
453 static struct key *open_key( struct key *key, const WCHAR *name, size_t maxlen )
454 {
455     int index;
456     WCHAR *path;
457
458     path = get_path_token( name, maxlen );
459     while (*path)
460     {
461         if (!(key = find_subkey( key, path, &index )))
462         {
463             set_error( STATUS_OBJECT_NAME_NOT_FOUND );
464             break;
465         }
466         path = get_path_token( NULL, 0 );
467     }
468
469     if (debug_level > 1) dump_operation( key, NULL, "Open" );
470     if (key) grab_object( key );
471     return key;
472 }
473
474 /* create a subkey */
475 static struct key *create_key( struct key *key, const WCHAR *name, size_t maxlen, WCHAR *class,
476                                unsigned int options, time_t modif, int *created )
477 {
478     struct key *base;
479     int base_idx, index, flags = 0;
480     WCHAR *path;
481
482     if (key->flags & KEY_DELETED) /* we cannot create a subkey under a deleted key */
483     {
484         set_error( STATUS_KEY_DELETED );
485         return NULL;
486     }
487     if (options & REG_OPTION_VOLATILE) flags |= KEY_VOLATILE;
488     else if (key->flags & KEY_VOLATILE)
489     {
490         set_error( STATUS_CHILD_MUST_BE_VOLATILE );
491         return NULL;
492     }
493
494     path = get_path_token( name, maxlen );
495     *created = 0;
496     while (*path)
497     {
498         struct key *subkey;
499         if (!(subkey = find_subkey( key, path, &index ))) break;
500         key = subkey;
501         path = get_path_token( NULL, 0 );
502     }
503
504     /* create the remaining part */
505
506     if (!*path) goto done;
507     *created = 1;
508     base = key;
509     base_idx = index;
510     key = alloc_subkey( key, path, index, modif );
511     while (key)
512     {
513         key->flags |= flags;
514         path = get_path_token( NULL, 0 );
515         if (!*path) goto done;
516         /* we know the index is always 0 in a new key */
517         key = alloc_subkey( key, path, 0, modif );
518     }
519     if (base_idx != -1) free_subkey( base, base_idx );
520     return NULL;
521
522  done:
523     if (debug_level > 1) dump_operation( key, NULL, "Create" );
524     if (class) key->class = strdupW(class);
525     grab_object( key );
526     return key;
527 }
528
529 /* find a subkey of a given key by its index */
530 static void enum_key( struct key *parent, int index, WCHAR *name, WCHAR *class, time_t *modif )
531 {
532     struct key *key;
533
534     if ((index < 0) || (index > parent->last_subkey)) set_error( STATUS_NO_MORE_ENTRIES );
535     else
536     {
537         key = parent->subkeys[index];
538         *modif = key->modif;
539         strcpyW( name, key->name );
540         if (key->class) strcpyW( class, key->class );  /* FIXME: length */
541         else *class = 0;
542         if (debug_level > 1) dump_operation( key, NULL, "Enum" );
543     }
544 }
545
546 /* query information about a key */
547 static void query_key( struct key *key, struct query_key_info_request *req )
548 {
549     int i, len;
550     int max_subkey = 0, max_class = 0;
551     int max_value = 0, max_data = 0;
552
553     for (i = 0; i <= key->last_subkey; i++)
554     {
555         struct key *subkey = key->subkeys[i];
556         len = strlenW( subkey->name );
557         if (len > max_subkey) max_subkey = len;
558         if (!subkey->class) continue;
559         len = strlenW( subkey->class );
560         if (len > max_class) max_class = len;
561     }
562     for (i = 0; i <= key->last_value; i++)
563     {
564         len = strlenW( key->values[i].name );
565         if (len > max_value) max_value = len;
566         len = key->values[i].len;
567         if (len > max_data) max_data = len;
568     }
569     req->subkeys    = key->last_subkey + 1;
570     req->max_subkey = max_subkey;
571     req->max_class  = max_class;
572     req->values     = key->last_value + 1;
573     req->max_value  = max_value;
574     req->max_data   = max_data;
575     req->modif      = key->modif;
576     strcpyW( req->name, key->name);
577     if (key->class) strcpyW( req->class, key->class );  /* FIXME: length */
578     else req->class[0] = 0;
579     if (debug_level > 1) dump_operation( key, NULL, "Query" );
580 }
581
582 /* delete a key and its values */
583 static void delete_key( struct key *key, const WCHAR *name, size_t maxlen )
584 {
585     int index;
586     struct key *parent;
587     WCHAR *path;
588
589     path = get_path_token( name, maxlen );
590     if (!*path)
591     {
592         /* deleting this key, must find parent and index */
593         if (key->flags & KEY_ROOT)
594         {
595             set_error( STATUS_ACCESS_DENIED );
596             return;
597         }
598         if (!(parent = key->parent) || (key->flags & KEY_DELETED))
599         {
600             set_error( STATUS_KEY_DELETED );
601             return;
602         }
603         for (index = 0; index <= parent->last_subkey; index++)
604             if (parent->subkeys[index] == key) break;
605         assert( index <= parent->last_subkey );
606     }
607     else while (*path)
608     {
609         parent = key;
610         if (!(key = find_subkey( parent, path, &index )))
611         {
612             set_error( STATUS_OBJECT_NAME_NOT_FOUND );
613             return;
614         }
615         path = get_path_token( NULL, 0 );
616     }
617
618     /* we can only delete a key that has no subkeys (FIXME) */
619     if ((key->flags & KEY_ROOT) || (key->last_subkey >= 0))
620     {
621         set_error( STATUS_ACCESS_DENIED );
622         return;
623     }
624     if (debug_level > 1) dump_operation( key, NULL, "Delete" );
625     free_subkey( parent, index );
626     touch_key( parent );
627 }
628
629 /* try to grow the array of values; return 1 if OK, 0 on error */
630 static int grow_values( struct key *key )
631 {
632     struct key_value *new_val;
633     int nb_values;
634
635     if (key->nb_values)
636     {
637         nb_values = key->nb_values + (key->nb_values / 2);  /* grow by 50% */
638         if (!(new_val = realloc( key->values, nb_values * sizeof(*new_val) )))
639         {
640             set_error( STATUS_NO_MEMORY );
641             return 0;
642         }
643     }
644     else
645     {
646         nb_values = MIN_VALUES;
647         if (!(new_val = mem_alloc( nb_values * sizeof(*new_val) ))) return 0;
648     }
649     key->values = new_val;
650     key->nb_values = nb_values;
651     return 1;
652 }
653
654 /* find the named value of a given key and return its index in the array */
655 static struct key_value *find_value( const struct key *key, const WCHAR *name, int *index )
656 {
657     int i, min, max, res;
658
659     min = 0;
660     max = key->last_value;
661     while (min <= max)
662     {
663         i = (min + max) / 2;
664         if (!(res = strcmpiW( key->values[i].name, name )))
665         {
666             *index = i;
667             return &key->values[i];
668         }
669         if (res > 0) max = i - 1;
670         else min = i + 1;
671     }
672     *index = min;  /* this is where we should insert it */
673     return NULL;
674 }
675
676 /* insert a new value or return a pointer to an existing one */
677 static struct key_value *insert_value( struct key *key, const WCHAR *name )
678 {
679     struct key_value *value;
680     WCHAR *new_name;
681     int i, index;
682
683     if (!(value = find_value( key, name, &index )))
684     {
685         /* not found, add it */
686         if (key->last_value + 1 == key->nb_values)
687         {
688             if (!grow_values( key )) return NULL;
689         }
690         if (!(new_name = strdupW(name))) return NULL;
691         for (i = ++key->last_value; i > index; i--) key->values[i] = key->values[i - 1];
692         value = &key->values[index];
693         value->name = new_name;
694         value->len  = 0;
695         value->data = NULL;
696     }
697     return value;
698 }
699
700 /* set a key value */
701 static void set_value( struct key *key, WCHAR *name, int type, unsigned int total_len,
702                        unsigned int offset, unsigned int data_len, void *data )
703 {
704     struct key_value *value;
705     void *ptr = NULL;
706
707     if (data_len + offset > total_len)
708     {
709         set_error( STATUS_INVALID_PARAMETER );
710         return;
711     }
712
713     if (offset)  /* adding data to an existing value */
714     {
715         int index;
716         if (!(value = find_value( key, name, &index )))
717         {
718             set_error( STATUS_OBJECT_NAME_NOT_FOUND );
719             return;
720         }
721         if (value->len != total_len)
722         {
723             set_error( STATUS_INVALID_PARAMETER );
724             return;
725         }
726         memcpy( (char *)value->data + offset, data, data_len );
727         if (debug_level > 1) dump_operation( key, value, "Set" );
728         return;
729     }
730
731     /* first copy the data */
732     if (total_len)
733     {
734         if (!(ptr = mem_alloc( total_len ))) return;
735         memcpy( ptr, data, data_len );
736         if (data_len < total_len) memset( (char *)ptr + data_len, 0, total_len - data_len );
737     }
738
739     if (!(value = insert_value( key, name )))
740     {
741         if (ptr) free( ptr );
742         return;
743     }
744     if (value->data) free( value->data ); /* already existing, free previous data */
745     value->type  = type;
746     value->len   = total_len;
747     value->data  = ptr;
748     touch_key( key );
749     if (debug_level > 1) dump_operation( key, value, "Set" );
750 }
751
752 /* get a key value */
753 static void get_value( struct key *key, WCHAR *name, unsigned int offset,
754                        unsigned int maxlen, int *type, int *len, void *data )
755 {
756     struct key_value *value;
757     int index;
758
759     if ((value = find_value( key, name, &index )))
760     {
761         *type = value->type;
762         *len  = value->len;
763         if (value->data && offset < value->len)
764         {
765             if (maxlen > value->len - offset) maxlen = value->len - offset;
766             memcpy( data, (char *)value->data + offset, maxlen );
767         }
768         if (debug_level > 1) dump_operation( key, value, "Get" );
769     }
770     else
771     {
772         *type = -1;
773         set_error( STATUS_OBJECT_NAME_NOT_FOUND );
774     }
775 }
776
777 /* enumerate a key value */
778 static void enum_value( struct key *key, int i, WCHAR *name, unsigned int offset,
779                         unsigned int maxlen, int *type, int *len, void *data )
780 {
781     struct key_value *value;
782
783     if (i < 0 || i > key->last_value) set_error( STATUS_NO_MORE_ENTRIES );
784     else
785     {
786         value = &key->values[i];
787         strcpyW( name, value->name );
788         *type = value->type;
789         *len  = value->len;
790         if (value->data && offset < value->len)
791         {
792             if (maxlen > value->len - offset) maxlen = value->len - offset;
793             memcpy( data, (char *)value->data + offset, maxlen );
794         }
795         if (debug_level > 1) dump_operation( key, value, "Enum" );
796     }
797 }
798
799 /* delete a value */
800 static void delete_value( struct key *key, const WCHAR *name )
801 {
802     struct key_value *value;
803     int i, index, nb_values;
804
805     if (!(value = find_value( key, name, &index )))
806     {
807         set_error( STATUS_OBJECT_NAME_NOT_FOUND );
808         return;
809     }
810     if (debug_level > 1) dump_operation( key, value, "Delete" );
811     free( value->name );
812     if (value->data) free( value->data );
813     for (i = index; i < key->last_value; i++) key->values[i] = key->values[i + 1];
814     key->last_value--;
815     touch_key( key );
816
817     /* try to shrink the array */
818     nb_values = key->nb_values;
819     if (nb_values > MIN_VALUES && key->last_value < nb_values / 2)
820     {
821         struct key_value *new_val;
822         nb_values -= nb_values / 3;  /* shrink by 33% */
823         if (nb_values < MIN_VALUES) nb_values = MIN_VALUES;
824         if (!(new_val = realloc( key->values, nb_values * sizeof(*new_val) ))) return;
825         key->values = new_val;
826         key->nb_values = nb_values;
827     }
828 }    
829
830 static struct key *get_hkey_obj( int hkey, unsigned int access );
831
832 static struct key *create_root_key( int hkey )
833 {
834     int dummy;
835     struct key *key;
836
837     switch(hkey)
838     {
839     /* the two real root-keys */
840     case HKEY_LOCAL_MACHINE:
841         {
842             static const WCHAR name[] = { 'M','A','C','H','I','N','E',0 };
843             key = alloc_key( name, time(NULL) );
844         }
845         break;
846     case HKEY_USERS:
847         {
848             static const WCHAR name[] = { 'U','S','E','R',0 };
849             key = alloc_key( name, time(NULL) );
850         }
851         break;
852     /* special subkeys */
853     case HKEY_CLASSES_ROOT:
854         {
855             static const WCHAR name[] =
856                           { 'S','O','F','T','W','A','R','E','\\','C','l','a','s','s','e','s',0 };
857
858             struct key *root = get_hkey_obj( HKEY_LOCAL_MACHINE, 0 );
859             assert( root );
860             key = create_key( root, name, sizeof(name), NULL, 0, time(NULL), &dummy );
861             release_object( root );
862         }
863         break;
864     case HKEY_CURRENT_CONFIG:
865         {
866             static const WCHAR name[] = {
867                 'S','Y','S','T','E','M','\\',
868                 'C','U','R','R','E','N','T','C','O','N','T','R','O','L','S','E','T','\\',
869                 'H','A','R','D','W','A','R','E','P','R','O','F','I','L','E','S','\\',
870                 'C','U','R','R','E','N','T',0};
871             struct key *root = get_hkey_obj( HKEY_LOCAL_MACHINE, 0 );
872             assert( root );
873             key = create_key( root, name, sizeof(name), NULL, 0, time(NULL), &dummy );
874             release_object( root );
875         }
876         break;
877     case HKEY_CURRENT_USER:
878         {
879             /* get the current user name */
880             int i, len;
881             WCHAR *name;
882             char buffer[10];
883             const char *p;
884             struct passwd *pwd = getpwuid( getuid() );
885
886             if (pwd) p = pwd->pw_name;
887             else
888             {
889                 sprintf( buffer, "%ld", (long) getuid() );
890                 p = buffer;
891             }
892             len = strlen(p);
893             if ((name = mem_alloc( (len+1) * sizeof(WCHAR) )))
894             {
895                 struct key *root = get_hkey_obj( HKEY_USERS, 0 );
896                 assert( root );
897                 for (i = 0; i <= len; i++) name[i] = p[i];
898                 key = create_key( root, name, (len+1) * sizeof(WCHAR),
899                                   NULL, 0, time(NULL), &dummy );
900                 release_object( root );
901                 free( name );
902             }
903             else key = NULL;
904         }
905         break;
906     /* dynamically generated keys */
907     case HKEY_PERFORMANCE_DATA:
908         {
909             static const WCHAR name[] = { 'P','E','R','F','D','A','T','A',0 };  /* FIXME */
910             key = alloc_key( name, time(NULL) );
911         }
912         break;
913     case HKEY_DYN_DATA:
914         {
915             static const WCHAR name[] = { 'D','Y','N','D','A','T','A',0 };  /* FIXME */
916             key = alloc_key( name, time(NULL) );
917         }
918         break;
919     default:
920         key = NULL;
921         assert(0);
922     }
923     if (key)
924     {
925         root_keys[hkey - HKEY_ROOT_FIRST] = key;
926         key->flags |= KEY_ROOT;
927     }
928     return key;
929 }
930
931 /* get the registry key corresponding to an hkey handle */
932 static struct key *get_hkey_obj( int hkey, unsigned int access )
933 {
934     struct key *key;
935
936     if (IS_ROOT_HKEY(hkey))
937     {
938         if (!(key = root_keys[hkey - HKEY_ROOT_FIRST])) key = create_root_key( hkey );
939         grab_object( key );
940     }
941     else
942         key = (struct key *)get_handle_obj( current->process, hkey, access, &key_ops );
943     return key;
944 }
945
946 /* read a line from the input file */
947 static int read_next_line( struct file_load_info *info )
948 {
949     char *newbuf;
950     int newlen, pos = 0;
951
952     info->line++;
953     for (;;)
954     {
955         if (!fgets( info->buffer + pos, info->len - pos, info->file ))
956             return (pos != 0);  /* EOF */
957         pos = strlen(info->buffer);
958         if (info->buffer[pos-1] == '\n')
959         {
960             /* got a full line */
961             info->buffer[--pos] = 0;
962             if (pos > 0 && info->buffer[pos-1] == '\r') info->buffer[pos-1] = 0;
963             return 1;
964         }
965         if (pos < info->len - 1) return 1;  /* EOF but something was read */
966
967         /* need to enlarge the buffer */
968         newlen = info->len + info->len / 2;
969         if (!(newbuf = realloc( info->buffer, newlen )))
970         {
971             set_error( STATUS_NO_MEMORY );
972             return -1;
973         }
974         info->buffer = newbuf;
975         info->len = newlen;
976     }
977 }
978
979 /* make sure the temp buffer holds enough space */
980 static int get_file_tmp_space( struct file_load_info *info, int size )
981 {
982     char *tmp;
983     if (info->tmplen >= size) return 1;
984     if (!(tmp = realloc( info->tmp, size )))
985     {
986         set_error( STATUS_NO_MEMORY );
987         return 0;
988     }
989     info->tmp = tmp;
990     info->tmplen = size;
991     return 1;
992 }
993
994 /* report an error while loading an input file */
995 static void file_read_error( const char *err, struct file_load_info *info )
996 {
997     fprintf( stderr, "Line %d: %s '%s'\n", info->line, err, info->buffer );
998 }
999
1000 /* parse an escaped string back into Unicode */
1001 /* return the number of chars read from the input, or -1 on output overflow */
1002 static int parse_strW( WCHAR *dest, int *len, const char *src, char endchar )
1003 {
1004     int count = sizeof(WCHAR);  /* for terminating null */
1005     const char *p = src;
1006     while (*p && *p != endchar)
1007     {
1008         if (*p != '\\') *dest = (WCHAR)*p++;
1009         else
1010         {
1011             p++;
1012             switch(*p)
1013             {
1014             case 'a': *dest = '\a'; p++; break;
1015             case 'b': *dest = '\b'; p++; break;
1016             case 'e': *dest = '\e'; p++; break;
1017             case 'f': *dest = '\f'; p++; break;
1018             case 'n': *dest = '\n'; p++; break;
1019             case 'r': *dest = '\r'; p++; break;
1020             case 't': *dest = '\t'; p++; break;
1021             case 'v': *dest = '\v'; p++; break;
1022             case 'x':  /* hex escape */
1023                 p++;
1024                 if (!isxdigit(*p)) *dest = 'x';
1025                 else
1026                 {
1027                     *dest = to_hex(*p++);
1028                     if (isxdigit(*p)) *dest = (*dest * 16) + to_hex(*p++);
1029                     if (isxdigit(*p)) *dest = (*dest * 16) + to_hex(*p++);
1030                     if (isxdigit(*p)) *dest = (*dest * 16) + to_hex(*p++);
1031                 }
1032                 break;
1033             case '0':
1034             case '1':
1035             case '2':
1036             case '3':
1037             case '4':
1038             case '5':
1039             case '6':
1040             case '7':  /* octal escape */
1041                 *dest = *p++ - '0';
1042                 if (*p >= '0' && *p <= '7') *dest = (*dest * 8) + (*p++ - '0');
1043                 if (*p >= '0' && *p <= '7') *dest = (*dest * 8) + (*p++ - '0');
1044                 break;
1045             default:
1046                 *dest = (WCHAR)*p++;
1047                 break;
1048             }
1049         }
1050         if ((count += sizeof(WCHAR)) > *len) return -1;  /* dest buffer overflow */
1051         dest++;
1052     }
1053     *dest = 0;
1054     if (!*p) return -1;  /* delimiter not found */
1055     *len = count;
1056     return p + 1 - src;
1057 }
1058
1059 /* convert a data type tag to a value type */
1060 static int get_data_type( const char *buffer, int *type, int *parse_type )
1061 {
1062     struct data_type { const char *tag; int len; int type; int parse_type; };
1063
1064     static const struct data_type data_types[] = 
1065     {                   /* actual type */  /* type to assume for parsing */
1066         { "\"",        1,   REG_SZ,              REG_SZ },
1067         { "str:\"",    5,   REG_SZ,              REG_SZ },
1068         { "str(2):\"", 8,   REG_EXPAND_SZ,       REG_SZ },
1069         { "str(7):\"", 8,   REG_MULTI_SZ,        REG_SZ },
1070         { "hex:",      4,   REG_BINARY,          REG_BINARY },
1071         { "dword:",    6,   REG_DWORD,           REG_DWORD },
1072         { "hex(",      4,   -1,                  REG_BINARY },
1073         { NULL, }
1074     };
1075
1076     const struct data_type *ptr;
1077     char *end;
1078
1079     for (ptr = data_types; ptr->tag; ptr++)
1080     {
1081         if (memcmp( ptr->tag, buffer, ptr->len )) continue;
1082         *parse_type = ptr->parse_type;
1083         if ((*type = ptr->type) != -1) return ptr->len;
1084         /* "hex(xx):" is special */
1085         *type = (int)strtoul( buffer + 4, &end, 16 );
1086         if ((end <= buffer) || memcmp( end, "):", 2 )) return 0;
1087         return end + 2 - buffer;
1088     }
1089     return 0;
1090 }
1091
1092 /* load and create a key from the input file */
1093 static struct key *load_key( struct key *base, const char *buffer, unsigned int options,
1094                              int prefix_len, struct file_load_info *info )
1095 {
1096     WCHAR *p;
1097     int res, len, modif;
1098
1099     len = strlen(buffer) * sizeof(WCHAR);
1100     if (!get_file_tmp_space( info, len )) return NULL;
1101
1102     if ((res = parse_strW( (WCHAR *)info->tmp, &len, buffer, ']' )) == -1)
1103     {
1104         file_read_error( "Malformed key", info );
1105         return NULL;
1106     }
1107     if (!sscanf( buffer + res, " %d", &modif )) modif = time(NULL);
1108
1109     p = (WCHAR *)info->tmp;
1110     while (prefix_len && *p) { if (*p++ == '\\') prefix_len--; }
1111
1112     if (!*p)
1113     {
1114         if (prefix_len > 1)
1115         {
1116             file_read_error( "Malformed key", info );
1117             return NULL;
1118         }
1119         /* empty key name, return base key */
1120         return (struct key *)grab_object( base );
1121     }
1122     return create_key( base, p, len - ((char *)p - info->tmp), NULL, options, modif, &res );
1123 }
1124
1125 /* parse a comma-separated list of hex digits */
1126 static int parse_hex( unsigned char *dest, int *len, const char *buffer )
1127 {
1128     const char *p = buffer;
1129     int count = 0;
1130     while (isxdigit(*p))
1131     {
1132         int val;
1133         char buf[3];
1134         memcpy( buf, p, 2 );
1135         buf[2] = 0;
1136         sscanf( buf, "%x", &val );
1137         if (count++ >= *len) return -1;  /* dest buffer overflow */
1138         *dest++ = (unsigned char )val;
1139         p += 2;
1140         if (*p == ',') p++;
1141     }
1142     *len = count;
1143     return p - buffer;
1144 }
1145
1146 /* parse a value name and create the corresponding value */
1147 static struct key_value *parse_value_name( struct key *key, const char *buffer, int *len,
1148                                            struct file_load_info *info )
1149 {
1150     int maxlen = strlen(buffer) * sizeof(WCHAR);
1151     if (!get_file_tmp_space( info, maxlen )) return NULL;
1152     if (buffer[0] == '@')
1153     {
1154         info->tmp[0] = info->tmp[1] = 0;
1155         *len = 1;
1156     }
1157     else
1158     {
1159         if ((*len = parse_strW( (WCHAR *)info->tmp, &maxlen, buffer + 1, '\"' )) == -1) goto error;
1160         (*len)++;  /* for initial quote */
1161     }
1162     if (buffer[*len] != '=') goto error;
1163     (*len)++;
1164     return insert_value( key, (WCHAR *)info->tmp );
1165
1166  error:
1167     file_read_error( "Malformed value name", info );
1168     return NULL;
1169 }
1170
1171 /* load a value from the input file */
1172 static int load_value( struct key *key, const char *buffer, struct file_load_info *info )
1173 {
1174     DWORD dw;
1175     void *ptr, *newptr;
1176     int maxlen, len, res;
1177     int type, parse_type;
1178     struct key_value *value;
1179
1180     if (!(value = parse_value_name( key, buffer, &len, info ))) return 0;
1181     if (!(res = get_data_type( buffer + len, &type, &parse_type ))) goto error;
1182     buffer += len + res;
1183
1184     switch(parse_type)
1185     {
1186     case REG_SZ:
1187         len = strlen(buffer) * sizeof(WCHAR);
1188         if (!get_file_tmp_space( info, len )) return 0;
1189         if ((res = parse_strW( (WCHAR *)info->tmp, &len, buffer, '\"' )) == -1) goto error;
1190         ptr = info->tmp;
1191         break;
1192     case REG_DWORD:
1193         dw = strtoul( buffer, NULL, 16 );
1194         ptr = &dw;
1195         len = sizeof(dw);
1196         break;
1197     case REG_BINARY:  /* hex digits */
1198         len = 0;
1199         for (;;)
1200         {
1201             maxlen = 1 + strlen(buffer)/3;  /* 3 chars for one hex byte */
1202             if (!get_file_tmp_space( info, len + maxlen )) return 0;
1203             if ((res = parse_hex( info->tmp + len, &maxlen, buffer )) == -1) goto error;
1204             len += maxlen;
1205             buffer += res;
1206             while (isspace(*buffer)) buffer++;
1207             if (!*buffer) break;
1208             if (*buffer != '\\') goto error;
1209             if (read_next_line( info) != 1) goto error;
1210             buffer = info->buffer;
1211             while (isspace(*buffer)) buffer++;
1212         }
1213         ptr = info->tmp;
1214         break;
1215     default:
1216         assert(0);
1217         ptr = NULL;  /* keep compiler quiet */
1218         break;
1219     }
1220
1221     if (!len) newptr = NULL;
1222     else if (!(newptr = memdup( ptr, len ))) return 0;
1223
1224     if (value->data) free( value->data );
1225     value->data = newptr;
1226     value->len  = len;
1227     value->type = type;
1228     /* update the key level but not the modification time */
1229     key->level = max( key->level, current_level );
1230     return 1;
1231
1232  error:
1233     file_read_error( "Malformed value", info );
1234     return 0;
1235 }
1236
1237 /* return the length (in path elements) of name that is part of the key name */
1238 /* for instance if key is USER\foo\bar and name is foo\bar\baz, return 2 */
1239 static int get_prefix_len( struct key *key, const char *name, struct file_load_info *info )
1240 {
1241     WCHAR *p;
1242     int res;
1243     int len = strlen(name) * sizeof(WCHAR);
1244     if (!get_file_tmp_space( info, len )) return 0;
1245
1246     if ((res = parse_strW( (WCHAR *)info->tmp, &len, name, ']' )) == -1)
1247     {
1248         file_read_error( "Malformed key", info );
1249         return 0;
1250     }
1251     for (p = (WCHAR *)info->tmp; *p; p++) if (*p == '\\') break;
1252     *p = 0;
1253     for (res = 1; key; res++)
1254     {
1255         if (!strcmpiW( (WCHAR *)info->tmp, key->name )) break;
1256         key = key->parent;
1257     }
1258     if (!key) res = 0;  /* no matching name */
1259     return res;
1260 }
1261
1262 /* load all the keys from the input file */
1263 static void load_keys( struct key *key, FILE *f )
1264 {
1265     struct key *subkey = NULL;
1266     struct file_load_info info;
1267     char *p;
1268     unsigned int options = 0;
1269     int prefix_len = -1;  /* number of key name prefixes to skip */
1270
1271     if (key->flags & KEY_VOLATILE) options |= REG_OPTION_VOLATILE;
1272
1273     info.file   = f;
1274     info.len    = 4;
1275     info.tmplen = 4;
1276     info.line   = 0;
1277     if (!(info.buffer = mem_alloc( info.len ))) return;
1278     if (!(info.tmp = mem_alloc( info.tmplen )))
1279     {
1280         free( info.buffer );
1281         return;
1282     }
1283
1284     if ((read_next_line( &info ) != 1) ||
1285         strcmp( info.buffer, "WINE REGISTRY Version 2" ))
1286     {
1287         set_error( STATUS_NOT_REGISTRY_FILE );
1288         goto done;
1289     }
1290
1291     while (read_next_line( &info ) == 1)
1292     {
1293         for (p = info.buffer; *p && isspace(*p); p++);
1294         switch(*p)
1295         {
1296         case '[':   /* new key */
1297             if (subkey) release_object( subkey );
1298             if (prefix_len == -1) prefix_len = get_prefix_len( key, p + 1, &info );
1299             if (!(subkey = load_key( key, p + 1, options, prefix_len, &info )))
1300                 file_read_error( "Error creating key", &info );
1301             break;
1302         case '@':   /* default value */
1303         case '\"':  /* value */
1304             if (subkey) load_value( subkey, p, &info );
1305             else file_read_error( "Value without key", &info );
1306             break;
1307         case '#':   /* comment */
1308         case ';':   /* comment */
1309         case 0:     /* empty line */
1310             break;
1311         default:
1312             file_read_error( "Unrecognized input", &info );
1313             break;
1314         }
1315     }
1316
1317  done:
1318     if (subkey) release_object( subkey );
1319     free( info.buffer );
1320     free( info.tmp );
1321 }
1322
1323 /* load a part of the registry from a file */
1324 static void load_registry( struct key *key, int handle )
1325 {
1326     struct object *obj;
1327     int fd;
1328
1329     if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL ))) return;
1330     fd = obj->ops->get_read_fd( obj );
1331     release_object( obj );
1332     if (fd != -1)
1333     {
1334         FILE *f = fdopen( fd, "r" );
1335         if (f)
1336         {
1337             load_keys( key, f );
1338             fclose( f );
1339         }
1340         else file_set_error();
1341     }
1342 }
1343
1344 /* update the level of the parents of a key (only needed for the old format) */
1345 static int update_level( struct key *key )
1346 {
1347     int i;
1348     int max = key->level;
1349     for (i = 0; i <= key->last_subkey; i++)
1350     {
1351         int sub = update_level( key->subkeys[i] );
1352         if (sub > max) max = sub;
1353     }
1354     key->level = max;
1355     return max;
1356 }
1357
1358 /* save a registry branch to a file */
1359 static void save_all_subkeys( struct key *key, FILE *f )
1360 {
1361     fprintf( f, "WINE REGISTRY Version 2\n" );
1362     fprintf( f, ";; All keys relative to " );
1363     dump_path( key, NULL, f );
1364     fprintf( f, "\n" );
1365     save_subkeys( key, key, f );
1366 }
1367
1368 /* save a registry branch to a file handle */
1369 static void save_registry( struct key *key, int handle )
1370 {
1371     struct object *obj;
1372     int fd;
1373
1374     if (key->flags & KEY_DELETED)
1375     {
1376         set_error( STATUS_KEY_DELETED );
1377         return;
1378     }
1379     if (!(obj = get_handle_obj( current->process, handle, GENERIC_WRITE, NULL ))) return;
1380     fd = obj->ops->get_write_fd( obj );
1381     release_object( obj );
1382     if (fd != -1)
1383     {
1384         FILE *f = fdopen( fd, "w" );
1385         if (f)
1386         {
1387             save_all_subkeys( key, f );
1388             if (fclose( f )) file_set_error();
1389         }
1390         else
1391         {
1392             file_set_error();
1393             close( fd );
1394         }
1395     }
1396 }
1397
1398 /* register a key branch for being saved on exit */
1399 static void register_branch_for_saving( struct key *key, const char *path, size_t len )
1400 {
1401     if (save_branch_count >= MAX_SAVE_BRANCH_INFO)
1402     {
1403         set_error( STATUS_NO_MORE_ENTRIES );
1404         return;
1405     }
1406     if (!(save_branch_info[save_branch_count].path = memdup( path, len+1 ))) return;
1407     save_branch_info[save_branch_count].path[len] = 0;
1408     save_branch_info[save_branch_count].key = (struct key *)grab_object( key );
1409     save_branch_count++;
1410 }
1411
1412 /* save a registry branch to a file */
1413 static int save_branch( struct key *key, const char *path )
1414 {
1415     char *p, *real, *tmp = NULL;
1416     int fd, count = 0, ret = 0;
1417     FILE *f;
1418
1419     /* get the real path */
1420
1421     if (!(real = malloc( PATH_MAX ))) return 0;
1422     if (!realpath( path, real ))
1423     {
1424         free( real );
1425         real = NULL;
1426     }
1427     else path = real;
1428
1429     /* test the file type */
1430
1431     if ((fd = open( path, O_WRONLY )) != -1)
1432     {
1433         struct stat st;
1434         /* if file is not a regular file or has multiple links,
1435            write directly into it; otherwise use a temp file */
1436         if (!fstat( fd, &st ) && (!S_ISREG(st.st_mode) || st.st_nlink > 1))
1437         {
1438             ftruncate( fd, 0 );
1439             goto save;
1440         }
1441         close( fd );
1442     }
1443
1444     /* create a temp file in the same directory */
1445
1446     if (!(tmp = malloc( strlen(path) + 20 ))) goto done;
1447     strcpy( tmp, path );
1448     if ((p = strrchr( tmp, '/' ))) p++;
1449     else p = tmp;
1450     for (;;)
1451     {
1452         sprintf( p, "reg%lx%04x.tmp", (long) getpid(), count++ );
1453         if ((fd = open( tmp, O_CREAT | O_EXCL | O_WRONLY, 0666 )) != -1) break;
1454         if (errno != EEXIST) goto done;
1455         close( fd );
1456     }
1457
1458     /* now save to it */
1459
1460  save:
1461     if (!(f = fdopen( fd, "w" )))
1462     {
1463         if (tmp) unlink( tmp );
1464         close( fd );
1465         goto done;
1466     }
1467
1468     if (debug_level > 1)
1469     {
1470         fprintf( stderr, "%s: ", path );
1471         dump_operation( key, NULL, "saving" );
1472     }
1473
1474     save_all_subkeys( key, f );
1475     ret = !fclose(f);
1476
1477     if (tmp)
1478     {
1479         /* if successfully written, rename to final name */
1480         if (ret) ret = !rename( tmp, path );
1481         if (!ret) unlink( tmp );
1482         free( tmp );
1483     }
1484
1485 done:
1486     if (real) free( real );
1487     return ret;
1488 }
1489
1490 /* periodic saving of the registry */
1491 static void periodic_save( void *arg )
1492 {
1493     int i;
1494     for (i = 0; i < save_branch_count; i++)
1495         save_branch( save_branch_info[i].key, save_branch_info[i].path );
1496     add_timeout( &next_save_time, save_period );
1497     save_timeout_user = add_timeout_user( &next_save_time, periodic_save, 0 );
1498 }
1499
1500 /* save the registry and close the top-level keys; used on server exit */
1501 void close_registry(void)
1502 {
1503     int i;
1504
1505     for (i = 0; i < save_branch_count; i++)
1506     {
1507         if (!save_branch( save_branch_info[i].key, save_branch_info[i].path ))
1508         {
1509             fprintf( stderr, "wineserver: could not save registry branch to %s",
1510                      save_branch_info[i].path );
1511             perror( " " );
1512         }
1513         release_object( save_branch_info[i].key );
1514     }
1515     for (i = 0; i < NB_ROOT_KEYS; i++)
1516     {
1517         if (root_keys[i]) release_object( root_keys[i] );
1518     }
1519 }
1520
1521
1522 /* create a registry key */
1523 DECL_HANDLER(create_key)
1524 {
1525     struct key *key, *parent;
1526     WCHAR *class;
1527     unsigned int access = req->access;
1528
1529     if (access & MAXIMUM_ALLOWED) access = KEY_ALL_ACCESS;  /* FIXME: needs general solution */
1530     req->hkey = -1;
1531     if ((parent = get_hkey_obj( req->parent, 0 /*FIXME*/ )))
1532     {
1533         if ((class = req_strdupW( req, req->class )))
1534         {
1535             if ((key = create_key( parent, req->name, sizeof(req->name), class, req->options,
1536                                    req->modif, &req->created )))
1537             {
1538                 req->hkey = alloc_handle( current->process, key, access, 0 );
1539                 release_object( key );
1540             }
1541             free( class );
1542         }
1543         release_object( parent );
1544     }
1545 }
1546
1547 /* open a registry key */
1548 DECL_HANDLER(open_key)
1549 {
1550     struct key *key, *parent;
1551     unsigned int access = req->access;
1552
1553     if (access & MAXIMUM_ALLOWED) access = KEY_ALL_ACCESS;  /* FIXME: needs general solution */
1554     req->hkey = -1;
1555     if ((parent = get_hkey_obj( req->parent, 0 /*FIXME*/ )))
1556     {
1557         if ((key = open_key( parent, req->name, sizeof(req->name) )))
1558         {
1559             req->hkey = alloc_handle( current->process, key, access, 0 );
1560             release_object( key );
1561         }
1562         release_object( parent );
1563     }
1564 }
1565
1566 /* delete a registry key */
1567 DECL_HANDLER(delete_key)
1568 {
1569     struct key *key;
1570
1571     if ((key = get_hkey_obj( req->hkey, 0 /*FIXME*/ )))
1572     {
1573         delete_key( key, req->name, sizeof(req->name) );
1574         release_object( key );
1575     }
1576 }
1577
1578 /* close a registry key */
1579 DECL_HANDLER(close_key)
1580 {
1581     int hkey = req->hkey;
1582     /* ignore attempts to close a root key */
1583     if (!IS_ROOT_HKEY(hkey)) close_handle( current->process, hkey );
1584 }
1585
1586 /* enumerate registry subkeys */
1587 DECL_HANDLER(enum_key)
1588 {
1589     struct key *key;
1590
1591     req->name[0] = req->class[0] = 0;
1592     if ((key = get_hkey_obj( req->hkey, KEY_ENUMERATE_SUB_KEYS )))
1593     {
1594         enum_key( key, req->index, req->name, req->class, &req->modif );
1595         release_object( key );
1596     }
1597 }
1598
1599 /* query information about a registry key */
1600 DECL_HANDLER(query_key_info)
1601 {
1602     struct key *key;
1603
1604     req->name[0] = req->class[0] = 0;
1605     if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE )))
1606     {
1607         query_key( key, req );
1608         release_object( key );
1609     }
1610 }
1611
1612 /* set a value of a registry key */
1613 DECL_HANDLER(set_key_value)
1614 {
1615     struct key *key;
1616     unsigned int max = get_req_size( req, req->data, sizeof(req->data[0]) );
1617     unsigned int datalen = req->len;
1618
1619     if (datalen > max) datalen = max;
1620     if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE )))
1621     {
1622         set_value( key, copy_path( req->name ), req->type, req->total,
1623                    req->offset, datalen, req->data );
1624         release_object( key );
1625     }
1626 }
1627
1628 /* retrieve the value of a registry key */
1629 DECL_HANDLER(get_key_value)
1630 {
1631     struct key *key;
1632     unsigned int max = get_req_size( req, req->data, sizeof(req->data[0]) );
1633
1634     req->len = 0;
1635     if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE )))
1636     {
1637         get_value( key, copy_path( req->name ), req->offset, max,
1638                    &req->type, &req->len, req->data );
1639         release_object( key );
1640     }
1641 }
1642
1643 /* enumerate the value of a registry key */
1644 DECL_HANDLER(enum_key_value)
1645 {
1646     struct key *key;
1647     unsigned int max = get_req_size( req, req->data, sizeof(req->data[0]) );
1648
1649     req->len = 0;
1650     req->name[0] = 0;
1651     if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE )))
1652     {
1653         enum_value( key, req->index, req->name, req->offset, max,
1654                     &req->type, &req->len, req->data );
1655         release_object( key );
1656     }
1657 }
1658
1659 /* delete a value of a registry key */
1660 DECL_HANDLER(delete_key_value)
1661 {
1662     WCHAR *name;
1663     struct key *key;
1664
1665     if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE )))
1666     {
1667         if ((name = req_strdupW( req, req->name )))
1668         {
1669             delete_value( key, name );
1670             free( name );
1671         }
1672         release_object( key );
1673     }
1674 }
1675
1676 /* load a registry branch from a file */
1677 DECL_HANDLER(load_registry)
1678 {
1679     struct key *key;
1680
1681     if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE | KEY_CREATE_SUB_KEY )))
1682     {
1683         /* FIXME: use subkey name */
1684         load_registry( key, req->file );
1685         release_object( key );
1686     }
1687 }
1688
1689 /* save a registry branch to a file */
1690 DECL_HANDLER(save_registry)
1691 {
1692     struct key *key;
1693
1694     if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS )))
1695     {
1696         save_registry( key, req->file );
1697         release_object( key );
1698     }
1699 }
1700
1701 /* set the current and saving level for the registry */
1702 DECL_HANDLER(set_registry_levels)
1703 {
1704     current_level  = req->current;
1705     saving_level   = req->saving;
1706
1707     /* set periodic save timer */
1708
1709     if (save_timeout_user)
1710     {
1711         remove_timeout_user( save_timeout_user );
1712         save_timeout_user = NULL;
1713     }
1714     if ((save_period = req->period))
1715     {
1716         if (save_period < 10000) save_period = 10000;  /* limit rate */
1717         gettimeofday( &next_save_time, 0 );
1718         add_timeout( &next_save_time, save_period );
1719         save_timeout_user = add_timeout_user( &next_save_time, periodic_save, 0 );
1720     }
1721 }
1722
1723 /* save a registry branch at server exit */
1724 DECL_HANDLER(save_registry_atexit)
1725 {
1726     struct key *key;
1727
1728     if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS )))
1729     {
1730         register_branch_for_saving( key, req->file, get_req_strlen( req, req->file ) );
1731         release_object( key );
1732     }
1733 }