Release 980614

Sun Jun 15 10:30:35 1998  Andreas Mohr <100.30936@germany.net>

	* [files/dos_fs.c] [files/file.c] [if1632/wprocs.spec]
	  [misc/aspi.c]
	Added support for scanners that need Adaptec's ASPI2DOS.

	* [graphics/env.c] [misc/printerdrv.c] [graphics/win16drv/init.c]
	  [if1632/gdi.spec] [include/gdi.h]
	Enhanced printer support (especially Win95):
	Drv[GS]etPrinterData, [GS]etEnvironment; added AbortProc handling.

	* [misc/tapi32.c] [relay32/tapi32.spec]
	Added some stubs.

	* [configure.in] [graphics/fontengine.c] [include/windows.h]
	  [misc/comm.c] [misc/w32skrnl.c] [misc/win32s16.c]
	Made Wine compile on HP-UX (just for fun ;)

	* [controls/menu.c] [include/windows.h]
	Complete rewrite of EnableMenuItem32.
	Free Agent 32 still doesn't work :(

	* [misc/version.c] [if1632/kernel.spec] [include/winbase.h]
	Implemented GetVersionEx16.

	* [misc/network.c] [if1632/user.spec]
	Fixed arguments of WNetGetPropertyText.

	* [misc/version.c] [relay32/comctl32.spec] [relay32/oleaut32.spec]
	Implemented COMCTL32_DllGetVersion, OaBuildVersion.

	* [win32/file.c]
	Fixed UNC handling of CreateFile32.

Sat Jun 13 22:35:12 1998  Douglas Ridgway  <ridgway@winehq.com>

	* [Makefile.in] [Make.rules.in]
	Added pattern for CVS merge files to 'make clean'

	* [ole/olecli.c] [windows/scroll.c] [windows/grahics.c]
	Add some DC handle unlocking. (When hdc's are always unlocked,
	they can be made moveable.)

	* [documentation/wine.texinfo] 
	Started a Wine Design chapter with discussion of 
	graphics driver model.

Sat Jun 13 11:19:25 1998  David Luyer <luyer@ucs.uwa.edu.au>

	* [misc/main.c] [relay32/relay386.c]
	Added new option -debugmsg +relay=.... or -debugmsg -relay=...

Fri Jun 12 22:56:09 1998  Marcus Meissner <marcus@jet.franken.de>

	* [relay32/snoop.c][relay32/builtin.c][loader/pe_image.c]
	Added inter win32 dll snooping. Use -debugmsg +snoop.
	Number of arguments and string references are autodetected.
	Some small bugfixes in the PE loader.

	* [misc/system.c]
	Disabled SystemTimers. They do not work with the current
	%fs handling in the 32->16 relaycode. (helps labview)

	* [msdos/dpmi.c][msdos/int2f.c][files/drive.c]
	Added a monoton linear increasing memory allocator for DPMI (required
	for LabView, HAFAS, ...)
	mscdex handling in emulated realmode interrupts (for mcicda.drv)
	allocate logical drives only once. (helps Myst)

	* [files/profile.c]
	Handle ^Z as space. Found on CDROMS (helps Myst Installer).

	* [multimedia/mmio.c]
	mmio* partially updated to win32. No funny additions.

	* [windows/driver.c]
	Added win32 driver handling (will be used for win32 multimedia/
	msvideo drivers).

	* [win32/device.c]
	Added device handling (K32OBJ_DEVICE_IOCTL). Implemented 
	VTDAPI.5 (used by win95' WINMM.timeGetTime())

Fri Jun 12 18:01:18 1998 Rein Klazes <rklazes@casema.net>

	* [ole/compobj.c relay32/ole32.spec]
	Add a stub for CoLockObjectExternal32.

	* [objects/clipping.c]
	Fix in IntersectClipRect(), when there is no initial clipping
	region.

	* [graphics/x11drv/graphics.c]
	Corrected several "one-off" errors for the Ellipse, Rectangle
	and RoundRectangle (especially small ones) draw routines. 
	Arc and friends still have to be done.

Fri Jun 12 06:23:19 1998  Matthew Becker <mbecker@glasscity.net>

	* [misc/ntdll.c]
	Fixed some of the parameter counts.

	* [misc/registry.c]
	General cleanup, documentation.
	Standard keys are allowed to be 'closed' and succeed.

	* [misc/shell.c]
	Check for correct return values from Reg* functions.

	* [win32/newfns.c]
	Added stubs for OpenDesktopA, SetThreadDesktop, and
	SetUserObjectInformationA.

Wed Jun 10  20:28:08 1998  James Juran  <jrj120@psu.edu>

	* [debugger/break.c]
	Fixed bug introduced in 980503 that broke the -debug command 
	line option for PE executable files.

	* [configure.in] [include/acconfig.h] [include/debugtools.h]
	  [documentation/debug-msgs]
	Added 'configure' options to compile out debugging messages.
	Use --disable-debug to disable all debugging messages, and
	--disable-trace to just disable TRACE messages.  This results
	in a stripped executable that is 15-20% smaller.  This option
	is very much untested--don't expect it to work.

	* [documentation/debug-msgs] [documentation/debugging]
	Minor updates.

	* [*/*.c]
	Fixed some compile warnings.  This also includes the
	compile_warnings_trivial patch from WineHQ.

Tue Jun 10 22:00:18 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [windows/sysmetrics.c][include/sysmetrics.h]
	Fixed some Win95 values.

	* [windows/nonclient.c][include/windows.h]
	Fixed some Win95 drawing bugs.
	Added extended window style flags (WS_EX_xxx).

	* [misc/printdrv.c][relay32/winspool.spec]
	Added stubs for DeletePrinterDriver32A, DeleteMonitor32A
	and DeletePort32A.

	* [windows/mdi.c][include/windows.h][relay32/user32.spec]
	Added stubs for CascadeWindows and TileWindows.

	* [controls/toolbar.c][include/toolbar.h]
	Fixed a few bugs and implemented new features.

	* [misc/shellord.c][relay32/shell32.spec]
	Added stubs for SHELL32_60, SHELL32_61 and SHELL32_184.

	* [controls/comctl32undoc.c][relay32/comctl32.spec]
	New file comctl32undoc.c. Contains undocumented functions
	of COMCTL32.DLL. These functions are needed to run EXPLORER.EXE
	IEXPLORE.EXE and TASKMAN.EXE.

	* [controls/status.c]
	Added text alignment.

Tue Jun  8 22:00:00 1998  Bertho Stultiens <bertho@akhphd.au.dk>

	* [programs/*/Makefile.in]
	Changed the rules to use wrc as resource compiler but
	passing the source through gcc first for macro expansion.

	* [programs/*/*.rc]
	Added #include "windows.h" for the resource compiler in the
	appropriate files.

	* [tools/wrc/wrc.[ch]] [tools/wrc/writeres.c]
	Added commandline option -A for autoregister code.
	Corrected the underscore problem by checking the proper define
	from config.h.

Sun Jun  7 22:09:29 1998  Pascal Cuoq <pcuoq@ens-lyon.fr>

	* [ole/ole2nls.c] [memory/string.c]
	Improved LCMapString32A, and changed CompareString32A,
	lstrcmp, lstrcmpi to use it.

Sat Jun  6 19:00:50 1998  Martin Strömberg <ams@ludd.luth.se>

	* [include/winnt.h]
	Added typedefs for security and tokens.

Sat Jun  6 12:26:31 1998  Morten Welinder  <terra@diku.dk>

	* [objects/text.c]
	Use debugstr_an in DrawText16.

	* [loader/resource.c]
	Use debugres_w in FindResourceEx32W.  Avoid crashing during
	debug when wm is NULL.

	* [if1632/relay.c]
	In RELAY_DebugCallTo16, send output to the right place and
	avoid side effects in macro arguments.

Wed Jun  3 20:56:03 1998  Huw D M Davies <daviesh@abacus.physics.ox.ac.uk>

	* [controls/scroll.c] [windows/nonclient.c]
	Fix several off by one errors in scrollbar painting.

Tue Jun  2 23:58:59 1998  Insomnia (Stea Greene) <insomnia@core.binghamton.edu>

	* [graphics/dsound.c]
	Rewrote mixer code to handle panning and volume for 16->16, 16->8,
	8->16, and 8->8 bit mixes.  Conforms to DirectX's "logarithmic
	hearing scale" as specified in M$VC docs.  Still does not handle
	mixing of different frequencies (I am still working on that). 
	Tested 16->16 extensively with StarCraft.  Other mixing combinations
	untested but should work fine.  Still kind of a work in progress,
	so be warned.

Tue Jun  2 03:31:33 1998  Alexander V. Lukyanov <lav@long.yar.ru>

	* [tools/wrc/utils.c]
	dup_basename: fix to strip directory.

Mon Jun  1 20:00:00 1998  Juergen Schmied <juergen.schmied@metronet.de>

	* [include/windows.h] [objects/cursoricon.c] [relay32/user32.spec]
	Added stubs LoadCursorFromFileW and LoadCursorFromFileA.
diff --git a/misc/Makefile.in b/misc/Makefile.in
index ee7f5c5..420d9e2 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -30,6 +30,7 @@
 	spy.c \
 	stress.c \
 	system.c \
+	tapi32.c \
 	toolhelp.c \
 	tweak.c \
 	ver.c \
diff --git a/misc/aspi.c b/misc/aspi.c
index 51e11b0..aad7f05 100644
--- a/misc/aspi.c
+++ b/misc/aspi.c
@@ -12,6 +12,9 @@
 #include "options.h"
 #include "heap.h"
 #include "debug.h"
+#include "selectors.h"
+#include "module.h"
+#include "miscemu.h"
 
 
 /* FIXME!
@@ -95,6 +98,8 @@
 typedef struct ASPI_DEVICE_INFO ASPI_DEVICE_INFO;
 static ASPI_DEVICE_INFO *ASPI_open_devices = NULL;
 
+static BOOL16 DOSASPI = FALSE;
+
 #ifdef linux
 static int
 ASPI_OpenDevice16(SRB_ExecSCSICmd16 *prb)
@@ -157,7 +162,10 @@
   BYTE *lpBuf;
   dbg_decl_str(aspi, 512);
 
-  lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+  if ((DOSASPI) && (prb->SRB_BufPointer)) /* translate real mode address */
+    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+  else
+    lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
 
   switch (prb->CDBByte[0]) {
   case CMD_INQUIRY:
@@ -229,7 +237,10 @@
 {
   BYTE *lpBuf;
 
-  lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+  if ((DOSASPI) && (prb->SRB_BufPointer)) /* translate real mode address */
+    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+  else
+    lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
 
   switch (prb->CDBByte[0]) {
   case CMD_INQUIRY:
@@ -255,6 +266,7 @@
 
   fd = ASPI_OpenDevice16(prb);
   if (fd == -1) {
+      WARN(aspi, "ASPI_ExecScsiCmd16 failed: could not open device.\n");
       prb->SRB_Status = SS_ERR;
       return SS_ERR;
   }
@@ -263,9 +275,13 @@
   sg_reply_hdr = NULL;
 
   prb->SRB_Status = SS_PENDING;
-  lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
+  if ((DOSASPI) && (prb->SRB_BufPointer)) /* translate real mode address */
+    lpBuf = (BYTE *)DOSMEM_MapRealToLinear((UINT32)prb->SRB_BufPointer);
+  else
+    lpBuf = PTR_SEG_TO_LIN(prb->SRB_BufPointer);
 
   if (!prb->SRB_CDBLen) {
+      WARN(aspi, "ASPI_ExecScsiCmd16 failed: prb->SRB_CDBLen = 0.\n");
       prb->SRB_Status = SS_ERR;
       return SS_ERR;
   }
@@ -406,7 +422,14 @@
 
   switch (lpSRB->common.SRB_cmd) {
   case SC_HA_INQUIRY:
-    FIXME(aspi, "Not implemented SC_HA_INQUIRY\n");
+    lpSRB->inquiry.SRB_Status = 0x1;           /* completed successfully */
+    lpSRB->inquiry.SRB_HaId = 1;               /* bogus value */
+    lpSRB->inquiry.HA_Count = 1;               /* not always */
+    lpSRB->inquiry.HA_SCSI_ID = 7;             /* not always ID 7 */
+    strcat(lpSRB->inquiry.HA_ManagerId, "Wine ASPI"); /* max 15 chars */
+    lpSRB->inquiry.SRB_55AASignature = 0x55aa; /* correct ??? */
+    lpSRB->inquiry.SRB_ExtBufferSize = 0x2000; /* bogus value */
+    FIXME(aspi, "ASPI: Partially implemented SC_HA_INQUIRY\n");
     break;
   case SC_GET_DEV_TYPE:
     FIXME(aspi, "Not implemented SC_GET_DEV_TYPE\n");
@@ -438,3 +461,39 @@
 	return (DWORD)0;
 #endif
 }
+
+
+void WINAPI ASPI_DOS_func(DWORD srb)
+{
+       LPSRB16 lpSRB = (LPSRB16)DOSMEM_MapRealToLinear(srb);
+       SEGPTR spSRB = MapLS(lpSRB);
+
+       TRACE(aspi, "DOSASPI: function #%d\n", lpSRB->common.SRB_cmd);
+       DOSASPI = TRUE;
+       SendASPICommand16(spSRB);
+       DOSASPI = FALSE;
+       UnMapLS(spSRB);
+}
+
+void ASPI_DOS_HandleInt(CONTEXT *context)
+/* returns a real mode call address to ASPI_DOS_func() */
+{
+#ifdef linux
+       FARPROC16 DOS_func;
+       DWORD dos;
+       LPBYTE dosptr;
+
+       DOS_func = MODULE_GetWndProcEntry16("ASPI_DOS_func");
+       dos = GlobalDOSAlloc(5);
+       dosptr = (BYTE *)PTR_SEG_OFF_TO_LIN(LOWORD(dos), 0);
+       *dosptr++ = 0xea; /* ljmp */
+       *(FARPROC16 *)dosptr = DOS_func;
+
+       *(DWORD *)PTR_SEG_OFF_TO_LIN(DS_reg(context), DX_reg(context))
+               = MAKELONG(0, HIWORD(dos)); /* real mode address */
+       RESET_CFLAG(context);
+       AX_reg(context) = CX_reg(context);
+#else
+       SET_CFLAG(context);
+#endif
+}
diff --git a/misc/comm.c b/misc/comm.c
index fe67f6f..a1f69d3 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -22,6 +22,9 @@
 #include <termios.h>
 #include <fcntl.h>
 #include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
 #include <errno.h>
 #include <ctype.h>
 #include <sys/stat.h>
@@ -33,6 +36,12 @@
 
 #include "windows.h"
 #include "comm.h"
+#ifdef HAVE_SYS_MODEM_H
+# include <sys/modem.h>
+#endif
+#ifdef HAVE_SYS_STRTIO_H
+# include <sys/strtio.h>
+#endif
 #include "heap.h"
 #include "options.h"
 #include "debug.h"
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 1e3cfec..03e57f9 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -3928,3 +3928,11 @@
   SEGPTR_FREE(lpcc16);
   return (BOOL32)ret;
 }
+
+/***********************************************************************
+ *            PageSetupDlgA  (COMDLG32.15)
+ */
+BOOL32 WINAPI PageSetupDlg32A(LPPAGESETUPDLG32A setupdlg) {
+	FIXME(commdlg,"(%p), stub!\n",setupdlg);
+	return FALSE;
+}
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 3d410ea..3b88c3f 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -987,11 +987,18 @@
 /*********************************************************************
  *                  _strdup          (CRTDLL.285)
  */
-LPSTR __cdecl CRTDLL__strdup(LPSTR ptr)
+LPSTR __cdecl CRTDLL__strdup(LPCSTR ptr)
 {
     return HEAP_strdupA(GetProcessHeap(),0,ptr);
 }
 
+/*********************************************************************
+ *                  _wcsdup          (CRTDLL.320)
+ */
+LPWSTR __cdecl CRTDLL__wcsdup(LPCWSTR ptr)
+{
+    return HEAP_strdupW(GetProcessHeap(),0,ptr);
+}
 
 /*********************************************************************
  *                  fclose           (CRTDLL.362)
@@ -1833,3 +1840,27 @@
 	/* FIXME: handle multibyte strings */
 	return strrchr(s,x);
 }
+
+/*********************************************************************
+ *                  _memicmp           (CRTDLL.233)(NTDLL.868)
+ * A stringcompare, without \0 check
+ * RETURNS
+ *	-1:if first string is alphabetically before second string
+ *	1:if second ''    ''      ''          ''   first   ''
+ *      0:if both are equal.
+ */
+INT32 __cdecl CRTDLL__memicmp(
+	LPCSTR s1,	/* [in] first string */
+	LPCSTR s2,	/* [in] second string */
+	DWORD len	/* [in] length to compare */
+) { 
+	int	i;
+
+	for (i=0;i<len;i++) {
+		if (tolower(s1[i])<tolower(s2[i]))
+			return -1;
+		if (tolower(s1[i])>tolower(s2[i]))
+			return  1;
+	}
+	return 0;
+}
diff --git a/misc/lstr.c b/misc/lstr.c
index bffd1e7..043a778 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -178,7 +178,7 @@
     if ((p > buffer) && (p[-1] == '\n')) p[1] = '\0'; /* Remove trailing \n */
     if (!GetModuleName( GetCurrentTask(), module, sizeof(module) ))
         strcpy( module, "???" );
-    TRACE(resource, "%s says '%s'\n", module, buffer );
+    DUMP("%s says '%s'\n", module, buffer );
     HeapFree( GetProcessHeap(), 0, buffer );
 }
 
diff --git a/misc/main.c b/misc/main.c
index 49ef6df..8db0f9d 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -209,6 +209,10 @@
  */
 static BOOL32 MAIN_ParseDebugOptions(char *options)
 {
+  /* defined in relay32/relay386.c */
+  extern char **debug_relay_includelist;
+  extern char **debug_relay_excludelist;
+
   int l, cls;
   if (strlen(options)<3)
     return FALSE;
@@ -243,6 +247,45 @@
 	    if(cls == -1 || cls == j)
 	      debug_msg_enabled[i][j]=(*options=='+');
       }
+    else if (!lstrncmpi32A(options+1, "relay=", 6))
+      {
+	int i, j;
+	char *s, *s2, ***output, c;
+
+	for (i=0; i<DEBUG_CHANNEL_COUNT; i++)
+	  if (debug_ch_name && (!lstrncmpi32A(debug_ch_name[i],"relay",5))){
+	    for(j=0; j<DEBUG_CLASS_COUNT; j++)
+	      if(cls == -1 || cls == j)
+		debug_msg_enabled[i][j]=TRUE;
+	    break;
+	  }
+	/* should never happen, maybe assert(i!=DEBUG_CHANNEL_COUNT)? */
+	if (i==DEBUG_CHANNEL_COUNT)
+	  return FALSE;
+	if (*options == '+')
+	  output = &debug_relay_includelist;
+	else
+	  output = &debug_relay_excludelist;
+	s = options + 7;
+	i = 1;
+	while((s = strchr(s, ':'))) i++, s++;
+	*output = malloc(sizeof(char **) * i + 1);
+	i = 0;
+	s = options + 7;
+	while((s2 = strchr(s, ':'))) {
+          c = *s2;
+          *s2 = '\0';
+	  *((*output)+i) = strdup(s);
+          *s2 = c;
+	  s = s2 + 1;
+	  i++;
+	}
+	c = *(options + l);
+	*(options + l) = '\0';
+	*((*output)+i) = strdup(s);
+	*(options + l) = c;
+	*((*output)+i+1) = NULL;
+      }
     else
       {
 	int i, j;
@@ -758,7 +801,6 @@
 		GetProfileString32A("Desktop", "IconTitleFaceName", "MS Sans Serif", 
 			lpLogFont->lfFaceName, LF_FACESIZE );
 		lpLogFont->lfHeight = -GetProfileInt32A("Desktop","IconTitleSize", 8);
-
 		lpLogFont->lfWidth = 0;
 		lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
 		lpLogFont->lfWeight = FW_NORMAL;
@@ -787,6 +829,7 @@
 
 		    SystemParametersInfo32A(SPI_GETICONTITLELOGFONT, 0,
 							(LPVOID)&(lpnm->lfCaptionFont),0);
+		    lpnm->lfCaptionFont.lfWeight = FW_BOLD;
 		    SystemParametersInfo32A(SPI_GETICONTITLELOGFONT, 0,
 							(LPVOID)&(lpnm->lfMenuFont),0);
 		    SystemParametersInfo32A(SPI_GETICONTITLELOGFONT, 0,
@@ -975,7 +1018,6 @@
 		    GetProfileString32A("Desktop", "IconTitleFaceName", "MS Sans Serif", 
 					lpLogFont->lfFaceName, LF_FACESIZE );
                     lpLogFont->lfHeight = -GetProfileInt32A("Desktop","IconTitleSize", 8);
-
                     lpLogFont->lfWidth = 0;
                     lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
                     lpLogFont->lfWeight = FW_NORMAL;
@@ -996,6 +1038,7 @@
 			/* FIXME: initialize geometry entries */
 			SystemParametersInfo16( SPI_GETICONTITLELOGFONT, 0, 
 							(LPVOID)&(lpnm->lfCaptionFont),0);
+			lpnm->lfCaptionFont.lfWeight = FW_BOLD;
 			SystemParametersInfo16( SPI_GETICONTITLELOGFONT, 0,
 							(LPVOID)&(lpnm->lfMenuFont),0);
 			SystemParametersInfo16( SPI_GETICONTITLELOGFONT, 0,
@@ -1085,6 +1128,7 @@
 	LPNONCLIENTMETRICS32W	lpnm=(LPNONCLIENTMETRICS32W)lpvParam;
 
 	SystemParametersInfo32W(SPI_GETICONTITLELOGFONT,0,(LPVOID)&(lpnm->lfCaptionFont),0);
+	lpnm->lfCaptionFont.lfWeight = FW_BOLD;
 	SystemParametersInfo32W(SPI_GETICONTITLELOGFONT,0,(LPVOID)&(lpnm->lfMenuFont),0);
 	SystemParametersInfo32W(SPI_GETICONTITLELOGFONT,0,(LPVOID)&(lpnm->lfStatusFont),0);
 	SystemParametersInfo32W(SPI_GETICONTITLELOGFONT,0,(LPVOID)&(lpnm->lfMessageFont),0);
diff --git a/misc/network.c b/misc/network.c
index 7936383..a0eedad 100644
--- a/misc/network.c
+++ b/misc/network.c
@@ -281,6 +281,22 @@
 	return ret;
 }
 
+/**************************************************************************
+ *				WNetGetConnectionW	[MPR.72]
+ */
+DWORD WINAPI
+WNetGetConnection32W(LPCWSTR localnameW,LPSTR remotenameW,LPDWORD buflen)
+{
+	UINT16	x;
+	CHAR	buf[200];	
+	LPSTR	lnA = HEAP_strdupWtoA(GetProcessHeap(),0,localnameW);
+	DWORD	ret = WNetGetConnection16(lnA,buf,&x);
+
+	*buflen = x; /* FIXME: *2 ? */
+	lstrcpyAtoW(remotenameW,buf);
+	HeapFree(GetProcessHeap(),0,lnA);
+	return ret;
+}
 
 /**************************************************************************
  *				WNetGetCaps		[USER.513]
@@ -508,11 +524,11 @@
 /**************************************************************************
  *              WNetGetPropertyText       [USER.532]
  */
-int WINAPI WNetGetPropertyText(HWND16 hwndParent,WORD iButton,WORD nPropSel,
-                               LPSTR lpszName,WORD nType)
+int WINAPI WNetGetPropertyText(WORD iButton, WORD nPropSel, LPSTR lpszName,
+                          LPSTR lpszButtonName, WORD cbButtonName, WORD nType)
 {
-	FIXME(wnet, "(%04x,%x,%x,'%s',%x): stub\n",
-	      hwndParent,iButton,nPropSel,lpszName,nType);
+	FIXME(wnet, "(%04x,%04x,'%s','%s',%04x): stub\n",
+	      iButton,nPropSel,lpszName,lpszButtonName, nType);
 	return WN_NO_NETWORK;
 }
 
diff --git a/misc/ntdll.c b/misc/ntdll.c
index 21efb50..d265d92 100644
--- a/misc/ntdll.c
+++ b/misc/ntdll.c
@@ -332,7 +332,7 @@
 }
 
 /**************************************************************************
- *                 RtlInitString			[NTDLL]
+ *                 RtlInitAnsiString			[NTDLL]
  */
 VOID WINAPI RtlInitAnsiString(LPANSI_STRING target,LPCSTR source)
 {
@@ -429,7 +429,7 @@
  */
 DWORD WINAPI RtlNtStatusToDosError(DWORD error)
 {
-    FIXME(ntdll, "(%x): map STATUS_ to ERROR_\n",error);
+    FIXME(ntdll, "(%lx): map STATUS_ to ERROR_\n",error);
     return error;
 }
 
@@ -556,6 +556,9 @@
 
 /**************************************************************************
  *                 NTDLL_chkstk   (NTDLL.862)
+ *
+ * NOTES
+ *    Should this be WINAPI?
  */
 void NTDLL_chkstk(void)
 {
@@ -574,12 +577,13 @@
 }
 
 
-/**************************************************************************
+/******************************************************************************
  * NtQueryDirectoryObject [NTDLL.149]
  */
-DWORD WINAPI NtQueryDirectoryObject(DWORD x1, DWORD x2)
+DWORD WINAPI NtQueryDirectoryObject( DWORD x1, DWORD x2, DWORD x3, DWORD x4,
+                                     DWORD x5, DWORD x6, DWORD x7 )
 {
-    FIXME(ntdll,"(%lx,%lx): stub\n",x1,x2);
+    FIXME(ntdll,"(%lx,%lx,%lx,%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4,x5,x6,x7);
     return 0;
 }
 
@@ -587,19 +591,19 @@
 /**************************************************************************
  * RtlFreeAnsiString [NTDLL.373]
  */
-DWORD WINAPI RtlFreeAnsiString(DWORD x1)
+VOID WINAPI RtlFreeAnsiString(LPANSI_STRING AnsiString)
 {
-    FIXME(ntdll,"(%lx): stub\n",x1);
-    return 0;
+    if( AnsiString->Buffer )
+        HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
 }
 
 
-/**************************************************************************
+/******************************************************************************
  * NtQuerySystemInformation [NTDLL.168]
  */
-DWORD WINAPI NtQuerySystemInformation( DWORD x1 )
+DWORD WINAPI NtQuerySystemInformation( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
 {
-    FIXME(ntdll,"(%lx): stub\n",x1);
+    FIXME(ntdll,"(%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4);
     return 0;
 }
 
@@ -607,9 +611,9 @@
 /******************************************************************************
  * NtQueryObject [NTDLL.161]
  */
-DWORD WINAPI NtQueryObject( DWORD x1, DWORD x2 )
+DWORD WINAPI NtQueryObject( DWORD x1, DWORD x2 ,DWORD x3, DWORD x4, DWORD x5 )
 {
-    FIXME(ntdll,"(%lx,%lx): stub\n",x1,x2);
+    FIXME(ntdll,"(%lx,%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4,x5);
     return 0;
 }
 
@@ -617,9 +621,9 @@
 /******************************************************************************
  * RtlTimeToElapsedTimeFields [NTDLL.502]
  */
-DWORD WINAPI RtlTimeToElapsedTimeFields( DWORD x1 )
+DWORD WINAPI RtlTimeToElapsedTimeFields( DWORD x1, DWORD x2 )
 {
-    FIXME(ntdll,"(%lx): stub\n",x1);
+    FIXME(ntdll,"(%lx,%lx): stub\n",x1,x2);
     return 0;
 }
 
@@ -627,10 +631,52 @@
 /******************************************************************************
  * NtSetInformationProcess [NTDLL.207]
  */
-DWORD WINAPI NtSetInformationProcess( DWORD x1 )
+DWORD WINAPI NtSetInformationProcess( DWORD x1, DWORD x2, DWORD x3, DWORD x4 )
 {
-    FIXME(ntdll,"(%lx): stub\n",x1);
+    FIXME(ntdll,"(%lx,%lx,%lx,%lx): stub\n",x1,x2,x3,x4);
     return 0;
 }
 
+/******************************************************************************
+ * NtFsControlFile [NTDLL.108]
+ */
+VOID WINAPI NtFsControlFile(VOID)
+{
+    FIXME(ntdll,"(void): stub\n");
+}
 
+/******************************************************************************
+ * RtlExtendedLargeIntegerDivide [NTDLL.359]
+ */
+INT32 WINAPI RtlExtendedLargeIntegerDivide(
+	LARGE_INTEGER dividend,
+	DWORD divisor,
+	LPDWORD rest
+) {
+#if SIZEOF_LONG_LONG==8
+	long long x1 = *(long long*)&dividend;
+
+	if (*rest)
+		*rest = x1 % divisor;
+	return x1/divisor;
+#else
+	FIXME(ntdll,"((%d<<32)+%d,%d,%p), implement this using normal integer arithmetic!\n",dividend.HighPart,dividend.LowPart,divisor,rest);
+	return 0;
+#endif
+}
+
+/******************************************************************************
+ * RtlExtendedLargeIntegerMultiply [NTDLL.359]
+ * Note: This even works, since gcc returns 64bit values in eax/edx just like
+ * the caller expects. However... The relay code won't grok this I think.
+ */
+long long /*LARGE_INTEGER*/ WINAPI RtlExtendedIntegerMultiply(
+	LARGE_INTEGER factor1,INT32 factor2
+) {
+#if SIZEOF_LONG_LONG==8
+	return (*(long long*)&factor1)*factor2;
+#else
+	FIXME(ntdll,"((%d<<32)+%d,%ld), implement this using normal integer arithmetic!\n",factor1.HighPart,factor1.LowPart,factor2);
+	return 0;
+#endif
+}
diff --git a/misc/printdrv.c b/misc/printdrv.c
index 20c2207..37a1748 100644
--- a/misc/printdrv.c
+++ b/misc/printdrv.c
@@ -10,8 +10,17 @@
 #include "windows.h"
 #include "win.h"
 #include "winerror.h"
+#include "winreg.h"
 #include "debug.h"
 
+#define INT_PD_DEFAULT_DEVMODE	1
+#define INT_PD_DEFAULT_MODEL	2
+
+static char PrinterModel[]	= "Printer Model";
+static char DefaultDevMode[]	= "Default DevMode";
+static char PrinterDriverData[] = "PrinterDriverData";
+static char Printers[]		= "System\\CurrentControlSet\\Control\\Print\\Printers\\";
+
 INT16 WINAPI StartDoc16( HDC16 hdc, const DOCINFO16 *lpdoc )
 {
   INT16 retVal;
@@ -32,42 +41,172 @@
   return  Escape16(hdc, ENDDOC, 0, 0, 0);
 }
 
+WORD DrvGetPrinterDataInternal(LPSTR RegStr_Printer, LPBYTE lpPrinterData, int cbData)
+{
+    WORD res = -1;
+    HKEY hkey;
+    DWORD dwType, cbQueryData;
+
+    if (!(RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey))) {
+        if (cbData > 1) { /* "Default DevMode" */
+            if (!(RegQueryValueEx32A(hkey, DefaultDevMode, 0, &dwType, 0, &cbQueryData))) {
+                if (!lpPrinterData) res = cbQueryData;
+		else
+		if ((cbQueryData) && (cbQueryData <= cbData)) {
+		    cbQueryData = cbData;
+		    if (RegQueryValueEx32A(hkey, DefaultDevMode, 0,
+				&dwType, lpPrinterData, &cbQueryData))
+		        res = cbQueryData;
+		}
+            }
+            else /* "Printer Driver" */
+	    {
+		cbQueryData = 32;
+	        RegQueryValueEx32A(hkey, "Printer Driver", 0,
+			&dwType, lpPrinterData, &cbQueryData);
+		res = cbQueryData;
+	    }
+	}
+    }
+    if (hkey) RegCloseKey(hkey);
+    return res;
+}
 
 
 DWORD WINAPI DrvGetPrinterData(LPSTR lpPrinter, LPSTR lpProfile,
                                LPDWORD lpType, LPBYTE lpPrinterData,
                                int cbData, LPDWORD lpNeeded)
 {
-    FIXME(print, "stub.\n");
+    LPSTR RegStr_Printer;
+    HKEY hkey = 0, hkey2 = 0;
+    DWORD res = 0;
+    DWORD dwType, PrinterAttr, cbPrinterAttr, SetData, size;
+
     if (HIWORD(lpPrinter))
-	    TRACE(print,"printer %s\n",lpPrinter);
+            TRACE(print,"printer %s\n",lpPrinter);
     else
-	    TRACE(print,"printer %p\n",lpPrinter);
+            TRACE(print,"printer %p\n",lpPrinter);
     if (HIWORD(lpProfile))
-	    TRACE(print,"profile %s\n",lpProfile);
+            TRACE(print,"profile %s\n",lpProfile);
     else
-	    TRACE(print,"profile %p\n",lpProfile);
+            TRACE(print,"profile %p\n",lpProfile);
     TRACE(print,"lpType %p\n",lpType);
-    return 0;
+
+    if ((!lpPrinter) || (!lpProfile) || (!lpNeeded))
+	return ERROR_INVALID_PARAMETER;
+
+    RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
+                               strlen(Printers) + strlen(lpPrinter) + 2);
+    strcpy(RegStr_Printer, Printers);
+    strcat(RegStr_Printer, lpPrinter);
+
+    if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) ||
+    (!lstrcmp32A(lpProfile, DefaultDevMode))) {
+	size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, cbData);
+	if (size+1) {
+	    *lpNeeded = size;
+	    if ((lpPrinterData) && (*lpNeeded > cbData))
+		res = ERROR_MORE_DATA;
+	}
+	else res = ERROR_INVALID_PRINTER_NAME;
+    }
+    else
+    if (((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) ||
+    (!lstrcmp32A(lpProfile, PrinterModel))) {
+	*lpNeeded = 32;
+	if (!lpPrinterData) goto failed;
+	if (cbData < 32) {
+	    res = ERROR_MORE_DATA;
+	    goto failed;
+	}
+	size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, 1);
+	if ((size+1) && (lpType))
+	    *lpType = REG_SZ;
+	else
+	    res = ERROR_INVALID_PRINTER_NAME;
+    }
+    else
+    {
+	if ((res = RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)))
+	    goto failed;
+        cbPrinterAttr = 4;
+	if ((res = RegQueryValueEx32A(hkey, "Attributes", 0, &dwType, (LPBYTE)&PrinterAttr, &cbPrinterAttr)))
+	    goto failed;
+	if ((res = RegOpenKey32A(hkey, PrinterDriverData, &hkey2)))
+	    goto failed;
+        *lpNeeded = cbData;
+	res = RegQueryValueEx32A(hkey2, lpProfile, 0, lpType, lpPrinterData, lpNeeded);
+	if ((res != ERROR_CANTREAD) && ((PrinterAttr & (0x800|0x10)) == 0x10))
+        {
+	    if (!(res) && (*lpType == REG_DWORD) && (*(LPDWORD)lpPrinterData == -1))
+	        res = ERROR_INVALID_DATA;
+	}
+	else
+        {
+	    SetData = -1;
+	    RegSetValueEx32A(hkey2, lpProfile, 0, REG_DWORD, (LPBYTE)&SetData, 4); /* no result returned */
+	}
+    }
+	
+failed:
+    if (hkey2) RegCloseKey(hkey2);
+    if (hkey) RegCloseKey(hkey);
+    HeapFree(GetProcessHeap(), 0, RegStr_Printer);
+    return res;
 }
 
 
 
 DWORD WINAPI DrvSetPrinterData(LPSTR lpPrinter, LPSTR lpProfile,
-                               LPDWORD lpType, LPBYTE lpPrinterData,
+                               DWORD lpType, LPBYTE lpPrinterData,
                                DWORD dwSize)
 {
-    FIXME(print, "stub.\n");
+    LPSTR RegStr_Printer;
+    HKEY hkey = 0;
+    DWORD res = 0;
+
     if (HIWORD(lpPrinter))
-	    TRACE(print,"printer %s\n",lpPrinter);
+            TRACE(print,"printer %s\n",lpPrinter);
     else
-	    TRACE(print,"printer %p\n",lpPrinter);
+            TRACE(print,"printer %p\n",lpPrinter);
     if (HIWORD(lpProfile))
-	    TRACE(print,"profile %s\n",lpProfile);
+            TRACE(print,"profile %s\n",lpProfile);
     else
-	    TRACE(print,"profile %p\n",lpProfile);
-    TRACE(print,"lpType %p\n",lpType);
-    return 0;
+            TRACE(print,"profile %p\n",lpProfile);
+    TRACE(print,"lpType %08lx\n",lpType);
+
+    if ((!lpPrinter) || (!lpProfile) ||
+    ((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) ||
+    (!lstrcmp32A(lpProfile, PrinterModel)))
+	return ERROR_INVALID_PARAMETER;
+
+    RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
+			strlen(Printers) + strlen(lpPrinter) + 2);
+    strcpy(RegStr_Printer, Printers);
+    strcat(RegStr_Printer, lpPrinter);
+
+    if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) ||
+    (!lstrcmp32A(lpProfile, DefaultDevMode))) {
+	if (!(RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)) ||
+	    (RegSetValueEx32A(hkey, DefaultDevMode, 0, REG_BINARY, lpPrinterData, dwSize)))
+	        res = ERROR_INVALID_PRINTER_NAME;
+    }
+    else
+    {
+	strcat(RegStr_Printer, "\\");
+
+	if (!(res = RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey))) {
+
+	    if (!lpPrinterData) 
+	        res = RegDeleteValue32A(hkey, lpProfile);
+	    else
+                res = RegSetValueEx32A(hkey, lpProfile, 0, lpType, lpPrinterData, dwSize);
+	}
+    }
+
+    if (hkey) RegCloseKey(hkey);
+    HeapFree(GetProcessHeap(), 0, RegStr_Printer);
+    return res;
 }
 
 
@@ -105,9 +244,39 @@
     *lpdwReturned=0;
     return TRUE;
 }
+
+
 BOOL32 WINAPI AddMonitor32A(LPCSTR pName, DWORD Level, LPBYTE pMonitors)
 {
     FIXME(print, "(%s,%lx,%p):stub!\n", pName, Level, pMonitors);
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
+
+
+BOOL32 WINAPI
+DeletePrinterDriver32A (LPSTR pName, LPSTR pEnvironment, LPSTR pDriverName)
+{
+    FIXME(print, "(%s,%s,%s):stub!\n", pName, pEnvironment, pDriverName);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+
+BOOL32 WINAPI
+DeleteMonitor32A (LPSTR pName, LPSTR pEnvironment, LPSTR pMonitorName)
+{
+    FIXME(print, "(%s,%s,%s):stub!\n", pName, pEnvironment, pMonitorName);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+
+BOOL32 WINAPI
+DeletePort32A (LPSTR pName, HWND32 hWnd, LPSTR pPortName)
+{
+    FIXME(print, "(%s,0x%08x,%s):stub!\n", pName, hWnd, pPortName);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
diff --git a/misc/registry.c b/misc/registry.c
index 55307e5..01b7498 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -2,21 +2,19 @@
  * 	Registry Functions
  *
  * Copyright 1996 Marcus Meissner
+ * Copyright 1998 Matthew Becker
  *
  * December 21, 1997 - Kevin Cozens
  * Fixed bugs in the _w95_loadreg() function. Added extra information
  * regarding the format of the Windows '95 registry files.
  *
- * May 5, 1998 - Matthew Becker
- * Changed optionflags to DWORD instead of int because it could be 0x8000000
- * All error return values must come from winerror.h
- *
  * NOTES
  *    When changing this file, please re-run the regtest program to ensure
  *    the conditions are handled properly.
  *
  * TODO
  *    Security access
+ *    Option handling
  */
 
 #include <stdlib.h>
@@ -93,8 +91,18 @@
 #define UNICONVMASK	((1<<REG_SZ)|(1<<REG_MULTI_SZ)|(1<<REG_EXPAND_SZ))
 
 
+static struct openhandle {
+	LPKEYSTRUCT	lpkey;
+	HKEY		hkey;
+	REGSAM		accessmask;
+}  *openhandles=NULL;
+static int	nrofopenhandles=0;
+/* Starts after 1 because 0,1 are reserved for Win16 */
+static int	currenthandle=1;
+
+
 /*
- * FIXME
+ * QUESTION
  *   Are these doing the same as HEAP_strdupAtoW and HEAP_strdupWtoA?
  *   If so, can we remove them?
  * ANSWER
@@ -104,30 +112,59 @@
  */
 static LPWSTR strdupA2W(LPCSTR src)
 {
+    if(src) {
 	LPWSTR dest=xmalloc(2*strlen(src)+2);
 	lstrcpyAtoW(dest,src);
 	return dest;
+    }
+    return NULL;
 }
 
 static LPWSTR strdupW(LPCWSTR a) {
 	LPWSTR	b;
 	int	len;
 
+    if(a) {
 	len=sizeof(WCHAR)*(lstrlen32W(a)+1);
 	b=(LPWSTR)xmalloc(len);
 	memcpy(b,a,len);
 	return b;
+    }
+    return NULL;
+}
+
+LPWSTR strcvtA2W(LPCSTR src, int nchars)
+
+{
+   LPWSTR dest = xmalloc (2 * nchars + 2);
+
+   lstrcpynAtoW(dest,src,nchars+1);
+   dest[nchars] = 0;
+   return dest;
 }
 
 
-static struct openhandle {
-	LPKEYSTRUCT	lpkey;
-	HKEY		hkey;
-	REGSAM		accessmask;
-}  *openhandles=NULL;
-static int	nrofopenhandles=0;
-static int	currenthandle=1;
-
+/******************************************************************************
+ * is_standard_hkey [Internal]
+ * Determines if a hkey is a standard key
+ */
+static BOOL32 is_standard_hkey( HKEY hkey )
+{
+    switch(hkey) {
+        case 0x00000000:
+        case 0x00000001:
+        case HKEY_CLASSES_ROOT:
+        case HKEY_CURRENT_CONFIG:
+        case HKEY_CURRENT_USER:
+        case HKEY_LOCAL_MACHINE:
+        case HKEY_USERS:
+        case HKEY_PERFORMANCE_DATA:
+        case HKEY_DYN_DATA:
+            return TRUE;
+        default:
+            return FALSE;
+    }
+}
 
 /******************************************************************************
  * add_handle [Internal]
@@ -137,9 +174,6 @@
     int i;
 
     TRACE(reg,"(%x,%p,%lx)\n",hkey,lpkey,accessmask);
-    if (lpkey)
-        TRACE(reg," (%s)\n",debugstr_w(lpkey->keyname));
-
     /* Check for duplicates */
     for (i=0;i<nrofopenhandles;i++) {
         if (openhandles[i].lpkey==lpkey) {
@@ -212,7 +246,6 @@
     return ERROR_SUCCESS;
 }
 
-
 /******************************************************************************
  * lookup_hkey [Internal]
  * 
@@ -431,8 +464,12 @@
  * [HKEY_CURRENT_USER\\Software\\The WINE team\\WINE\\Registry]
  * SaveOnlyUpdatedKeys=yes
  */
-static int
-_save_check_tainted(LPKEYSTRUCT lpkey) {
+
+/******************************************************************************
+ * _save_check_tainted [Internal]
+ */
+static int _save_check_tainted( LPKEYSTRUCT lpkey )
+{
 	int		tainted;
 
 	if (!lpkey)
@@ -451,8 +488,11 @@
 	return tainted;
 }
 
-static void
-_save_USTRING(FILE *F,LPWSTR wstr,int escapeeq) {
+/******************************************************************************
+ * _save_USTRING [Internal]
+ */
+static void _save_USTRING( FILE *F, LPWSTR wstr, int escapeeq )
+{
 	LPWSTR	s;
 	int	doescape;
 
@@ -477,8 +517,11 @@
 	}
 }
 
-static int
-_savesubkey(FILE *F,LPKEYSTRUCT lpkey,int level,int all) {
+/******************************************************************************
+ * _savesubkey [Internal]
+ */
+static int _savesubkey( FILE *F, LPKEYSTRUCT lpkey, int level, int all )
+{
 	LPKEYSTRUCT	lpxkey;
 	int		i,tabs,j;
 
@@ -515,15 +558,23 @@
 	return 1;
 }
 
-static int
-_savesubreg(FILE *F,LPKEYSTRUCT lpkey,int all) {
+
+/******************************************************************************
+ * _savesubreg [Internal]
+ */
+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 BOOL32
-_savereg(LPKEYSTRUCT lpkey,char *fn,int all) {
+
+/******************************************************************************
+ * _savereg [Internal]
+ */
+static BOOL32 _savereg( LPKEYSTRUCT lpkey, char *fn, int all )
+{
 	FILE	*F;
 
 	F=fopen(fn,"w");
@@ -617,9 +668,11 @@
 		WARN(reg,"Failed to get homedirectory of UID %d.\n",getuid());
 }
 
+
 /************************ LOAD Registry Function ****************************/
 
 
+
 /******************************************************************************
  * _find_or_add_key [Internal]
  */
@@ -649,11 +702,12 @@
 	return lpxkey;
 }
 
-static void
-_find_or_add_value(
-	LPKEYSTRUCT lpkey,LPWSTR name,DWORD type,LPBYTE data,DWORD len,
-	DWORD lastmodified
-) {
+/******************************************************************************
+ * _find_or_add_value [Internal]
+ */
+static void _find_or_add_value( LPKEYSTRUCT lpkey, LPWSTR name, DWORD type,
+                                LPBYTE data, DWORD len, DWORD lastmodified )
+{
 	LPKEYVALUE	val=NULL;
 	int		i;
 
@@ -698,11 +752,14 @@
 }
 
 
-/* reads a line including dynamically enlarging the readbuffer and throwing
+/******************************************************************************
+ * _wine_read_line [Internal]
+ *
+ * reads a line including dynamically enlarging the readbuffer and throwing
  * away comments
  */
-static int 
-_wine_read_line(FILE *F,char **buf,int *len) {
+static int _wine_read_line( FILE *F, char **buf, int *len )
+{
 	char	*s,*curread;
 	int	mylen,curoff;
 
@@ -740,11 +797,15 @@
 	return 1;
 }
 
-/* converts a char* into a UNICODE string (up to a special char)
+
+/******************************************************************************
+ * _wine_read_USTRING [Internal]
+ *
+ * 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) {
+static char* _wine_read_USTRING( char *buf, LPWSTR *str )
+{
 	char	*s;
 	LPWSTR	ws;
 
@@ -1114,16 +1175,6 @@
   int  lastmodified;
 };
 
-LPWSTR strcvtA2W(LPCSTR src, int nchars)
-
-{
-   LPWSTR dest = xmalloc (2 * nchars + 2);
-
-   lstrcpynAtoW(dest,src,nchars+1);
-   dest[nchars] = 0;
-   return dest;
-}
-
 
 /******************************************************************************
  * _w95_processKey [Internal]
@@ -1239,8 +1290,11 @@
 	return (lpxkey);
 }
 
-static void
-_w95_walkrgkn(LPKEYSTRUCT prevkey, char *off, struct _w95_info *info)
+/******************************************************************************
+ * _w95_walkrgkn [Internal]
+ */
+static void _w95_walkrgkn( LPKEYSTRUCT prevkey, char *off, 
+                           struct _w95_info *info )
 
 {
   /* Disk Key Entry structure (RGKN part) */
@@ -1286,8 +1340,12 @@
   return;
 }
 
-static void
-_w95_loadreg(char* fn,LPKEYSTRUCT lpkey) {
+
+/******************************************************************************
+ * _w95_loadreg [Internal]
+ */
+static void _w95_loadreg( char* fn, LPKEYSTRUCT lpkey )
+{
 	HFILE32		hfd;
 	char		magic[5];
 	unsigned long	where,version,rgdbsection,end;
@@ -1644,8 +1702,6 @@
  * All functions are stubs to RegOpenKeyEx32W where all the
  * magic happens. 
  *
- * FIXME: security,options,desiredaccess,...
- *
  * Callpath:
  * RegOpenKey16 -> RegOpenKey32A -> RegOpenKeyEx32A \
  *                                  RegOpenKey32W   -> RegOpenKeyEx32W 
@@ -1679,11 +1735,9 @@
     TRACE(reg,"(%x,%s,%ld,%lx,%p)\n", hkey,debugstr_w(lpszSubKey),dwReserved,
           samDesired,retkey);
 
-    lpNextKey = lookup_hkey(hkey);
-    if (!lpNextKey) {
-        WARN(reg,"Invalid handle: %x\n",hkey);
+    lpNextKey = lookup_hkey( hkey );
+    if (!lpNextKey)
         return ERROR_INVALID_HANDLE;
-    }
 
     if (!lpszSubKey || !*lpszSubKey) {
         /* Either NULL or pointer to empty string, so return a new handle
@@ -1693,6 +1747,11 @@
         return ERROR_SUCCESS;
     }
 
+    if (lpszSubKey[0] == '\\') {
+        WARN(reg,"Subkey %s must not begin with backslash.\n",debugstr_w(lpszSubKey));
+        return ERROR_BAD_PATHNAME;
+    }
+
 	split_keypath(lpszSubKey,&wps,&wpc);
 	i = 0;
 	while ((i<wpc) && (wps[i][0]=='\0')) i++;
@@ -1710,7 +1769,7 @@
         if (!lpxkey) {
             TRACE(reg,"Could not find subkey %s\n",debugstr_w(wps[i]));
             FREE_KEY_PATH;
-            return ERROR_BADKEY;
+            return ERROR_FILE_NOT_FOUND;
         }
         i++;
         lpNextKey = lpxkey;
@@ -1725,40 +1784,52 @@
 
 
 /******************************************************************************
- * RegOpenKey32W [ADVAPI32.151]
- */
-DWORD WINAPI RegOpenKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPHKEY retkey )
-{
-    TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_w(lpszSubKey),retkey);
-    return RegOpenKeyEx32W(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey);
-}
-
-
-/******************************************************************************
  * RegOpenKeyEx32A [ADVAPI32.149]
  */
 DWORD WINAPI RegOpenKeyEx32A( HKEY hkey, LPCSTR lpszSubKey, DWORD dwReserved,
                               REGSAM samDesired, LPHKEY retkey )
 {
-    LPWSTR lpszSubKeyW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszSubKey);
+    LPWSTR lpszSubKeyW = strdupA2W(lpszSubKey);
     DWORD ret;
 
     TRACE(reg,"(%x,%s,%ld,%lx,%p)\n",hkey,debugstr_a(lpszSubKey),dwReserved,
           samDesired,retkey);
-
-    ret = RegOpenKeyEx32W(hkey,lpszSubKeyW,dwReserved,samDesired,retkey);
-    HeapFree(GetProcessHeap(),0,lpszSubKeyW);
+    ret = RegOpenKeyEx32W( hkey, lpszSubKeyW, dwReserved, samDesired, retkey );
+    free(lpszSubKeyW);
     return ret;
 }
 
 
 /******************************************************************************
+ * RegOpenKey32W [ADVAPI32.151]
+ *
+ * PARAMS
+ *    hkey       [I] Handle of open key
+ *    lpszSubKey [I] Address of name of subkey to open
+ *    retkey     [O] Address of handle of open key
+ *
+ * RETURNS
+ *    Success: ERROR_SUCCESS
+ *    Failure: Error code
+ */
+DWORD WINAPI RegOpenKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPHKEY retkey )
+{
+    TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_w(lpszSubKey),retkey);
+    return RegOpenKeyEx32W( hkey, lpszSubKey, 0, KEY_ALL_ACCESS, retkey );
+}
+
+
+/******************************************************************************
  * RegOpenKey32A [ADVAPI32.148]
  */
 DWORD WINAPI RegOpenKey32A( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
 {
+    DWORD ret;
+    LPWSTR lpszSubKeyW = strdupA2W(lpszSubKey);
     TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_a(lpszSubKey),retkey);
-    return RegOpenKeyEx32A(hkey,lpszSubKey,0,KEY_ALL_ACCESS,retkey);
+    ret =  RegOpenKey32W( hkey, lpszSubKeyW, retkey );
+    free(lpszSubKeyW);
+    return ret;
 }
 
 
@@ -1768,7 +1839,7 @@
 DWORD WINAPI RegOpenKey16( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
 {
     TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_a(lpszSubKey),retkey);
-    return RegOpenKey32A(hkey,lpszSubKey,retkey);
+    return RegOpenKey32A( hkey, lpszSubKey, retkey );
 }
 
 
@@ -1778,11 +1849,12 @@
  * All those functions convert their respective 
  * arguments and call RegCreateKeyExW at the end.
  *
- * FIXME: no security,no access attrib,no optionhandling yet.
+ * We stay away from the Ex functions as long as possible because there are
+ * differences in the return values
  *
  * Callpath:
- * RegCreateKey16 -> RegCreateKey32A -> RegCreateKeyEx32A \
- *                                      RegCreateKey32W   -> RegCreateKeyEx32W
+ *                                      RegCreateKeyEx32A \
+ * RegCreateKey16 -> RegCreateKey32A -> RegCreateKey32W   -> RegCreateKeyEx32W
  */
 
 
@@ -1790,9 +1862,15 @@
  * RegCreateKeyEx32W [ADVAPI32.131]
  *
  * PARAMS
- *    ...
- *    retkey   [O] Address of buffer for opened handle
- *    lpDispos [O] Receives REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY
+ *    hkey         [I] Handle of an open key
+ *    lpszSubKey   [I] Address of subkey name
+ *    dwReserved   [I] Reserved - must be 0
+ *    lpszClass    [I] Address of class string
+ *    fdwOptions   [I] Special options flag
+ *    samDesired   [I] Desired security access
+ *    lpSecAttribs [I] Address of key security structure
+ *    retkey       [O] Address of buffer for opened handle
+ *    lpDispos     [O] Receives REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY
  */
 DWORD WINAPI RegCreateKeyEx32W( HKEY hkey, LPCWSTR lpszSubKey, 
                                 DWORD dwReserved, LPWSTR lpszClass, 
@@ -1804,15 +1882,30 @@
 	LPWSTR		*wps;
 	int		wpc,i;
 
-    /*FIXME: handle security/access/whatever */
-
     TRACE(reg,"(%x,%s,%ld,%s,%lx,%lx,%p,%p,%p)\n", hkey,
 		debugstr_w(lpszSubKey), dwReserved, debugstr_w(lpszClass),
 		fdwOptions, samDesired, lpSecAttribs, retkey, lpDispos);
 
     lpNextKey = lookup_hkey(hkey);
     if (!lpNextKey)
-        return ERROR_BADKEY;
+        return ERROR_INVALID_HANDLE;
+
+    /* Check for valid options */
+    switch(fdwOptions) {
+        case REG_OPTION_NON_VOLATILE:
+        case REG_OPTION_VOLATILE:
+        case REG_OPTION_BACKUP_RESTORE:
+            break;
+        default:
+            return ERROR_INVALID_PARAMETER;
+    }
+
+    /* Sam has to be a combination of the following */
+    if (!(samDesired & 
+          (KEY_ALL_ACCESS | KEY_CREATE_LINK | KEY_CREATE_SUB_KEY | 
+           KEY_ENUMERATE_SUB_KEYS | KEY_EXECUTE | KEY_NOTIFY |
+           KEY_QUERY_VALUE | KEY_READ | KEY_SET_VALUE | KEY_WRITE)))
+        return ERROR_INVALID_PARAMETER;
 
 	if (!lpszSubKey || !*lpszSubKey) {
 		add_handle(++currenthandle,lpNextKey,samDesired);
@@ -1901,20 +1994,6 @@
 
 
 /******************************************************************************
- * RegCreateKey32W [ADVAPI32.132]
- */
-DWORD WINAPI RegCreateKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPHKEY retkey )
-{
-    DWORD junk;
-
-    TRACE(reg,"(%x,%s,%p)\n", hkey,debugstr_w(lpszSubKey),retkey);
-    return RegCreateKeyEx32W( hkey, lpszSubKey, 0, NULL, 
-                              REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,NULL,
-                              retkey, &junk);
-}
-
-
-/******************************************************************************
  * RegCreateKeyEx32A [ADVAPI32.130]
  */
 DWORD WINAPI RegCreateKeyEx32A( HKEY hkey, LPCSTR lpszSubKey, DWORD dwReserved,
@@ -1930,51 +2009,55 @@
           dwReserved,debugstr_a(lpszClass),fdwOptions,samDesired,lpSecAttribs,
           retkey,lpDispos);
 
-    lpszSubKeyW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszSubKey);
-/*
-	if (lpszSubKey)
-		lpszSubKeyW=strdupA2W(lpszSubKey);
-	else
-		lpszSubKeyW=NULL;
-*/
-	if (lpszClass)
-		lpszClassW=strdupA2W(lpszClass);
-	else
-		lpszClassW=NULL;
+    lpszSubKeyW = lpszSubKey?strdupA2W(lpszSubKey):NULL;
+    lpszClassW = lpszClass?strdupA2W(lpszClass):NULL;
+
     ret = RegCreateKeyEx32W( hkey, lpszSubKeyW, dwReserved, lpszClassW, 
                              fdwOptions, samDesired, lpSecAttribs, retkey, 
                              lpDispos );
-    HeapFree(GetProcessHeap(),0,lpszSubKeyW);
-/*
-	if (lpszSubKeyW)
-		free(lpszSubKeyW);
-*/
-	if (lpszClassW)
-		free(lpszClassW);
+
+    if(lpszSubKeyW) free(lpszSubKeyW);
+    if(lpszClassW) free(lpszClassW);
+
     return ret;
 }
 
 
 /******************************************************************************
+ * RegCreateKey32W [ADVAPI32.132]
+ */
+DWORD WINAPI RegCreateKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPHKEY retkey )
+{
+    DWORD junk;
+    LPKEYSTRUCT	lpNextKey;
+
+    TRACE(reg,"(%x,%s,%p)\n", hkey,debugstr_w(lpszSubKey),retkey);
+
+    /* This check is here because the return value is different than the
+       one from the Ex functions */
+    lpNextKey = lookup_hkey(hkey);
+    if (!lpNextKey)
+        return ERROR_BADKEY;
+
+    return RegCreateKeyEx32W( hkey, lpszSubKey, 0, NULL, 
+                              REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
+                              retkey, &junk);
+}
+
+
+/******************************************************************************
  * RegCreateKey32A [ADVAPI32.129]
  */
 DWORD WINAPI RegCreateKey32A( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey )
 {
-    DWORD junk;
+    DWORD ret;
+    LPWSTR lpszSubKeyW;
 
     TRACE(reg,"(%x,%s,%p)\n",hkey,debugstr_a(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 */
-	);
+    lpszSubKeyW = lpszSubKey?strdupA2W(lpszSubKey):NULL;
+    ret = RegCreateKey32W( hkey, lpszSubKeyW, retkey );
+    if(lpszSubKeyW) free(lpszSubKeyW);
+    return ret;
 }
 
 
@@ -2030,10 +2113,12 @@
           lpdwReserved, lpdwType, lpbData, lpcbData?*lpcbData:0);
 
     lpkey = lookup_hkey(hkey);
-    if (!lpkey) {
-        TRACE(reg, "Invalid handle(%x)\n",hkey);
+    if (!lpkey)
         return ERROR_INVALID_HANDLE;
-    }
+
+    /* Reserved must be NULL (at least for now) */
+    if (lpdwReserved)
+        return ERROR_INVALID_PARAMETER;
 
     /* An empty name string is equivalent to NULL */
     if (lpValueName && !*lpValueName)
@@ -2066,7 +2151,7 @@
                         TRACE(reg, "Returning an empty string\n");
 			return ERROR_SUCCESS;
 		}
-		return ERROR_BADKEY; /* FIXME */
+		return ERROR_BAD_PATHNAME;
 	}
 
     if (lpdwType)
@@ -2122,9 +2207,6 @@
 
 /******************************************************************************
  * RegQueryValue32W [ADVAPI32.159]
- *
- * NOTES
- *    Why is this calling RegOpenKey32W?
  */
 DWORD WINAPI RegQueryValue32W( HKEY hkey, LPWSTR lpszSubKey, LPWSTR lpszData,
                                LPDWORD lpcbData )
@@ -2135,33 +2217,27 @@
     TRACE(reg,"(%x,%s,%p,%ld)\n",hkey,debugstr_w(lpszSubKey),lpszData,
           lpcbData?*lpcbData:0);
 
-	/* 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;
+    /* Only open subkey, if we really do descend */
+    if (lpszSubKey && *lpszSubKey) {
+        ret = RegOpenKey32W( hkey, lpszSubKey, &xhkey );
+        if (ret != ERROR_SUCCESS) {
+            WARN(reg, "Could not open %s\n", debugstr_w(lpszSubKey));
+            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;
+    lpdwType = REG_SZ;
+    ret = RegQueryValueEx32W( xhkey, NULL, NULL, &lpdwType, (LPBYTE)lpszData,
+                              lpcbData );
+    if (xhkey != hkey)
+        RegCloseKey(xhkey);
+    return ret;
 }
 
 
 /******************************************************************************
  * RegQueryValueEx32A [ADVAPI32.157]
- *
- * Can this use HEAP_strdupAtoW?
  */
 DWORD WINAPI RegQueryValueEx32A( HKEY hkey, LPSTR lpszValueName,
                                  LPDWORD lpdwReserved, LPDWORD lpdwType,
@@ -2176,27 +2252,19 @@
     TRACE(reg,"(%x,%s,%p,%p,%p,%ld)\n", hkey,debugstr_a(lpszValueName),
           lpdwReserved,lpdwType,lpbData,lpcbData?*lpcbData:0);
 
-    if (lpszValueName)
-        lpszValueNameW=strdupA2W(lpszValueName);
-    else 
-        lpszValueNameW=NULL;
+    lpszValueNameW = lpszValueName?strdupA2W(lpszValueName):NULL;
 
+    /* Why would this be set? It is just an output */
     if (lpdwType)
-        type=*lpdwType;
+        type = *lpdwType;
 
 	if (lpbData) {
 		myxlen  = 0;
 		mylen	= &myxlen;
 		buf	= xmalloc(4);
                 /* Only get the size for now */
-		ret=RegQueryValueEx32W(
-			hkey,
-			lpszValueNameW,
-			lpdwReserved,
-			&type,
-			buf,
-			mylen
-		);
+		ret = RegQueryValueEx32W( hkey, lpszValueNameW, lpdwReserved,
+                                          &type, buf, mylen );
 		free(buf);
 		if (ret==ERROR_MORE_DATA) {
 			buf	= (LPBYTE)xmalloc(*mylen);
@@ -2205,6 +2273,7 @@
 			myxlen  = 2*(*lpcbData);
 		}
 	} else {
+		/* Data is not required */
 		buf=NULL;
 		if (lpcbData) {
 			myxlen	= *lpcbData*2;
@@ -2212,15 +2281,10 @@
 		} else
 			mylen	= NULL;
 	}
+
         /* Now get the data */
-	ret=RegQueryValueEx32W(
-		hkey,
-		lpszValueNameW,
-		lpdwReserved,
-		&type,
-		buf,
-		mylen
-	);
+	ret = RegQueryValueEx32W( hkey, lpszValueNameW, lpdwReserved, &type,
+                                  buf, mylen );
 	if (lpdwType) 
 		*lpdwType=type;
 
@@ -2246,9 +2310,9 @@
 		if ((UNICONVMASK & (1<<(type))) && lpcbData)
 			*lpcbData	= myxlen/2;
 	}
-	if (buf)
-		free(buf);
 
+    if(buf) free(buf);
+    if(lpszValueNameW) free(lpszValueNameW);
     return ret;
 }
 
@@ -2269,42 +2333,29 @@
 
 /******************************************************************************
  * RegQueryValue32A [ADVAPI32.156]
- *
- * NOTES
- *    Why is this calling RegOpenKey16?
  */
-DWORD WINAPI RegQueryValue32A(
-	HKEY	hkey,
-	LPSTR	lpszSubKey,
-	LPSTR	lpszData,
-	LPDWORD	lpcbData
-) {
-	HKEY	xhkey;
-	DWORD	ret,lpdwType;
+DWORD WINAPI RegQueryValue32A( HKEY hkey, LPSTR lpszSubKey, LPSTR lpszData,
+                               LPDWORD lpcbData )
+{
+    HKEY xhkey;
+    DWORD ret, dwType;
 
     TRACE(reg,"(%x,%s,%p,%ld)\n",hkey,debugstr_a(lpszSubKey),lpszData,
           lpcbData?*lpcbData:0);
 
-	/* 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;
+    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;
+    dwType = REG_SZ;
+    ret = RegQueryValueEx32A( xhkey, NULL,NULL, &dwType, (LPBYTE)lpszData,
+                              lpcbData );
+    if( xhkey != hkey )
+        RegCloseKey( xhkey );
+    return ret;
 }
 
 
@@ -2380,11 +2431,9 @@
             TRACE(reg,"Unknown type: %ld\n", dwType);
     }
 
-	lpkey = lookup_hkey(hkey);
-	if (!lpkey) {
-            WARN(reg,"Returning badkey\n");
-            return ERROR_INVALID_HANDLE;
-        }
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
 
 	lpkey->flags |= REG_OPTION_TAINTED;
 
@@ -2427,8 +2476,6 @@
 /******************************************************************************
  * RegSetValueEx32A [ADVAPI32.169]
  *
- * NOTES
- *    Can this use the standard HEAP_strdupAtoW instead?
  */
 DWORD WINAPI RegSetValueEx32A( HKEY hkey, LPSTR lpszValueName,
                                DWORD dwReserved, DWORD dwType, LPBYTE lpbData,
@@ -2475,13 +2522,9 @@
 /******************************************************************************
  * RegSetValue32W	[ADVAPI32.171]
  */
-DWORD WINAPI RegSetValue32W(
-	HKEY	hkey,
-	LPCWSTR	lpszSubKey,
-	DWORD	dwType,
-	LPCWSTR	lpszData,
-	DWORD	cbData
-) {
+DWORD WINAPI RegSetValue32W( HKEY hkey, LPCWSTR lpszSubKey, DWORD dwType,
+                             LPCWSTR lpszData, DWORD cbData )
+{
 	HKEY	xhkey;
 	DWORD	ret;
 
@@ -2495,11 +2538,11 @@
 	} else
 		xhkey=hkey;
 	if (dwType!=REG_SZ) {
-		TRACE(reg,"RegSetValueX called with dwType=%ld!\n",dwType);
+		TRACE(reg,"dwType=%ld - Changing to REG_SZ\n",dwType);
 		dwType=REG_SZ;
 	}
 	if (cbData!=2*lstrlen32W(lpszData)+2) {
-		TRACE(reg,"RegSetValueX called with len=%ld != strlen(%s)+1=%d!\n",
+		TRACE(reg,"Len=%ld != strlen(%s)+1=%d!\n",
 			cbData,debugstr_w(lpszData),2*lstrlen32W(lpszData)+2
 		);
 		cbData=2*lstrlen32W(lpszData)+2;
@@ -2514,22 +2557,14 @@
 /******************************************************************************
  * RegSetValue32A [ADVAPI32.168]
  *
- * NOTES
- *    Why is this calling RegCreateKey16?
  */
-DWORD WINAPI RegSetValue32A(
-	HKEY	hkey,
-	LPCSTR	lpszSubKey,
-	DWORD	dwType,
-	LPCSTR	lpszData,
-	DWORD	cbData
-) {
+DWORD WINAPI RegSetValue32A( HKEY hkey, LPCSTR lpszSubKey, DWORD dwType,
+                             LPCSTR lpszData, DWORD cbData )
+{
 	DWORD	ret;
 	HKEY	xhkey;
 
-	TRACE(reg,"(%x,%s,%ld,%s,%ld)\n",
-		hkey,lpszSubKey,dwType,lpszData,cbData
-	);
+	TRACE(reg,"(%x,%s,%ld,%s,%ld)\n",hkey,lpszSubKey,dwType,lpszData,cbData);
 	if (lpszSubKey && *lpszSubKey) {
 		ret=RegCreateKey16(hkey,lpszSubKey,&xhkey);
 		if (ret!=ERROR_SUCCESS)
@@ -2538,7 +2573,7 @@
 		xhkey=hkey;
 
 	if (dwType!=REG_SZ) {
-		TRACE(reg,"RegSetValueA called with dwType=%ld!\n",dwType);
+		TRACE(reg,"dwType=%ld!\n",dwType);
 		dwType=REG_SZ;
 	}
 	if (cbData!=strlen(lpszData)+1)
@@ -2584,7 +2619,7 @@
     TRACE(reg,"(%x,%ld,%p,%ld,%p,%p,%p,%p)\n",hkey,iSubkey,lpszName,
           *lpcchName,lpdwReserved,lpszClass,lpcchClass,ft);
 
-    lpkey = lookup_hkey(hkey);
+    lpkey = lookup_hkey( hkey );
     if (!lpkey)
         return ERROR_INVALID_HANDLE;
 
@@ -2622,17 +2657,14 @@
 }
 
 
-/* RegEnumKeyExA		[ADVAPI32.138] */
-DWORD WINAPI RegEnumKeyEx32A(
-	HKEY	hkey,
-	DWORD	iSubkey,
-	LPSTR	lpszName,
-	LPDWORD	lpcchName,
-	LPDWORD	lpdwReserved,
-	LPSTR	lpszClass,
-	LPDWORD	lpcchClass,
-	FILETIME	*ft
-) {
+/******************************************************************************
+ * RegEnumKeyEx32A [ADVAPI32.138]
+ */
+DWORD WINAPI RegEnumKeyEx32A( HKEY hkey, DWORD iSubkey, LPSTR lpszName,
+                              LPDWORD lpcchName, LPDWORD lpdwReserved, 
+                              LPSTR lpszClass, LPDWORD lpcchClass, 
+                              FILETIME *ft )
+{
 	DWORD	ret,lpcchNameW,lpcchClassW;
 	LPWSTR	lpszNameW,lpszClassW;
 
@@ -2715,29 +2747,34 @@
 
 /******************************************************************************
  * RegEnumValue32W [ADVAPI32.142]
+ *
+ * PARAMS
+ *    hkey   [I]
+ *    iValue [I]
+ *    ...
  */
-DWORD WINAPI RegEnumValue32W(
-	HKEY hkey,
-	DWORD iValue,
-	LPWSTR lpszValue,
-	LPDWORD	lpcchValue,
-	LPDWORD	lpdReserved,
-	LPDWORD	lpdwType,
-	LPBYTE	lpbData,
-	LPDWORD	lpcbData
-) {
+DWORD WINAPI RegEnumValue32W( HKEY hkey, DWORD iValue, LPWSTR lpszValue,
+                              LPDWORD lpcchValue, LPDWORD lpdReserved,
+                              LPDWORD lpdwType, LPBYTE lpbData, 
+                              LPDWORD lpcbData )
+{
 	LPKEYSTRUCT	lpkey;
 	LPKEYVALUE	val;
 
-	TRACE(reg,"(%x,%ld,%p,%p,%p,%p,%p,%p)\n",
-		hkey,iValue,lpszValue,lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData
-	);
-	lpkey = lookup_hkey(hkey);
-	if (!lpkey)
-		return ERROR_INVALID_HANDLE;
+    TRACE(reg,"(%x,%ld,%p,%p,%p,%p,%p,%p)\n",hkey,iValue,debugstr_w(lpszValue),
+          lpcchValue,lpdReserved,lpdwType,lpbData,lpcbData);
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
+    /* None asked for */
+    if (!iValue)
+        return ERROR_SUCCESS;
 
 	if (lpkey->nrofvalues<=iValue)
 		return ERROR_NO_MORE_ITEMS;
+
 	val	= lpkey->values+iValue;
 
 	if (val->name) {
@@ -2763,17 +2800,14 @@
 }
 
 
-/* RegEnumValueA		[ADVAPI32.141] */
-DWORD WINAPI RegEnumValue32A(
-	HKEY	hkey,
-	DWORD	iValue,
-	LPSTR	lpszValue,
-	LPDWORD	lpcchValue,
-	LPDWORD	lpdReserved,
-	LPDWORD	lpdwType,
-	LPBYTE	lpbData,
-	LPDWORD	lpcbData
-) {
+/******************************************************************************
+ * RegEnumValue32A [ADVAPI32.141]
+ */
+DWORD WINAPI RegEnumValue32A( HKEY hkey, DWORD iValue, LPSTR lpszValue,
+                              LPDWORD lpcchValue, LPDWORD lpdReserved,
+                              LPDWORD lpdwType, LPBYTE lpbData, 
+                              LPDWORD lpcbData )
+{
 	LPWSTR	lpszValueW;
 	LPBYTE	lpbDataW;
 	DWORD	ret,lpcbDataW;
@@ -2850,6 +2884,12 @@
 DWORD WINAPI RegCloseKey( HKEY hkey )
 {
     TRACE(reg,"(%x)\n",hkey);
+
+    /* The standard handles are allowed to succeed, even though they are not
+       closed */
+    if (is_standard_hkey(hkey))
+        return ERROR_SUCCESS;
+
     return remove_handle(hkey);
 }
 
@@ -2882,16 +2922,13 @@
     TRACE(reg,"(%x,%s)\n",hkey,debugstr_w(lpszSubKey));
 
     lpNextKey = lookup_hkey(hkey);
-    if (!lpNextKey) {
-        TRACE(reg, "  Invalid handle.\n");
+    if (!lpNextKey)
         return ERROR_INVALID_HANDLE;
-    }
 
-	/* we need to know the previous key in the hier. */
-	if (!lpszSubKey || !*lpszSubKey) {
-		TRACE(reg, "  Badkey[2].\n");
-		return ERROR_BADKEY;
-	}
+    /* We need to know the previous key in the hier. */
+    if (!lpszSubKey || !*lpszSubKey)
+        return ERROR_BADKEY;
+
 	split_keypath(lpszSubKey,&wps,&wpc);
 	i 	= 0;
 	lpxkey	= lpNextKey;
@@ -2956,10 +2993,10 @@
     LPWSTR lpszSubKeyW;
     DWORD  ret;
 
-    TRACE(reg,"(%x,%s)\n",hkey,lpszSubKey);
-    lpszSubKeyW = HEAP_strdupAtoW( GetProcessHeap(), 0, lpszSubKey );
+    TRACE(reg,"(%x,%s)\n",hkey,debugstr_a(lpszSubKey));
+    lpszSubKeyW = lpszSubKey?strdupA2W(lpszSubKey):NULL;
     ret = RegDeleteKey32W( hkey, lpszSubKeyW );
-    HeapFree( GetProcessHeap(), 0, lpszSubKeyW );
+    if(lpszSubKeyW) free(lpszSubKeyW);
     return ret;
 }
 
@@ -2999,7 +3036,7 @@
 
     TRACE(reg,"(%x,%s)\n",hkey,debugstr_w(lpszValue));
 
-    lpkey = lookup_hkey(hkey);
+    lpkey = lookup_hkey( hkey );
     if (!lpkey)
         return ERROR_INVALID_HANDLE;
 
@@ -3044,9 +3081,9 @@
     DWORD  ret;
 
     TRACE(reg, "(%x,%s)\n",hkey,debugstr_a(lpszValue));
-    lpszValueW=HEAP_strdupAtoW(GetProcessHeap(),0,lpszValue);
+    lpszValueW = lpszValue?strdupA2W(lpszValue):NULL;
     ret = RegDeleteValue32W( hkey, lpszValueW );
-    HeapFree(GetProcessHeap(),0,lpszValueW);
+    if(lpszValueW) free(lpszValueW);
     return ret;
 }
 
@@ -3057,7 +3094,7 @@
 DWORD WINAPI RegDeleteValue16( HKEY hkey, LPSTR lpszValue )
 {
     TRACE(reg,"(%x,%s)\n", hkey,debugstr_a(lpszValue));
-    return RegDeleteValue32A(hkey,lpszValue);
+    return RegDeleteValue32A( hkey, lpszValue );
 }
 
 
@@ -3074,8 +3111,23 @@
  */
 DWORD WINAPI RegFlushKey( HKEY hkey )
 {
-    FIXME(reg, "(%x): stub\n", hkey);
-    return ERROR_SUCCESS;
+    LPKEYSTRUCT	lpkey;
+    BOOL32 ret;
+
+    TRACE(reg, "(%x)\n", hkey);
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
+    ERR(reg, "What is the correct filename?\n");
+
+    ret = _savereg( lpkey, "foo.bar", TRUE);
+
+    if( ret ) {
+        return ERROR_SUCCESS;
+    } else
+        return ERROR_UNKNOWN;  /* FIXME */
 }
 
 
@@ -3215,11 +3267,24 @@
 
 /******************************************************************************
  * RegConnectRegistry32W [ADVAPI32.128]
+ *
+ * PARAMS
+ *    lpMachineName [I] Address of name of remote computer
+ *    hHey          [I] Predefined registry handle
+ *    phkResult     [I] Address of buffer for remote registry handle
  */
-LONG WINAPI RegConnectRegistry32W( LPCWSTR machine, HKEY hkey, LPHKEY reskey )
+LONG WINAPI RegConnectRegistry32W( LPCWSTR lpMachineName, HKEY hKey, 
+                                   LPHKEY phkResult )
 {
-    FIXME(reg,"(%s,%x,%p): stub\n",debugstr_w(machine),hkey,reskey);
-    return ERROR_BAD_NETPATH; /* FIXME */
+    TRACE(reg,"(%s,%x,%p): stub\n",debugstr_w(lpMachineName),hKey,phkResult);
+
+    if (!lpMachineName || !*lpMachineName) {
+        /* Use the local machine name */
+        return RegOpenKey16( hKey, "", phkResult );
+    }
+
+    FIXME(reg,"Cannot connect to %s\n",debugstr_w(lpMachineName));
+    return ERROR_BAD_NETPATH;
 }
 
 
@@ -3229,9 +3294,9 @@
 LONG WINAPI RegConnectRegistry32A( LPCSTR machine, HKEY hkey, LPHKEY reskey )
 {
     DWORD ret;
-    LPWSTR machineW = HEAP_strdupAtoW(GetProcessHeap(),0,machine);
+    LPWSTR machineW = strdupA2W(machine);
     ret = RegConnectRegistry32W( machineW, hkey, reskey );
-    HeapFree(GetProcessHeap(),0,machineW);
+    free(machineW);
     return ret;
 }
 
@@ -3240,6 +3305,12 @@
  * RegGetKeySecurity [ADVAPI32.144]
  * Retrieves a copy of security descriptor protecting the registry key
  *
+ * PARAMS
+ *    hkey                   [I]   Open handle of key to set
+ *    SecurityInformation    [I]   Descriptor contents
+ *    pSecurityDescriptor    [O]   Address of descriptor for key
+ *    lpcbSecurityDescriptor [I/O] Address of size of buffer and description
+ *
  * RETURNS
  *    Success: ERROR_SUCCESS
  *    Failure: Error code
@@ -3250,23 +3321,43 @@
                                LPDWORD lpcbSecurityDescriptor )
 {
     LPKEYSTRUCT	lpkey;
-    lpkey = lookup_hkey(hkey);
+
+    FIXME(reg, "(%x,%ld,%p,%ld): stub\n",hkey,SecurityInformation,
+          pSecurityDescriptor,lpcbSecurityDescriptor?*lpcbSecurityDescriptor:0);
+
+    lpkey = lookup_hkey( hkey );
     if (!lpkey)
         return ERROR_INVALID_HANDLE;
 
-    FIXME(reg, "(%d,%ld,%p,%p): stub\n", hkey, SecurityInformation,
-          pSecurityDescriptor, lpcbSecurityDescriptor);
+    if (*lpcbSecurityDescriptor < sizeof(*pSecurityDescriptor))
+        return ERROR_INSUFFICIENT_BUFFER;
+
     return ERROR_SUCCESS;
 }
 
 
 /******************************************************************************
  * RegLoadKey32W [ADVAPI32.???]
+ *
+ * PARAMS
+ *    hkey       [I] Handle of open key
+ *    lpszSubKey [I] Address of name of subkey
+ *    lpszFile   [I] Address of filename for registry information
  */
 LONG WINAPI RegLoadKey32W( HKEY hkey, LPCWSTR lpszSubKey, LPCWSTR lpszFile )
 {
+    LPKEYSTRUCT	lpkey;
     FIXME(reg,"(%x,%s,%s): stub\n",hkey,debugstr_w(lpszSubKey),
           debugstr_w(lpszFile));
+
+    /* Do this check before the hkey check */
+    if (!lpszSubKey || !*lpszSubKey || !lpszFile || !*lpszFile)
+        return ERROR_INVALID_PARAMETER;
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
@@ -3277,30 +3368,47 @@
 LONG WINAPI RegLoadKey32A( HKEY hkey, LPCSTR lpszSubKey, LPCSTR lpszFile )
 {
     LONG ret;
-    LPWSTR lpszSubKeyW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszSubKey);
-    LPWSTR lpszFileW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszFile);
+    LPWSTR lpszSubKeyW = strdupA2W(lpszSubKey);
+    LPWSTR lpszFileW = strdupA2W(lpszFile);
     ret = RegLoadKey32W( hkey, lpszSubKeyW, lpszFileW );
-    HeapFree(GetProcessHeap(),0,lpszFileW);
-    HeapFree(GetProcessHeap(),0,lpszSubKeyW);
+    if(lpszFileW) free(lpszFileW);
+    if(lpszSubKeyW) free(lpszSubKeyW);
     return ret;
 }
 
 
 /******************************************************************************
  * RegNotifyChangeKeyValue [ADVAPI32.???]
+ *
+ * PARAMS
+ *    hkey            [I] Handle of key to watch
+ *    fWatchSubTree   [I] Flag for subkey notification
+ *    fdwNotifyFilter [I] Changes to be reported
+ *    hEvent          [I] Handle of signaled event
+ *    fAsync          [I] Flag for asynchronous reporting
  */
 LONG WINAPI RegNotifyChangeKeyValue( HKEY hkey, BOOL32 fWatchSubTree, 
                                      DWORD fdwNotifyFilter, HANDLE32 hEvent,
                                      BOOL32 fAsync )
 {
-    FIXME(reg,"(%x,%i,%ld,%d,%i): stub\n",hkey,fWatchSubTree,fdwNotifyFilter,
+    LPKEYSTRUCT	lpkey;
+    FIXME(reg,"(%x,%i,%ld,%x,%i): stub\n",hkey,fWatchSubTree,fdwNotifyFilter,
           hEvent,fAsync);
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
 
 /******************************************************************************
  * RegUnLoadKey32W [ADVAPI32.173]
+ *
+ * PARAMS
+ *    hkey     [I] Handle of open key
+ *    lpSubKey [I] Address of name of subkey to unload
  */
 LONG WINAPI RegUnLoadKey32W( HKEY hkey, LPCWSTR lpSubKey )
 {
@@ -3315,31 +3423,71 @@
 LONG WINAPI RegUnLoadKey32A( HKEY hkey, LPCSTR lpSubKey )
 {
     LONG ret;
-    LPWSTR lpSubKeyW = HEAP_strdupAtoW( GetProcessHeap(), 0, lpSubKey );
+    LPWSTR lpSubKeyW = strdupA2W(lpSubKey);
     ret = RegUnLoadKey32W( hkey, lpSubKeyW );
-    HeapFree( GetProcessHeap(), 0, lpSubKeyW );
+    if(lpSubKeyW) free(lpSubKeyW);
     return ret;
 }
 
 
 /******************************************************************************
  * RegSetKeySecurity [ADVAPI32.167]
+ *
+ * PARAMS
+ *    hkey          [I] Open handle of key to set
+ *    SecurityInfo  [I] Descriptor contents
+ *    pSecurityDesc [I] Address of descriptor for key
  */
 LONG WINAPI RegSetKeySecurity( HKEY hkey, SECURITY_INFORMATION SecurityInfo,
                                LPSECURITY_DESCRIPTOR pSecurityDesc )
 {
-    FIXME(reg, "%x,%ld,%p): stub\n", hkey, SecurityInfo, pSecurityDesc);
+    LPKEYSTRUCT	lpkey;
+
+    FIXME(reg, "(%x,%ld,%p): stub\n", hkey, SecurityInfo, pSecurityDesc);
+
+    /* It seems to perform this check before the hkey check */
+    if ((SecurityInfo & OWNER_SECURITY_INFORMATION) ||
+        (SecurityInfo & GROUP_SECURITY_INFORMATION) ||
+        (SecurityInfo & DACL_SECURITY_INFORMATION) ||
+        (SecurityInfo & SACL_SECURITY_INFORMATION)) {
+        /* Param OK */
+    } else
+        return ERROR_INVALID_PARAMETER;
+
+    if (!pSecurityDesc)
+        return ERROR_INVALID_PARAMETER;
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
 
 /******************************************************************************
  * RegSaveKey32W [ADVAPI32.166]
+ *
+ * PARAMS
+ *    hkey   [I] Handle of key where save begins
+ *    lpFile [I] Address of filename to save to
+ *    sa     [I] Address of security structure
  */
 LONG WINAPI RegSaveKey32W( HKEY hkey, LPCWSTR lpFile, 
                            LPSECURITY_ATTRIBUTES sa )
 {
-    FIXME(reg, "%x,%s,%p): stub\n", hkey, debugstr_w(lpFile), sa);
+    LPKEYSTRUCT	lpkey;
+
+    FIXME(reg, "(%x,%s,%p): stub\n", hkey, debugstr_w(lpFile), sa);
+
+    /* It appears to do this check before the hkey check */
+    if (!lpFile || !*lpFile)
+        return ERROR_INVALID_PARAMETER;
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
@@ -3351,19 +3499,36 @@
                            LPSECURITY_ATTRIBUTES sa )
 {
     LONG ret;
-    LPWSTR lpFileW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpFile);
+    LPWSTR lpFileW = strdupA2W(lpFile);
     ret = RegSaveKey32W( hkey, lpFileW, sa );
-    HeapFree( GetProcessHeap(), 0, lpFileW );
+    free(lpFileW);
     return ret;
 }
 
 
 /******************************************************************************
  * RegRestoreKey32W [ADVAPI32.164]
+ *
+ * PARAMS
+ *    hkey    [I] Handle of key where restore begins
+ *    lpFile  [I] Address of filename containing saved tree
+ *    dwFlags [I] Optional flags
  */
 LONG WINAPI RegRestoreKey32W( HKEY hkey, LPCWSTR lpFile, DWORD dwFlags )
 {
-    FIXME(reg, "%x,%s,%ld): stub\n", hkey, debugstr_w(lpFile), dwFlags);
+    LPKEYSTRUCT	lpkey;
+    FIXME(reg, "(%x,%s,%ld): stub\n", hkey, debugstr_w(lpFile), dwFlags);
+
+    /* It seems to do this check before the hkey check */
+    if (!lpFile || !*lpFile)
+        return ERROR_INVALID_PARAMETER;
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
+    /* Check for file existence */
+
     return ERROR_SUCCESS;
 }
 
@@ -3374,21 +3539,34 @@
 LONG WINAPI RegRestoreKey32A( HKEY hkey, LPCSTR lpFile, DWORD dwFlags )
 {
     LONG ret;
-    LPWSTR lpFileW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpFile);
+    LPWSTR lpFileW = strdupA2W(lpFile);
     ret = RegRestoreKey32W( hkey, lpFileW, dwFlags );
-    HeapFree( GetProcessHeap(), 0, lpFileW );
+    if(lpFileW) free(lpFileW);
     return ret;
 }
 
 
 /******************************************************************************
  * RegReplaceKey32W [ADVAPI32.162]
+ *
+ * PARAMS
+ *    hkey      [I] Handle of open key
+ *    lpSubKey  [I] Address of name of subkey
+ *    lpNewFile [I] Address of filename for file with new data
+ *    lpOldFile [I] Address of filename for backup file
  */
 LONG WINAPI RegReplaceKey32W( HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpNewFile,
                               LPCWSTR lpOldFile )
 {
-    FIXME(reg, "%x,%s,%s,%s): stub\n", hkey, debugstr_w(lpSubKey), 
+    LPKEYSTRUCT	lpkey;
+
+    FIXME(reg, "(%x,%s,%s,%s): stub\n", hkey, debugstr_w(lpSubKey), 
           debugstr_w(lpNewFile),debugstr_w(lpOldFile));
+
+    lpkey = lookup_hkey( hkey );
+    if (!lpkey)
+        return ERROR_INVALID_HANDLE;
+
     return ERROR_SUCCESS;
 }
 
@@ -3400,13 +3578,13 @@
                               LPCSTR lpOldFile )
 {
     LONG ret;
-    LPWSTR lpSubKeyW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpSubKey);
-    LPWSTR lpNewFileW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpNewFile);
-    LPWSTR lpOldFileW = HEAP_strdupAtoW(GetProcessHeap(), 0, lpOldFile);
+    LPWSTR lpSubKeyW = strdupA2W(lpSubKey);
+    LPWSTR lpNewFileW = strdupA2W(lpNewFile);
+    LPWSTR lpOldFileW = strdupA2W(lpOldFile);
     ret = RegReplaceKey32W( hkey, lpSubKeyW, lpNewFileW, lpOldFileW );
-    HeapFree( GetProcessHeap(), 0, lpOldFileW );
-    HeapFree( GetProcessHeap(), 0, lpNewFileW );
-    HeapFree( GetProcessHeap(), 0, lpSubKeyW );
+    free(lpOldFileW);
+    free(lpNewFileW);
+    free(lpSubKeyW);
     return ret;
 }
 
diff --git a/misc/shell.c b/misc/shell.c
index 4ac0d7c..40a8084 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -375,8 +375,8 @@
 	  }
 
     /* Check registry */
-    if (RegQueryValue16( (HKEY)HKEY_CLASSES_ROOT, tmpext, filetype,
-                         &filetypelen ) == SHELL_ERROR_SUCCESS )
+    if (RegQueryValue16( HKEY_CLASSES_ROOT, tmpext, filetype,
+                         &filetypelen ) == ERROR_SUCCESS )
     {
 	filetype[filetypelen]='\0';
 	TRACE(exec, "File type: %s\n",
@@ -387,8 +387,8 @@
 	strcat( filetype, lpOperation );
 	strcat( filetype, "\\command" );
 	
-	if (RegQueryValue16( (HKEY)HKEY_CLASSES_ROOT, filetype, command,
-                             &commandlen ) == SHELL_ERROR_SUCCESS )
+	if (RegQueryValue16( HKEY_CLASSES_ROOT, filetype, command,
+                             &commandlen ) == ERROR_SUCCESS )
 	{
 	    /* Is there a replace() function anywhere? */
 	    command[commandlen]='\0';
@@ -1172,7 +1172,7 @@
 	for (i=0;i<n;i++) {
 	    LPIMAGE_RESOURCE_DIRECTORY	xresdir;
 
-	    xresdir = GetResDirEntryW(iconresdir,(LPWSTR)RetPtr[i],(DWORD)rootresdir,FALSE);
+	    xresdir = GetResDirEntryW(iconresdir,(LPWSTR)&(RetPtr[i]),(DWORD)rootresdir,FALSE);
 	    xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
 
 	    idataent = (LPIMAGE_RESOURCE_DATA_ENTRY)xresdir;
@@ -1563,11 +1563,11 @@
 }
 
 /*************************************************************************
+ * FreeIconList
  */
-
 void WINAPI FreeIconList( DWORD dw )
 {
-    FIXME(reg, "empty stub\n" );
+    FIXME(reg, "(%lx): stub\n",dw);
 }
 
 /*************************************************************************
@@ -1580,7 +1580,6 @@
     char	xclsid[50],xiid[50];
     HRESULT	hres = E_OUTOFMEMORY;
 
-
     WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
     WINE_StringFromCLSID((LPCLSID)iid,xiid);
     TRACE(shell,"(%s,%s,%p)\n",xclsid,xiid,ppv);
@@ -1610,7 +1609,7 @@
 	return 0;
     }
 
-    FIXME(shell, "   -> clsid not found. returning E_OUTOFMEMORY.\n");
+    FIXME(shell, "clsid(%s) not found.  Returning E_OUTOFMEMORY.\n",xclsid);
     return hres;
 }
 
@@ -1669,3 +1668,18 @@
 	lstrcpy32A(pszPath,"E:\\"); /* FIXME */
 	return NOERROR;
 }
+
+/*************************************************************************
+ * SHHelpShortcuts_RunDLL [SHELL32.224]
+ *
+ */
+
+DWORD WINAPI
+SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
+{
+    FIXME (exec, "(%lx, %lx, %lx, %lx) empty stub!\n",
+	   dwArg1, dwArg2, dwArg3, dwArg4);
+
+    return 0;
+}
+
diff --git a/misc/shellord.c b/misc/shellord.c
index 41f0538..62de68b 100644
--- a/misc/shellord.c
+++ b/misc/shellord.c
@@ -42,6 +42,9 @@
 /*************************************************************************
  *	 		 SHELL32_16   			[SHELL32.16]
  * find_lastitem_in_itemidlist()
+ *
+ * NOTES
+ *     Original name: ILFindLast (exported by ordinal)
  */
 LPSHITEMID WINAPI SHELL32_16(LPITEMIDLIST iil) {
 	LPSHITEMID	lastsii,sii;
@@ -56,9 +59,13 @@
 	}
 	return lastsii;
 }
+
 /*************************************************************************
  *	 		 SHELL32_29   			[SHELL32.29]
  * is_rootdir(const char*path)
+ *
+ * NOTES
+ *     Original Name: PathIsRoot
  */
 BOOL32 WINAPI SHELL32_29(LPCSTR x) {
 	if (!lstrcmp32A(x+1,":\\"))		/* "X:\" */
@@ -81,6 +88,9 @@
 /*************************************************************************
  *	 		 SHELL32_30   			[SHELL32.30]
  * get_rootdir(char*path,int drive)
+ *
+ * NOTES
+ *     Original Name: PathBuildRoot
  */
 LPSTR WINAPI SHELL32_30(LPSTR root,BYTE drive) {
 	strcpy(root,"A:\\");
@@ -381,9 +391,16 @@
 /*************************************************************************
  *				SHELL32_181	[SHELL32.181]
  * unknown
+ *
+ * PARAMS
+ *      hwnd [I]  window handle
+ *      y    [I]  flag ????
+ *
+ * NOTES
+ *     Original name: RegisterShellHook (exported by ordinal)
  */
-void WINAPI SHELL32_181(DWORD x,DWORD y) {
-    FIXME(shell,"(0x%08lx,0x%08lx):stub.\n",x,y);
+void WINAPI SHELL32_181(HWND32 hwnd, DWORD y) {
+    FIXME(shell,"(0x%08lx,0x%08lx):stub.\n",hwnd,y);
 }
 
 /*************************************************************************
@@ -524,6 +541,9 @@
 /*************************************************************************
  *			 SHELL32_183   			[SHELL32.183]
  * Format and output errormessage.
+ *
+ * NOTES
+ *     Original name: ShellMessageBoxA
  */
 void __cdecl SHELL32_183(HMODULE32 hmod,HWND32 hwnd,DWORD id,DWORD x,DWORD type,LPVOID arglist) {
 	char	buf[100],buf2[100],*buf3;
@@ -701,3 +721,43 @@
     return 0;
 }
 
+
+/*************************************************************************
+ * SHELL32_61 [SHELL32.61]
+ * Shell/Run-Dialog
+ */
+DWORD WINAPI
+SHELL32_61 (HWND32 hwndOwner, DWORD dwParam1, DWORD dwParam2,
+	    LPSTR lpszTitle, LPSTR lpszPrompt, UINT32 uFlags)
+{
+    FIXME (shell,"(0x%08x 0x%lx 0x%lx \"%s\" \"%s\" 0x%lx):stub.\n",
+	   hwndOwner, dwParam1, dwParam2, lpszTitle, lpszPrompt, uFlags);
+    return 0;
+}
+
+
+/*************************************************************************
+ * SHELL32_60 [SHELL32.60]
+ * Shell/Shutdown-Dialog
+ */
+DWORD WINAPI
+SHELL32_60 (HWND32 hwndOwner)
+{
+    FIXME (shell,"(0x%08x):stub.\n", hwndOwner);
+    return 0;
+}
+
+
+/*************************************************************************
+ * SHELL32_184 [SHELL32.184]
+ * unknown
+ */
+DWORD WINAPI
+SHELL32_184 (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3,
+	     DWORD dwParam4, DWORD dwParam5)
+{
+    FIXME (shell,"(0x%lx 0x%lx 0x%lx 0x%lx 0x%lx):stub.\n",
+	   dwParam1, dwParam2, dwParam3, dwParam4, dwParam5);
+    return 0;
+}
+
diff --git a/misc/system.c b/misc/system.c
index 77e4940..22a5dde 100644
--- a/misc/system.c
+++ b/misc/system.c
@@ -15,6 +15,8 @@
 #include "callback.h"
 #include "windows.h"
 #include "miscemu.h"
+#include "selectors.h"
+#include "sig_context.h"
 #include "debug.h"
 
 typedef struct
@@ -33,10 +35,17 @@
 
 /***********************************************************************
  *           SYSTEM_TimerTick
+ * FIXME: It is a very bad idea to call 16bit code in a signal handler:
+ *	  If the signal reached us in 16 bit code, we could have a broken
+ *	  %FS, which is in turned saved into the single global
+ *	  CALLTO16_Current_fs temporary storage, so a single misplaced
+ *	  signal crashes the whole WINE process.
+ *	  This needs more thought. -MM
  */
-static void SYSTEM_TimerTick(void)
+static HANDLER_DEF(SYSTEM_TimerTick)
 {
     int i;
+    HANDLER_INIT();
 
     for (i = 0; i < NB_SYS_TIMERS; i++)
     {
@@ -44,12 +53,15 @@
         if ((SYS_Timers[i].ticks -= SYS_TIMER_RATE) <= 0)
         {
             SYS_Timers[i].ticks += SYS_Timers[i].rate;
-            Callbacks->CallSystemTimerProc( SYS_Timers[i].callback );
+
+	    if (SYS_Timers[i].callback == (FARPROC16)DOSMEM_Tick) {
+	    	DOSMEM_Tick();
+	    } else
+		Callbacks->CallSystemTimerProc( SYS_Timers[i].callback );
         }
     }
 }
 
-
 /**********************************************************************
  *           SYSTEM_StartTicks
  *
@@ -62,7 +74,7 @@
     if (!handler_installed)
     {
         handler_installed = TRUE;
-        SIGNAL_SetHandler( SIGALRM, SYSTEM_TimerTick, 1 );
+	SIGNAL_SetHandler( SIGALRM, SYSTEM_TimerTick, 1 );
     }
 #ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
     {
@@ -130,6 +142,14 @@
 {
     int i;
 
+    /* FIXME: HACK: do not create system timers due to problems mentioned
+     * above, except DOSMEM_Tick().
+     */
+    if (callback!=(FARPROC16)DOSMEM_Tick) {
+    	FIXME(system,"are currently broken, returning 0.\n");
+    	return 0;
+    }
+
     for (i = 0; i < NB_SYS_TIMERS; i++)
         if (!SYS_Timers[i].callback)  /* Found one */
         {
diff --git a/misc/tapi32.c b/misc/tapi32.c
new file mode 100644
index 0000000..87e45fb
--- /dev/null
+++ b/misc/tapi32.c
@@ -0,0 +1,42 @@
+/*
+ * TAPI32
+ *
+ * Copyright (c) 1998 Andreas Mohr
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "windows.h"
+#include "debug.h"
+
+UINT32 WINAPI lineInitialize(
+  LPVOID lphLineApp, /* FIXME */
+  HINSTANCE32 hInstance,
+  LPVOID lpfnCallback, /* FIXME */
+  LPCSTR lpszAppName,
+  LPDWORD lpdwNumDevs)
+{
+    FIXME(comm, "stub.\n");
+    return 0;
+}
+
+UINT32 WINAPI lineShutdown( HANDLE32 hLineApp ) /* FIXME */
+{
+    FIXME(comm, "stub.\n");
+    return 0;
+}
+
+UINT32 WINAPI lineNegotiateAPIVersion(
+  HANDLE32 hLineApp, /* FIXME */
+  DWORD dwDeviceID,
+  DWORD dwAPILowVersion,
+  DWORD dwAPIHighVersion,
+  LPDWORD lpdwAPIVersion,
+  LPVOID lpExtensionID /* FIXME */
+)
+{
+    FIXME(comm, "stub.\n");
+    *lpdwAPIVersion = dwAPIHighVersion;
+    return 0;
+}
diff --git a/misc/version.c b/misc/version.c
index 89cb8cd..ea0348c 100644
--- a/misc/version.c
+++ b/misc/version.c
@@ -11,6 +11,7 @@
 #include "process.h"
 #include "options.h"
 #include "debug.h"
+#include "ole.h"
 
 typedef enum
 {
@@ -163,6 +164,26 @@
 
 
 /***********************************************************************
+ *         GetVersionEx16   (KERNEL.149)
+ */
+BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16 *v)
+{
+    VERSION ver = VERSION_GetVersion();
+    if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFO16))
+    {
+        WARN(ver,"wrong OSVERSIONINFO size from app");
+        return FALSE;
+    }
+    v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
+    v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
+    v->dwBuildNumber  = VersionData[ver].getVersionEx.dwBuildNumber;
+    v->dwPlatformId   = VersionData[ver].getVersionEx.dwPlatformId;
+    strcpy( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
+    return TRUE;
+}
+
+
+/***********************************************************************
  *         GetVersionEx32A   (KERNEL32.428)
  */
 BOOL32 WINAPI GetVersionEx32A(OSVERSIONINFO32A *v)
@@ -300,3 +321,81 @@
         /* FIXME */
 	DPRINTF("DIAGOUTPUT:%s\n",str);
 }
+
+/***********************************************************************
+ * DllGetVersion [COMCTL32.25]
+ *
+ *
+ *
+ */
+HRESULT WINAPI COMCTL32_DllGetVersion(DLLVERSIONINFO *pdvi)
+{
+    VERSION ver = VERSION_GetVersion();
+
+    if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
+    {
+        WARN(ver, "wrong DLLVERSIONINFO size from app");
+        return OLE_ERROR_SIZE; /* FIXME: is this error correct ? */
+    }
+
+    pdvi->dwPlatformID = VersionData[ver].getVersionEx.dwPlatformId;
+    switch(VersionData[ver].getVersion32)
+    {
+        case 0x80000a03: /* Win 3.1 */
+        {
+            pdvi->dwMajorVersion = 3;
+            pdvi->dwMinorVersion = 51;
+            pdvi->dwBuildNumber = 0;
+        }
+        break;
+        case 0xc0000004: /* Win 95 */
+        {
+            pdvi->dwMajorVersion = 4;
+            pdvi->dwMinorVersion = 0;
+            pdvi->dwBuildNumber = 950;
+        }
+        break;
+        case 0x04213303: /* NT 3.51 FIXME: correct ? */
+        {
+            pdvi->dwMajorVersion = 3;
+            pdvi->dwMinorVersion = 51;
+            pdvi->dwBuildNumber = 0x421;
+        }
+        break;
+        case 0x05650004: /* NT 4.0 FIXME: correct ? */
+        {
+            pdvi->dwMajorVersion = 4;
+            pdvi->dwMinorVersion = 0;
+            pdvi->dwBuildNumber = 0x565;
+        }
+        break;
+        default:
+        {
+            ERR(ver, "Unknown Windows version, please add it to the list !\n");
+        }
+        break;
+    }
+    return 0; /* winerror.h: NOERROR */
+}
+
+/***********************************************************************
+ *           OaBuildVersion           [OLEAUT32.170]
+ */
+UINT32 WINAPI OaBuildVersion()
+{
+    VERSION ver = VERSION_GetVersion();
+
+    switch(VersionData[ver].getVersion32)
+    {
+        case 0x80000a03: /* Win 3.1 */
+		return 0x140fd1; /* from Win32s 1.1e */
+        case 0xc0000004: /* Win 95 */
+		return 0x0a0bd3;
+        case 0x04213303: /* NT 3.51 */
+		return 0x0; /* FIXME */
+        case 0x05650004: /* NT 4.0 */
+		return 0x141016;
+	default:
+		return 0x0;
+    }
+}
diff --git a/misc/w32skrnl.c b/misc/w32skrnl.c
index df9d65a..6f3030f 100644
--- a/misc/w32skrnl.c
+++ b/misc/w32skrnl.c
@@ -5,10 +5,10 @@
  * Copyright (c) 1997 Andreas Mohr
  */
 
-#include "windows.h"
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include "windows.h"
 
 LPSTR WINAPI GetWin32sDirectory(void)
 {
diff --git a/misc/win32s16.c b/misc/win32s16.c
index 5fc0484..48b00cb 100644
--- a/misc/win32s16.c
+++ b/misc/win32s16.c
@@ -5,10 +5,10 @@
  * Copyright (c) 1997 Andreas Mohr
  */
 
-#include "windows.h"
-#include "debug.h"
 #include <string.h>
 #include <stdlib.h>
+#include "windows.h"
+#include "debug.h"
 
 void BootTask()
 {
diff --git a/misc/winsock.c b/misc/winsock.c
index 4dae6c4..44c1ecd 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -1929,7 +1929,7 @@
 
 INT16 WINAPI WSACancelAsyncRequest16(HANDLE16 hAsyncTaskHandle)
 {
-    return (HANDLE16)WSACancelAsyncRequest16((HANDLE32)hAsyncTaskHandle);
+    return (HANDLE16)WSACancelAsyncRequest32((HANDLE32)hAsyncTaskHandle);
 }
 
 /***********************************************************************