/*
 * 	Registry Functions
 *
 * Copyright 1996 Marcus Meissner
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <pwd.h>
#include <time.h>
#include "windows.h"
#include "win.h"
#include "winerror.h"
#include "string32.h"	
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"
#include "winreg.h"

#define MAKE_DWORD(x,y) ((DWORD)MAKELONG(x,y))

/* FIXME: following defines should be configured global ... */

/* NOTE: do not append a /. linux' mkdir() WILL FAIL if you do that */
#define WINE_PREFIX			"/.wine"
#define SAVE_USERS_DEFAULT		"/usr/local/etc/wine.userreg"
#define SAVE_LOCAL_MACHINE_DEFAULT	"/usr/local/etc/wine.systemreg"

/* relative in ~user/.wine/ : */
#define SAVE_CURRENT_USER		"user.reg"
#define SAVE_LOCAL_MACHINE		"system.reg"

#define KEY_REGISTRY	"Software\\The WINE team\\WINE\\Registry"
#define VAL_SAVEUPDATED	"SaveOnlyUpdatedKeys"

static KEYSTRUCT	*key_classes_root=NULL;	/* windows 3.1 global values */
static KEYSTRUCT	*key_current_user=NULL;	/* user specific values */
static KEYSTRUCT	*key_local_machine=NULL;/* machine specific values */
static KEYSTRUCT	*key_users=NULL;	/* all users? */

/* dynamic, not saved */
static KEYSTRUCT	*key_performance_data=NULL;
static KEYSTRUCT	*key_current_config=NULL;
static KEYSTRUCT	*key_dyn_data=NULL;

/* what valuetypes do we need to convert? */
#define UNICONVMASK	((1<<REG_SZ)|(1<<REG_MULTI_SZ)|(1<<REG_EXPAND_SZ))

#define strdupA2W(x)	STRING32_DupAnsiToUni(x)
#define strdupW2A(x)	STRING32_DupUniToAnsi(x)
#define strdupW(x)	STRING32_strdupW(x)
#define strcmpW(a,b)	STRING32_lstrcmpW(a,b)
#define strcmpniW(a,b)	STRING32_lstrcmpniW(a,b)
#define strchrW(a,c)	STRING32_lstrchrW(a,c)
#define strlenW(a)	STRING32_UniLen(a)
#define strcpyWA(a,b)	STRING32_UniToAnsi(a,b)

static struct openhandle {
	LPKEYSTRUCT	lpkey;
	HKEY		hkey;
	REGSAM		accessmask;
}  *openhandles=NULL;
static int	nrofopenhandles=0;
static int	currenthandle=1;

static void
add_handle(HKEY hkey,LPKEYSTRUCT lpkey,REGSAM accessmask) {
	int	i;

	for (i=0;i<nrofopenhandles;i++) {
		if (openhandles[i].lpkey==lpkey) {
			dprintf_reg(stddeb,"add_handle:Tried to add %p twice!\n",lpkey);
		}
		if (openhandles[i].hkey==hkey) {
			dprintf_reg(stddeb,"add_handle:Tried to add %lx twice!\n",(LONG)hkey);
		}
	}
	openhandles=xrealloc(	openhandles,
				sizeof(struct openhandle)*(nrofopenhandles+1)
		);
	openhandles[i].lpkey	= lpkey;
	openhandles[i].hkey	= hkey;
	openhandles[i].accessmask= accessmask;
	nrofopenhandles++;
}

static LPKEYSTRUCT
get_handle(HKEY hkey) {
	int	i;

	for (i=0;i<nrofopenhandles;i++)
		if (openhandles[i].hkey==hkey)
			return openhandles[i].lpkey;
	dprintf_reg(stddeb,"get_handle:Didn't find handle %lx?\n",(LONG)hkey);
	return NULL;
}

static void
remove_handle(HKEY hkey) {
	int	i;

	for (i=0;i<nrofopenhandles;i++)
		if (openhandles[i].hkey==hkey)
			break;
	if (i==nrofopenhandles) {
		dprintf_reg(stddeb,"remove_handle:Didn't find handle %08x?\n",hkey);
		return;
	}
	memcpy(	openhandles+i,
		openhandles+i+1,
		sizeof(struct openhandle)*(nrofopenhandles-i-1)
	);
	openhandles=xrealloc(openhandles,sizeof(struct openhandle)*(nrofopenhandles-1));
	nrofopenhandles--;
	return;
}


/* debug function, converts a unicode into a static memory area 
 * (sub for using two static strings, in case we need them in a single call)
 */
LPSTR
W2C(LPCWSTR x,int sub) {
	static	LPSTR	unicodedebug[2]={NULL,NULL};
	if (x==NULL)
		return "<NULL>";
	if (sub!=0 && sub!=1)
		return "<W2C:bad sub>";
	if (unicodedebug[sub]) free(unicodedebug[sub]);
	unicodedebug[sub]	= strdupW2A(x);
	return unicodedebug[sub];
}

static LPKEYSTRUCT
lookup_hkey(HKEY hkey) {
	switch (hkey) {
	case 0x00000000:
	case 0x00000001:
	case HKEY_CLASSES_ROOT:
		return key_classes_root;
	case HKEY_CURRENT_USER:
		return key_current_user;
	case HKEY_LOCAL_MACHINE:
		return key_local_machine;
	case HKEY_USERS:
		return key_users;
	case HKEY_PERFORMANCE_DATA:
		return key_performance_data;
	case HKEY_DYN_DATA:
		return key_dyn_data;
	case HKEY_CURRENT_CONFIG:
		return key_current_config;
	default:
		dprintf_reg(stddeb,"lookup_hkey(%lx), special key!\n",
			(LONG)hkey
		);
		return get_handle(hkey);
	}
	/*NOTREACHED*/
}

/* 
 * splits the unicode string 'wp' into an array of strings.
 * the array is allocated by this function. 
 * the number of components will be stored in 'wpc'
 * Free the array using FREE_KEY_PATH
 */
static void
split_keypath(LPCWSTR wp,LPWSTR **wpv,int *wpc) {
	int	i,j,len;
	LPWSTR	ws;

	ws	= strdupW(wp);
	*wpc	= 1;
	for (i=0;ws[i];i++) {
		if (ws[i]=='\\') {
			ws[i]=0;
			(*wpc)++;
		}
	}
	len	= i;
	*wpv	= (LPWSTR*)xmalloc(sizeof(LPWSTR)*(*wpc+2));
	(*wpv)[0]= ws;
	j	= 1;
	for (i=1;i<len;i++)
		if (ws[i-1]==0)
			(*wpv)[j++]=ws+i;
	(*wpv)[j]=NULL;
}
#define FREE_KEY_PATH	free(wps[0]);free(wps);

/*
 * Shell initialisation, allocates keys. 
 */
void
SHELL_Init() {
	struct	passwd	*pwd;

	HKEY	cl_r_hkey,c_u_hkey;
#define ADD_ROOT_KEY(xx) \
	xx = (LPKEYSTRUCT)xmalloc(sizeof(KEYSTRUCT));\
	memset(xx,'\0',sizeof(KEYSTRUCT));\
	xx->keyname= strdupA2W("<should_not_appear_anywhere>");

	ADD_ROOT_KEY(key_local_machine);
	if (RegCreateKey16(HKEY_LOCAL_MACHINE,"\\SOFTWARE\\Classes",&cl_r_hkey)!=ERROR_SUCCESS) {
		fprintf(stderr,"couldn't create HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes. This is impossible.\n");
		exit(1);
	}
	key_classes_root = lookup_hkey(cl_r_hkey);

	ADD_ROOT_KEY(key_users);

#if 0
	/* FIXME: load all users and their resp. pwd->pw_dir/.wine/user.reg 
	 *	  (later, when a win32 registry editing tool becomes avail.)
	 */
	while (pwd=getpwent()) {
		if (pwd->pw_name == NULL)
			continue;
		RegCreateKey16(HKEY_USERS,pwd->pw_name,&c_u_hkey);
		RegCloseKey(c_u_hkey);
	}
#endif
	pwd=getpwuid(getuid());
	if (pwd && pwd->pw_name) {
		RegCreateKey16(HKEY_USERS,pwd->pw_name,&c_u_hkey);
		key_current_user = lookup_hkey(c_u_hkey);
	} else {
		ADD_ROOT_KEY(key_current_user);
	}
	ADD_ROOT_KEY(key_performance_data);
	ADD_ROOT_KEY(key_current_config);
	ADD_ROOT_KEY(key_dyn_data);
#undef ADD_ROOT_KEY
}

/************************ SAVE Registry Function ****************************/

#define REGISTRY_SAVE_VERSION	0x00000001

/* Registry saveformat:
 * If you change it, increase above number by 1, which will flush
 * old registry database files.
 * 
 * Global:
 * 	"WINE REGISTRY Version %d"
 * 	subkeys....
 * Subkeys:
 * 	keyname
 *		valuename=lastmodified,type,data
 *		...
 *		subkeys
 *	...
 * keyname,valuename,stringdata:
 *	the usual ascii characters from 0x00-0xff (well, not 0x00)
 *	and \uXXXX as UNICODE value XXXX with XXXX>0xff
 *	( "=\\\t" escaped in \uXXXX form.)
 * type,lastmodified: 
 *	int
 * 
 * FIXME: doesn't save 'class' (what does it mean anyway?), nor flags.
 *
 * [HKEY_CURRENT_USER\\Software\\The WINE team\\WINE\\Registry]
 * SaveOnlyUpdatedKeys=yes
 */
static int
_save_check_tainted(LPKEYSTRUCT lpkey) {
	int		tainted;

	if (!lpkey)
		return 0;
	if (lpkey->flags & REG_OPTION_TAINTED)
		tainted = 1;
	else
		tainted = 0;
	while (lpkey) {
		if (_save_check_tainted(lpkey->nextsub)) {
			lpkey->flags |= REG_OPTION_TAINTED;
			tainted = 1;
		}
		lpkey	= lpkey->next;
	}
	return tainted;
}

static void
_save_USTRING(FILE *F,LPWSTR wstr,int escapeeq) {
	LPWSTR	s;
	int	doescape;

	if (wstr==NULL)
		return;
	s=wstr;
	while (*s) {
		doescape=0;
		if (*s>0xff)
			doescape = 1;
		if (*s=='\n')
			doescape = 1;
		if (escapeeq && *s=='=')
			doescape = 1;
		if (*s=='\\')
			fputc(*s,F); /* if \\ than put it twice. */
		if (doescape)
			fprintf(F,"\\u%04x",*((unsigned short*)s));
		else
			fputc(*s,F);
		s++;
	}
}

static int
_savesubkey(FILE *F,LPKEYSTRUCT lpkey,int level,int all) {
	LPKEYSTRUCT	lpxkey;
	int		i,tabs,j;

	lpxkey	= lpkey;
	while (lpxkey) {
		if (	!(lpxkey->flags & REG_OPTION_VOLATILE) &&
			(all || (lpxkey->flags & REG_OPTION_TAINTED))
		) {
			for (tabs=level;tabs--;)
				fputc('\t',F);
			_save_USTRING(F,lpxkey->keyname,1);
			fputs("\n",F);
			for (i=0;i<lpxkey->nrofvalues;i++) {
				LPKEYVALUE	val=lpxkey->values+i;

				for (tabs=level+1;tabs--;)
					fputc('\t',F);
				_save_USTRING(F,val->name,0);
				fputc('=',F);
				fprintf(F,"%ld,%ld,",val->type,val->lastmodified);
				if ((1<<val->type) & UNICONVMASK)
					_save_USTRING(F,(LPWSTR)val->data,0);
				else
					for (j=0;j<val->len;j++)
						fprintf(F,"%02x",*((unsigned char*)val->data+j));
				fputs("\n",F);
			}
			/* descend recursively */
			if (!_savesubkey(F,lpxkey->nextsub,level+1,all))
				return 0;
		}
		lpxkey=lpxkey->next;
	}
	return 1;
}

static int
_savesubreg(FILE *F,LPKEYSTRUCT lpkey,int all) {
	fprintf(F,"WINE REGISTRY Version %d\n",REGISTRY_SAVE_VERSION);
	_save_check_tainted(lpkey->nextsub);
	return _savesubkey(F,lpkey->nextsub,0,all);
}

static void
_savereg(LPKEYSTRUCT lpkey,char *fn,int all) {
	FILE	*F;

	F=fopen(fn,"w");
	if (F==NULL) {
		fprintf(stddeb,__FILE__":_savereg:Couldn't open %s for writing: %s\n",
			fn,strerror(errno)
		);
		return;
	}
	if (!_savesubreg(F,lpkey,all)) {
		fclose(F);
		unlink(fn);
		fprintf(stddeb,__FILE__":_savereg:Failed to save keys, perhaps no more diskspace for %s?\n",fn);
		return;
	}
	fclose(F);
}

void
SHELL_SaveRegistry() {
	char	*fn;
	struct	passwd	*pwd;
	char	buf[4];
	HKEY	hkey;
	int	all;

	all=0;
	if (RegOpenKey16(HKEY_CURRENT_USER,KEY_REGISTRY,&hkey)!=ERROR_SUCCESS) {
		strcpy(buf,"yes");
	} else {
		DWORD len,junk,type;

		len=4;
		if (	(ERROR_SUCCESS!=RegQueryValueEx32A(
				hkey,
				VAL_SAVEUPDATED,
				&junk,
				&type,
				buf,
				&len
			))|| (type!=REG_SZ)
		)
			strcpy(buf,"yes");
		RegCloseKey(hkey);
	}
	if (strcasecmp(buf,"yes"))
		all=1;
	pwd=getpwuid(getuid());
	if (pwd!=NULL && pwd->pw_dir!=NULL) {
		fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_USERS_DEFAULT)+2);
		strcpy(fn,pwd->pw_dir);
		strcat(fn,WINE_PREFIX);
		/* create the directory. don't care about errorcodes. */
		mkdir(fn,0755); /* drwxr-xr-x */
		strcat(fn,"/"SAVE_CURRENT_USER);
		_savereg(key_current_user,fn,all);
		free(fn);
		fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_LOCAL_MACHINE)+2);
		strcpy(fn,pwd->pw_dir);
		strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE);
		_savereg(key_local_machine,fn,all);
		free(fn);
	} else
		fprintf(stderr,"SHELL_SaveRegistry:failed to get homedirectory of UID %d.\n",getuid());
}

/************************ LOAD Registry Function ****************************/

static LPKEYSTRUCT
_find_or_add_key(LPKEYSTRUCT lpkey,LPWSTR keyname) {
	LPKEYSTRUCT	lpxkey,*lplpkey;

	lplpkey= &(lpkey->nextsub);
	lpxkey	= *lplpkey;
	while (lpxkey) {
		if (!strcmpW(lpxkey->keyname,keyname))
			break;
		lplpkey	= &(lpxkey->next);
		lpxkey	= *lplpkey;
	}
	if (lpxkey==NULL) {
		*lplpkey = (LPKEYSTRUCT)xmalloc(sizeof(KEYSTRUCT));
		lpxkey	= *lplpkey;
		memset(lpxkey,'\0',sizeof(KEYSTRUCT));
		lpxkey->keyname	= keyname;
	} else
		free(keyname);
	return lpxkey;
}

static void
_find_or_add_value(
	LPKEYSTRUCT lpkey,LPWSTR name,DWORD type,LPBYTE data,DWORD len,
	DWORD lastmodified
) {
	LPKEYVALUE	val=NULL;
	int		i;

	for (i=0;i<lpkey->nrofvalues;i++) {
		val=lpkey->values+i;
		if (name==NULL) {
			if (val->name==NULL)
				break;
		} else {
			if (	val->name!=NULL && 
				!strcmpW(val->name,name)
			)
				break;
		}
	}
	if (i==lpkey->nrofvalues) {
		lpkey->values = xrealloc(
			lpkey->values,
			(++lpkey->nrofvalues)*sizeof(KEYVALUE)
		);
		val=lpkey->values+i;
		memset(val,'\0',sizeof(KEYVALUE));
		val->name = name;
	} else {
		if (name)
			free(name);
	}
	if (val->lastmodified<lastmodified) {
		val->lastmodified=lastmodified;
		val->type = type;
		val->len  = len;
		if (val->data) 
			free(val->data);
		val->data = data;
	} else
		free(data);
}


/* reads a line including dynamically enlarging the readbuffer and throwing
 * away comments
 */
static int 
_wine_read_line(FILE *F,char **buf,int *len) {
	char	*s,*curread;
	int	mylen,curoff;

	curread	= *buf;
	mylen	= *len;
	**buf	= '\0';
	while (1) {
		while (1) {
			s=fgets(curread,mylen,F);
			if (s==NULL)
				return 0; /* EOF */
			if (NULL==(s=strchr(curread,'\n'))) {
				/* buffer wasn't large enough */
				curoff	= strlen(*buf);
				*buf	= xrealloc(*buf,*len*2);
				curread	= *buf + curoff;
				mylen	= *len;	/* we filled up the buffer and 
						 * got new '*len' bytes to fill
						 */
				*len	= *len * 2;
			} else {
				*s='\0';
				break;
			}
		}
		/* throw away comments */
		if (**buf=='#' || **buf==';') {
			curread	= *buf;
			mylen	= *len;
			continue;
		}
		if (s) 	/* got end of line */
			break;
	}
	return 1;
}

/* converts a char* into a UNICODE string (up to a special char)
 * and returns the position exactly after that string
 */
static char*
_wine_read_USTRING(char *buf,LPWSTR *str) {
	char	*s;
	LPWSTR	ws;

	/* read up to "=" or "\0" or "\n" */
	s	= buf;
	if (*s == '=') {
		/* empty string is the win3.1 default value(NULL)*/
		*str	= NULL;
		return s;
	}
	*str	= (LPWSTR)xmalloc(2*strlen(buf)+2);
	ws	= *str;
	while (*s && (*s!='\n') && (*s!='=')) {
		if (*s!='\\')
			*ws++=*((unsigned char*)s++);
		else {
			s++;
			if (*s=='\\') {
				*ws+='\\';
				s++;
				continue;
			}
			if (*s!='u') {
				fprintf(stderr,"_wine_read_USTRING:Non unicode escape sequence \\%c found in |%s|\n",*s,buf);
				*ws++='\\';
				*ws++=*s++;
			} else {
				char	xbuf[5];
				int	wc;

				s++;
				memcpy(xbuf,s,4);xbuf[4]='\0';
				if (!sscanf(xbuf,"%x",&wc))
					fprintf(stderr,"_wine_read_USTRING:strange escape sequence %s found in |%s|\n",xbuf,buf);
				s+=4;
				*ws++	=(unsigned short)wc;
			}
		}
	}
	*ws	= 0;
	ws	= *str;
	*str	= strdupW(*str);
	free(ws);
	return s;
}

static int
_wine_loadsubkey(
	FILE *F,LPKEYSTRUCT lpkey,int level,char **buf,int *buflen,int optflag
) {
	LPKEYSTRUCT	lpxkey;
	int		i;
	char		*s;
	LPWSTR		name;

	lpkey->flags |= optflag;

	/* good. we already got a line here ... so parse it */
	lpxkey	= NULL;
	while (1) {
		i=0;s=*buf;
		while (*s=='\t') {
			s++;
			i++;
		}
		if (i>level) {
			if (lpxkey==NULL) {
				fprintf(stderr,"_load_subkey:Got a subhierarchy without resp. key?\n");
				return 0;
			}
			_wine_loadsubkey(F,lpxkey,level+1,buf,buflen,optflag);
			continue;
		}
		/* let the caller handle this line */
		if (i<level || **buf=='\0')
			return 1;

		/* it can be: a value or a keyname. Parse the name first */
		s=_wine_read_USTRING(s,&name);

		/* switch() default: hack to avoid gotos */
		switch (0) {
		default:
			if (*s=='\0') {
				lpxkey=_find_or_add_key(lpkey,name);
			} else {
				LPBYTE		data;
				int		len,lastmodified,type;

				if (*s!='=') {
					fprintf(stderr,"_wine_load_subkey:unexpected character: %c\n",*s);
					break;
				}
				s++;
				if (2!=sscanf(s,"%d,%d,",&type,&lastmodified)) {
					fprintf(stderr,"_wine_load_subkey: haven't understood possible value in |%s|, skipping.\n",*buf);
					break;
				}
				/* skip the 2 , */
				s=strchr(s,',');s++;
				s=strchr(s,',');s++;
				if ((1<<type) & UNICONVMASK) {
					s=_wine_read_USTRING(s,(LPWSTR*)&data);
					if (data)
						len = strlenW((LPWSTR)data)*2+2;
					else	
						len = 0;
				} else {
					len=strlen(s)/2;
					data = (LPBYTE)xmalloc(len+1);
					for (i=0;i<len;i++) {
						data[i]=0;
						if (*s>='0' && *s<='9')
							data[i]=(*s-'0')<<4;
						if (*s>='a' && *s<='f')
							data[i]=(*s-'a')<<4;
						if (*s>='A' && *s<='F')
							data[i]=(*s-'A')<<4;
						s++;
						if (*s>='0' && *s<='9')
							data[i]|=*s-'0';
						if (*s>='a' && *s<='f')
							data[i]|=*s-'a';
						if (*s>='A' && *s<='F')
							data[i]|=*s-'A';
						s++;
					}
				}
				_find_or_add_value(lpkey,name,type,data,len,lastmodified);
			}
		}
		/* read the next line */
		if (!_wine_read_line(F,buf,buflen))
			return 1;
	}
	return 1;
}

static int
_wine_loadsubreg(FILE *F,LPKEYSTRUCT lpkey,int optflag) {
	int	ver;
	char	*buf;
	int	buflen;

	buf=xmalloc(10);buflen=10;
	if (!_wine_read_line(F,&buf,&buflen)) {
		free(buf);
		return 0;
	}
	if (!sscanf(buf,"WINE REGISTRY Version %d",&ver)) {
		free(buf);
		return 0;
	}
	if (ver!=REGISTRY_SAVE_VERSION) {
		dprintf_reg(stddeb,__FILE__":_wine_loadsubreg:Old format (%d) registry found, ignoring it. (buf was %s).\n",ver,buf);
		free(buf);
		return 0;
	}
	if (!_wine_read_line(F,&buf,&buflen)) {
		free(buf);
		return 0;
	}
	if (!_wine_loadsubkey(F,lpkey,0,&buf,&buflen,optflag)) {
		free(buf);
		return 0;
	}
	free(buf);
	return 1;
}

static void
_wine_loadreg(LPKEYSTRUCT lpkey,char *fn,int optflag) {
	FILE	*F;

	F=fopen(fn,"rb");
	if (F==NULL) {
		dprintf_reg(stddeb,__FILE__":Couldn't open %s for reading: %s\n",
			fn,strerror(errno)
		);
		return;
	}
	if (!_wine_loadsubreg(F,lpkey,optflag)) {
		fclose(F);
		unlink(fn);
		return;
	}
	fclose(F);
}

static void
_copy_registry(LPKEYSTRUCT from,LPKEYSTRUCT to) {
	LPKEYSTRUCT	lpxkey;
	int		j;
	LPKEYVALUE	valfrom;

	from=from->nextsub;
	while (from) {
		lpxkey = _find_or_add_key(to,strdupW(from->keyname));

		for (j=0;j<from->nrofvalues;j++) {
			LPWSTR	name;
			LPBYTE	data;

			valfrom = from->values+j;
			name=valfrom->name;
			if (name) name=strdupW(name);
			data=(LPBYTE)malloc(valfrom->len);
			memcpy(data,valfrom->data,valfrom->len);

			_find_or_add_value(
				lpxkey,
				name,
				valfrom->type,
				data,
				valfrom->len,
				valfrom->lastmodified
			);
		}
		_copy_registry(from,lpxkey);
		from = from->next;
	}
}

/* WINDOWS 95 REGISTRY LOADER */
/* 
 * Structure of a win95 registry database.
 * main header:
 * 0 :	"CREG"	- magic
 * 4 :	DWORD version
 * 8 :	DWORD offset_of_RGDB_part
 * 0C..1F:	? (someone fill in please)
 *
 * 20: RGKN_section:
 *   header:
 * 	0 :		"RGKN"	- magic
 * 	4..0x1B: 	? (fill in)
 *      0x20 ... offset_of_RGDB_part: Disk Key Entry structures
 *
 *   Disk Key Entry Structure:
 *	00: DWORD	- unknown
 *	04: DWORD	- unknown
 *	08: DWORD	- unknown, but usually 0xFFFFFFFF on win95 systems
 *	0C: DWORD	- disk address of PreviousLevel Key.
 *	10: DWORD	- disk address of Next Sublevel Key.
 *	14: DWORD	- disk address of Next Key (on same level).
 * DKEP>18: WORD	- Nr, Low Significant part.
 *	1A: WORD	- Nr, High Significant part.
 *
 * The disk address always points to the nr part of the previous key entry 
 * of the referenced key. Don't ask me why, or even if I got this correct
 * from staring at 1kg of hexdumps. (DKEP)
 *
 * The number of the entry is the low byte of the Low Significant Part ored
 * with 0x100 * (low byte of the High Significant part)
 * (C expression : nr = (nrLS & 0xFF) | ((nrHS &0xFF)<<8))
 *
 * There are two minor corrections to the position of that structure.
 * 1. If the address is xxx014 or xxx018 it will be aligned to xxx01c AND 
 *    the DKE reread from there.
 * 2. If the address is xxxFFx it will be aligned to (xxx+1)000.
 * (FIXME: slightly better explanation needed here)
 *
 * RGDB_section:
 * 	00:		"RGDB"	- magic
 *	04: DWORD	offset to next RGDB section (perhaps WORD)
 *	08...1F:	?
 *	20.....:	disk keys
 *
 * disk key:
 * 	00: 	DWORD	nextkeyoffset	- offset to the next disk key structure
 *	08: 	WORD	nrLS		- low significant part of NR
 *	0A: 	WORD	nrHS		- high significant part of NR
 *	0C: 	DWORD	bytesused	- bytes used in this structure.
 *	10: 	WORD	name_len	- length of name in bytes. without \0
 *	12: 	WORD	nr_of_values	- number of values.
 *	14: 	char	name[name_len]	- name string. No \0.
 *	14+name_len: disk values
 *	nextkeyoffset: ... next disk key
 *
 * disk value:
 *	00:	DWORD	type		- value type (hmm, could be WORD too)
 *	04:	DWORD			- unknown, usually 0
 *	08:	WORD	namelen		- length of Name. 0 means name=NULL
 *	0C:	WORD	datalen		- length of Data.
 *	10:	char	name[namelen]	- name, no \0
 *	10+namelen: BYTE	data[datalen] - data, without \0 if string
 *	10+namelen+datalen: next values or disk key
 *
 * Disk keys are layed out flat ... But, sometimes, nrLS and nrHS are both
 * 0xFFFF, which means skipping over nextkeyoffset bytes (including this
 * structure) and reading another RGDB_section.
 * repeat until end of file.
 *
 * FIXME: this description needs some serious help, yes.
 */

struct	_w95keyvalue {
	unsigned long		type;
	unsigned short		datalen;
	char			*name;
	unsigned char		*data;
	unsigned long		x1;
	int			lastmodified;
};

struct 	_w95key {
	char			*name;
	int			nrofvals;
	struct	_w95keyvalue	*values;
	unsigned long		dkeaddr;
	unsigned long 		x1;
	unsigned long 		x2;
	unsigned long 		x3;
	unsigned long 		xx1;
	struct _w95key		*prevlvl;
	struct _w95key		*nextsub;
	struct _w95key		*next;
};

/* fast lookup table dkeaddr->nr */
struct	_w95nr2da {
	unsigned long		dkeaddr;
	unsigned long		nr;
};


static void
_w95_walk_tree(LPKEYSTRUCT lpkey,struct _w95key *key) {
	int		i;
	LPKEYSTRUCT	lpxkey;
	LPWSTR		name;

	while (key) {
		if (key->name == NULL) {
			fprintf(stderr,"key with dkeaddr %lx not loaded, skipping hierarchy\n",
				key->dkeaddr
			);
			key = key->next;
			continue;
		}
		lpxkey=_find_or_add_key(lpkey,strdupA2W(key->name));

		if (key->nrofvals<0) {
			/* shouldn't happen */
			fprintf(stderr,"key %s already processed!\n",key->name);
			key = key->next;
			continue;
		}
		for (i=0;i<key->nrofvals;i++) {
			LPBYTE	data;
			int	len;

			name = strdupA2W(key->values[i].name);
			if (!*name) name = NULL;
			free(key->values[i].name);

			len	= key->values[i].datalen;
			data	= key->values[i].data;
			if ((1<<key->values[i].type) & UNICONVMASK) {
				data = (BYTE*)strdupA2W(data);
				len  = strlenW((LPWSTR)data)*2+2;
				free(key->values[i].data);
			}
			_find_or_add_value(
				lpxkey,
				name,
				key->values[i].type,
				data,
				len,
				key->values[i].lastmodified
			);
		}
		if (key->values) {
			free(key->values);
			key->values = NULL;
		}
		key->nrofvals=-key->nrofvals-1;
		_w95_walk_tree(lpxkey,key->nextsub);
		key=key->next;
	}
}

/* small helper function to adjust address offset (dkeaddrs) */
static unsigned long
_w95_adj_da(unsigned long dkeaddr) {
	if ((dkeaddr&0xFFF)<0x018) {
		int	diff;

		diff=0x1C-(dkeaddr&0xFFF);
		return dkeaddr+diff;
	}
	if (((dkeaddr+0x1C)&0xFFF)<0x1C) {
		/* readjust to 0x000,
		 * but ONLY if we are >0x1000 already
		 */
		if (dkeaddr & ~0xFFF)
			return dkeaddr & ~0xFFF;
	}
	return dkeaddr;
}

static int
_w95dkecomp(struct _w95nr2da *a,struct _w95nr2da *b){return a->dkeaddr-b->dkeaddr;}

static struct _w95key*
_w95dkelookup(unsigned long dkeaddr,int n,struct _w95nr2da *nr2da,struct _w95key *keys) {
	int	i,off;

	if (dkeaddr == 0xFFFFFFFF)
		return NULL;
	if (dkeaddr<0x20)
		return NULL;
	dkeaddr=_w95_adj_da(dkeaddr+0x1c);
	off = (dkeaddr-0x3c)/0x1c;
	for (i=0;i<n;i++)
		if (nr2da[(i+off)%n].dkeaddr == dkeaddr)
			return keys+nr2da[(i+off)%n].nr;
	fprintf(stderr,"search didn't found dkeaddr %lx?\n",dkeaddr);
	return NULL;
}

static void
_w95_loadreg(char* fn,LPKEYSTRUCT lpkey) {
	/* Disk Key Entry structure (RGKN part) */
	struct	dke {
		unsigned long		x1;
		unsigned long		x2;
		unsigned long		x3;/*usually 0xFFFFFFFF */
		unsigned long		prevlvl;
		unsigned long		nextsub;
		unsigned long		next;
		unsigned short		nrLS;
		unsigned short		nrMS;
	};
	/* Disk Key Header structure (RGDB part) */
	struct	dkh {
		unsigned long		nextkeyoff; 
		unsigned short		nrLS;
		unsigned short		nrMS;
		unsigned long		bytesused;
		unsigned short		keynamelen;
		unsigned short		values;
		unsigned long		xx1;
		/* keyname */
		/* disk key values or nothing */
	};
	/* Disk Key Value structure */
	struct	dkv {
		unsigned long		type;
		unsigned long		x1;
		unsigned short		valnamelen;
		unsigned short		valdatalen;
		/* valname, valdata */
	};
	struct	_w95nr2da 	*nr2da;

	HFILE		hfd;
	int		fd,lastmodified;
	char		magic[5];
	unsigned long	nr,pos,i,where,version,rgdbsection,end,off_next_rgdb;
	struct	_w95key	*keys;
	int		nrofdkes;
	unsigned char	*data,*curdata,*nextrgdb;
	OFSTRUCT	ofs;
	struct	stat	stbuf;

	dprintf_reg(stddeb,"Loading Win95 registry database '%s'\n",fn);
	hfd=OpenFile(fn,&ofs,OF_READ);
	if (hfd==HFILE_ERROR)
		return;
	fd = FILE_GetUnixHandle(hfd);
	magic[4]=0;
	if (4!=read(fd,magic,4))
		return;
	if (strcmp(magic,"CREG")) {
		fprintf(stddeb,"%s is not a w95 registry.\n",fn);
		return;
	}
	if (4!=read(fd,&version,4))
		return;
	if (4!=read(fd,&rgdbsection,4))
		return;
	if (-1==lseek(fd,0x20,SEEK_SET))
		return;
	if (4!=read(fd,magic,4))
		return;
	if (strcmp(magic,"RGKN")) {
		dprintf_reg(stddeb,"second IFF header not RGKN, but %s\n",magic);
		return;
	}

	/* STEP 1: Keylink structures */
	if (-1==lseek(fd,0x40,SEEK_SET))
		return;
	where	= 0x40;
	end	= rgdbsection;

	nrofdkes = (end-where)/sizeof(struct dke);
	data = (char*)xmalloc(end-where);
	if ((end-where)!=read(fd,data,end-where))
		return;
	curdata = data;

	keys = (struct _w95key*)xmalloc(nrofdkes * sizeof(struct _w95key));
	memset(keys,'\0',nrofdkes*sizeof(struct _w95key));
	nr2da= (struct _w95nr2da*)xmalloc(nrofdkes * sizeof(struct _w95nr2da));

	for (i=0;i<nrofdkes;i++) {
		struct	dke	dke;
		unsigned long 	dkeaddr;

		pos=curdata-data+0x40;
		memcpy(&dke,curdata,sizeof(dke));
		curdata+=sizeof(dke);
		nr = dke.nrLS + (dke.nrMS<<8);
		dkeaddr=pos-4;
		if ((dkeaddr&0xFFF)<0x018) {
			int	diff;

			diff=0x1C-(dkeaddr&0xFFF);
			dkeaddr+=diff;
			curdata+=diff-sizeof(dke);
			memcpy(&dke,curdata,sizeof(dke));
			nr = dke.nrLS + (dke.nrMS<<8);
			curdata+=sizeof(dke);
		}
		if (((dkeaddr+0x1C)&0xFFF)<0x1C) {
			/* readjust to 0x000,
			 * but ONLY if we are >0x1000 already
			 */
			if (dkeaddr & ~0xFFF)
				dkeaddr = dkeaddr & ~0xFFF;
		}
		if (nr>nrofdkes) {
			dprintf_reg(stddeb,"nr %ld exceeds nrofdkes %d, skipping.\n",nr,nrofdkes);
			continue;
		}
		if (keys[nr].dkeaddr) {
			int	x;

			for (x=sizeof(dke);x--;)
				if (((char*)&dke)[x])
					break;
			if (x==-1)
				break; /* finished reading if we got only 0 */
			if (nr)
				dprintf_reg(stddeb,"key doubled? nr=%ld,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,keys[nr].dkeaddr,dkeaddr);
			continue;
		}
		nr2da[i].nr	 = nr;
		nr2da[i].dkeaddr = dkeaddr;

		keys[nr].dkeaddr = dkeaddr;
		keys[nr].x1 = dke.x1;
		keys[nr].x2 = dke.x2;
		keys[nr].x3 = dke.x3;
		keys[nr].prevlvl= (struct _w95key*)dke.prevlvl;
		keys[nr].nextsub= (struct _w95key*)dke.nextsub;
		keys[nr].next 	= (struct _w95key*)dke.next;
	}
	free(data);

	qsort(nr2da,nrofdkes,sizeof(nr2da[0]),_w95dkecomp);

	/* STEP 2: keydata & values */
	if (-1==fstat(fd,&stbuf))
		return;
	end		= stbuf.st_size;
	lastmodified	= stbuf.st_mtime;

	if (-1==lseek(fd,rgdbsection,SEEK_SET))
		return;
	data = (char*)xmalloc(end-rgdbsection);
	if ((end-rgdbsection)!=read(fd,data,end-rgdbsection))
		return;
	_lclose(hfd);
	curdata = data;
	memcpy(magic,curdata,4);
	memcpy(&off_next_rgdb,curdata+4,4);
	nextrgdb = curdata+off_next_rgdb;
	if (strcmp(magic,"RGDB")) {
		dprintf_reg(stddeb,"third IFF header not RGDB, but %s\n",magic);
		return;
	}
	curdata=data+0x20;
	while (1) {
		struct	dkh dkh;
		int	bytesread;
		struct	_w95key	*key,xkey;

		bytesread = 0;
		if (curdata>=nextrgdb) {
			curdata = nextrgdb;
			if (!strncmp(curdata,"RGDB",4)) {
				memcpy(&off_next_rgdb,curdata+4,4);
				nextrgdb = curdata+off_next_rgdb;
				curdata+=0x20;
			} else {
				dprintf_reg(stddeb,"at end of RGDB section, but no next header. Breaking.\n");
				break;
			}
		}
#define XREAD(whereto,len) \
	if ((curdata-data+len)<end) {\
		memcpy(whereto,curdata,len);\
		curdata+=len;\
		bytesread+=len;\
	}

		XREAD(&dkh,sizeof(dkh));
		nr = dkh.nrLS + (dkh.nrMS<<8);
		if (nr>nrofdkes) {
			if (dkh.nrLS == 0xFFFF) {
				curdata+= dkh.nextkeyoff - bytesread;
				XREAD(magic,4);
				if (strcmp(magic,"RGDB")) {
					if ((curdata-data)<end)
						dprintf_reg(stddeb,"while skipping to next RGDB block found magic %s\n",magic);
					break;
				}
				curdata+=0x1c;
				continue;
			}
			if (dkh.nrLS == 0xFFFE) {
				dprintf_reg(stddeb,"0xFFFE at %x\n",curdata-data);
				break;
			}
			dprintf_reg(stddeb,"haven't found nr %ld.\n",nr);
			key = &xkey;
			memset(key,'\0',sizeof(xkey));
		} else {
			key = keys+nr;
			if (!key->dkeaddr)
				dprintf_reg(stddeb,"key with nr=%ld has no dkeaddr?\n",nr);
		}
		key->nrofvals	= dkh.values;
		key->name	= (char*)xmalloc(dkh.keynamelen+1);
		key->xx1	= dkh.xx1;
		XREAD(key->name,dkh.keynamelen);
		key->name[dkh.keynamelen]=0;
		if (key->nrofvals) {
			key->values = (struct _w95keyvalue*)xmalloc(
				sizeof(struct _w95keyvalue)*key->nrofvals
			);
			for (i=0;i<key->nrofvals;i++) {
				struct	dkv	dkv;

				XREAD(&dkv,sizeof(dkv));
				key->values[i].type = dkv.type;
				key->values[i].name = (char*)xmalloc(
					dkv.valnamelen+1
				);
				key->values[i].datalen = dkv.valdatalen;
				key->values[i].data = (unsigned char*)xmalloc(
					dkv.valdatalen+1
				);
				key->values[i].x1   = dkv.x1;
				XREAD(key->values[i].name,dkv.valnamelen);
				XREAD(key->values[i].data,dkv.valdatalen);
				key->values[i].data[dkv.valdatalen]=0;
				key->values[i].name[dkv.valnamelen]=0;
				key->values[i].lastmodified=lastmodified;
			}
		}
		if (bytesread != dkh.nextkeyoff) {
			if (dkh.bytesused != bytesread)
				dprintf_reg(stddeb,
					"read has difference in read bytes (%d) and nextoffset (%ld) (bytesused=%ld)\n",bytesread,dkh.nextkeyoff,
					dkh.bytesused
				);
			curdata += dkh.nextkeyoff-bytesread;
		}
		key->prevlvl	= _w95dkelookup((long)key->prevlvl,nrofdkes,nr2da,keys);
		key->nextsub	= _w95dkelookup((long)key->nextsub,nrofdkes,nr2da,keys);
		key->next	= _w95dkelookup((long)key->next,nrofdkes,nr2da,keys);
		if (!bytesread)
			break;
	}
	free(data);
	_w95_walk_tree(lpkey,keys);
	free(keys);
}

void
SHELL_LoadRegistry() {
	char	*fn;
	struct	passwd	*pwd;
	LPKEYSTRUCT	lpkey;
	HKEY		hkey;


	if (key_classes_root==NULL)
		SHELL_Init();

	/* Load windows 95 entries */
	_w95_loadreg("C:\\system.1st",	key_local_machine);
	_w95_loadreg("system.dat",	key_local_machine);
	_w95_loadreg("user.dat",	key_users);

	/* FIXME: win3.1 reg.dat loader still missing */

	/* the global user default is loaded under HKEY_USERS\\.Default */
	RegCreateKey16(HKEY_USERS,".Default",&hkey);
	lpkey = lookup_hkey(hkey);
	_wine_loadreg(lpkey,SAVE_USERS_DEFAULT,0);

	/* HKEY_USERS\\.Default is copied to HKEY_CURRENT_USER */
	_copy_registry(lpkey,key_current_user);
	RegCloseKey(hkey);

	/* the global machine defaults */
	_wine_loadreg(key_local_machine,SAVE_LOCAL_MACHINE_DEFAULT,0);

	/* load the user saved registries */

	/* FIXME: use getenv("HOME") or getpwuid(getuid())->pw_dir ?? */

	pwd=getpwuid(getuid());
	if (pwd!=NULL && pwd->pw_dir!=NULL) {
		fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_CURRENT_USER)+2);
		strcpy(fn,pwd->pw_dir);
		strcat(fn,WINE_PREFIX"/"SAVE_CURRENT_USER);
		_wine_loadreg(key_current_user,fn,REG_OPTION_TAINTED);
		free(fn);
		fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_LOCAL_MACHINE)+2);
		strcpy(fn,pwd->pw_dir);
		strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE);
		_wine_loadreg(key_local_machine,fn,REG_OPTION_TAINTED);
		free(fn);
	} else
		fprintf(stderr,"SHELL_LoadRegistry:failed to get homedirectory of UID %d.\n",getuid());
	if (ERROR_SUCCESS==RegCreateKey16(HKEY_CURRENT_USER,KEY_REGISTRY,&hkey)) {
		DWORD	junk,type,len;
		char	data[5];

		len=4;
		if ((	RegQueryValueEx32A(
				hkey,
				VAL_SAVEUPDATED,
				&junk,
				&type,
				data,
				&len
			)!=ERROR_SUCCESS) ||
			type != REG_SZ
		)
			RegSetValueEx32A(hkey,VAL_SAVEUPDATED,0,REG_SZ,"yes",4);
		RegCloseKey(hkey);
	}
}


/********************* API FUNCTIONS ***************************************/
/*
 * Open Keys.
 *
 * All functions are stubs to RegOpenKeyEx32W where all the
 * magic happens. 
 *
 * FIXME: security,options,desiredaccess,...
 *
 * Callpath:
 * RegOpenKey16 -> RegOpenKey32A -> RegOpenKeyEx32A \
 *                                  RegOpenKey32W   -> RegOpenKeyEx32W 
 */

/* RegOpenKeyExW		[ADVAPI32.150] */
DWORD RegOpenKeyEx32W(
	HKEY	hkey,
	LPCWSTR	lpszSubKey,
	DWORD	dwReserved,
	REGSAM	samDesired,
	LPHKEY	retkey
) {
	LPKEYSTRUCT	lpNextKey,lpxkey;
	LPWSTR		*wps;
	int		wpc,i;
	dprintf_reg(stddeb,"RegOpenKeyEx32W(%lx,%s,%ld,%lx,%p)\n",
		(LONG)hkey,W2C(lpszSubKey,0),dwReserved,samDesired,retkey
	);

	lpNextKey	= lookup_hkey(hkey);
	if (!lpNextKey)
		return SHELL_ERROR_BADKEY;
	if (!lpszSubKey || !*lpszSubKey) {
		add_handle(++currenthandle,lpNextKey,samDesired);
		*retkey=currenthandle;
		return SHELL_ERROR_SUCCESS;
	}
	split_keypath(lpszSubKey,&wps,&wpc);
	i 	= 0;
	while ((i<wpc) && (wps[i][0]=='\0')) i++;
	lpxkey	= lpNextKey;
	while (i<wpc) {
		lpxkey=lpNextKey->nextsub;
		while (lpxkey) {
			if (!strcmpW(wps[i],lpxkey->keyname))
				break;
			lpxkey=lpxkey->next;
		}
		if (!lpxkey) {
			FREE_KEY_PATH;
			return SHELL_ERROR_BADKEY;
		}
		i++;
		lpNextKey	= lpxkey;
	}
	add_handle(++currenthandle,lpxkey,samDesired);
	*retkey	= currenthandle;
	FREE_KEY_PATH;
	return	SHELL_ERROR_SUCCESS;
}

/* RegOpenKeyW			[ADVAPI32.151] */
DWORD RegOpenKey32W(
	HKEY	hkey,
	LPCWSTR	lpszSubKey,
	LPHKEY	retkey
) {
	dprintf_reg(stddeb,"RegOpenKey32W(%lx,%s,%p)\n",
		(LONG)hkey,W2C(lpszSubKey,0),retkey
	);
	return RegOpenKeyEx32W(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey);
}


/* RegOpenKeyExA		[ADVAPI32.149] */
DWORD RegOpenKeyEx32A(
	HKEY	hkey,
	LPCSTR	lpszSubKey,
	DWORD	dwReserved,
	REGSAM	samDesired,
	LPHKEY	retkey
) {
	LPWSTR	lpszSubKeyW;
	DWORD	ret;

	dprintf_reg(stddeb,"RegOpenKeyEx32A(%lx,%s,%ld,%lx,%p)\n",
		(LONG)hkey,lpszSubKey,dwReserved,samDesired,retkey
	);
	if (lpszSubKey)
		lpszSubKeyW=strdupA2W(lpszSubKey);
	else
		lpszSubKeyW=NULL;
	ret=RegOpenKeyEx32W(hkey,lpszSubKeyW,dwReserved,samDesired,retkey);
	if (lpszSubKeyW)
		free(lpszSubKeyW);
	return ret;
}

/* RegOpenKeyA			[ADVAPI32.148] */
DWORD RegOpenKey32A(
	HKEY	hkey,
	LPCSTR	lpszSubKey,
	LPHKEY	retkey
) {
	dprintf_reg(stddeb,"RegOpenKey32A(%lx,%s,%p)\n",
		(LONG)hkey,lpszSubKey,retkey
	);
	return	RegOpenKeyEx32A(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey);
}

/* RegOpenKey			[SHELL.1] [KERNEL.217] */
DWORD RegOpenKey16(
	HKEY	hkey,
	LPCSTR	lpszSubKey,
	LPHKEY	retkey
) {
	dprintf_reg(stddeb,"RegOpenKey16(%lx,%s,%p)\n",
		(LONG)hkey,lpszSubKey,retkey
	);
	return RegOpenKey32A(hkey,lpszSubKey,retkey);
}

/* 
 * Create keys
 * 
 * All those functions convert their respective 
 * arguments and call RegCreateKeyExW at the end.
 *
 * FIXME: no security,no access attrib,no optionhandling yet.
 *
 * Callpath:
 * RegCreateKey16 -> RegCreateKey32A -> RegCreateKeyEx32A \
 *                                      RegCreateKey32W   -> RegCreateKeyEx32W
 */

/* RegCreateKeyExW		[ADVAPI32.131] */
DWORD RegCreateKeyEx32W(
	HKEY	hkey,
	LPCWSTR	lpszSubKey,
	DWORD	dwReserved,
	LPWSTR	lpszClass,
	DWORD	fdwOptions,
	REGSAM	samDesired,
	LPSECURITY_ATTRIBUTES lpSecAttribs,
	LPHKEY	retkey,
	LPDWORD	lpDispos
) {
	LPKEYSTRUCT	*lplpPrevKey,lpNextKey,lpxkey;
	LPWSTR		*wps;
	int		wpc,i;

/*FIXME: handle security/access/whatever */
	dprintf_reg(stddeb,"RegCreateKeyEx32W(%lx,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n",
		(LONG)hkey,
		W2C(lpszSubKey,0),
		dwReserved,
		W2C(lpszClass,1),
		fdwOptions,
		samDesired,
		lpSecAttribs,
		retkey,
		lpDispos
	);

	lpNextKey	= lookup_hkey(hkey);
	if (!lpNextKey)
		return SHELL_ERROR_BADKEY;
	if (!lpszSubKey || !*lpszSubKey) {
		add_handle(++currenthandle,lpNextKey,samDesired);
		*retkey=currenthandle;
		return SHELL_ERROR_SUCCESS;
	}
	split_keypath(lpszSubKey,&wps,&wpc);
	i 	= 0;
	while ((i<wpc) && (wps[i][0]=='\0')) i++;
	lpxkey	= lpNextKey;
	while (i<wpc) {
		lpxkey=lpNextKey->nextsub;
		while (lpxkey) {
			if (!strcmpW(wps[i],lpxkey->keyname))
				break;
			lpxkey=lpxkey->next;
		}
		if (!lpxkey)
			break;
		i++;
		lpNextKey	= lpxkey;
	}
	if (lpxkey) {
		add_handle(++currenthandle,lpxkey,samDesired);
		*retkey		= currenthandle;
		*lpDispos	= REG_OPENED_EXISTING_KEY;
		FREE_KEY_PATH;
		return	SHELL_ERROR_SUCCESS;
	}
	/* good. now the hard part */
	while (i<wpc) {
		lplpPrevKey	= &(lpNextKey->nextsub);
		lpxkey		= *lplpPrevKey;
		while (lpxkey) {
			lplpPrevKey	= &(lpxkey->next);
			lpxkey		= *lplpPrevKey;
		}
		*lplpPrevKey=malloc(sizeof(KEYSTRUCT));
		if (!*lplpPrevKey) {
			FREE_KEY_PATH;
			return SHELL_ERROR_OUTOFMEMORY;
		}
		memset(*lplpPrevKey,'\0',sizeof(KEYSTRUCT));
		(*lplpPrevKey)->keyname	= strdupW(wps[i]);
		(*lplpPrevKey)->next	= NULL;
		(*lplpPrevKey)->nextsub	= NULL;
		(*lplpPrevKey)->values	= NULL;
		(*lplpPrevKey)->nrofvalues = 0;
		if (lpszClass)
			(*lplpPrevKey)->class = strdupW(lpszClass);
		else
			(*lplpPrevKey)->class = NULL;
		lpNextKey	= *lplpPrevKey;
		i++;
	}
	add_handle(++currenthandle,lpNextKey,samDesired);

	/*FIXME: flag handling correct? */
	lpNextKey->flags= fdwOptions;
	if (lpszClass)
		lpNextKey->class = strdupW(lpszClass);
	else
		lpNextKey->class = NULL;
	lpNextKey->flags|=REG_OPTION_TAINTED;
	*retkey		= currenthandle;
	*lpDispos	= REG_CREATED_NEW_KEY;
	FREE_KEY_PATH;
	return SHELL_ERROR_SUCCESS;
}

/* RegCreateKeyW		[ADVAPI32.132] */
DWORD RegCreateKey32W(
	HKEY	hkey,
	LPCWSTR	lpszSubKey,
	LPHKEY	retkey
) {
	DWORD	junk,ret;

	dprintf_reg(stddeb,"RegCreateKey32W(%lx,%s,%p)\n",
		(LONG)hkey,W2C(lpszSubKey,0),retkey
	);
	ret=RegCreateKeyEx32W(
		hkey,		/* key handle */
		lpszSubKey,	/* subkey name */
		0,		/* reserved = 0 */
		NULL,		/* lpszClass? FIXME: ? */
		REG_OPTION_NON_VOLATILE,	/* options */
		KEY_ALL_ACCESS,	/* desired access attribs */
		NULL,		/* lpsecurity attributes */
		retkey,		/* lpretkey */
		&junk		/* disposition value */
	);
	return	ret;
}

/* RegCreateKeyExA		[ADVAPI32.130] */
DWORD RegCreateKeyEx32A(
	HKEY	hkey,
	LPCSTR	lpszSubKey,
	DWORD	dwReserved,
	LPSTR	lpszClass,
	DWORD	fdwOptions,
	REGSAM	samDesired,
	LPSECURITY_ATTRIBUTES lpSecAttribs,
	LPHKEY	retkey,
	LPDWORD	lpDispos
) {
	LPWSTR	lpszSubKeyW,lpszClassW;
	DWORD	ret;

	dprintf_reg(stddeb,"RegCreateKeyEx32A(%lx,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n",
		(LONG)hkey,
		lpszSubKey,
		dwReserved,
		lpszClass,
		fdwOptions,
		samDesired,
		lpSecAttribs,
		retkey,
		lpDispos
	);
	if (lpszSubKey)
		lpszSubKeyW=strdupA2W(lpszSubKey);
	else
		lpszSubKeyW=NULL;
	if (lpszClass)
		lpszClassW=strdupA2W(lpszClass);
	else
		lpszClassW=NULL;
	ret=RegCreateKeyEx32W(
		hkey,
		lpszSubKeyW,
		dwReserved,
		lpszClassW,
		fdwOptions,
		samDesired,
		lpSecAttribs,
		retkey,
		lpDispos
	);
	if (lpszSubKeyW)
		free(lpszSubKeyW);
	if (lpszClassW)
		free(lpszClassW);
	return ret;
}

/* RegCreateKeyA		[ADVAPI32.129] */
DWORD RegCreateKey32A(
	HKEY	hkey,
	LPCSTR	lpszSubKey,
	LPHKEY	retkey
) {
	DWORD	junk;

	dprintf_reg(stddeb,"RegCreateKey32A(%lx,%s,%p)\n",
		(LONG)hkey,lpszSubKey,retkey
	);
	return	RegCreateKeyEx32A(
		hkey,		/* key handle */
		lpszSubKey,	/* subkey name */
		0,		/* reserved = 0 */
		NULL,		/* lpszClass? FIXME: ? */
		REG_OPTION_NON_VOLATILE,/* options */
		KEY_ALL_ACCESS,	/* desired access attribs */
		NULL,		/* lpsecurity attributes */
		retkey,		/* lpretkey */
		&junk		/* disposition value */
	);
}

/* RegCreateKey			[SHELL.2] [KERNEL.218] */
DWORD RegCreateKey16(
	HKEY	hkey,
	LPCSTR	lpszSubKey,
	LPHKEY	retkey
) {
	dprintf_reg(stddeb,"RegCreateKey16(%lx,%s,%p)\n",
		(LONG)hkey,lpszSubKey,retkey
	);
	return RegCreateKey32A(hkey,lpszSubKey,retkey);
}

/* 
 * Query Value Functions
 * Win32 differs between keynames and valuenames. 
 * multiple values may belong to one key, the special value
 * with name NULL is the default value used by the win31
 * compat functions.
 *
 * Callpath:
 * RegQueryValue16 -> RegQueryValue32A -> RegQueryValueEx32A \
 *                                          RegQueryValue32W -> RegQueryValueEx32W
 */

/* RegQueryValueExW		[ADVAPI32.158] */
DWORD RegQueryValueEx32W(
	HKEY	hkey,
	LPWSTR	lpszValueName,
	LPDWORD	lpdwReserved,
	LPDWORD	lpdwType,
	LPBYTE	lpbData,
	LPDWORD	lpcbData
) {
	LPKEYSTRUCT	lpkey;
	int		i;

	dprintf_reg(stddeb,"RegQueryValueEx32W(%x,%s,%p,%p,%p,%p)\n",
		hkey,W2C(lpszValueName,0),lpdwReserved,lpdwType,lpbData,lpcbData
	);

	lpkey	= lookup_hkey(hkey);
	if (!lpkey)
		return SHELL_ERROR_BADKEY;
	if (lpszValueName==NULL) {
		for (i=0;i<lpkey->nrofvalues;i++)
			if (lpkey->values[i].name==NULL)
				break;
	} else {
		for (i=0;i<lpkey->nrofvalues;i++)
			if (!strcmpW(lpszValueName,lpkey->values[i].name))
				break;
	}
	if (i==lpkey->nrofvalues) {
		if (lpszValueName==NULL) {
			*(WCHAR*)lpbData = 0;
			*lpcbData	= 2;
			*lpdwType	= REG_SZ;
			return SHELL_ERROR_SUCCESS;
		}
		return SHELL_ERROR_BADKEY;/*FIXME: correct return? */
	}
	if (lpdwType)
		*lpdwType	= lpkey->values[i].type;
	if (lpbData==NULL) {
		if (lpcbData==NULL)
			return SHELL_ERROR_SUCCESS;
		*lpcbData	= lpkey->values[i].len;
		return SHELL_ERROR_SUCCESS;
	}
	if (*lpcbData<lpkey->values[i].len) {
		*(WCHAR*)lpbData
			= 0;
		*lpcbData	= lpkey->values[i].len;
		return ERROR_MORE_DATA;
	}
	memcpy(lpbData,lpkey->values[i].data,lpkey->values[i].len);
	*lpcbData	= lpkey->values[i].len;
	return SHELL_ERROR_SUCCESS;
}

/* RegQueryValueW		[ADVAPI32.159] */
DWORD RegQueryValue32W(
	HKEY	hkey,
	LPWSTR	lpszSubKey,
	LPWSTR	lpszData,
	LPDWORD	lpcbData
) {
	HKEY	xhkey;
	DWORD	ret,lpdwType;

	dprintf_reg(stddeb,"RegQueryValue32W(%x,%s,%p,%p)\n->",
		hkey,W2C(lpszSubKey,0),lpszData,lpcbData
	);

	/* only open subkey, if we really do descend */
	if (lpszSubKey && *lpszSubKey) {
		ret	= RegOpenKey32W(hkey,lpszSubKey,&xhkey);
		if (ret!=ERROR_SUCCESS)
			return ret;
	} else
		xhkey	= hkey;

	lpdwType	= REG_SZ;
	ret	= RegQueryValueEx32W(
		xhkey,
		NULL,		/* varname NULL -> compat */
		NULL,		/* lpdwReserved, must be NULL */
		&lpdwType,
		(LPBYTE)lpszData,
		lpcbData
	);
	if (xhkey!=hkey)
		RegCloseKey(xhkey);
	return ret;
}

/* RegQueryValueExA		[ADVAPI32.157] */
DWORD RegQueryValueEx32A(
	HKEY	hkey,
	LPSTR	lpszValueName,
	LPDWORD	lpdwReserved,
	LPDWORD	lpdwType,
	LPBYTE	lpbData,
	LPDWORD	lpcbData
) {
	LPWSTR	lpszValueNameW;
	LPBYTE	buf;
	DWORD	ret,myxlen;
	DWORD	*mylen;

	dprintf_reg(stddeb,"RegQueryValueEx32A(%x,%s,%p,%p,%p,%p)\n->",
		hkey,lpszValueName,lpdwReserved,lpdwType,lpbData,lpcbData
	);
	if (lpbData) {
		/* double buffer */
		buf	= (LPBYTE)xmalloc((*lpcbData)*2);
		myxlen	= *lpcbData*2;
		mylen	= &myxlen;
	} else {
		buf=NULL;
		if (lpcbData) {
			myxlen	= *lpcbData*2;
			mylen	= &myxlen;
		}
			mylen	= NULL;
	}
	if (lpszValueName)
		lpszValueNameW=strdupA2W(lpszValueName);
	else 
		lpszValueNameW=NULL;

	ret=RegQueryValueEx32W(
		hkey,
		lpszValueNameW,
		lpdwReserved,
		lpdwType,
		buf,
		mylen
	);

	if (ret==ERROR_SUCCESS) {
		if (buf) {
			if (UNICONVMASK & (1<<(*lpdwType))) {
				/* convert UNICODE to ASCII */
				strcpyWA(lpbData,(LPWSTR)buf);
				*lpcbData	= myxlen/2;
			} else {
				if (myxlen>*lpcbData)
					ret	= ERROR_MORE_DATA;
				else
					memcpy(lpbData,buf,myxlen);

				*lpcbData	= myxlen;
			}
		} else {
			if ((UNICONVMASK & (1<<(*lpdwType))) && lpcbData)
				*lpcbData	= myxlen/2;
		}
	} else {
		if ((UNICONVMASK & (1<<(*lpdwType))) && lpcbData)
			*lpcbData	= myxlen/2;
	}
	if (buf)
		free(buf);
	return ret;
}

/* RegQueryValueEx		[KERNEL.225] */
DWORD RegQueryValueEx16(
	HKEY	hkey,
	LPSTR	lpszValueName,
	LPDWORD	lpdwReserved,
	LPDWORD	lpdwType,
	LPBYTE	lpbData,
	LPDWORD	lpcbData
) {
	dprintf_reg(stddeb,"RegQueryValueEx16(%x,%s,%p,%p,%p,%p)\n",
		hkey,lpszValueName,lpdwReserved,lpdwType,lpbData,lpcbData
	);
	return RegQueryValueEx32A(
		hkey,
		lpszValueName,
		lpdwReserved,
		lpdwType,
		lpbData,
		lpcbData
	);
}

/* RegQueryValueA		[ADVAPI32.156] */
DWORD RegQueryValue32A(
	HKEY	hkey,
	LPSTR	lpszSubKey,
	LPSTR	lpszData,
	LPDWORD	lpcbData
) {
	HKEY	xhkey;
	DWORD	ret,lpdwType;

	dprintf_reg(stddeb,"RegQueryValue32A(%x,%s,%p,%p)\n",
		hkey,lpszSubKey,lpszData,lpcbData
	);

	/* only open subkey, if we really do descend */
	if (lpszSubKey && *lpszSubKey) {
		ret	= RegOpenKey16(hkey,lpszSubKey,&xhkey);
		if (ret!=ERROR_SUCCESS)
			return ret;
	} else
		xhkey	= hkey;

	lpdwType	= REG_SZ;
	ret	= RegQueryValueEx32A(
		xhkey,
		NULL,		/* lpszValueName NULL -> compat */
		NULL,		/* lpdwReserved, must be NULL */
		&lpdwType,
		(LPBYTE)lpszData,
		lpcbData
	);
	if (xhkey!=hkey)
		RegCloseKey(xhkey);
	return ret;
}

/* RegQueryValue		[SHELL.6] [KERNEL.224] */
DWORD RegQueryValue16(
	HKEY	hkey,
	LPSTR	lpszSubKey,
	LPSTR	lpszData,
	LPDWORD	lpcbData
) {
	dprintf_reg(stddeb,"RegQueryValue16(%x,%s,%p,%p)\n",
		hkey,lpszSubKey,lpszData,lpcbData
	);
	return RegQueryValue32A(hkey,lpszSubKey,lpszData,lpcbData);
}

/*
 * Setting values of Registry keys
 *
 * Callpath:
 * RegSetValue16 -> RegSetValue32A -> RegSetValueEx32A \
 *                                    RegSetValue32W   -> RegSetValueEx32W
 */

/* RegSetValueExW		[ADVAPI32.170] */
DWORD RegSetValueEx32W(
	HKEY	hkey,
	LPWSTR	lpszValueName,
	DWORD	dwReserved,
	DWORD	dwType,
	LPBYTE	lpbData,
	DWORD	cbData
) {
	LPKEYSTRUCT	lpkey;
	int		i;

	dprintf_reg(stddeb,"RegSetValueEx32W(%x,%s,%ld,%ld,%p,%ld)\n",
		hkey,W2C(lpszValueName,0),dwReserved,dwType,lpbData,cbData
	);
	/* we no longer care about the lpbData type here... */
	lpkey	= lookup_hkey(hkey);
	if (!lpkey)
		return SHELL_ERROR_BADKEY;

	lpkey->flags |= REG_OPTION_TAINTED;

	if (lpszValueName==NULL) {
		for (i=0;i<lpkey->nrofvalues;i++)
			if (lpkey->values[i].name==NULL)
				break;
	} else {
		for (i=0;i<lpkey->nrofvalues;i++)
			if (!strcmpW(lpszValueName,lpkey->values[i].name))
				break;
	}
	if (i==lpkey->nrofvalues) {
		lpkey->values = (LPKEYVALUE)xrealloc(
					lpkey->values,
					(lpkey->nrofvalues+1)*sizeof(KEYVALUE)
				);
		lpkey->nrofvalues++;
		memset(lpkey->values+i,'\0',sizeof(KEYVALUE));
	}
	if (lpkey->values[i].name==NULL)
		if (lpszValueName)
			lpkey->values[i].name = strdupW(lpszValueName);
		else
			lpkey->values[i].name = NULL;
	lpkey->values[i].len	= cbData;
	lpkey->values[i].type	= dwType;
	if (lpkey->values[i].data !=NULL)
		free(lpkey->values[i].data);
	lpkey->values[i].data	= (LPBYTE)xmalloc(cbData);
	lpkey->values[i].lastmodified = time(NULL);
	memcpy(lpkey->values[i].data,lpbData,cbData);
	return SHELL_ERROR_SUCCESS;
}

/* RegSetValueExA		[ADVAPI32.169] */
DWORD RegSetValueEx32A(
	HKEY	hkey,
	LPSTR	lpszValueName,
	DWORD	dwReserved,
	DWORD	dwType,
	LPBYTE	lpbData,
	DWORD	cbData
) {
	LPBYTE	buf;
	LPWSTR	lpszValueNameW;
	DWORD	ret;

	dprintf_reg(stddeb,"RegSetValueEx32A(%x,%s,%ld,%ld,%p,%ld)\n->",
		hkey,lpszValueName,dwReserved,dwType,lpbData,cbData
	);
	if ((1<<dwType) & UNICONVMASK) {
		buf=(LPBYTE)strdupA2W(lpbData);
		cbData=2*strlen(lpbData)+2;
	} else
		buf=lpbData;
	if (lpszValueName)
		lpszValueNameW = strdupA2W(lpszValueName);
	else
		lpszValueNameW = NULL;
	ret=RegSetValueEx32W(hkey,lpszValueNameW,dwReserved,dwType,buf,cbData);
	if (lpszValueNameW)
		free(lpszValueNameW);
	if (buf!=lpbData)
		free(buf);
	return ret;
}

/* RegSetValueEx		[KERNEL.226] */
DWORD RegSetValueEx16(
	HKEY	hkey,
	LPSTR	lpszValueName,
	DWORD	dwReserved,
	DWORD	dwType,
	LPBYTE	lpbData,
	DWORD	cbData
) {
	dprintf_reg(stddeb,"RegSetValueEx16(%x,%s,%ld,%ld,%p,%ld)\n->",
		hkey,lpszValueName,dwReserved,dwType,lpbData,cbData
	);
	return RegSetValueEx32A(hkey,lpszValueName,dwReserved,dwType,lpbData,cbData);
}

/* RegSetValueW			[ADVAPI32.171] */
DWORD RegSetValue32W(
	HKEY	hkey,
	LPCWSTR	lpszSubKey,
	DWORD	dwType,
	LPCWSTR	lpszData,
	DWORD	cbData
) {
	HKEY	xhkey;
	DWORD	ret;

	dprintf_reg(stddeb,"RegSetValue32W(%x,%s,%ld,%s,%ld)\n->",
		hkey,W2C(lpszSubKey,0),dwType,W2C(lpszData,0),cbData
	);
	if (lpszSubKey && *lpszSubKey) {
		ret=RegCreateKey32W(hkey,lpszSubKey,&xhkey);
		if (ret!=ERROR_SUCCESS)
			return ret;
	} else
		xhkey=hkey;
	if (dwType!=REG_SZ) {
		fprintf(stddeb,"RegSetValueX called with dwType=%ld!\n",dwType);
		dwType=REG_SZ;
	}
	if (cbData!=2*strlenW(lpszData)+2) {
		dprintf_reg(stddeb,"RegSetValueX called with len=%ld != strlen(%s)+1=%d!\n",
			cbData,W2C(lpszData,0),2*strlenW(lpszData)+2
		);
		cbData=2*strlenW(lpszData)+2;
	}
	ret=RegSetValueEx32W(xhkey,NULL,0,dwType,(LPBYTE)lpszData,cbData);
	if (hkey!=xhkey)
		RegCloseKey(xhkey);
	return ret;

}
/* RegSetValueA			[ADVAPI32.168] */
DWORD RegSetValue32A(
	HKEY	hkey,
	LPCSTR	lpszSubKey,
	DWORD	dwType,
	LPCSTR	lpszData,
	DWORD	cbData
) {
	DWORD	ret;
	HKEY	xhkey;

	dprintf_reg(stddeb,"RegSetValue32A(%x,%s,%ld,%s,%ld)\n->",
		hkey,lpszSubKey,dwType,lpszData,cbData
	);
	if (lpszSubKey && *lpszSubKey) {
		ret=RegCreateKey16(hkey,lpszSubKey,&xhkey);
		if (ret!=ERROR_SUCCESS)
			return ret;
	} else
		xhkey=hkey;

	if (dwType!=REG_SZ) {
		dprintf_reg(stddeb,"RegSetValueA called with dwType=%ld!\n",dwType);
		dwType=REG_SZ;
	}
	if (cbData!=strlen(lpszData)+1)
		cbData=strlen(lpszData)+1;
	ret=RegSetValueEx32A(xhkey,NULL,0,dwType,(LPBYTE)lpszData,cbData);
	if (xhkey!=hkey)
		RegCloseKey(xhkey);
	return ret;
}

/* RegSetValue			[KERNEL.221] [SHELL.5] */
DWORD RegSetValue16(
	HKEY	hkey,
	LPCSTR	lpszSubKey,
	DWORD	dwType,
	LPCSTR	lpszData,
	DWORD	cbData
) {
	DWORD	ret;
	dprintf_reg(stddeb,"RegSetValue16(%x,%s,%ld,%s,%ld)\n->",
		hkey,lpszSubKey,dwType,lpszData,cbData
	);
	ret=RegSetValue32A(hkey,lpszSubKey,dwType,lpszData,cbData);
	return ret;
}

/* 
 * Key Enumeration
 *
 * Callpath:
 * RegEnumKey16 -> RegEnumKey32A -> RegEnumKeyEx32A \
 *                              RegEnumKey32W   -> RegEnumKeyEx32W
 */

/* RegEnumKeyExW		[ADVAPI32.139] */
DWORD RegEnumKeyEx32W(
	HKEY	hkey,
	DWORD	iSubkey,
	LPWSTR	lpszName,
	LPDWORD	lpcchName,
	LPDWORD	lpdwReserved,
	LPWSTR	lpszClass,
	LPDWORD	lpcchClass,
	FILETIME	*ft
) {
	LPKEYSTRUCT	lpkey,lpxkey;

	dprintf_reg(stddeb,"RegEnumKeyEx32W(%x,%ld,%p,%ld,%p,%p,%p,%p)\n",
		hkey,iSubkey,lpszName,*lpcchName,lpdwReserved,lpszClass,lpcchClass,ft
	);
	lpkey=lookup_hkey(hkey);
	if (!lpkey)
		return SHELL_ERROR_BADKEY;
	if (!lpkey->nextsub)
		return ERROR_NO_MORE_ITEMS;
	lpxkey=lpkey->nextsub;
	while (iSubkey && lpxkey) {
		iSubkey--;
		lpxkey=lpxkey->next;
	}
	if (iSubkey || !lpxkey)
		return ERROR_NO_MORE_ITEMS;
	if (2*strlenW(lpxkey->keyname)+2>*lpcchName)
		return ERROR_MORE_DATA;
	memcpy(lpszName,lpxkey->keyname,strlenW(lpxkey->keyname)*2+2);
	if (lpszClass) {
		/* what should we write into it? */
		*lpszClass		= 0;
		*lpcchClass	= 2;
	}
	return ERROR_SUCCESS;

}

/* RegEnumKeyW			[ADVAPI32.140] */
DWORD RegEnumKey32W(
	HKEY	hkey,
	DWORD	iSubkey,
	LPWSTR	lpszName,
	DWORD	lpcchName
) {
	FILETIME	ft;

	dprintf_reg(stddeb,"RegEnumKey32W(%x,%ld,%p,%ld)\n->",
		hkey,iSubkey,lpszName,lpcchName
	);
	return RegEnumKeyEx32W(hkey,iSubkey,lpszName,&lpcchName,NULL,NULL,NULL,&ft);
}
/* RegEnumKeyExA		[ADVAPI32.138] */
DWORD RegEnumKeyEx32A(
	HKEY	hkey,
	DWORD	iSubkey,
	LPSTR	lpszName,
	LPDWORD	lpcchName,
	LPDWORD	lpdwReserved,
	LPSTR	lpszClass,
	LPDWORD	lpcchClass,
	FILETIME	*ft
) {
	DWORD	ret,lpcchNameW,lpcchClassW;
	LPWSTR	lpszNameW,lpszClassW;


	dprintf_reg(stddeb,"RegEnumKeyEx32A(%x,%ld,%p,%ld,%p,%p,%p,%p)\n->",
		hkey,iSubkey,lpszName,*lpcchName,lpdwReserved,lpszClass,lpcchClass,ft
	);
	if (lpszName) {
		lpszNameW	= (LPWSTR)xmalloc(*lpcchName*2);
		lpcchNameW	= *lpcchName*2;
	} else {
		lpszNameW	= NULL;
		lpcchNameW 	= 0;
	}
	if (lpszClass) {
		lpszClassW		= (LPWSTR)xmalloc(*lpcchClass*2);
		lpcchClassW	= *lpcchClass*2;
	} else {
		lpszClassW	=0;
		lpcchClassW=0;
	}
	ret=RegEnumKeyEx32W(
		hkey,
		iSubkey,
		lpszNameW,
		&lpcchNameW,
		lpdwReserved,
		lpszClassW,
		&lpcchClassW,
		ft
	);
	if (ret==ERROR_SUCCESS) {
		strcpyWA(lpszName,lpszNameW);
		*lpcchName=strlen(lpszName);
		if (lpszClassW) {
			strcpyWA(lpszClass,lpszClassW);
			*lpcchClass=strlen(lpszClass);
		}
	}
	if (lpszNameW)
		free(lpszNameW);
	if (lpszClassW)
		free(lpszClassW);
	return ret;
}

/* RegEnumKeyA			[ADVAPI32.137] */
DWORD RegEnumKey32A(
	HKEY	hkey,
	DWORD	iSubkey,
	LPSTR	lpszName,
	DWORD	lpcchName
) {
	FILETIME	ft;

	dprintf_reg(stddeb,"RegEnumKey32A(%x,%ld,%p,%ld)\n->",
		hkey,iSubkey,lpszName,lpcchName
	);
	return	RegEnumKeyEx32A(
		hkey,
		iSubkey,
		lpszName,
		&lpcchName,
		NULL,
		NULL,
		NULL,
		&ft
	);
}

/* RegEnumKey			[SHELL.7] [KERNEL.216] */
DWORD RegEnumKey16(
	HKEY	hkey,
	DWORD	iSubkey,
	LPSTR	lpszName,
	DWORD	lpcchName
) {
	dprintf_reg(stddeb,"RegEnumKey16(%x,%ld,%p,%ld)\n->",
		hkey,iSubkey,lpszName,lpcchName
	);
	return RegEnumKey32A(hkey,iSubkey,lpszName,lpcchName);
}

/* 
 * Enumerate Registry Values
 *
 * Callpath:
 * RegEnumValue16 -> RegEnumValue32A -> RegEnumValue32W
 */

/* RegEnumValueW		[ADVAPI32.142] */
DWORD RegEnumValue32W(
	HKEY	hkey,
	DWORD	iValue,
	LPWSTR	lpszValue,
	LPDWORD	lpcchValue,
	LPDWORD	lpdReserved,
	LPDWORD	lpdwType,
	LPBYTE	lpbData,
	LPDWORD	lpcbData
) {
	LPKEYSTRUCT	lpkey;
	LPKEYVALUE	val;

	dprintf_reg(stddeb,"RegEnumValue32W(%x,%ld,%p,%p,%p,%p,%p,%p)\n",
		hkey,iValue,lpszValue,lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData
	);
	lpkey = lookup_hkey(hkey);
	if (!lpkey)
		return SHELL_ERROR_BADKEY;
	if (lpkey->nrofvalues<=iValue)
		return ERROR_NO_MORE_ITEMS;
	val	= lpkey->values+iValue;

	if (val->name) {
		if (strlenW(val->name)*2+2>*lpcchValue) {
			*lpcchValue = strlenW(val->name)*2+2;
			return ERROR_MORE_DATA;
		}
		memcpy(lpszValue,val->name,2*strlenW(val->name)+2);
		*lpcchValue=strlenW(val->name)*2+2;
	} else {
		/* how to handle NULL value? */
		*lpszValue	= 0;
		*lpcchValue	= 2;
	}
	*lpdwType=val->type;
	if (lpbData) {
		if (val->len>*lpcbData)
			return ERROR_MORE_DATA;
		memcpy(lpbData,val->data,val->len);
		*lpcbData = val->len;
	}
	return SHELL_ERROR_SUCCESS;
}

/* RegEnumValueA		[ADVAPI32.141] */
DWORD RegEnumValue32A(
	HKEY	hkey,
	DWORD	iValue,
	LPSTR	lpszValue,
	LPDWORD	lpcchValue,
	LPDWORD	lpdReserved,
	LPDWORD	lpdwType,
	LPBYTE	lpbData,
	LPDWORD	lpcbData
) {
	LPWSTR	lpszValueW;
	LPBYTE	lpbDataW;
	DWORD	ret,lpcbDataW;

	dprintf_reg(stddeb,"RegEnumValue32A(%x,%ld,%p,%p,%p,%p,%p,%p)\n",
		hkey,iValue,lpszValue,lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData
	);

	lpszValueW = (LPWSTR)xmalloc(*lpcchValue*2);
	if (lpbData) {
		lpbDataW = (LPBYTE)xmalloc(*lpcbData*2);
		lpcbDataW = *lpcbData*2;
	} else
		lpbDataW = NULL;
	ret=RegEnumValue32W(
		hkey,
		iValue,
		lpszValueW,
		lpcchValue,
		lpdReserved,
		lpdwType,
		lpbDataW,
		&lpcbDataW
	);

	if (ret==ERROR_SUCCESS) {
		strcpyWA(lpszValue,lpszValueW);
		if (lpbData) {
			if ((1<<*lpdwType) & UNICONVMASK) {
				strcpyWA(lpbData,(LPWSTR)lpbDataW);
			} else {
				if (lpcbDataW > *lpcbData)
					ret	= ERROR_MORE_DATA;
				else
					memcpy(lpbData,lpbDataW,lpcbDataW);
			}
			*lpcbData = lpcbDataW;
		}
	}
	if (lpbDataW)
		free(lpbDataW);
	if (lpszValueW)
		free(lpszValueW);
	return ret;
}

/* RegEnumValue			[KERNEL.223] */
DWORD RegEnumValue16(
	HKEY	hkey,
	DWORD	iValue,
	LPSTR	lpszValue,
	LPDWORD	lpcchValue,
	LPDWORD	lpdReserved,
	LPDWORD	lpdwType,
	LPBYTE	lpbData,
	LPDWORD	lpcbData
) {
	dprintf_reg(stddeb,"RegEnumValue(%x,%ld,%p,%p,%p,%p,%p,%p)\n",
		hkey,iValue,lpszValue,lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData
	);
	return RegEnumValue32A(
		hkey,
		iValue,
		lpszValue,
		lpcchValue,
		lpdReserved,
		lpdwType,
		lpbData,
		lpcbData
	);
}

/* 
 *  Close registry key
 */
/* RegCloseKey			[SHELL.3] [KERNEL.220] [ADVAPI32.126] */
DWORD RegCloseKey(HKEY hkey) {
	dprintf_reg(stddeb,"RegCloseKey(%x)\n",hkey);
	remove_handle(hkey);
	return ERROR_SUCCESS;
}
/* 
 * Delete registry key
 *
 * Callpath:
 * RegDeleteKey16 -> RegDeleteKey32A -> RegDeleteKey32W
 */
/* RegDeleteKeyW		[ADVAPI32.134] */
DWORD RegDeleteKey32W(HKEY hkey,LPWSTR lpszSubKey) {
	LPKEYSTRUCT	*lplpPrevKey,lpNextKey,lpxkey;
	LPWSTR		*wps;
	int		wpc,i;

	dprintf_reg(stddeb,"RegDeleteKey32W(%x,%s)\n",
		hkey,W2C(lpszSubKey,0)
	);
	lpNextKey	= lookup_hkey(hkey);
	if (!lpNextKey)
		return SHELL_ERROR_BADKEY;
	/* we need to know the previous key in the hier. */
	if (!lpszSubKey || !*lpszSubKey)
		return SHELL_ERROR_BADKEY;
	split_keypath(lpszSubKey,&wps,&wpc);
	i 	= 0;
	lpxkey	= lpNextKey;
	while (i<wpc-1) {
		lpxkey=lpNextKey->nextsub;
		while (lpxkey) {
			if (!strcmpW(wps[i],lpxkey->keyname))
				break;
			lpxkey=lpxkey->next;
		}
		if (!lpxkey) {
			FREE_KEY_PATH;
			/* not found is success */
			return SHELL_ERROR_SUCCESS;
		}
		i++;
		lpNextKey	= lpxkey;
	}
	lpxkey	= lpNextKey->nextsub;
	lplpPrevKey = &(lpNextKey->nextsub);
	while (lpxkey) {
		if (!strcmpW(wps[i],lpxkey->keyname))
			break;
		lplpPrevKey	= &(lpxkey->next);
		lpxkey		= lpxkey->next;
	}
	if (!lpxkey)
		return SHELL_ERROR_SUCCESS;
	if (lpxkey->nextsub)
		return SHELL_ERROR_CANTWRITE;
	*lplpPrevKey	= lpxkey->next;
	free(lpxkey->keyname);
	if (lpxkey->class)
		free(lpxkey->class);
	if (lpxkey->values)
		free(lpxkey->values);
	free(lpxkey);
	FREE_KEY_PATH;
	return	SHELL_ERROR_SUCCESS;
}

/* RegDeleteKeyA		[ADVAPI32.133] */
DWORD RegDeleteKey32A(HKEY hkey,LPCSTR lpszSubKey) {
	LPWSTR	lpszSubKeyW;
	DWORD	ret;

	dprintf_reg(stddeb,"RegDeleteKey32A(%x,%s)\n",
		hkey,lpszSubKey
	);
	lpszSubKeyW=strdupA2W(lpszSubKey);
	ret=RegDeleteKey32W(hkey,lpszSubKeyW);
	free(lpszSubKeyW);
	return ret;
}

/* RegDeleteKey			[SHELL.4] [KERNEL.219] */
DWORD RegDeleteKey16(HKEY hkey,LPCSTR lpszSubKey) {
	dprintf_reg(stddeb,"RegDeleteKey16(%x,%s)\n",
		hkey,lpszSubKey
	);
	return RegDeleteKey32A(hkey,lpszSubKey);
}

/* 
 * Delete registry value
 *
 * Callpath:
 * RegDeleteValue16 -> RegDeleteValue32A -> RegDeleteValue32W
 */
/* RegDeleteValueW		[ADVAPI32.136] */
DWORD RegDeleteValue32W(HKEY hkey,LPWSTR lpszValue) {
	DWORD		i;
	LPKEYSTRUCT	lpkey;
	LPKEYVALUE	val;

	dprintf_reg(stddeb,"RegDeleteValue32W(%x,%s)\n",
		hkey,W2C(lpszValue,0)
	);
	lpkey=lookup_hkey(hkey);
	if (!lpkey)
		return SHELL_ERROR_BADKEY;
	if (lpszValue) {
		for (i=0;i<lpkey->nrofvalues;i++)
			if (!strcmpW(lpkey->values[i].name,lpszValue))
				break;
	} else {
		for (i=0;i<lpkey->nrofvalues;i++)
			if (lpkey->values[i].name==NULL)
				break;
	}
	if (i==lpkey->nrofvalues)
		return SHELL_ERROR_BADKEY;/*FIXME: correct errorcode? */
	val	= lpkey->values+i;
	if (val->name) free(val->name);
	if (val->data) free(val->data);
	memcpy(	
		lpkey->values+i,
		lpkey->values+i+1,
		sizeof(KEYVALUE)*(lpkey->nrofvalues-i-1)
	);
	lpkey->values	= (LPKEYVALUE)xrealloc(
				lpkey->values,
				(lpkey->nrofvalues-1)*sizeof(KEYVALUE)
			);
	lpkey->nrofvalues--;
	return SHELL_ERROR_SUCCESS;
}

/* RegDeleteValueA		[ADVAPI32.135] */
DWORD RegDeleteValue32A(HKEY hkey,LPSTR lpszValue) {
	LPWSTR	lpszValueW;
	DWORD	ret;

	dprintf_reg( stddeb, "RegDeleteValue32A(%x,%s)\n", hkey,lpszValue );
	if (lpszValue)
		lpszValueW=strdupA2W(lpszValue);
	else
		lpszValueW=NULL;
	ret=RegDeleteValue32W(hkey,lpszValueW);
	if (lpszValueW)
		free(lpszValueW);
	return ret;
}

/* RegDeleteValue		[KERNEL.222] */
DWORD RegDeleteValue16(HKEY hkey,LPSTR lpszValue) {
	dprintf_reg( stddeb,"RegDeleteValue16(%x,%s)\n", hkey,lpszValue );
	return RegDeleteValue32A(hkey,lpszValue);
}

/* RegFlushKey			[ADVAPI32.143] [KERNEL.227] */
DWORD RegFlushKey(HKEY hkey) {
	dprintf_reg(stddeb,"RegFlushKey(%x), STUB.\n",hkey);
	return SHELL_ERROR_SUCCESS;
}

/* FIXME: lpcchXXXX ... is this counting in WCHARS or in BYTEs ?? */

/* RegQueryInfoKeyW		[ADVAPI32.153] */
DWORD RegQueryInfoKey32W(
	HKEY	hkey,
	LPWSTR	lpszClass,
	LPDWORD	lpcchClass,
	LPDWORD	lpdwReserved,
	LPDWORD	lpcSubKeys,
	LPDWORD	lpcchMaxSubkey,
	LPDWORD	lpcchMaxClass,
	LPDWORD	lpcValues,
	LPDWORD	lpcchMaxValueName,
	LPDWORD	lpccbMaxValueData,
	LPDWORD	lpcbSecurityDescriptor,
	FILETIME	*ft
) {
	LPKEYSTRUCT	lpkey,lpxkey;
	int		nrofkeys,maxsubkey,maxclass,maxvalues,maxvname,maxvdata;
	int		i;

	dprintf_reg(stddeb,"RegQueryInfoKey32W(%x,......)\n",hkey);
	lpkey=lookup_hkey(hkey);
	if (!lpkey)
		return SHELL_ERROR_BADKEY;
	if (lpszClass) {
		if (lpkey->class) {
			if (strlenW(lpkey->class)*2+2>*lpcchClass) {
				*lpcchClass=strlenW(lpkey->class)*2;
				return ERROR_MORE_DATA;
			}
			*lpcchClass=strlenW(lpkey->class)*2;
			memcpy(lpszClass,lpkey->class,strlenW(lpkey->class));
		} else {
			*lpszClass	= 0;
			*lpcchClass	= 0;
		}
	} else {
		if (lpcchClass)
			*lpcchClass	= strlenW(lpkey->class)*2;
	}
	lpxkey=lpkey->nextsub;
	nrofkeys=maxsubkey=maxclass=maxvalues=maxvname=maxvdata=0;
	while (lpxkey) {
		nrofkeys++;
		if (strlenW(lpxkey->keyname)>maxsubkey)
			maxsubkey=strlenW(lpxkey->keyname);
		if (lpxkey->class && strlenW(lpxkey->class)>maxclass)
			maxclass=strlenW(lpxkey->class);
		if (lpxkey->nrofvalues>maxvalues)
			maxvalues=lpxkey->nrofvalues;
		for (i=0;i<lpxkey->nrofvalues;i++) {
			LPKEYVALUE	val=lpxkey->values+i;

			if (val->name && strlenW(val->name)>maxvname)
				maxvname=strlenW(val->name);
			if (val->len>maxvdata)
				maxvdata=val->len;
		}
		lpxkey=lpxkey->next;
	}
	if (!maxclass) maxclass	= 1;
	if (!maxvname) maxvname	= 1;
	if (lpcSubKeys)
		*lpcSubKeys	= nrofkeys;
	if (lpcchMaxSubkey)
		*lpcchMaxSubkey	= maxsubkey*2;
	if (lpcchMaxClass)
		*lpcchMaxClass	= maxclass*2;
	if (lpcValues)
		*lpcValues	= maxvalues;
	if (lpcchMaxValueName)
		*lpcchMaxValueName= maxvname;
	if (lpccbMaxValueData)
		*lpccbMaxValueData= maxvdata;
	return SHELL_ERROR_SUCCESS;
}

/* RegQueryInfoKeyA		[ADVAPI32.152] */
DWORD RegQueryInfoKey32A(
	HKEY	hkey,
	LPSTR	lpszClass,
	LPDWORD	lpcchClass,
	LPDWORD	lpdwReserved,
	LPDWORD	lpcSubKeys,
	LPDWORD	lpcchMaxSubkey,
	LPDWORD	lpcchMaxClass,
	LPDWORD	lpcValues,
	LPDWORD	lpcchMaxValueName,
	LPDWORD	lpccbMaxValueData,
	LPDWORD	lpcbSecurityDescriptor,
	FILETIME	*ft
) {
	LPWSTR		lpszClassW;
	DWORD		ret;

	dprintf_reg(stddeb,"RegQueryInfoKey32A(%x,......)\n",hkey);
	if (lpszClass) {
		*lpcchClass*= 2;
		lpszClassW  = (LPWSTR)xmalloc(*lpcchClass);

	} else
		lpszClassW  = NULL;
	ret=RegQueryInfoKey32W(
		hkey,
		lpszClassW,
		lpcchClass,
		lpdwReserved,
		lpcSubKeys,
		lpcchMaxSubkey,
		lpcchMaxClass,
		lpcValues,
		lpcchMaxValueName,
		lpccbMaxValueData,
		lpcbSecurityDescriptor,
		ft
	);
	if (ret==ERROR_SUCCESS)
		strcpyWA(lpszClass,lpszClassW);
	if (lpcchClass)
		*lpcchClass/=2;
	if (lpcchMaxSubkey)
		*lpcchMaxSubkey/=2;
	if (lpcchMaxClass)
		*lpcchMaxClass/=2;
	if (lpcchMaxValueName)
		*lpcchMaxValueName/=2;
	if (lpszClassW)
		free(lpszClassW);
	return ret;
}
