Removed most inclusions of options.h.
[wine] / misc / registry.c
1 /*
2  *      Registry Functions
3  *
4  * Copyright 1996 Marcus Meissner
5  * Copyright 1998 Matthew Becker
6  * Copyright 1999 Sylvain St-Germain
7  *
8  * December 21, 1997 - Kevin Cozens
9  * Fixed bugs in the _w95_loadreg() function. Added extra information
10  * regarding the format of the Windows '95 registry files.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  *
26  * NOTES
27  *    When changing this file, please re-run the regtest program to ensure
28  *    the conditions are handled properly.
29  *
30  * TODO
31  *    Security access
32  *    Option handling
33  *    Time for RegEnumKey*, RegQueryInfoKey*
34  */
35
36 #include "config.h"
37 #include "wine/port.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include <unistd.h>
43 #include <errno.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #ifdef HAVE_SYS_MMAN_H
48 # include <sys/mman.h>
49 #endif
50
51 #include "winerror.h"
52 #include "winnt.h"
53 #include "winreg.h"
54
55 #include "wine/winbase16.h"
56 #include "wine/server.h"
57 #include "wine/unicode.h"
58 #include "file.h"
59
60 #include "wine/debug.h"
61
62 WINE_DEFAULT_DEBUG_CHANNEL(reg);
63
64 /* FIXME: following defines should be configured global */
65 #define SAVE_GLOBAL_REGBRANCH_USER_DEFAULT  ETCDIR"/wine.userreg"
66 #define SAVE_GLOBAL_REGBRANCH_LOCAL_MACHINE ETCDIR"/wine.systemreg"
67
68 /* relative in ~user/.wine/ : */
69 #define SAVE_LOCAL_REGBRANCH_CURRENT_USER  "user.reg"
70 #define SAVE_LOCAL_REGBRANCH_USER_DEFAULT  "userdef.reg"
71 #define SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE "system.reg"
72
73 /* _xmalloc [Internal] */
74 static void *_xmalloc( size_t size )
75 {
76     void *res;
77
78     res = malloc (size ? size : 1);
79     if (res == NULL) {
80         WARN("Virtual memory exhausted.\n");
81         exit (1);
82     }
83     return res;
84 }
85
86 /* _strdupnA [Internal] */
87 static LPSTR _strdupnA(LPCSTR str,size_t len)
88 {
89     LPSTR ret;
90
91     if (!str) return NULL;
92     ret = _xmalloc( len + 1 );
93     memcpy( ret, str, len );
94     ret[len] = 0x00;
95     return ret;
96 }
97
98 /* convert ansi string to unicode [Internal] */
99 static LPWSTR _strdupnAtoW(LPCSTR strA,size_t lenA)
100 {
101     LPWSTR ret;
102     size_t lenW;
103
104     if (!strA) return NULL;
105     lenW = MultiByteToWideChar(CP_ACP,0,strA,lenA,NULL,0);
106     ret = _xmalloc(lenW*sizeof(WCHAR)+sizeof(WCHAR));
107     MultiByteToWideChar(CP_ACP,0,strA,lenA,ret,lenW);
108     ret[lenW] = 0;
109     return ret;
110 }
111
112 /* dump a Unicode string with proper escaping [Internal] */
113 /* FIXME: this code duplicates server/unicode.c */
114 static int _dump_strW(const WCHAR *str,size_t len,FILE *f,char escape[2])
115 {
116     static const char escapes[32] = ".......abtnvfr.............e....";
117     char buffer[256];
118     LPSTR pos = buffer;
119     int count = 0;
120
121     for (; len; str++, len--)
122     {
123         if (pos > buffer + sizeof(buffer) - 8)
124         {
125             fwrite( buffer, pos - buffer, 1, f );
126             count += pos - buffer;
127             pos = buffer;
128         }
129         if (*str > 127)  /* hex escape */
130         {
131             if (len > 1 && str[1] < 128 && isxdigit((char)str[1]))
132                 pos += sprintf( pos, "\\x%04x", *str );
133             else
134                 pos += sprintf( pos, "\\x%x", *str );
135             continue;
136         }
137         if (*str < 32)  /* octal or C escape */
138         {
139             if (!*str && len == 1) continue;  /* do not output terminating NULL */
140             if (escapes[*str] != '.')
141                 pos += sprintf( pos, "\\%c", escapes[*str] );
142             else if (len > 1 && str[1] >= '0' && str[1] <= '7')
143                 pos += sprintf( pos, "\\%03o", *str );
144             else
145                 pos += sprintf( pos, "\\%o", *str );
146             continue;
147         }
148         if (*str == '\\' || *str == escape[0] || *str == escape[1]) *pos++ = '\\';
149         *pos++ = *str;
150     }
151     fwrite( buffer, pos - buffer, 1, f );
152     count += pos - buffer;
153     return count;
154 }
155
156 /* convert ansi string to unicode and dump with proper escaping [Internal] */
157 static int _dump_strAtoW(LPCSTR strA,size_t len,FILE *f,char escape[2])
158 {
159     WCHAR *strW;
160     int ret;
161
162     if (strA == NULL) return 0;
163     strW = _strdupnAtoW(strA,len);
164     ret = _dump_strW(strW,len,f,escape);
165     free(strW);
166     return ret;
167 }
168
169 /* a key value */
170 /* FIXME: this code duplicates server/registry.c */
171 struct key_value {
172     WCHAR            *nameW;   /* value name */
173     int               type;    /* value type */
174     size_t            len;     /* value data length in bytes */
175     void             *data;    /* pointer to value data */
176 };
177
178 /* dump a value to a text file */
179 /* FIXME: this code duplicates server/registry.c */
180 static void _dump_value(struct key_value *value,FILE *f)
181 {
182     int i, count;
183
184     if (value->nameW[0]) {
185         fputc( '\"', f );
186         count = 1 + _dump_strW(value->nameW,strlenW(value->nameW),f,"\"\"");
187         count += fprintf( f, "\"=" );
188     }
189     else count = fprintf( f, "@=" );
190
191     switch(value->type) {
192         case REG_SZ:
193         case REG_EXPAND_SZ:
194         case REG_MULTI_SZ:
195             if (value->type != REG_SZ) fprintf( f, "str(%d):", value->type );
196             fputc( '\"', f );
197             if (value->data) _dump_strW(value->data,value->len/sizeof(WCHAR),f,"\"\"");
198             fputc( '\"', f );
199             break;
200         case REG_DWORD:
201             if (value->len == sizeof(DWORD)) {
202                 DWORD dw;
203                 memcpy( &dw, value->data, sizeof(DWORD) );
204                 fprintf( f, "dword:%08lx", dw );
205                 break;
206             }
207             /* else fall through */
208         default:
209             if (value->type == REG_BINARY) count += fprintf( f, "hex:" );
210             else count += fprintf( f, "hex(%x):", value->type );
211             for (i = 0; i < value->len; i++) {
212                 count += fprintf( f, "%02x", *((unsigned char *)value->data + i) );
213                 if (i < value->len-1) {
214                     fputc( ',', f );
215                     if (++count > 76) {
216                         fprintf( f, "\\\n  " );
217                         count = 2;
218                     }
219                 }
220             }
221             break;
222     }
223     fputc( '\n', f );
224 }
225
226 /******************************************************************/
227 /* WINDOWS 31 REGISTRY LOADER, supplied by Tor Sjøwall, tor@sn.no */
228 /*
229     reghack - windows 3.11 registry data format demo program.
230
231     The reg.dat file has 3 parts, a header, a table of 8-byte entries that is
232     a combined hash table and tree description, and finally a text table.
233
234     The header is obvious from the struct header. The taboff1 and taboff2
235     fields are always 0x20, and their usage is unknown.
236
237     The 8-byte entry table has various entry types.
238
239     tabent[0] is a root index. The second word has the index of the root of
240             the directory.
241     tabent[1..hashsize] is a hash table. The first word in the hash entry is
242             the index of the key/value that has that hash. Data with the same
243             hash value are on a circular list. The other three words in the
244             hash entry are always zero.
245     tabent[hashsize..tabcnt] is the tree structure. There are two kinds of
246             entry: dirent and keyent/valent. They are identified by context.
247     tabent[freeidx] is the first free entry. The first word in a free entry
248             is the index of the next free entry. The last has 0 as a link.
249             The other three words in the free list are probably irrelevant.
250
251     Entries in text table are preceded by a word at offset-2. This word
252     has the value (2*index)+1, where index is the referring keyent/valent
253     entry in the table. I have no suggestion for the 2* and the +1.
254     Following the word, there are N bytes of data, as per the keyent/valent
255     entry length. The offset of the keyent/valent entry is from the start
256     of the text table to the first data byte.
257
258     This information is not available from Microsoft. The data format is
259     deduced from the reg.dat file by me. Mistakes may
260     have been made. I claim no rights and give no guarantees for this program.
261
262     Tor Sjøwall, tor@sn.no
263 */
264
265 /* reg.dat header format */
266 struct _w31_header {
267     char                cookie[8];      /* 'SHCC3.10' */
268     unsigned long       taboff1;        /* offset of hash table (??) = 0x20 */
269     unsigned long       taboff2;        /* offset of index table (??) = 0x20 */
270     unsigned long       tabcnt;         /* number of entries in index table */
271     unsigned long       textoff;        /* offset of text part */
272     unsigned long       textsize;       /* byte size of text part */
273     unsigned short      hashsize;       /* hash size */
274     unsigned short      freeidx;        /* free index */
275 };
276
277 /* generic format of table entries */
278 struct _w31_tabent {
279     unsigned short w0, w1, w2, w3;
280 };
281
282 /* directory tabent: */
283 struct _w31_dirent {
284     unsigned short      sibling_idx;    /* table index of sibling dirent */
285     unsigned short      child_idx;      /* table index of child dirent */
286     unsigned short      key_idx;        /* table index of key keyent */
287     unsigned short      value_idx;      /* table index of value valent */
288 };
289
290 /* key tabent: */
291 struct _w31_keyent {
292     unsigned short      hash_idx;       /* hash chain index for string */
293     unsigned short      refcnt;         /* reference count */
294     unsigned short      length;         /* length of string */
295     unsigned short      string_off;     /* offset of string in text table */
296 };
297
298 /* value tabent: */
299 struct _w31_valent {
300     unsigned short      hash_idx;       /* hash chain index for string */
301     unsigned short      refcnt;         /* reference count */
302     unsigned short      length;         /* length of string */
303     unsigned short      string_off;     /* offset of string in text table */
304 };
305
306 /* recursive helper function to display a directory tree  [Internal] */
307 void _w31_dumptree(unsigned short idx,unsigned char *txt,struct _w31_tabent *tab,struct _w31_header *head,HKEY hkey,time_t lastmodified, int level)
308 {
309     struct _w31_dirent *dir;
310     struct _w31_keyent *key;
311     struct _w31_valent *val;
312     HKEY subkey = 0;
313     static char tail[400];
314
315     while (idx!=0) {
316         dir=(struct _w31_dirent*)&tab[idx];
317
318         if (dir->key_idx) {
319             key = (struct _w31_keyent*)&tab[dir->key_idx];
320
321             memcpy(tail,&txt[key->string_off],key->length);
322             tail[key->length]='\0';
323             /* all toplevel entries AND the entries in the 
324              * toplevel subdirectory belong to \SOFTWARE\Classes
325              */
326             if (!level && !strcmp(tail,".classes")) {
327                 _w31_dumptree(dir->child_idx,txt,tab,head,hkey,lastmodified,level+1);
328                 idx=dir->sibling_idx;
329                 continue;
330             }
331             if (subkey) RegCloseKey( subkey );
332             if (RegCreateKeyA( hkey, tail, &subkey ) != ERROR_SUCCESS) subkey = 0;
333             /* only add if leaf node or valued node */
334             if (dir->value_idx!=0||dir->child_idx==0) {
335                 if (dir->value_idx) {
336                     val=(struct _w31_valent*)&tab[dir->value_idx];
337                     memcpy(tail,&txt[val->string_off],val->length);
338                     tail[val->length]='\0';
339                     RegSetValueA( subkey, NULL, REG_SZ, tail, 0 );
340                 }
341             }
342         } else TRACE("strange: no directory key name, idx=%04x\n", idx);
343         _w31_dumptree(dir->child_idx,txt,tab,head,subkey,lastmodified,level+1);
344         idx=dir->sibling_idx;
345     }
346     if (subkey) RegCloseKey( subkey );
347 }
348
349
350 /******************************************************************************
351  * _w31_loadreg [Internal]
352  */
353 void _w31_loadreg(void) 
354 {
355     HFILE hf;
356     struct _w31_header  head;
357     struct _w31_tabent  *tab;
358     unsigned char               *txt;
359     unsigned int                len;
360     OFSTRUCT            ofs;
361     BY_HANDLE_FILE_INFORMATION hfinfo;
362     time_t                      lastmodified;
363
364     TRACE("(void)\n");
365
366     hf = OpenFile("reg.dat",&ofs,OF_READ);
367     if (hf==HFILE_ERROR) return;
368
369     /* read & dump header */
370     if (sizeof(head)!=_lread(hf,&head,sizeof(head))) {
371         ERR("reg.dat is too short.\n");
372         _lclose(hf);
373         return;
374     }
375     if (memcmp(head.cookie, "SHCC3.10", sizeof(head.cookie))!=0) {
376         ERR("reg.dat has bad signature.\n");
377         _lclose(hf);
378         return;
379     }
380
381     len = head.tabcnt * sizeof(struct _w31_tabent);
382     /* read and dump index table */
383     tab = _xmalloc(len);
384     if (len!=_lread(hf,tab,len)) {
385         ERR("couldn't read %d bytes.\n",len); 
386         free(tab);
387         _lclose(hf);
388         return;
389     }
390
391     /* read text */
392     txt = _xmalloc(head.textsize);
393     if (-1==_llseek(hf,head.textoff,SEEK_SET)) {
394         ERR("couldn't seek to textblock.\n"); 
395         free(tab);
396         free(txt);
397         _lclose(hf);
398         return;
399     }
400     if (head.textsize!=_lread(hf,txt,head.textsize)) {
401         ERR("textblock too short (%d instead of %ld).\n",len,head.textsize); 
402         free(tab);
403         free(txt);
404         _lclose(hf);
405         return;
406     }
407
408     if (!GetFileInformationByHandle(hf,&hfinfo)) {
409         ERR("GetFileInformationByHandle failed?.\n"); 
410         free(tab);
411         free(txt);
412         _lclose(hf);
413         return;
414     }
415     lastmodified = DOSFS_FileTimeToUnixTime(&hfinfo.ftLastWriteTime,NULL);
416     _w31_dumptree(tab[0].w1,txt,tab,&head,HKEY_CLASSES_ROOT,lastmodified,0);
417     free(tab);
418     free(txt);
419     _lclose(hf);
420     return;
421 }
422
423 /***********************************************************************************/
424 /*                        windows 95 registry loader                               */
425 /***********************************************************************************/
426
427 /* SECTION 1: main header
428  *
429  * once at offset 0
430  */
431 #define W95_REG_CREG_ID 0x47455243
432
433 typedef struct {
434     DWORD       id;             /* "CREG" = W95_REG_CREG_ID */
435     DWORD       version;        /* ???? 0x00010000 */
436     DWORD       rgdb_off;       /* 0x08 Offset of 1st RGDB-block */
437     DWORD       uk2;            /* 0x0c */
438     WORD        rgdb_num;       /* 0x10 # of RGDB-blocks */
439     WORD        uk3;
440     DWORD       uk[3];
441     /* rgkn */
442 } _w95creg;
443
444 /* SECTION 2: Directory information (tree structure)
445  *
446  * once on offset 0x20
447  *
448  * structure: [rgkn][dke]*      (repeat till last_dke is reached)
449  */
450 #define W95_REG_RGKN_ID 0x4e4b4752
451
452 typedef struct {
453     DWORD       id;             /*"RGKN" = W95_REG_RGKN_ID */
454     DWORD       size;           /* Size of the RGKN-block */
455     DWORD       root_off;       /* Rel. Offset of the root-record */
456     DWORD   last_dke;       /* Offset to last DKE ? */
457     DWORD       uk[4];
458 } _w95rgkn;
459
460 /* Disk Key Entry Structure
461  *
462  * the 1st entry in a "usual" registry file is a nul-entry with subkeys: the
463  * hive itself. It looks the same like other keys. Even the ID-number can
464  * be any value.
465  *
466  * The "hash"-value is a value representing the key's name. Windows will not
467  * search for the name, but for a matching hash-value. if it finds one, it
468  * will compare the actual string info, otherwise continue with the next key.
469  * To calculate the hash initialize a D-Word with 0 and add all ASCII-values 
470  * of the string which are smaller than 0x80 (128) to this D-Word.   
471  *
472  * If you want to modify key names, also modify the hash-values, since they
473  * cannot be found again (although they would be displayed in REGEDIT)
474  * End of list-pointers are filled with 0xFFFFFFFF
475  *
476  * Disk keys are layed out flat ... But, sometimes, nrLS and nrMS are both
477  * 0xFFFF, which means skipping over nextkeyoffset bytes (including this
478  * structure) and reading another RGDB_section.
479  *
480  * The last DKE (see field last_dke in _w95_rgkn) has only 3 DWORDs with
481  * 0x80000000 (EOL indicator ?) as x1, the hash value and 0xFFFFFFFF as x3.
482  * The remaining space between last_dke and the offset calculated from
483  * rgkn->size seems to be free for use for more dke:s.
484  * So it seems if more dke:s are added, they are added to that space and
485  * last_dke is grown, and in case that "free" space is out, the space
486  * gets grown and rgkn->size gets adjusted.
487  *
488  * there is a one to one relationship between dke and dkh
489  */
490  /* key struct, once per key */
491 typedef struct {
492     DWORD       x1;             /* Free entry indicator(?) */
493     DWORD       hash;           /* sum of bytes of keyname */
494     DWORD       x3;             /* Root key indicator? usually 0xFFFFFFFF */
495     DWORD       prevlvl;        /* offset of previous key */
496     DWORD       nextsub;        /* offset of child key */
497     DWORD       next;           /* offset of sibling key */
498     WORD        nrLS;           /* id inside the rgdb block */
499     WORD        nrMS;           /* number of the rgdb block */
500 } _w95dke;
501
502 /* SECTION 3: key information, values and data
503  *
504  * structure:
505  *  section:    [blocks]*               (repeat creg->rgdb_num times)
506  *  blocks:     [rgdb] [subblocks]*     (repeat till block size reached )
507  *  subblocks:  [dkh] [dkv]*            (repeat dkh->values times )
508  *
509  * An interesting relationship exists in RGDB_section. The DWORD value
510  * at offset 0x10 equals the one at offset 0x04 minus the one at offset 0x08.
511  * I have no idea at the moment what this means.  (Kevin Cozens)
512  */
513
514 /* block header, once per block */
515 #define W95_REG_RGDB_ID 0x42444752
516
517 typedef struct {
518     DWORD       id;     /* 0x00 'RGDB' = W95_REG_RGDB_ID */
519     DWORD       size;   /* 0x04 */
520     DWORD       uk1;    /* 0x08 */
521     DWORD       uk2;    /* 0x0c */
522     DWORD       uk3;    /* 0x10 */
523     DWORD       uk4;    /* 0x14 */
524     DWORD       uk5;    /* 0x18 */
525     DWORD       uk6;    /* 0x1c */
526     /* dkh */
527 } _w95rgdb;
528
529 /* Disk Key Header structure (RGDB part), once per key */
530 typedef struct {
531     DWORD       nextkeyoff;     /* 0x00 offset to next dkh */
532     WORD        nrLS;           /* 0x04 id inside the rgdb block */
533     WORD        nrMS;           /* 0x06 number of the rgdb block */
534     DWORD       bytesused;      /* 0x08 */
535     WORD        keynamelen;     /* 0x0c len of name */
536     WORD        values;         /* 0x0e number of values */
537     DWORD       xx1;            /* 0x10 */
538     char        name[1];        /* 0x14 */
539     /* dkv */           /* 0x14 + keynamelen */
540 } _w95dkh;
541
542 /* Disk Key Value structure, once per value */
543 typedef struct {
544     DWORD       type;           /* 0x00 */
545     DWORD       x1;             /* 0x04 */
546     WORD        valnamelen;     /* 0x08 length of name, 0 is default key */
547     WORD        valdatalen;     /* 0x0A length of data */
548     char        name[1];        /* 0x0c */
549     /* raw data */              /* 0x0c + valnamelen */
550 } _w95dkv;
551
552 /******************************************************************************
553  * _w95_lookup_dkh [Internal]
554  *
555  * seeks the dkh belonging to a dke
556  */
557 static _w95dkh *_w95_lookup_dkh(_w95creg *creg,int nrLS,int nrMS)
558 {
559     _w95rgdb * rgdb;
560     _w95dkh * dkh;
561     int i;
562
563     /* get the beginning of the rgdb datastore */
564     rgdb = (_w95rgdb*)((char*)creg+creg->rgdb_off);
565
566     /* check: requested block < last_block) */
567     if (creg->rgdb_num <= nrMS) {
568         ERR("registry file corrupt! requested block no. beyond end.\n");
569         goto error;
570     }
571
572     /* find the right block */
573     for(i=0; i<nrMS ;i++) {
574         if(rgdb->id != W95_REG_RGDB_ID) {  /* check the magic */
575             ERR("registry file corrupt! bad magic 0x%08lx\n", rgdb->id);
576             goto error;
577         }
578         rgdb = (_w95rgdb*) ((char*)rgdb+rgdb->size);            /* find next block */
579     }
580
581     dkh = (_w95dkh*)(rgdb + 1);                         /* first sub block within the rgdb */
582
583     do {
584         if(nrLS==dkh->nrLS ) return dkh;
585         dkh = (_w95dkh*)((char*)dkh + dkh->nextkeyoff); /* find next subblock */
586     } while ((char *)dkh < ((char*)rgdb+rgdb->size));
587
588 error:
589     return NULL;
590 }
591
592 /******************************************************************************
593  * _w95_dump_dkv [Internal]
594  */
595 static int _w95_dump_dkv(_w95dkh *dkh,int nrLS,int nrMS,FILE *f)
596 {
597     _w95dkv * dkv;
598     int i;
599
600     /* first value block */
601     dkv = (_w95dkv*)((char*)dkh+dkh->keynamelen+0x14);
602
603     /* loop through the values */
604     for (i=0; i< dkh->values; i++) {
605         struct key_value value;
606         WCHAR *pdata;
607
608         value.nameW = _strdupnAtoW(dkv->name,dkv->valnamelen);
609         value.type = dkv->type;
610         value.len = dkv->valdatalen;
611
612         value.data = &(dkv->name[dkv->valnamelen]);
613         pdata = NULL;
614         if ( (value.type==REG_SZ) || (value.type==REG_EXPAND_SZ) || (value.type==REG_MULTI_SZ) ) {
615             pdata = _strdupnAtoW(value.data,value.len);
616             value.len *= 2;
617         }
618         if (pdata != NULL) value.data = pdata;
619
620         _dump_value(&value,f);
621         free(value.nameW);
622         if (pdata != NULL) free(pdata);
623
624         /* next value */
625         dkv = (_w95dkv*)((char*)dkv+dkv->valnamelen+dkv->valdatalen+0x0c);
626     }
627     return TRUE;
628 }
629
630 /******************************************************************************
631  * _w95_dump_dke [Internal]
632  */
633 static int _w95_dump_dke(LPSTR key_name,_w95creg *creg,_w95rgkn *rgkn,_w95dke *dke,FILE *f,int level)
634 {
635     _w95dkh * dkh;
636     LPSTR new_key_name = NULL;
637
638     /* special root key */
639     if (dke->nrLS == 0xffff || dke->nrMS==0xffff)               /* eg. the root key has no name */
640     {
641         /* parse the one subkey */
642         if (dke->nextsub != 0xffffffff) return _w95_dump_dke(key_name, creg, rgkn, (_w95dke*)((char*)rgkn+dke->nextsub),f,level);
643         /* has no sibling keys */
644         return FALSE;
645     }
646
647     /* search subblock */
648     if (!(dkh = _w95_lookup_dkh(creg, dke->nrLS, dke->nrMS))) {
649         ERR("dke pointing to missing dkh !\n");
650         return FALSE;
651     }
652
653     if (level <= 0) {
654         /* create new subkey name */
655         new_key_name = _strdupnA(key_name,strlen(key_name)+dkh->keynamelen+1);
656         if (strcmp(new_key_name,"") != 0) strcat(new_key_name,"\\");
657         strncat(new_key_name,dkh->name,dkh->keynamelen);
658
659         /* walk sibling keys */
660         if (dke->next != 0xffffffff ) {
661             if (!_w95_dump_dke(key_name, creg, rgkn, (_w95dke*)((char*)rgkn+dke->next),f,level)) {
662                 free(new_key_name);
663                 return FALSE;
664             }
665         }
666
667         /* write the key path (something like [Software\\Microsoft\\..]) only if: 
668            1) key has some values
669            2) key has no values and no subkeys
670         */
671         if (dkh->values > 0) {
672             /* there are some values */
673             fprintf(f,"\n[");
674             _dump_strAtoW(new_key_name,strlen(new_key_name),f,"[]");
675             fprintf(f,"]\n");
676             if (!_w95_dump_dkv(dkh, dke->nrLS, dke->nrMS,f)) {
677               free(new_key_name);
678               return FALSE;
679             }
680         }
681         if ((dke->nextsub == 0xffffffff) && (dkh->values == 0)) {
682             /* no subkeys and no values */
683             fprintf(f,"\n[");
684             _dump_strAtoW(new_key_name,strlen(new_key_name),f,"[]");
685             fprintf(f,"]\n");
686         }
687     } else new_key_name = _strdupnA(key_name,strlen(key_name));
688
689     /* next sub key */
690     if (dke->nextsub != 0xffffffff) {
691         if (!_w95_dump_dke(new_key_name, creg, rgkn, (_w95dke*)((char*)rgkn+dke->nextsub),f,level-1)) {
692           free(new_key_name);
693           return FALSE;
694         }
695     }
696
697     free(new_key_name);
698     return TRUE;
699 }
700 /* end windows 95 loader */
701
702 /***********************************************************************************/
703 /*                        windows NT registry loader                               */
704 /***********************************************************************************/
705
706 /* NT REGISTRY LOADER */
707
708 #ifdef HAVE_SYS_MMAN_H
709 # include <sys/mman.h>
710 #endif
711
712 #ifndef MAP_FAILED
713 #define MAP_FAILED ((LPVOID)-1)
714 #endif
715
716 #define NT_REG_BLOCK_SIZE            0x1000
717
718 #define NT_REG_HEADER_BLOCK_ID       0x66676572 /* regf */
719 #define NT_REG_POOL_BLOCK_ID         0x6E696268 /* hbin */
720 #define NT_REG_KEY_BLOCK_ID          0x6b6e /* nk */
721 #define NT_REG_VALUE_BLOCK_ID        0x6b76 /* vk */
722
723 /* subblocks of nk */
724 #define NT_REG_HASH_BLOCK_ID         0x666c /* lf */
725 #define NT_REG_NOHASH_BLOCK_ID       0x696c /* li */
726 #define NT_REG_RI_BLOCK_ID           0x6972 /* ri */
727
728 #define NT_REG_KEY_BLOCK_TYPE        0x20
729 #define NT_REG_ROOT_KEY_BLOCK_TYPE   0x2c
730
731 typedef struct {
732     DWORD       id;             /* 0x66676572 'regf'*/
733     DWORD       uk1;            /* 0x04 */
734     DWORD       uk2;            /* 0x08 */
735     FILETIME    DateModified;   /* 0x0c */
736     DWORD       uk3;            /* 0x14 */
737     DWORD       uk4;            /* 0x18 */
738     DWORD       uk5;            /* 0x1c */
739     DWORD       uk6;            /* 0x20 */
740     DWORD       RootKeyBlock;   /* 0x24 */
741     DWORD       BlockSize;      /* 0x28 */
742     DWORD   uk7[116];   
743     DWORD       Checksum; /* at offset 0x1FC */
744 } nt_regf;
745
746 typedef struct {
747     DWORD       blocksize;
748     BYTE        data[1];
749 } nt_hbin_sub;
750
751 typedef struct {
752     DWORD       id;             /* 0x6E696268 'hbin' */
753     DWORD       off_prev;
754     DWORD       off_next;
755     DWORD       uk1;
756     DWORD       uk2;            /* 0x10 */
757     DWORD       uk3;            /* 0x14 */
758     DWORD       uk4;            /* 0x18 */
759     DWORD       size;           /* 0x1C */
760     nt_hbin_sub hbin_sub;       /* 0x20 */
761 } nt_hbin;
762
763 /*
764  * the value_list consists of offsets to the values (vk)
765  */
766 typedef struct {
767     WORD        SubBlockId;             /* 0x00 0x6B6E */
768     WORD        Type;                   /* 0x02 for the root-key: 0x2C, otherwise 0x20*/
769     FILETIME    writetime;      /* 0x04 */
770     DWORD       uk1;                    /* 0x0C */
771     DWORD       parent_off;             /* 0x10 Offset of Owner/Parent key */
772     DWORD       nr_subkeys;             /* 0x14 number of sub-Keys */
773     DWORD       uk8;                    /* 0x18 */
774     DWORD       lf_off;                 /* 0x1C Offset of the sub-key lf-Records */
775     DWORD       uk2;                    /* 0x20 */
776     DWORD       nr_values;              /* 0x24 number of values */
777     DWORD       valuelist_off;          /* 0x28 Offset of the Value-List */
778     DWORD       off_sk;                 /* 0x2c Offset of the sk-Record */
779     DWORD       off_class;              /* 0x30 Offset of the Class-Name */
780     DWORD       uk3;                    /* 0x34 */
781     DWORD       uk4;                    /* 0x38 */
782     DWORD       uk5;                    /* 0x3c */
783     DWORD       uk6;                    /* 0x40 */
784     DWORD       uk7;                    /* 0x44 */
785     WORD        name_len;               /* 0x48 name-length */
786     WORD        class_len;              /* 0x4a class-name length */
787     char        name[1];                /* 0x4c key-name */
788 } nt_nk;
789
790 typedef struct {
791     DWORD       off_nk; /* 0x00 */
792     DWORD       name;   /* 0x04 */
793 } hash_rec;
794
795 typedef struct {
796     WORD        id;             /* 0x00 0x666c */
797     WORD        nr_keys;        /* 0x06 */
798     hash_rec    hash_rec[1];
799 } nt_lf;
800
801 /*
802  list of subkeys without hash
803
804  li --+-->nk
805       |
806       +-->nk
807  */
808 typedef struct {
809     WORD        id;             /* 0x00 0x696c */
810     WORD        nr_keys;
811     DWORD       off_nk[1];
812 } nt_li;
813
814 /*
815  this is a intermediate node
816
817  ri --+-->li--+-->nk
818       |       +
819       |       +-->nk
820       |
821       +-->li--+-->nk
822               +
823               +-->nk
824  */
825 typedef struct {
826     WORD        id;             /* 0x00 0x6972 */
827     WORD        nr_li;          /* 0x02 number off offsets */
828     DWORD       off_li[1];      /* 0x04 points to li */
829 } nt_ri;
830
831 typedef struct {
832     WORD        id;             /* 0x00 'vk' */
833     WORD        nam_len;
834     DWORD       data_len;
835     DWORD       data_off;
836     DWORD       type;
837     WORD        flag;
838     WORD        uk1;
839     char        name[1];
840 } nt_vk;
841
842 /*
843  * gets a value
844  *
845  * vk->flag:
846  *  0 value is a default value
847  *  1 the value has a name
848  *
849  * vk->data_len
850  *  len of the whole data block
851  *  - reg_sz (unicode)
852  *    bytes including the terminating \0 = 2*(number_of_chars+1)
853  *  - reg_dword, reg_binary:
854  *    if highest bit of data_len is set data_off contains the value
855  */
856 static int _nt_dump_vk(LPSTR key_name, char *base, nt_vk *vk,FILE *f)
857 {
858     BYTE *pdata = (BYTE *)(base+vk->data_off+4); /* start of data */
859     struct key_value value;
860
861     if (vk->id != NT_REG_VALUE_BLOCK_ID) {
862         ERR("unknown block found (0x%04x), please report!\n", vk->id);
863         return FALSE;
864     }
865
866     value.nameW = _strdupnAtoW(vk->name,vk->nam_len);
867     value.type = vk->type;
868     value.len = (vk->data_len & 0x7fffffff);
869     value.data = (vk->data_len & 0x80000000) ? (LPBYTE)&(vk->data_off): pdata;
870
871     _dump_value(&value,f);
872     free(value.nameW);
873
874     return TRUE;
875 }
876
877 /* it's called from _nt_dump_lf() */
878 static int _nt_dump_nk(LPSTR key_name,char *base,nt_nk *nk,FILE *f,int level);
879
880 /*
881  * get the subkeys
882  *
883  * this structure contains the hash of a keyname and points to all
884  * subkeys
885  *
886  * exception: if the id is 'il' there are no hash values and every 
887  * dword is a offset
888  */
889 static int _nt_dump_lf(LPSTR key_name, char *base, int subkeys, nt_lf *lf, FILE *f, int level)
890 {
891     int i;
892     
893     if (lf->id == NT_REG_HASH_BLOCK_ID) {
894         if (subkeys != lf->nr_keys) goto error1;
895     
896         for (i=0; i<lf->nr_keys; i++) 
897             if (!_nt_dump_nk(key_name, base, (nt_nk*)(base+lf->hash_rec[i].off_nk+4), f, level)) goto error;
898     } else if (lf->id == NT_REG_NOHASH_BLOCK_ID) {
899         nt_li * li = (nt_li*)lf;
900         if (subkeys != li->nr_keys) goto error1;
901
902         for (i=0; i<li->nr_keys; i++)
903             if (!_nt_dump_nk(key_name, base, (nt_nk*)(base+li->off_nk[i]+4), f, level)) goto error;
904     } else if (lf->id == NT_REG_RI_BLOCK_ID) {  /* ri */
905         nt_ri * ri = (nt_ri*)lf;
906         int li_subkeys = 0;
907
908         /* count all subkeys */
909         for (i=0; i<ri->nr_li; i++) {
910             nt_li * li = (nt_li*)(base+ri->off_li[i]+4);
911             if(li->id != NT_REG_NOHASH_BLOCK_ID) goto error2;
912             li_subkeys += li->nr_keys;
913         }
914
915         /* check number */
916         if (subkeys != li_subkeys) goto error1;
917
918         /* loop through the keys */
919         for (i=0; i<ri->nr_li; i++) {
920             nt_li *li = (nt_li*)(base+ri->off_li[i]+4);
921             if (!_nt_dump_lf(key_name, base, li->nr_keys, (nt_lf*)li, f, level)) goto error;
922         }
923     } else goto error2;
924
925     return TRUE;
926
927 error2:
928     if (lf->id == 0x686c)
929         FIXME("unknown Win XP node id 0x686c: do we need to add support for it ?\n");
930     else
931         ERR("unknown node id 0x%04x, please report!\n", lf->id);
932     return TRUE;
933
934 error1:
935     ERR("registry file corrupt! (inconsistent number of subkeys)\n");
936     return FALSE;
937
938 error:
939     ERR("error reading lf block\n");
940     return FALSE;
941 }
942
943 /* _nt_dump_nk [Internal] */
944 static int _nt_dump_nk(LPSTR key_name,char *base,nt_nk *nk,FILE *f,int level)
945 {
946     unsigned int n;
947     DWORD *vl;
948     LPSTR new_key_name = NULL;
949
950     TRACE("%s\n", key_name);
951
952     if (nk->SubBlockId != NT_REG_KEY_BLOCK_ID) {
953         ERR("unknown node id 0x%04x, please report!\n", nk->SubBlockId);
954         return FALSE;
955     }
956
957     if ((nk->Type!=NT_REG_ROOT_KEY_BLOCK_TYPE) && (((nt_nk*)(base+nk->parent_off+4))->SubBlockId != NT_REG_KEY_BLOCK_ID)) {
958         ERR("registry file corrupt!\n");
959         return FALSE;
960     }
961
962     /* create the new key */
963     if (level <= 0) {
964         /* create new subkey name */
965         new_key_name = _strdupnA(key_name,strlen(key_name)+nk->name_len+1);
966         if (strcmp(new_key_name,"") != 0) strcat(new_key_name,"\\");
967         strncat(new_key_name,nk->name,nk->name_len);
968
969         /* write the key path (something like [Software\\Microsoft\\..]) only if: 
970            1) key has some values
971            2) key has no values and no subkeys
972         */
973         if (nk->nr_values > 0) {
974             /* there are some values */
975             fprintf(f,"\n[");
976             _dump_strAtoW(new_key_name,strlen(new_key_name),f,"[]");
977             fprintf(f,"]\n");
978         }
979         if ((nk->nr_subkeys == 0) && (nk->nr_values == 0)) {
980             /* no subkeys and no values */
981             fprintf(f,"\n[");
982             _dump_strAtoW(new_key_name,strlen(new_key_name),f,"[]");
983             fprintf(f,"]\n");
984         }
985
986         /* loop trough the value list */
987         vl = (DWORD *)(base+nk->valuelist_off+4);
988         for (n=0; n<nk->nr_values; n++) {
989             nt_vk * vk = (nt_vk*)(base+vl[n]+4);
990             if (!_nt_dump_vk(new_key_name, base, vk, f)) {
991                 free(new_key_name);
992                 return FALSE;
993             }
994         }
995     } else new_key_name = _strdupnA(key_name,strlen(key_name));
996
997     /* loop through the subkeys */
998     if (nk->nr_subkeys) {
999         nt_lf *lf = (nt_lf*)(base+nk->lf_off+4);
1000         if (!_nt_dump_lf(new_key_name, base, nk->nr_subkeys, lf, f, level-1)) {
1001             free(new_key_name);
1002             return FALSE;
1003         }
1004     }
1005
1006     free(new_key_name);
1007     return TRUE;
1008 }
1009
1010 /* end nt loader */
1011
1012 /**********************************************************************************
1013  * _set_registry_levels [Internal]
1014  *
1015  * set level to 0 for loading system files
1016  * set level to 1 for loading user files
1017  */
1018 static void _set_registry_levels(int level,int saving,int period)
1019 {
1020     SERVER_START_REQ( set_registry_levels )
1021     {
1022         req->current = level;
1023         req->saving  = saving;
1024         req->period  = period;
1025         wine_server_call( req );
1026     }
1027     SERVER_END_REQ;
1028 }
1029
1030 /* _save_at_exit [Internal] */
1031 static void _save_at_exit(HKEY hkey,LPCSTR path)
1032 {
1033     LPCSTR confdir = get_config_dir();
1034
1035     SERVER_START_REQ( save_registry_atexit )
1036     {
1037         req->hkey = hkey;
1038         wine_server_add_data( req, confdir, strlen(confdir) );
1039         wine_server_add_data( req, path, strlen(path)+1 );
1040         wine_server_call( req );
1041     }
1042     SERVER_END_REQ;
1043 }
1044
1045 /* configure save files and start the periodic saving timer [Internal] */
1046 static void _init_registry_saving( HKEY hkey_users_default )
1047 {
1048     int all;
1049     int period = 0;
1050     char buffer[20];
1051
1052     all = !PROFILE_GetWineIniBool("registry","SaveOnlyUpdatedKeys",1);
1053     PROFILE_GetWineIniString( "registry", "PeriodicSave", "", buffer, sizeof(buffer) );
1054     if (buffer[0]) period = atoi(buffer);
1055
1056     /* set saving level (0 for saving everything, 1 for saving only modified keys) */
1057     _set_registry_levels(1,!all,period*1000);
1058
1059     if (PROFILE_GetWineIniBool("registry","WritetoHomeRegistryFiles",1))
1060     {
1061         _save_at_exit(HKEY_CURRENT_USER,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER );
1062         _save_at_exit(HKEY_LOCAL_MACHINE,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE);
1063         _save_at_exit(hkey_users_default,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT);
1064     }
1065
1066 }
1067
1068 /******************************************************************************
1069  * _allocate_default_keys [Internal]
1070  * Registry initialisation, allocates some default keys. 
1071  */
1072 static void _allocate_default_keys(void) {
1073         HKEY    hkey;
1074         char    buf[200];
1075
1076         TRACE("(void)\n");
1077
1078         RegCreateKeyA(HKEY_DYN_DATA,"PerfStats\\StatData",&hkey);
1079         RegCloseKey(hkey);
1080
1081         /* This was an Open, but since it is called before the real registries
1082            are loaded, it was changed to a Create - MTB 980507*/
1083         RegCreateKeyA(HKEY_LOCAL_MACHINE,"HARDWARE\\DESCRIPTION\\System",&hkey);
1084         RegSetValueExA(hkey,"Identifier",0,REG_SZ,"SystemType WINE",strlen("SystemType WINE"));
1085         RegCloseKey(hkey);
1086
1087         /* \\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion
1088          *                                              CurrentVersion
1089          *                                              CurrentBuildNumber
1090          *                                              CurrentType
1091          *                                      string  RegisteredOwner
1092          *                                      string  RegisteredOrganization
1093          *
1094          */
1095         /* System\\CurrentControlSet\\Services\\SNMP\\Parameters\\RFC1156Agent
1096          *                                      string  SysContact
1097          *                                      string  SysLocation
1098          *                                              SysServices
1099          */
1100         if (-1!=gethostname(buf,200)) {
1101                 RegCreateKeyA(HKEY_LOCAL_MACHINE,"System\\CurrentControlSet\\Control\\ComputerName\\ComputerName",&hkey);
1102                 RegSetValueExA(hkey,"ComputerName",0,REG_SZ,buf,strlen(buf)+1);
1103                 RegCloseKey(hkey);
1104         }
1105
1106         RegCreateKeyA(HKEY_USERS,".Default",&hkey);
1107         RegCloseKey(hkey);
1108 }
1109
1110 #define REG_DONTLOAD -1
1111 #define REG_WIN31     0
1112 #define REG_WIN95     1
1113 #define REG_WINNT     2
1114
1115 /* return the type of native registry [Internal] */
1116 static int _get_reg_type(void)
1117 {
1118     char windir[MAX_PATHNAME_LEN];
1119     char tmp[MAX_PATHNAME_LEN];
1120     int ret = REG_WIN31;
1121
1122     GetWindowsDirectoryA(windir,MAX_PATHNAME_LEN);
1123
1124     /* test %windir%/system32/config/system --> winnt */
1125     strcpy(tmp, windir);
1126     strncat(tmp, "\\system32\\config\\system", MAX_PATHNAME_LEN - strlen(tmp) - 1);
1127     if(GetFileAttributesA(tmp) != (DWORD)-1) {
1128       ret = REG_WINNT;
1129     }
1130     else
1131     {
1132        /* test %windir%/system.dat --> win95 */
1133       strcpy(tmp, windir);
1134       strncat(tmp, "\\system.dat", MAX_PATHNAME_LEN - strlen(tmp) - 1);
1135       if(GetFileAttributesA(tmp) != (DWORD)-1) {
1136         ret = REG_WIN95;
1137       }
1138     }
1139
1140     if ((ret == REG_WINNT) && (!PROFILE_GetWineIniString( "Wine", "Profile", "", tmp, MAX_PATHNAME_LEN))) {
1141        MESSAGE("When you are running with a native NT directory specify\n");
1142        MESSAGE("'Profile=<profiledirectory>' or disable loading of Windows\n");
1143        MESSAGE("registry (LoadWindowsRegistryFiles=N)\n");
1144        ret = REG_DONTLOAD;
1145     }
1146
1147     return ret;
1148 }
1149
1150 #define WINE_REG_VER_ERROR  -1
1151 #define WINE_REG_VER_1       0
1152 #define WINE_REG_VER_2       1
1153 #define WINE_REG_VER_OLD     2
1154 #define WINE_REG_VER_UNKNOWN 3
1155
1156 /* return the version of wine registry file [Internal] */
1157 static int _get_wine_registry_file_format_version(LPCSTR fn)
1158 {
1159     FILE *f;
1160     char tmp[50];
1161     int ver;
1162
1163     if ((f=fopen(fn,"rt")) == NULL) {
1164         WARN("Couldn't open %s for reading: %s\n",fn,strerror(errno));
1165         return WINE_REG_VER_ERROR;
1166     }
1167
1168     if (fgets(tmp,50,f) == NULL) {
1169         WARN("Error reading %s: %s\n",fn,strerror(errno));
1170         fclose(f);
1171         return WINE_REG_VER_ERROR;
1172     }
1173     fclose(f);
1174
1175     if (sscanf(tmp,"WINE REGISTRY Version %d",&ver) != 1) return WINE_REG_VER_UNKNOWN;
1176     switch (ver) {
1177         case 1:
1178             return WINE_REG_VER_1;
1179             break;
1180         case 2:
1181             return WINE_REG_VER_2;
1182             break;
1183         default:
1184             return WINE_REG_VER_UNKNOWN;
1185     }
1186 }
1187
1188 /* load the registry file in wine format [Internal] */
1189 static void load_wine_registry(HKEY hkey,LPCSTR fn)
1190 {
1191     int file_format;
1192
1193     file_format = _get_wine_registry_file_format_version(fn);
1194     switch (file_format) {
1195
1196         case WINE_REG_VER_1:
1197             WARN("Unable to load registry file %s: old format which is no longer supported.\n",fn);
1198             break;
1199
1200         case WINE_REG_VER_2: {
1201             HANDLE file;
1202             if ((file = FILE_CreateFile( fn, GENERIC_READ, 0, NULL, OPEN_EXISTING,
1203                                               FILE_ATTRIBUTE_NORMAL, 0, TRUE, DRIVE_UNKNOWN )))
1204             {
1205                 SERVER_START_REQ( load_registry )
1206                 {
1207                     req->hkey    = hkey;
1208                     req->file    = file;
1209                     wine_server_call( req );
1210                 }
1211                 SERVER_END_REQ;
1212                 CloseHandle( file );
1213             }
1214             break;
1215         }
1216
1217         case WINE_REG_VER_UNKNOWN:
1218             WARN("Unable to load registry file %s: unknown format.\n",fn);
1219             break;
1220
1221         case WINE_REG_VER_ERROR:
1222             break;
1223     }
1224 }
1225
1226 /* generate and return the name of the tmp file and associated stream [Internal] */
1227 static LPSTR _get_tmp_fn(FILE **f)
1228 {
1229     LPSTR ret;
1230     int tmp_fd,count;
1231
1232     ret = _xmalloc(50);
1233     for (count = 0;;) {
1234         sprintf(ret,"/tmp/reg%lx%04x.tmp",(long)getpid(),count++);
1235         if ((tmp_fd = open(ret,O_CREAT | O_EXCL | O_WRONLY,0666)) != -1) break;
1236         if (errno != EEXIST) {
1237             ERR("Unexpected error while open() call: %s\n",strerror(errno));
1238             free(ret);
1239             *f = NULL;
1240             return NULL;
1241         }
1242     }
1243
1244     if ((*f = fdopen(tmp_fd,"w")) == NULL) {
1245         ERR("Unexpected error while fdopen() call: %s\n",strerror(errno));
1246         close(tmp_fd);
1247         free(ret);
1248         return NULL;
1249     }
1250
1251     return ret;
1252 }
1253
1254 /* convert win95 native registry file to wine format [Internal] */
1255 static LPSTR _convert_win95_registry_to_wine_format(LPCSTR fn,int level)
1256 {
1257     int fd;
1258     FILE *f;
1259     DOS_FULL_NAME full_name;
1260     void *base;
1261     LPSTR ret = NULL;
1262     struct stat st;
1263
1264     _w95creg *creg;
1265     _w95rgkn *rgkn;
1266     _w95dke *dke, *root_dke;
1267
1268     if (!DOSFS_GetFullName( fn, 0, &full_name )) return NULL;
1269
1270     /* map the registry into the memory */
1271     if ((fd = open(full_name.long_name, O_RDONLY | O_NONBLOCK)) == -1) return NULL;
1272     if ((fstat(fd, &st) == -1)) goto error1;
1273     if (!st.st_size) goto error1;
1274     if ((base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) goto error1;
1275
1276     /* control signature */
1277     if (*(LPDWORD)base != W95_REG_CREG_ID) {
1278         ERR("unable to load native win95 registry file %s: unknown signature.\n",fn);
1279         goto error;
1280     }
1281
1282     creg = base;
1283     /* load the header (rgkn) */
1284     rgkn = (_w95rgkn*)(creg + 1);
1285     if (rgkn->id != W95_REG_RGKN_ID) {
1286         ERR("second IFF header not RGKN, but %lx\n", rgkn->id);
1287         goto error;
1288     }
1289     if (rgkn->root_off != 0x20) {
1290         ERR("rgkn->root_off not 0x20, please report !\n");
1291         goto error;
1292     }
1293     if (rgkn->last_dke > rgkn->size)
1294     {
1295       ERR("registry file corrupt! last_dke > size!\n");
1296       goto error;
1297     }
1298     /* verify last dke */
1299     dke = (_w95dke*)((char*)rgkn + rgkn->last_dke);
1300     if (dke->x1 != 0x80000000)
1301     { /* wrong magic */
1302       ERR("last dke invalid !\n");
1303       goto error;
1304     }
1305     if (rgkn->size > creg->rgdb_off)
1306     {
1307       ERR("registry file corrupt! rgkn size > rgdb_off !\n");
1308       goto error;
1309     }
1310     root_dke = (_w95dke*)((char*)rgkn + rgkn->root_off);
1311     if ( (root_dke->prevlvl != 0xffffffff) || (root_dke->next != 0xffffffff) )
1312     {
1313         ERR("registry file corrupt! invalid root dke !\n");
1314         goto error;
1315     }
1316
1317     if ( (ret = _get_tmp_fn(&f)) == NULL) goto error;
1318     fprintf(f,"WINE REGISTRY Version 2");
1319     _w95_dump_dke("",creg,rgkn,root_dke,f,level);
1320     fclose(f);
1321
1322 error:
1323     if(ret == NULL) {
1324         ERR("Unable to load native win95 registry file %s.\n",fn);
1325         ERR("Please report this.\n");
1326         ERR("Make a backup of the file, run a good reg cleaner program and try again!\n");
1327     }
1328
1329     munmap(base, st.st_size);
1330 error1:
1331     close(fd);
1332     return ret;
1333 }
1334
1335 /* convert winnt native registry file to wine format [Internal] */
1336 static LPSTR _convert_winnt_registry_to_wine_format(LPCSTR fn,int level)
1337 {
1338     FILE *f;
1339     void *base;
1340     LPSTR ret = NULL;
1341     HANDLE hFile;
1342     HANDLE hMapping;
1343
1344     nt_regf *regf;
1345     nt_hbin *hbin;
1346     nt_hbin_sub *hbin_sub;
1347     nt_nk *nk;
1348
1349     TRACE("%s\n", fn);
1350
1351     hFile = CreateFileA( fn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
1352     if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
1353     hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY|SEC_COMMIT, 0, 0, NULL );
1354     if (!hMapping) goto error1;
1355     base = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
1356     CloseHandle( hMapping );
1357     if (!base) goto error1;
1358
1359     /* control signature */
1360     if (*(LPDWORD)base != NT_REG_HEADER_BLOCK_ID) {
1361         ERR("unable to load native winnt registry file %s: unknown signature.\n",fn);
1362         goto error;
1363     }
1364
1365     /* start block */
1366     regf = base;
1367
1368     /* hbin block */
1369     hbin = (nt_hbin*)((char*) base + 0x1000);
1370     if (hbin->id != NT_REG_POOL_BLOCK_ID) {
1371       ERR( "hbin block invalid\n");
1372       goto error;
1373     }
1374
1375     /* hbin_sub block */
1376     hbin_sub = (nt_hbin_sub*)&(hbin->hbin_sub);
1377     if ((hbin_sub->data[0] != 'n') || (hbin_sub->data[1] != 'k')) {
1378       ERR( "hbin_sub block invalid\n");
1379       goto error;
1380     }
1381
1382     /* nk block */
1383     nk = (nt_nk*)&(hbin_sub->data[0]);
1384     if (nk->Type != NT_REG_ROOT_KEY_BLOCK_TYPE) {
1385       ERR( "special nk block not found\n");
1386       goto error;
1387     }
1388
1389     if ( (ret = _get_tmp_fn(&f)) == NULL) goto error;
1390     fprintf(f,"WINE REGISTRY Version 2");
1391     _nt_dump_nk("",(char*)base+0x1000,nk,f,level);
1392     fclose(f);
1393
1394 error:
1395     UnmapViewOfFile( base );
1396 error1:
1397     CloseHandle(hFile);
1398     return ret;
1399 }
1400
1401 /* convert native registry to wine format and load it via server call [Internal] */
1402 static void _convert_and_load_native_registry(LPCSTR fn,HKEY hkey,int reg_type,int level)
1403 {
1404     LPSTR tmp = NULL;
1405
1406     switch (reg_type) {
1407         case REG_WINNT:
1408             /* FIXME: following function doesn't really convert yet */
1409             tmp = _convert_winnt_registry_to_wine_format(fn,level);
1410             break;
1411         case REG_WIN95:
1412             tmp = _convert_win95_registry_to_wine_format(fn,level);
1413             break;
1414         case REG_WIN31:
1415             ERR("Don't know how to convert native 3.1 registry yet.\n");
1416             break;
1417         default:
1418             ERR("Unknown registry format parameter (%d)\n",reg_type);
1419             break;
1420     }
1421
1422     if (tmp != NULL) {
1423         load_wine_registry(hkey,tmp);
1424         TRACE("File %s successfully converted to %s and loaded to registry.\n",fn,tmp);
1425         unlink(tmp);
1426     }
1427     else WARN("Unable to convert %s (doesn't exist?)\n",fn);
1428     free(tmp);
1429 }
1430
1431 /* load all native windows registry files [Internal] */
1432 static void _load_windows_registry( HKEY hkey_users_default )
1433 {
1434     int reg_type;
1435     char windir[MAX_PATHNAME_LEN];
1436     char path[MAX_PATHNAME_LEN];
1437
1438     GetWindowsDirectoryA(windir,MAX_PATHNAME_LEN);
1439
1440     reg_type = _get_reg_type();
1441     switch (reg_type) {
1442         case REG_WINNT: {
1443             HKEY hkey;
1444
1445             /* user specific ntuser.dat */
1446             if (PROFILE_GetWineIniString( "Wine", "Profile", "", path, MAX_PATHNAME_LEN)) {
1447                 strcat(path,"\\ntuser.dat");
1448                 _convert_and_load_native_registry(path,HKEY_CURRENT_USER,REG_WINNT,1);
1449             }
1450
1451             /* default user.dat */
1452             if (hkey_users_default) {
1453                 strcpy(path,windir);
1454                 strcat(path,"\\system32\\config\\default");
1455                 _convert_and_load_native_registry(path,hkey_users_default,REG_WINNT,1);
1456             }
1457
1458             /*
1459             * FIXME
1460             *  map HLM\System\ControlSet001 to HLM\System\CurrentControlSet
1461             */
1462
1463             if (!RegCreateKeyA(HKEY_LOCAL_MACHINE, "SYSTEM", &hkey)) {
1464               strcpy(path,windir);
1465               strcat(path,"\\system32\\config\\system");
1466               _convert_and_load_native_registry(path,hkey,REG_WINNT,1);
1467               RegCloseKey(hkey);
1468             }
1469
1470             if (!RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE", &hkey)) {
1471                 strcpy(path,windir);
1472                 strcat(path,"\\system32\\config\\software");
1473                 _convert_and_load_native_registry(path,hkey,REG_WINNT,1);
1474                 RegCloseKey(hkey);
1475             }
1476
1477             strcpy(path,windir);
1478             strcat(path,"\\system32\\config\\sam");
1479             _convert_and_load_native_registry(path,HKEY_LOCAL_MACHINE,REG_WINNT,0);
1480
1481             strcpy(path,windir);
1482             strcat(path,"\\system32\\config\\security");
1483             _convert_and_load_native_registry(path,HKEY_LOCAL_MACHINE,REG_WINNT,0);
1484
1485             /* this key is generated when the nt-core booted successfully */
1486             if (!RegCreateKeyA(HKEY_LOCAL_MACHINE,"System\\Clone",&hkey)) RegCloseKey(hkey);
1487             break;
1488         }
1489
1490         case REG_WIN95:
1491             _convert_and_load_native_registry("c:\\system.1st",HKEY_LOCAL_MACHINE,REG_WIN95,0);
1492
1493             strcpy(path,windir);
1494             strcat(path,"\\system.dat");
1495             _convert_and_load_native_registry(path,HKEY_LOCAL_MACHINE,REG_WIN95,0);
1496
1497             strcpy(path,windir);
1498             strcat(path,"\\classes.dat");
1499             _convert_and_load_native_registry(path,HKEY_CLASSES_ROOT,REG_WIN95,0);
1500
1501             if (PROFILE_GetWineIniString("Wine","Profile","",path,MAX_PATHNAME_LEN)) {
1502                 /* user specific user.dat */
1503                 strncat(path, "\\user.dat", MAX_PATHNAME_LEN - strlen(path) - 1);
1504                 _convert_and_load_native_registry(path,HKEY_CURRENT_USER,REG_WIN95,1);
1505
1506                 /* default user.dat */
1507                 if (hkey_users_default) {
1508                     strcpy(path,windir);
1509                     strcat(path,"\\user.dat");
1510                     _convert_and_load_native_registry(path,hkey_users_default,REG_WIN95,1);
1511                 }
1512             } else {
1513                 strcpy(path,windir);
1514                 strcat(path,"\\user.dat");
1515                 _convert_and_load_native_registry(path,HKEY_CURRENT_USER,REG_WIN95,1);
1516             }
1517             break;
1518
1519         case REG_WIN31:
1520             /* FIXME: here we should convert to *.reg file supported by server and call REQ_LOAD_REGISTRY, see REG_WIN95 case */
1521             _w31_loadreg();
1522             break;
1523
1524         case REG_DONTLOAD:
1525             TRACE("REG_DONTLOAD\n");
1526             break;
1527
1528         default:
1529             ERR("switch: no match (%d)\n",reg_type);
1530             break;
1531
1532     }
1533 }
1534
1535 /* load global registry files (stored in /etc/wine) [Internal] */
1536 static void _load_global_registry(void)
1537 {
1538     TRACE("(void)\n");
1539
1540     /* Load the global HKU hive directly from sysconfdir */
1541     load_wine_registry( HKEY_USERS, SAVE_GLOBAL_REGBRANCH_USER_DEFAULT );
1542
1543     /* Load the global machine defaults directly from sysconfdir */
1544     load_wine_registry( HKEY_LOCAL_MACHINE, SAVE_GLOBAL_REGBRANCH_LOCAL_MACHINE );
1545 }
1546
1547 /* load home registry files (stored in ~/.wine) [Internal] */
1548 static void _load_home_registry( HKEY hkey_users_default )
1549 {
1550     LPCSTR confdir = get_config_dir();
1551     LPSTR tmp = _xmalloc(strlen(confdir)+20);
1552
1553     strcpy(tmp,confdir);
1554     strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT);
1555     load_wine_registry(hkey_users_default,tmp);
1556
1557     strcpy(tmp,confdir);
1558     strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER);
1559     load_wine_registry(HKEY_CURRENT_USER,tmp);
1560
1561     strcpy(tmp,confdir);
1562     strcat(tmp,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE);
1563     load_wine_registry(HKEY_LOCAL_MACHINE,tmp);
1564
1565     free(tmp);
1566 }
1567
1568 /* load all registry (native and global and home) */
1569 void SHELL_LoadRegistry( void )
1570 {
1571     HKEY hkey_users_default;
1572
1573     TRACE("(void)\n");
1574
1575     if (!CLIENT_IsBootThread()) return;  /* already loaded */
1576
1577     if (RegCreateKeyA(HKEY_USERS,".Default",&hkey_users_default))
1578     {
1579         ERR("Cannot create HKEY_USERS/.Default\n" );
1580         ExitProcess(1);
1581     }
1582
1583     _allocate_default_keys();
1584     _set_registry_levels(0,0,0);
1585     if (PROFILE_GetWineIniBool("Registry","LoadWindowsRegistryFiles",1))
1586         _load_windows_registry( hkey_users_default );
1587     if (PROFILE_GetWineIniBool("Registry","LoadGlobalRegistryFiles",1))
1588         _load_global_registry();
1589     _set_registry_levels(1,0,0);
1590     if (PROFILE_GetWineIniBool("Registry","LoadHomeRegistryFiles",1))
1591         _load_home_registry( hkey_users_default );
1592     _init_registry_saving( hkey_users_default );
1593     RegCloseKey(hkey_users_default);
1594 }
1595
1596 /***************************************************************************/
1597 /*                          API FUNCTIONS                                  */
1598 /***************************************************************************/
1599
1600 /******************************************************************************
1601  * RegFlushKey [ADVAPI32.@]
1602  * Immediately writes key to registry.
1603  * Only returns after data has been written to disk.
1604  *
1605  * FIXME: does it really wait until data is written ?
1606  *
1607  * PARAMS
1608  *    hkey [I] Handle of key to write
1609  *
1610  * RETURNS
1611  *    Success: ERROR_SUCCESS
1612  *    Failure: Error code
1613  */
1614 DWORD WINAPI RegFlushKey( HKEY hkey )
1615 {
1616     FIXME( "(%x): stub\n", hkey );
1617     return ERROR_SUCCESS;
1618 }
1619
1620
1621 /******************************************************************************
1622  * RegUnLoadKeyA [ADVAPI32.@]
1623  */
1624 LONG WINAPI RegUnLoadKeyA( HKEY hkey, LPCSTR lpSubKey )
1625 {
1626     FIXME("(%x,%s): stub\n",hkey, debugstr_a(lpSubKey));
1627     return ERROR_SUCCESS;
1628 }
1629
1630
1631 /******************************************************************************
1632  * RegReplaceKeyA [ADVAPI32.@]
1633  */
1634 LONG WINAPI RegReplaceKeyA( HKEY hkey, LPCSTR lpSubKey, LPCSTR lpNewFile,
1635                               LPCSTR lpOldFile )
1636 {
1637     FIXME("(%x,%s,%s,%s): stub\n", hkey, debugstr_a(lpSubKey),
1638           debugstr_a(lpNewFile),debugstr_a(lpOldFile));
1639     return ERROR_SUCCESS;
1640 }
1641
1642
1643
1644
1645
1646
1647 /* 16-bit functions */
1648
1649 /* 0 and 1 are valid rootkeys in win16 shell.dll and are used by
1650  * some programs. Do not remove those cases. -MM
1651  */
1652 static inline void fix_win16_hkey( HKEY *hkey )
1653 {
1654     if (*hkey == 0 || *hkey == 1) *hkey = HKEY_CLASSES_ROOT;
1655 }
1656
1657 /******************************************************************************
1658  *           RegEnumKey   [KERNEL.216]
1659  *           RegEnumKey   [SHELL.7]
1660  */
1661 DWORD WINAPI RegEnumKey16( HKEY hkey, DWORD index, LPSTR name, DWORD name_len )
1662 {
1663     fix_win16_hkey( &hkey );
1664     return RegEnumKeyA( hkey, index, name, name_len );
1665 }
1666
1667 /******************************************************************************
1668  *           RegOpenKey   [KERNEL.217]
1669  *           RegOpenKey   [SHELL.1]
1670  */
1671 DWORD WINAPI RegOpenKey16( HKEY hkey, LPCSTR name, LPHKEY retkey )
1672 {
1673     fix_win16_hkey( &hkey );
1674     return RegOpenKeyA( hkey, name, retkey );
1675 }
1676
1677 /******************************************************************************
1678  *           RegCreateKey   [KERNEL.218]
1679  *           RegCreateKey   [SHELL.2]
1680  */
1681 DWORD WINAPI RegCreateKey16( HKEY hkey, LPCSTR name, LPHKEY retkey )
1682 {
1683     fix_win16_hkey( &hkey );
1684     return RegCreateKeyA( hkey, name, retkey );
1685 }
1686
1687 /******************************************************************************
1688  *           RegDeleteKey   [KERNEL.219]
1689  *           RegDeleteKey   [SHELL.4]
1690  */
1691 DWORD WINAPI RegDeleteKey16( HKEY hkey, LPCSTR name )
1692 {
1693     fix_win16_hkey( &hkey );
1694     return RegDeleteKeyA( hkey, name );
1695 }
1696
1697 /******************************************************************************
1698  *           RegCloseKey   [KERNEL.220]
1699  *           RegCloseKey   [SHELL.3]
1700  */
1701 DWORD WINAPI RegCloseKey16( HKEY hkey )
1702 {
1703     fix_win16_hkey( &hkey );
1704     return RegCloseKey( hkey );
1705 }
1706
1707 /******************************************************************************
1708  *           RegSetValue   [KERNEL.221]
1709  *           RegSetValue   [SHELL.5]
1710  */
1711 DWORD WINAPI RegSetValue16( HKEY hkey, LPCSTR name, DWORD type, LPCSTR data, DWORD count )
1712 {
1713     fix_win16_hkey( &hkey );
1714     return RegSetValueA( hkey, name, type, data, count );
1715 }
1716
1717 /******************************************************************************
1718  *           RegDeleteValue  [KERNEL.222]
1719  */
1720 DWORD WINAPI RegDeleteValue16( HKEY hkey, LPSTR name )
1721 {
1722     fix_win16_hkey( &hkey );
1723     return RegDeleteValueA( hkey, name );
1724 }
1725
1726 /******************************************************************************
1727  *           RegEnumValue   [KERNEL.223]
1728  */
1729 DWORD WINAPI RegEnumValue16( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
1730                              LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count )
1731 {
1732     fix_win16_hkey( &hkey );
1733     return RegEnumValueA( hkey, index, value, val_count, reserved, type, data, count );
1734 }
1735
1736 /******************************************************************************
1737  *           RegQueryValue   [KERNEL.224]
1738  *           RegQueryValue   [SHELL.6]
1739  *
1740  * NOTES
1741  *    Is this HACK still applicable?
1742  *
1743  * HACK
1744  *    The 16bit RegQueryValue doesn't handle selectorblocks anyway, so we just
1745  *    mask out the high 16 bit.  This (not so much incidently) hopefully fixes
1746  *    Aldus FH4)
1747  */
1748 DWORD WINAPI RegQueryValue16( HKEY hkey, LPCSTR name, LPSTR data, LPDWORD count )
1749 {
1750     fix_win16_hkey( &hkey );
1751     if (count) *count &= 0xffff;
1752     return RegQueryValueA( hkey, name, data, count );
1753 }
1754
1755 /******************************************************************************
1756  *           RegQueryValueEx   [KERNEL.225]
1757  */
1758 DWORD WINAPI RegQueryValueEx16( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWORD type,
1759                                 LPBYTE data, LPDWORD count )
1760 {
1761     fix_win16_hkey( &hkey );
1762     return RegQueryValueExA( hkey, name, reserved, type, data, count );
1763 }
1764
1765 /******************************************************************************
1766  *           RegSetValueEx   [KERNEL.226]
1767  */
1768 DWORD WINAPI RegSetValueEx16( HKEY hkey, LPCSTR name, DWORD reserved, DWORD type,
1769                               CONST BYTE *data, DWORD count )
1770 {
1771     fix_win16_hkey( &hkey );
1772     if (!count && (type==REG_SZ)) count = strlen(data);
1773     return RegSetValueExA( hkey, name, reserved, type, data, count );
1774 }
1775
1776 /******************************************************************************
1777  *           RegFlushKey   [KERNEL.227]
1778  */
1779 DWORD WINAPI RegFlushKey16( HKEY hkey )
1780 {
1781     fix_win16_hkey( &hkey );
1782     return RegFlushKey( hkey );
1783 }