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