Release 970914

Thu Sep 11 18:24:56 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [objects/dc.c]
	In DC_SetupGCForPatBlt, replace R2_NOT by GXxor with (black xor white).

Tue Sep  9 23:04:02 1997  U. Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>

	* [memory/virtual.c] 
	Do not write debugging info unconditionally to stderr.

	* [files/profile.c]
	Call PROFILE_GetSection in PROFILE_GetString for key_name "" too.

	* [misc/crtdll.c]
	Many new functions.

	* [include/windows.h] [windows/winpos.c]
	ClientToScreen16 doesn't have a return value.

Sun Sep  7 10:06:39 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [misc/main.c] [AUTHORS]
	Update the list of contributors. Please let me know if I forgot
	someone.

	* [if1632/*.spec] [if1632/builtin.c] [tools/build.c]
	Ordinal base for Win32 DLLs is now computed automatically from the
	lowest ordinal found.

	* [include/wintypes.h]
	WINAPI is now defined as attribute((stdcall)). This will require
	gcc to compile.

	* [if1632/thunk.c]
	Removed Win32 thunks (no longer needed with stdcall).

	* [if1632/crtdll.spec] [misc/crtdll.c]
	Make sure we only reference cdecl functions in the spec file.

	* [objects/dc.c]
	Use CapNotLast drawing style for 1-pixel wide lines.

	* [tools/build.c]
	Added 'double' argument type.
	Added 'varargs' function type for Win32.
	Made CallTo16_xxx functions stdcall.

Fri Sep  5 14:50:49 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [tools/build.c] [windows/win.c] [windows/event.c] [windows/message.c]
	More fixes to get message exchange closer to the original.

	* [misc/spy.c]
	Message logs now contain window names.

	* [loader/resource.c] [loader/ne_resource.c] [loader/task.c]
	  [objects/cursoricon.c] [windows/user.c]
	Added some obscure features to fix memory leaks.

Fri Sep  5 00:46:28 1997  Jan Willamowius <jan@janhh.shnet.org>

	* [if1632/kernel32.spec] [win32/newfns.c]
	Added stub for UTRegister() and UTUnRegister().

Thu Sep  4 12:03:12 1997  Frans van Dorsselaer <dorssel@rulhmpc49.LeidenUniv.nl>
	* [controls/edit.c]
	Allow ASCII codes > 127 in WM_CHAR.

Mon Sep  1 17:23:24 1997  Dimitrie O. Paun  <dimi@mail.cs.toronto.edu>

	* [controls/widgets.c]
	In InitCommonControls, remember the name of the class
	because lpszClassName was made to point to a local array
	Added the ProgressBar to the list of implemented controls.
	Call InitCommonControls from WIDGETS_Init to register all
	implemented Common Controls.
	
	* [include/commctrl.h]
	Added misc decl for the Progress Bar.

	* [controls/progress.c] [include/progress.h]
	First attempt at implementiong the Progress Bar class.

	* [objects/brush.h]
	Implementation for GetSysColorBrush[16|32]

	* [controls/status.c]
	Use DrawEdge to draw the borders and fill the background

	* [controls/uitools.c]
	Added DrawDiagEdge32 and DrawRectEdge32

	* [graphics/painting.c]
	Implement DrawEdge[16|32]
	Started DrawFrameControl32

Mon Sep  1 10:07:09 1997  Lawson Whitney <lawson_whitney@juno.com>

	* [misc/comm.c] [include/windows.h]
	SetCommEventMask returns a SEGPTR.

Sun Aug 31 23:28:32 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [loader/pe_image.c][loader/module.c][include/pe_image.h]
	  [include/module.h]
	Cleaned up the whole Win32 library mess (a bit).

	* [debugger/stabs.c]
	If 'wine' has no absolute path and isn't found, check $PATH too.

	* [misc/ole2nls.c]
	Some fixes.

	* [misc/ver.c]
	Added support for PE style version resources.

	* [memory/string.c]
	Check for NULL pointers to _lstr* functions, just as Windows95 does.

	* [multimedia/time.c]
	Made list of timers a simple linked list.

	* [loader/resource.c]
	Netscape 3 seems to pass NEGATIVE resource Ids (in an
	unsigned int, yes). Don't know why, fixed it anyway.

	* [objects/bitmap.c]
	LoadImageW added.

	* [include/win.h][windows/win.c]
	Change wIDmenu from UINT16 to UINT32 and changed the
	SetWindow(Long|Word) accordingly.

Thu Aug 28 19:30:08 1997  Morten Welinder  <terra@diku.dk>

	* [include/windows.h]
	Add a few more colors defined for Win95.
	Add a few more brush styles.

	* [windows/syscolor.c]
 	Add error checks for SYSCOLOR_SetColor, SYSCOLOR_Init,
	GetSysColor16, GetSysColor32.  Add support for above colors.

Sun Aug 24 16:22:57 1997  Andrew Taylor <andrew@riscan.com>

	* [multimedia/mmsystem.c]
	Changed mmioDescend to use mmio functions for file I/O, neccessary
	for memory files.
diff --git a/misc/comm.c b/misc/comm.c
index f23666f..22e16c9 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -1,4 +1,4 @@
-/*
+ /*
  * DEC 93 Erik Bos <erik@xs4all.nl>
  *
  * Copyright 1996 Marcus Meissner
@@ -11,6 +11,9 @@
  *   IMHO, they are still wrong, but they at least implement the RXCHAR
  *   event and return I/O queue sizes, which makes the app I'm interested
  *   in (analog devices EZKIT DSP development system) work.
+ *
+ * August 12, 1997.  Take a bash at SetCommEventMask - Lawson Whitney
+ *                                     <lawson_whitney@juno.com>
  */
 
 #include <stdio.h>
@@ -38,7 +41,7 @@
 #ifndef TIOCINQ
 #define	TIOCINQ FIONREAD
 #endif
-
+#define msr  35       /* offset in unknown structure commMask */
 /*
  * [RER] These are globals are wrong.  They should be in DosDeviceStruct
  * on a per port basis.
@@ -47,6 +50,7 @@
 
 struct DosDeviceStruct COM[MAX_PORTS];
 struct DosDeviceStruct LPT[MAX_PORTS];
+LPCVOID *unknown[MAX_PORTS];
 
 void COMM_Init(void)
 {
@@ -126,6 +130,18 @@
 	return NULL;
 }
 
+int    GetCommPort(int fd)
+{
+        int x;
+        
+        for (x=0; x<MAX_PORTS; x++) {
+             if (COM[x].fd == fd)
+                 return x;
+       }
+       
+       return -1;
+} 
+
 int ValidCOMPort(int x)
 {
 	return(x < MAX_PORTS ? (int) COM[x].devicename : 0); 
@@ -436,6 +452,8 @@
 			commerror = WinError();
 			return -1;
 		} else {
+                        unknown[port] = SEGPTR_ALLOC(40);
+                        bzero(unknown[port],40);
 			COM[port].fd = fd;	
 			return fd;
 		}
@@ -470,16 +488,16 @@
  */
 INT16 WINAPI CloseComm(INT16 fd)
 {
-	struct DosDeviceStruct *ptr;
-
+        int port;
     	dprintf_comm(stddeb,"CloseComm: fd %d\n", fd);
-	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+       	if ((port = GetCommPort(fd)) !=-1) {  /* [LW]       */
+    	        SEGPTR_FREE(unknown[port]); 
+    	        COM[port].fd = 0;       /*  my adaptation of RER's fix   */  
+        }  else {  	        
 		commerror = IE_BADID;
 		return -1;
 	}
 
-	ptr->fd = 0;	/* [RER] Really, -1 would be a better value */
-
 	if (close(fd) == -1) {
 		commerror = WinError();
 		return -1;
@@ -738,7 +756,17 @@
 	}
 }  
 
-/*****************************************************************************
+/********************************************************************
+ *      PurgeComm        (KERNEL32.557)
+ */
+BOOL32 WINAPI PurgeComm( HANDLE32 hFile, DWORD flags) 
+{
+    dprintf_comm(stdnimp, "PurgeComm(%08x %08lx) unimplemented stub\n",
+                 hFile, flags);
+    return 0;
+}
+
+/********************************************************************
  *	GetCommError	(USER.203)
  */
 INT16 WINAPI GetCommError(INT16 fd,LPCOMSTAT lpStat)
@@ -794,11 +822,26 @@
 /*****************************************************************************
  *	SetCommEventMask	(USER.208)
  */
-UINT16* WINAPI SetCommEventMask(INT16 fd,UINT16 fuEvtMask)
+SEGPTR WINAPI SetCommEventMask(INT16 fd,UINT16 fuEvtMask)
 {
+        unsigned char *stol;
+        int act;
+        int repid;
+        unsigned int mstat;
     	dprintf_comm(stddeb,"SetCommEventMask:fd %d,mask %d\n",fd,fuEvtMask);
 	eventmask |= fuEvtMask;
-	return (UINT16 *)&eventmask;	/* FIXME, should be SEGPTR */
+        if ((act = GetCommPort(fd)) == -1) {
+            dprintf_comm(stddeb," fd %d not comm port\n",act);
+            return NULL;}
+        stol =  unknown[act];
+        stol += msr;    
+	repid = ioctl(fd,TIOCMGET,&mstat);
+	dprintf_comm(stddeb,
+	" ioctl  %d, msr %x at %lx %lx\n",repid,mstat,stol,unknown[act]);
+	if ((mstat&TIOCM_CAR)) {*stol |= 0x80;}
+	     else {*stol &=0x7f;}
+	dprintf_comm(stddeb," modem dcd construct %x\n",*stol);
+	return SEGPTR_GET(unknown[act]);	
 }
 
 /*****************************************************************************
@@ -846,6 +889,15 @@
 }
 
 /*****************************************************************************
+ *      SetupComm       (KERNEL32.676)
+ */
+BOOL32 WINAPI SetupComm( HANDLE32 hFile, DWORD insize, DWORD outsize)
+{
+        dprintf_comm(stdnimp, "SetupComm: insize %ld outsize %ld unimplemented stub\n", insize, outsize);
+       return FALSE;
+} 
+
+/*****************************************************************************
  *	GetCommMask	(KERNEL32.156)
  */
 BOOL32 WINAPI GetCommMask(INT32 fd,LPDWORD evtmask)
@@ -1599,7 +1651,7 @@
  */
 INT16 WINAPI ReadComm(INT16 fd,LPSTR lpvBuf,INT16 cbRead)
 {
-	int status, length;
+	int status, x, length;
 	struct DosDeviceStruct *ptr;
 
     	dprintf_comm(stddeb,
@@ -1634,6 +1686,9 @@
                         return length;
                 }
  	} else {
+                for (x=0; x < length+status; x++)  	
+ 	        dprintf_comm(stddeb,"%c",*(lpvBuf+x));
+ 	        dprintf_comm(stddeb,"\nthus  endeth\n");
 		commerror = 0;
 		return length + status;
 	}
@@ -1661,7 +1716,7 @@
 	
 	for (x=0; x != cbWrite ; x++)
         dprintf_comm(stddeb,"%c", *(lpvBuf + x) );
-
+        dprintf_comm(stddeb,"\n");
 	length = write(fd, (void *) lpvBuf, cbWrite);
 	
 	if (length == -1) {
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 34f91a7..f21978e 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -58,7 +58,7 @@
  */
 BOOL16 WINAPI GetOpenFileName16( SEGPTR ofn )
 {
-    HINSTANCE16 hInst;
+    HINSTANCE32 hInst;
     HANDLE32 hDlgTmpl = 0, hResInfo;
     BOOL32 bRet = FALSE, win32Format = FALSE;
     HWND32 hwndDialog;
@@ -148,7 +148,7 @@
  */
 BOOL16 WINAPI GetSaveFileName16( SEGPTR ofn)
 {
-    HINSTANCE16 hInst;
+    HINSTANCE32 hInst;
     HANDLE32 hDlgTmpl = 0;
     BOOL32 bRet = FALSE, win32Format = FALSE;
     LPOPENFILENAME16 lpofn = (LPOPENFILENAME16)PTR_SEG_TO_LIN(ofn);
@@ -3028,7 +3028,8 @@
 	memset(ofn16,'\0',sizeof(*ofn16));				\
 	ofn16->lStructSize = sizeof(*ofn16);				\
 	ofn16->hwndOwner = ofn->hwndOwner;				\
-	ofn16->hInstance = ofn->hInstance;				\
+	/* FIXME: OPENFILENAME16 got only 16 bit for HINSTANCE... */	\
+	ofn16->hInstance = MODULE_HANDLEtoHMODULE16(ofn->hInstance);	\
 	if (ofn->lpstrFilter) {						\
 		LPSTR	s,x;						\
 									\
@@ -3107,7 +3108,8 @@
 	memset(ofn16,'\0',sizeof(*ofn16));				\
 	ofn16->lStructSize = sizeof(*ofn16);				\
 	ofn16->hwndOwner = ofn->hwndOwner;				\
-	ofn16->hInstance = ofn->hInstance;				\
+	/* FIXME: OPENFILENAME16 got only 16 bit for HINSTANCE... */	\
+	ofn16->hInstance = MODULE_HANDLEtoHMODULE16(ofn->hInstance);	\
 	if (ofn->lpstrFilter) {						\
 		LPWSTR	s;						\
 		LPSTR	x,y;						\
@@ -3119,7 +3121,7 @@
 			s = s+lstrlen32W(s)+1;				\
 		s++;							\
 		n = s - ofn->lpstrFilter; /* already divides by 2. ptr magic */\
-		x = y = (LPSTR)SEGPTR_ALLOC(n);			\
+		x = y = (LPSTR)SEGPTR_ALLOC(n);				\
 		s = (LPWSTR)ofn->lpstrFilter;				\
 		while (*s) {						\
 			lstrcpyWtoA(x,s);				\
diff --git a/misc/compobj.c b/misc/compobj.c
index 6fa4010..40c9444 100644
--- a/misc/compobj.c
+++ b/misc/compobj.c
@@ -72,6 +72,14 @@
 }
 
 /***********************************************************************
+ *           IsEqualGUID [COMPOBJ.18]
+ */
+BOOL16 WINAPI IsEqualGUID(GUID* g1, GUID* g2)
+{
+    return !memcmp( g1, g2, sizeof(GUID) );
+}
+
+/***********************************************************************
  *           CLSIDFromString [COMPOBJ.20]
  */
 
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 707e479..7ba7d07 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -5,8 +5,21 @@
  *
  * Copyright 1996 Marcus Meissner
  * Copyright 1996 Jukka Iivonen
+ * Copyright 1997 Uwe Bonnes
  */
 
+/*
+Unresolved issues Uwe Bonnes 970904:
+- Handling of Binary/Text Files is crude. If in doubt, use fromdos or recode
+- Arguments in crtdll.spec for functions with double argument
+- system-call calls another wine process, but without debugging arguments
+              and uses the first wine executable in the path
+- tested with ftp://ftp.remcomp.com/pub/remcomp/lcc-win32.zip, a C-Compiler
+ 		for Win32, based on lcc, from Jacob Navia
+*/
+
+/* FIXME: all the file handling is hopelessly broken -- AJ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -15,6 +28,7 @@
 #include <time.h>
 #include <ctype.h>
 #include <math.h>
+#include <fcntl.h>
 #include "win.h"
 #include "windows.h"
 #include "stddebug.h"
@@ -24,6 +38,11 @@
 #include "heap.h"
 #include "crtdll.h"
 #include "drive.h"
+#include "file.h"
+
+extern int FILE_GetUnixHandle( HFILE32  );
+
+static DOS_FULL_NAME CRTDLL_tmpname;
 
 extern INT32 WIN32_wsprintf32W( DWORD *args );
 
@@ -49,18 +68,20 @@
 /*********************************************************************
  *                  _GetMainArgs  (CRTDLL.022)
  */
-DWORD
-CRTDLL__GetMainArgs(LPDWORD argc,LPSTR **argv,LPSTR *environ,DWORD flag)
+DWORD __cdecl CRTDLL__GetMainArgs(LPDWORD argc,LPSTR **argv,
+                                LPSTR *environ,DWORD flag)
 {
         char *cmdline;
         char  **xargv;
 	int	xargc,i,afterlastspace;
 	DWORD	version;
 
-	dprintf_crtdll(stderr,"__GetMainArgs(%p,%p,%p,%ld).\n",
+	dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs(%p,%p,%p,%ld).\n",
 		argc,argv,environ,flag
 	);
 	CRTDLL_acmdln_dll = cmdline = xstrdup( GetCommandLine32A() );
+ 	dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs got \"%s\"\n",
+		cmdline);
 
 	version	= GetVersion32();
 	CRTDLL_osver_dll       = version >> 16;
@@ -98,6 +119,8 @@
 	CRTDLL_argv_dll	= xargv;
 	*argv		= xargv;
 
+	dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs found %d arguments\n",
+		CRTDLL_argc_dll);
 	/* FIXME ... use real environment */
 	*environ	= xmalloc(sizeof(LPSTR));
 	CRTDLL_environ_dll = *environ;
@@ -105,12 +128,13 @@
 	return 0;
 }
 
+
 typedef void (*_INITTERMFUN)();
 
 /*********************************************************************
  *                  _initterm     (CRTDLL.135)
  */
-DWORD CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
+DWORD __cdecl CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
 {
 	_INITTERMFUN	*current;
 
@@ -124,9 +148,208 @@
 }
 
 /*********************************************************************
+ *                  _fdopen     (CRTDLL.91)
+ */
+DWORD __cdecl CRTDLL__fdopen(INT32 handle, LPCSTR mode)
+{
+  FILE *file;
+
+  switch (handle) 
+    {
+    case 0 : file=stdin;
+      break;
+    case 1 : file=stdout;
+      break;
+    case 2 : file=stderr;
+      break;
+    default:
+      file=fdopen(handle,mode);
+    }
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fdopen open handle %d mode %s  got file %p\n",
+		 handle, mode, file);
+  return (DWORD)file;
+}
+
+/*********************************************************************
+ *                  fopen     (CRTDLL.372)
+ */
+DWORD __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
+{
+  FILE *file;
+  HFILE32 dos_fildes;
+#if 0
+  DOS_FULL_NAME full_name;
+  
+  if (!DOSFS_GetFullName( path, FALSE, &full_name )) {
+    dprintf_crtdll(stddeb,"CRTDLL_fopen file %s bad name\n",path);
+   return 0;
+  }
+  
+  file=fopen(full_name.long_name ,mode);
+#endif
+  INT32 flagmode=0;
+  int unix_fildes=0;
+
+  if ((strchr(mode,'r')&&strchr(mode,'a'))||
+      (strchr(mode,'r')&&strchr(mode,'w'))||
+      (strchr(mode,'w')&&strchr(mode,'a')))
+    return 0;
+       
+  if (strstr(mode,"r+")) flagmode=O_RDWR;
+  else if (strchr(mode,'r')) flagmode = O_RDONLY;
+  else if (strstr(mode,"w+")) flagmode= O_RDWR | O_TRUNC | O_CREAT;
+  else if (strchr(mode,'w')) flagmode = O_WRONLY | O_TRUNC | O_CREAT;
+  else if (strstr(mode,"a+")) flagmode= O_RDWR | O_CREAT | O_APPEND;
+  else if (strchr(mode,'w')) flagmode = O_RDWR | O_CREAT | O_APPEND;
+  else if (strchr(mode,'b'))
+    dprintf_crtdll(stderr,
+		   "CRTDLL_fopen %s in BINARY mode\n",path);
+      
+  dos_fildes=FILE_Open(path, flagmode);
+  unix_fildes=FILE_GetUnixHandle(dos_fildes);
+  file = fdopen(unix_fildes,mode);
+
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fopen file %s mode %s got ufh %d dfh %d file %p\n",
+		 path,mode,unix_fildes,dos_fildes,file);
+  return (DWORD)file;
+}
+
+/*********************************************************************
+ *                  fread     (CRTDLL.377)
+ */
+DWORD __cdecl CRTDLL_fread(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID file)
+{
+  size_t ret=1;
+#if 0
+  int i=0;
+  void *temp=ptr;
+
+  /* If we would honour CR/LF <-> LF translation, we could do it like this.
+     We should keep track of all files opened, and probably files with \
+     known binary extensions must be unchanged */
+  while ( (i < (nmemb*size)) && (ret==1)) {
+    ret=fread(temp,1,1,file);
+    dprintf_crtdll(stddeb,
+		 "CRTDLL_fread got %c 0x%02x ret %d\n",
+		   (isalpha(*(unsigned char*)temp))? *(unsigned char*)temp:
+		    ' ',*(unsigned char*)temp, ret);
+    if (*(unsigned char*)temp != 0xd) { /* skip CR */
+      temp++;
+      i++;
+    }
+    else
+      dprintf_crtdll(stddeb, "CRTDLL_fread skipping ^M\n");
+  }
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fread 0x%08x items of size %d from file %p to %p%s\n",
+		 nmemb,size,file,ptr,(i!=nmemb)?" failed":"");
+  return i;
+#else
+    
+  ret=fread(ptr,size,nmemb,file);
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fread 0x%08x items of size %d from file %p to %p%s\n",
+		 nmemb,size,file,ptr,(ret!=nmemb)?" failed":"");
+  return ret;
+#endif
+}
+  
+/*********************************************************************
+ *                  fseek     (CRTDLL.382)
+ */
+LONG __cdecl CRTDLL_fseek(LPVOID stream, LONG offset, INT32 whence)
+{
+  long ret;
+
+  ret=fseek(stream,offset,whence);
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fseek file %p to 0x%08lx pos %s%s\n",
+		 stream,offset,(whence==SEEK_SET)?"SEEK_SET":
+		 (whence==SEEK_CUR)?"SEEK_CUR":
+		 (whence==SEEK_END)?"SEEK_END":"UNKNOWN",
+		 (ret)?"failed":"");
+  return ret;
+}
+  
+/*********************************************************************
+ *                  ftell     (CRTDLL.384)
+ */
+LONG __cdecl CRTDLL_ftell(LPVOID stream)
+{
+  long ret;
+
+  ret=ftell(stream);
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_ftell file %p at 0x%08lx\n",
+		 stream,ret);
+  return ret;
+}
+  
+/*********************************************************************
+ *                  fwrite     (CRTDLL.386)
+ */
+DWORD __cdecl CRTDLL_fwrite(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID file)
+{
+  size_t ret;
+
+  ret=fwrite(ptr,size,nmemb,file);
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fwrite 0x%08x items of size %d from %p to file %p%s\n",
+		 nmemb,size,ptr,file,(ret!=nmemb)?" failed":"");
+  return ret;
+}
+
+/*********************************************************************
+ *                  setbuf     (CRTDLL.452)
+ */
+INT32 __cdecl CRTDLL_setbuf(LPVOID file, LPSTR buf)
+{
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_setbuf(file %p buf %p)\n",
+		 file,buf);
+  /* this doesn't work:"void value not ignored as it ought to be" 
+  return setbuf(file,buf); 
+  */
+  setbuf(file,buf);
+  return 0;
+}
+
+/*********************************************************************
+ *                  _open_osfhandle         (CRTDLL.240)
+ */
+HFILE32 __cdecl CRTDLL__open_osfhandle(LONG osfhandle, INT32 flags)
+{
+HFILE32 handle;
+ 
+	switch (osfhandle) {
+	case STD_INPUT_HANDLE :
+	case 0 :
+	  handle=0;
+	  break;
+ 	case STD_OUTPUT_HANDLE:
+ 	case 1:
+	  handle=1;
+	  break;
+	case STD_ERROR_HANDLE:
+	case 2:
+	  handle=2;
+	  break;
+	default:
+	  return (-1);
+	}
+	dprintf_crtdll(stddeb,
+		       "CRTDLL_open_osfhandle(handle %08lx,flags %d) return %d\n",
+		       osfhandle,flags,handle);
+	return handle;
+	
+}
+
+/*********************************************************************
  *                  srand         (CRTDLL.460)
  */
-void CRTDLL_srand(DWORD seed)
+void __cdecl CRTDLL_srand(DWORD seed)
 {
 	/* FIXME: should of course be thread? process? local */
 	srand(seed);
@@ -135,35 +358,29 @@
 /*********************************************************************
  *                  fprintf       (CRTDLL.373)
  */
-int CRTDLL_fprintf(DWORD *args)
+INT32 __cdecl CRTDLL_fprintf( FILE *file, LPSTR format, ... )
 {
-	/* FIXME: use args[0] */
-	/* CMF - This makes a BIG assumption about va_list */
-	return vfprintf(stderr, (LPSTR) args[1], (va_list) &args[2]);
+    va_list valist;
+    INT32 res;
+
+    va_start( valist, format );
+    res = vfprintf( file, format, valist );
+    va_end( valist );
+    return res;
 }
 
 /*********************************************************************
- *                  printf        (CRTDLL.440)
+ *                  vfprintf       (CRTDLL.373)
  */
-int CRTDLL_printf(DWORD *args)
+INT32 __cdecl CRTDLL_vfprintf( FILE *file, LPSTR format, va_list args )
 {
-	/* CMF - This makes a BIG assumption about va_list */
-	return vfprintf(stdout, (LPSTR) args[0], (va_list) &args[1]);
-}
-
-/*********************************************************************
- *                  sprintf        (CRTDLL.458)
- */
-int CRTDLL_sprintf(DWORD *args)
-{
-	/* CMF - This makes a BIG assumption about va_list */
-	return vsprintf((LPSTR) args[0], (LPSTR) args[1], (va_list) &args[2]);
+    return vfprintf( file, format, args );
 }
 
 /*********************************************************************
  *                  time          (CRTDLL.488)
  */
-time_t CRTDLL_time(time_t *timeptr)
+time_t __cdecl CRTDLL_time(time_t *timeptr)
 {
 	time_t	curtime = time(NULL);
 
@@ -175,7 +392,7 @@
 /*********************************************************************
  *                  _isatty       (CRTDLL.137)
  */
-BOOL32 CRTDLL__isatty(DWORD x)
+BOOL32 __cdecl CRTDLL__isatty(DWORD x)
 {
 	dprintf_crtdll(stderr,"CRTDLL__isatty(%ld)\n",x);
 	return TRUE;
@@ -184,22 +401,45 @@
 /*********************************************************************
  *                  _write        (CRTDLL.332)
  */
-INT32 CRTDLL__write(DWORD x,LPVOID buf,DWORD len)
+INT32 __cdecl CRTDLL__write(INT32 fd,LPCVOID buf,UINT32 count)
 {
-	if (x<=2)
-		return write(x,buf,len);
-	/* hmm ... */
-	dprintf_crtdll(stderr,"CRTDLL__write(%ld,%p,%ld)\n",x,buf,len);
+        INT32 len=0;
+
+	if (fd == -1)
+	  len = -1;
+	else if (fd<=2)
+	  len = (UINT32)write(fd,buf,(LONG)len);
+	else
+	  len = _lwrite32(fd,buf,count);
+	dprintf_crtdll(stddeb,"CRTDLL_write %d/%d byte to dfh %d from %p,\n",
+		       len,count,fd,buf);
 	return len;
 }
 
 
 /*********************************************************************
+ *                  _cexit          (CRTDLL.49)
+ *
+ *  FIXME: What the heck is the difference between 
+ *  FIXME           _c_exit         (CRTDLL.47)
+ *  FIXME           _cexit          (CRTDLL.49)
+ *  FIXME           _exit           (CRTDLL.87)
+ *  FIXME           exit            (CRTDLL.359)
+ *
+ */
+void __cdecl CRTDLL__cexit(INT32 ret)
+{
+        dprintf_crtdll(stddeb,"CRTDLL__cexit(%d)\n",ret);
+	ExitProcess(ret);
+}
+
+
+/*********************************************************************
  *                  exit          (CRTDLL.359)
  */
-void CRTDLL_exit(DWORD ret)
+void __cdecl CRTDLL_exit(DWORD ret)
 {
-        dprintf_crtdll(stderr,"CRTDLL_exit(%ld)\n",ret);
+        dprintf_crtdll(stddeb,"CRTDLL_exit(%ld)\n",ret);
 	ExitProcess(ret);
 }
 
@@ -207,16 +447,20 @@
 /*********************************************************************
  *                  fflush        (CRTDLL.365)
  */
-void CRTDLL_fflush(DWORD x)
+INT32 __cdecl CRTDLL_fflush(LPVOID stream)
 {
-    dprintf_crtdll(stderr,"CRTDLL_fflush(%ld)\n",x);
+    int ret;
+
+    ret = fflush(stream);
+    dprintf_crtdll(stddeb,"CRTDLL_fflush %p returnd %d %s\n",stream,ret,(ret)?"":" failed");
+    return ret;
 }
 
 
 /*********************************************************************
  *                  gets          (CRTDLL.391)
  */
-LPSTR CRTDLL_gets(LPSTR buf)
+LPSTR __cdecl CRTDLL_gets(LPSTR buf)
 {
   /* BAD, for the whole WINE process blocks... just done this way to test
    * windows95's ftp.exe.
@@ -226,335 +470,131 @@
 
 
 /*********************************************************************
- *                  abs           (CRTDLL.339)
- */
-INT32 CRTDLL_abs(INT32 x)
-{
-    return abs(x);
-}
-
-
-/*********************************************************************
- *                  acos          (CRTDLL.340)
- */
-float CRTDLL_acos(float x)
-{
-    return acos(x);
-}
-
-
-/*********************************************************************
- *                  asin          (CRTDLL.342)
- */
-float CRTDLL_asin(float x)
-{
-    return asin(x);
-}
-
-
-/*********************************************************************
- *                  atan          (CRTDLL.343)
- */
-float CRTDLL_atan(float x)
-{
-    return atan(x);
-}
-
-
-/*********************************************************************
- *                  atan2         (CRTDLL.344)
- */
-float CRTDLL_atan2(float x, float y)
-{
-    return atan2(x,y);
-}
-
-
-/*********************************************************************
- *                  atof          (CRTDLL.346)
- */
-float CRTDLL_atof(LPCSTR x)
-{
-    return atof(x);
-}
-
-
-/*********************************************************************
- *                  atoi          (CRTDLL.347)
- */
-INT32 CRTDLL_atoi(LPCSTR x)
-{
-    if (!x) return 0;
-    return atoi(x);
-}
-
-
-/*********************************************************************
- *                  atol          (CRTDLL.348)
- */
-LONG CRTDLL_atol(LPCSTR x)
-{
-    if (!x) return 0;
-    return atol(x);
-}
-
-
-/*********************************************************************
- *                  cos           (CRTDLL.354)
- */
-float CRTDLL_cos(float x)
-{
-    return cos(x);
-}
-
-
-/*********************************************************************
- *                  cosh          (CRTDLL.355)
- */
-float CRTDLL_cosh(float x)
-{
-    return cosh(x);
-}
-
-
-/*********************************************************************
- *                  exp           (CRTDLL.360)
- */
-float CRTDLL_exp(float x)
-{
-    return exp(x);
-}
-
-
-/*********************************************************************
- *                  fabs          (CRTDLL.361)
- */
-float CRTDLL_fabs(float x)
-{
-    return fabs(x);
-}
-
-
-/*********************************************************************
- *                  isalnum       (CRTDLL.394)
- */
-CHAR CRTDLL_isalnum(CHAR x)
-{
-    return isalnum(x);
-}
-
-
-/*********************************************************************
- *                  isalpha       (CRTDLL.395)
- */
-CHAR CRTDLL_isalpha(CHAR x)
-{
-    return isalpha(x);
-}
-
-
-/*********************************************************************
- *                  iscntrl       (CRTDLL.396)
- */
-CHAR CRTDLL_iscntrl(CHAR x)
-{
-    return iscntrl(x);
-}
-
-
-/*********************************************************************
- *                  isdigit       (CRTDLL.397)
- */
-CHAR CRTDLL_isdigit(CHAR x)
-{
-    return isdigit(x);
-}
-
-
-/*********************************************************************
- *                  isgraph       (CRTDLL.398)
- */
-CHAR CRTDLL_isgraph(CHAR x)
-{
-    return isgraph(x);
-}
-
-
-/*********************************************************************
- *                  islower       (CRTDLL.400)
- */
-CHAR CRTDLL_islower(CHAR x)
-{
-    return islower(x);
-}
-
-
-/*********************************************************************
- *                  isprint       (CRTDLL.401)
- */
-CHAR CRTDLL_isprint(CHAR x)
-{
-    return isprint(x);
-}
-
-
-/*********************************************************************
- *                  ispunct       (CRTDLL.402)
- */
-CHAR CRTDLL_ispunct(CHAR x)
-{
-    return ispunct(x);
-}
-
-
-/*********************************************************************
- *                  isspace       (CRTDLL.403)
- */
-CHAR CRTDLL_isspace(CHAR x)
-{
-    return isspace(x);
-}
-
-
-/*********************************************************************
- *                  isupper       (CRTDLL.404)
- */
-CHAR CRTDLL_isupper(CHAR x)
-{
-    return isupper(x);
-}
-
-
-/*********************************************************************
- *                  isxdigit      (CRTDLL.418)
- */
-CHAR CRTDLL_isxdigit(CHAR x)
-{
-    return isxdigit(x);
-}
-
-
-/*********************************************************************
- *                  labs          (CRTDLL.419)
- */
-LONG CRTDLL_labs(LONG x)
-{
-    return labs(x);
-}
-
-
-/*********************************************************************
- *                  log           (CRTDLL.424)
- */
-float CRTDLL_log(float x)
-{
-    return log(x);
-}
-
-
-/*********************************************************************
- *                  log10         (CRTDLL.425)
- */
-float CRTDLL_log10(float x)
-{
-    return log10(x);
-}
-
-
-/*********************************************************************
- *                  pow           (CRTDLL.439)
- */
-float CRTDLL_pow(float x, float y)
-{
-    return pow(x,y);
-}
-
-
-/*********************************************************************
  *                  rand          (CRTDLL.446)
  */
-INT32 CRTDLL_rand()
+INT32 __cdecl CRTDLL_rand()
 {
     return rand();
 }
 
 
 /*********************************************************************
- *                  sin           (CRTDLL.456)
- */
-float CRTDLL_sin(float x)
-{
-    return sin(x);
-}
-
-
-/*********************************************************************
- *                  sinh          (CRTDLL.457)
- */
-float CRTDLL_sinh(float x)
-{
-    return sinh(x);
-}
-
-
-/*********************************************************************
- *                  sqrt          (CRTDLL.459)
- */
-double CRTDLL_sqrt(double x)
-{
-    return sqrt(x);
-}
-
-
-/*********************************************************************
- *                  tan           (CRTDLL.486)
- */
-float CRTDLL_tan(float x)
-{
-    return tan(x);
-}
-
-
-/*********************************************************************
- *                  tanh          (CRTDLL.487)
- */
-float CRTDLL_tanh(float x)
-{
-    return tanh(x);
-}
-
-
-/*********************************************************************
- *                  tolower       (CRTDLL.491)
- */
-CHAR CRTDLL_tolower(CHAR x)
-{
-    return tolower(x);
-}
-
-
-/*********************************************************************
- *                  toupper       (CRTDLL.492)
- */
-CHAR CRTDLL_toupper(CHAR x)
-{
-    return toupper(x);
-}
-
-
-/*********************************************************************
  *                  putchar       (CRTDLL.442)
  */
-void CRTDLL_putchar(INT32 x)
+void __cdecl CRTDLL_putchar( INT32 x )
 {
     putchar(x);
 }
 
 
 /*********************************************************************
+ *                  fputc       (CRTDLL.374)
+ */
+INT32 __cdecl CRTDLL_fputc( INT32 c, FILE *stream )
+{
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fputc %c to file %p\n",c,stream);
+    return fputc(c,stream);
+}
+
+
+/*********************************************************************
+ *                  fputs       (CRTDLL.375)
+ */
+INT32 __cdecl CRTDLL_fputs( LPCSTR s, FILE *stream )
+{
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fputs %s to file %p\n",s,stream);
+    return fputs(s,stream);
+}
+
+
+/*********************************************************************
+ *                  puts       (CRTDLL.443)
+ */
+INT32 __cdecl CRTDLL_puts(LPCSTR s)
+{
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fputs %s \n",s);
+    return puts(s);
+}
+
+
+/*********************************************************************
+ *                  putc       (CRTDLL.441)
+ */
+INT32 __cdecl CRTDLL_putc(INT32 c, FILE *stream)
+{
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_putc %c to file %p\n",c,stream);
+    return fputc(c,stream);
+}
+/*********************************************************************
+ *                  fgetc       (CRTDLL.366)
+ */
+INT32 __cdecl CRTDLL_fgetc( FILE *stream )
+{
+  int ret= fgetc(stream);
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fgetc got %d\n",ret);
+  return ret;
+}
+
+
+/*********************************************************************
+ *                  getc       (CRTDLL.388)
+ */
+INT32 __cdecl CRTDLL_getc( FILE *stream )
+{
+  int ret= fgetc(stream);
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_getc got %d\n",ret);
+  return ret;
+}
+
+/*********************************************************************
+ *                  _lrotl          (CRTDLL.176)
+ */
+DWORD __cdecl CRTDLL__lrotl(DWORD x,INT32 shift)
+{
+   unsigned long ret = (x >> shift)|( x >>((sizeof(x))-shift));
+
+   dprintf_crtdll(stddeb,
+		  "CRTDLL_lrotl got 0x%08lx rot %d ret 0x%08lx\n",
+		  x,shift,ret);
+   return ret;
+    
+}
+
+
+/*********************************************************************
+ *                  fgets       (CRTDLL.368)
+ */
+CHAR* __cdecl CRTDLL_fgets(LPSTR s,INT32 size, LPVOID stream)
+{
+  char * ret;
+  char * control_M;
+  
+  ret=fgets(s, size,stream);
+  /*FIXME: Control with CRTDLL_setmode */
+  control_M= strrchr(s,'\r');
+  /*delete CR if we read a DOS File */
+  if (control_M)
+    {
+      *control_M='\n';
+      *(control_M+1)=0;
+    }
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_fgets got %s for %d chars from file %p%s\n",
+		 s,size,stream,(ret)?"":" failed");
+  return ret;
+}
+
+
+/*********************************************************************
  *                  _mbsicmp      (CRTDLL.204)
  */
-int CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
+int __cdecl CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
 {
     do {
 	if (!*x)
@@ -573,7 +613,7 @@
 /*********************************************************************
  *                  _mbsinc       (CRTDLL.205)
  */
-unsigned char* CRTDLL__mbsinc(unsigned char *x)
+unsigned char * __cdecl CRTDLL__mbsinc(unsigned char *x)
 {
     /* FIXME: mbcs */
     return x++;
@@ -583,27 +623,25 @@
 /*********************************************************************
  *                  vsprintf      (CRTDLL.500)
  */
-int CRTDLL_vsprintf(DWORD *args)
+INT32 __cdecl CRTDLL_vsprintf( LPSTR buffer, LPCSTR spec, va_list args )
 {
-	/* CMF - This makes a BIG assumption about va_list */
-	return vsprintf((char *) args[0], (char *) args[1], (va_list) &args[2]);
+    return wvsprintf32A( buffer, spec, args );
 }
 
 /*********************************************************************
- *                  vsprintf      (CRTDLL.500) (NTDLL.913)
+ *                  vswprintf      (CRTDLL.501)
  */
-int CRTDLL_sscanf(DWORD *args)
+INT32 __cdecl CRTDLL_vswprintf( LPWSTR buffer, LPCWSTR spec, va_list args )
 {
-	/* CMF - This makes a BIG assumption about va_list */
-	return vsscanf((char *) args[0], (char *) args[1], (va_list) &args[2]);
+    return wvsprintf32W( buffer, spec, args );
 }
 
-
 /*********************************************************************
  *                  _mbscpy       (CRTDLL.200)
  */
-unsigned char* CRTDLL__mbscpy(unsigned char *x,unsigned char *y)
+unsigned char* __cdecl CRTDLL__mbscpy(unsigned char *x,unsigned char *y)
 {
+    dprintf_crtdll(stddeb,"CRTDLL_mbscpy %s and %s\n",x,y);
     return strcpy(x,y);
 }
 
@@ -611,15 +649,96 @@
 /*********************************************************************
  *                  _mbscat       (CRTDLL.197)
  */
-unsigned char* CRTDLL__mbscat(unsigned char *x,unsigned char *y)
+unsigned char* __cdecl CRTDLL__mbscat(unsigned char *x,unsigned char *y)
 {
     return strcat(x,y);
 }
 
+
+/*********************************************************************
+ *                  _strcmpi   (CRTDLL.282) (CRTDLL.287)
+ */
+INT32 __cdecl CRTDLL__strcmpi( LPCSTR s1, LPCSTR s2 )
+{
+    return lstrcmpi32A( s1, s2 );
+}
+
+
+/*********************************************************************
+ *                  _strnicmp   (CRTDLL.293)
+ */
+INT32 __cdecl CRTDLL__strnicmp( LPCSTR s1, LPCSTR s2, INT32 n )
+{
+    return lstrncmpi32A( s1, s2, n );
+}
+
+
+/*********************************************************************
+ *                  _strlwr      (CRTDLL.293)
+ *
+ * convert a string in place to lowercase 
+ */
+LPSTR CRTDLL__strlwr(LPSTR x)
+{
+  unsigned char *y =x;
+  
+  dprintf_crtdll(stddeb,
+		 "CRTDLL_strlwr got %s",x);
+  while (*y) {
+    if ((*y > 0x40) && (*y< 0x5b))
+      *y = *y + 0x20;
+    y++;
+  }
+  dprintf_crtdll(stddeb," returned %s\n",x);
+		 
+  return x;
+}
+
+/*********************************************************************
+ *                  system       (CRTDLL.485)
+ */
+INT32 CRTDLL_system(LPSTR x)
+{
+#define SYSBUF_LENGTH 1500
+  char buffer[SYSBUF_LENGTH]="wine \"";
+  unsigned char *y =x;
+  unsigned char *bp =buffer+strlen(buffer);
+  int i =strlen(buffer) + strlen(x) +2;
+
+  /* Calculate needed buffer size tp prevent overflow*/
+  while (*y) {
+    if (*y =='\\') i++;
+    y++;
+  }
+  /* if buffer to short, exit */
+  if (i > SYSBUF_LENGTH) {
+    dprintf_crtdll(stddeb,"_system buffer to small\n");
+    return 127;
+  }
+  
+  y =x;
+
+  while (*y) {
+    *bp = *y;
+    bp++; y++;
+    if (*(y-1) =='\\') *bp++ = '\\';
+  }
+  /* remove spaces from end of string */
+  while (*(y-1) == ' ') {
+    bp--;y--;
+  }
+  *bp++ = '"';
+  *bp = 0;
+  dprintf_crtdll(stddeb,
+		 "_system got \"%s\", executing \"%s\"\n",x,buffer);
+
+  return system(buffer);
+}
+
 /*********************************************************************
  *                  _strupr       (CRTDLL.300)
  */
-LPSTR CRTDLL__strupr(LPSTR x)
+LPSTR __cdecl CRTDLL__strupr(LPSTR x)
 {
 	LPSTR	y=x;
 
@@ -633,7 +752,7 @@
 /*********************************************************************
  *                  _wcsupr       (CRTDLL.328)
  */
-LPWSTR CRTDLL__wcsupr(LPWSTR x)
+LPWSTR __cdecl CRTDLL__wcsupr(LPWSTR x)
 {
 	LPWSTR	y=x;
 
@@ -647,7 +766,7 @@
 /*********************************************************************
  *                  _wcslwr       (CRTDLL.323)
  */
-LPWSTR CRTDLL__wcslwr(LPWSTR x)
+LPWSTR __cdecl CRTDLL__wcslwr(LPWSTR x)
 {
 	LPWSTR	y=x;
 
@@ -662,7 +781,7 @@
 /*********************************************************************
  *                  malloc        (CRTDLL.427)
  */
-VOID* CRTDLL_malloc(DWORD size)
+VOID* __cdecl CRTDLL_malloc(DWORD size)
 {
     return HeapAlloc(GetProcessHeap(),0,size);
 }
@@ -670,7 +789,7 @@
 /*********************************************************************
  *                  new           (CRTDLL.001)
  */
-VOID* CRTDLL_new(DWORD size)
+VOID* __cdecl CRTDLL_new(DWORD size)
 {
     VOID* result;
     if(!(result = HeapAlloc(GetProcessHeap(),0,size)) && new_handler)
@@ -681,7 +800,7 @@
 /*********************************************************************
  *                  set_new_handler(CRTDLL.003)
  */
-new_handler_type CRTDLL_set_new_handler(new_handler_type func)
+new_handler_type __cdecl CRTDLL_set_new_handler(new_handler_type func)
 {
     new_handler_type old_handler = new_handler;
     new_handler = func;
@@ -691,7 +810,7 @@
 /*********************************************************************
  *                  calloc        (CRTDLL.350)
  */
-VOID* CRTDLL_calloc(DWORD size, DWORD count)
+VOID* __cdecl CRTDLL_calloc(DWORD size, DWORD count)
 {
     return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
 }
@@ -699,7 +818,7 @@
 /*********************************************************************
  *                  realloc        (CRTDLL.447)
  */
-VOID* CRTDLL_realloc( VOID *ptr, DWORD size )
+VOID* __cdecl CRTDLL_realloc( VOID *ptr, DWORD size )
 {
     return HeapReAlloc( GetProcessHeap(), 0, ptr, size );
 }
@@ -707,7 +826,7 @@
 /*********************************************************************
  *                  free          (CRTDLL.427)
  */
-VOID CRTDLL_free(LPVOID ptr)
+VOID __cdecl CRTDLL_free(LPVOID ptr)
 {
     HeapFree(GetProcessHeap(),0,ptr);
 }
@@ -715,7 +834,7 @@
 /*********************************************************************
  *                  delete       (CRTDLL.002)
  */
-VOID CRTDLL_delete(VOID* ptr)
+VOID __cdecl CRTDLL_delete(VOID* ptr)
 {
     HeapFree(GetProcessHeap(),0,ptr);
 }
@@ -723,24 +842,108 @@
 /*********************************************************************
  *                  _strdup          (CRTDLL.285)
  */
-LPSTR CRTDLL__strdup(LPSTR ptr)
+LPSTR __cdecl CRTDLL__strdup(LPSTR ptr)
 {
     return HEAP_strdupA(GetProcessHeap(),0,ptr);
 }
 
+
 /*********************************************************************
  *                  fclose           (CRTDLL.362)
  */
-DWORD CRTDLL_fclose(LPVOID x)
+INT32 __cdecl CRTDLL_fclose( FILE *stream )
 {
-    dprintf_crtdll(stdnimp,"fclose(%p)\n",x);
-    return 0;
+    int unix_handle=fileno(stream);
+    HFILE32 dos_handle=3;
+    HFILE32 ret=EOF;
+
+    if (unix_handle<4) ret= fclose(stream);
+    else {
+      while(FILE_GetUnixHandle(dos_handle) != unix_handle) dos_handle++;
+      fclose(stream);
+      ret = _lclose32( dos_handle);
+    }
+    dprintf_crtdll(stddeb,"CRTDLL_fclose(%p) ufh %d dfh %d%s\n",
+		   stream,unix_handle,dos_handle,(ret)?" failed":"");
+    return ret;
+}
+
+/*********************************************************************
+ *                  _unlink           (CRTDLL.315)
+ */
+INT32 __cdecl CRTDLL__unlink(LPCSTR pathname)
+{
+    int ret=0;
+    DOS_FULL_NAME full_name;
+
+    if (!DOSFS_GetFullName( pathname, FALSE, &full_name )) {
+      dprintf_crtdll(stddeb,"CRTDLL_unlink file %s bad name\n",pathname);
+      return EOF;
+    }
+  
+    ret=unlink(full_name.long_name);
+    dprintf_crtdll(stddeb,"CRTDLL_unlink(%s unix %s)%s\n",
+		   pathname,full_name.long_name, (ret)?" failed":"");
+    return ret;
+}
+
+/*********************************************************************
+ *                  _open           (CRTDLL.239)
+ */
+HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags)
+{
+    HFILE32 ret=0;
+    int wineflags=0;
+    
+    /* FIXME:
+       the flags in lcc's header differ from the ones in Linux, e.g.
+       Linux: define O_APPEND         02000   (= 0x400)
+       lcc:  define _O_APPEND       0x0008  
+       so here a scheme to translate them
+       Probably lcc is wrong here, but at least a hack to get is going
+       */
+    wineflags = (flags & 3);
+    if (flags & 0x0008 ) wineflags |= O_APPEND;
+    if (flags & 0x0100 ) wineflags |= O_CREAT;
+    if (flags & 0x0200 ) wineflags |= O_TRUNC;
+    if (flags & 0x0400 ) wineflags |= O_EXCL;
+    if (flags & 0xf0f4 ) 
+      dprintf_crtdll(stddeb,"CRTDLL_open file unsupported flags 0x%04x\n",flags);
+    /* End Fixme */
+
+    ret = FILE_Open(path,wineflags);
+    dprintf_crtdll(stddeb,"CRTDLL_open file %s mode 0x%04x (lccmode 0x%04x) got dfh %d\n",
+		   path,wineflags,flags,ret);
+    return ret;
+}
+
+/*********************************************************************
+ *                  _close           (CRTDLL.57)
+ */
+INT32 __cdecl CRTDLL__close(HFILE32 fd)
+{
+    int ret=_lclose32(fd);
+
+    dprintf_crtdll(stddeb,"CRTDLL_close(%d)%s\n",fd,(ret)?" failed":"");
+    return ret;
+}
+
+/*********************************************************************
+ *                  feof           (CRTDLL.363)
+ */
+INT32 __cdecl CRTDLL_feof( FILE *stream )
+{
+    int ret;
+    
+    ret=feof(stream);
+    dprintf_crtdll(stddeb,"CRTDLL_feof(%p) %s\n",stream,(ret)?"true":"false");
+    return ret;
 }
 
 /*********************************************************************
  *                  setlocale           (CRTDLL.453)
  */
-LPSTR CRTDLL_setlocale(INT32 category,LPCSTR locale)
+LPSTR __cdecl CRTDLL_setlocale(INT32 category,LPCSTR locale)
 {
 	LPSTR categorystr;
 
@@ -753,31 +956,53 @@
 	case CRTDLL_LC_TIME: categorystr="LC_TIME";break;
 	default: categorystr = "UNKNOWN?";break;
 	}
-	fprintf(stderr,"CRTDLL.setlocale(%s,%s),stub!\n",categorystr,locale);
+	fprintf(stderr,"CRTDLL_setlocale(%s,%s),stub!\n",categorystr,locale);
 	return "C";
 }
 
 /*********************************************************************
- *                  wcsspn           (CRTDLL.516)
+ *                  wcscat           (CRTDLL.503)
  */
-INT32 CRTDLL_wcsspn(LPWSTR str,LPWSTR accept)
+LPWSTR __cdecl CRTDLL_wcscat( LPWSTR s1, LPCWSTR s2 )
 {
-	LPWSTR	s,t;
+    return lstrcat32W( s1, s2 );
+}
+
+/*********************************************************************
+ *                  wcschr           (CRTDLL.504)
+ */
+LPWSTR __cdecl CRTDLL_wcschr(LPWSTR str,WCHAR xchar)
+{
+	LPWSTR	s;
 
 	s=str;
 	do {
-		t=accept;
-		while (*t) { if (*t==*s) break;t++;}
-		if (!*t) break;
-		s++;
-	} while (*s);
-	return s-str; /* nr of wchars */
+		if (*s==xchar)
+			return s;
+	} while (*s++);
+	return NULL;
+}
+
+/*********************************************************************
+ *                  wcscmp           (CRTDLL.505)
+ */
+INT32 __cdecl CRTDLL_wcscmp( LPCWSTR s1, LPCWSTR s2 )
+{
+    return lstrcmp32W( s1, s2 );
+}
+
+/*********************************************************************
+ *                  wcscpy           (CRTDLL.507)
+ */
+LPWSTR __cdecl CRTDLL_wcscpy( LPWSTR s1, LPCWSTR s2 )
+{
+    return lstrcpy32W( s1, s2 );
 }
 
 /*********************************************************************
  *                  wcscspn           (CRTDLL.508)
  */
-INT32 CRTDLL_wcscspn(LPWSTR str,LPWSTR reject)
+INT32 __cdecl CRTDLL_wcscspn(LPWSTR str,LPWSTR reject)
 {
 	LPWSTR	s,t;
 
@@ -792,49 +1017,91 @@
 }
 
 /*********************************************************************
- *                  wcschr           (CRTDLL.504)
+ *                  wcslen           (CRTDLL.510)
  */
-LPWSTR CRTDLL_wcschr(LPWSTR str,WCHAR xchar)
+INT32 __cdecl CRTDLL_wcslen( LPCWSTR s )
 {
-	LPWSTR	s;
+    return lstrlen32W( s );
+}
+
+/*********************************************************************
+ *                  wcsncat           (CRTDLL.511)
+ */
+LPWSTR __cdecl CRTDLL_wcsncat( LPWSTR s1, LPCWSTR s2, INT32 n )
+{
+    return lstrcatn32W( s1, s2, n );
+}
+
+/*********************************************************************
+ *                  wcsncmp           (CRTDLL.512)
+ */
+INT32 __cdecl CRTDLL_wcsncmp( LPCWSTR s1, LPCWSTR s2, INT32 n )
+{
+    return lstrncmp32W( s1, s2, n );
+}
+
+/*********************************************************************
+ *                  wcsncpy           (CRTDLL.513)
+ */
+LPWSTR __cdecl CRTDLL_wcsncpy( LPWSTR s1, LPCWSTR s2, INT32 n )
+{
+    return lstrcpyn32W( s1, s2, n );
+}
+
+/*********************************************************************
+ *                  wcsspn           (CRTDLL.516)
+ */
+INT32 __cdecl CRTDLL_wcsspn(LPWSTR str,LPWSTR accept)
+{
+	LPWSTR	s,t;
 
 	s=str;
 	do {
-		if (*s==xchar)
-			return s;
-	} while (*s++);
-	return NULL;
+		t=accept;
+		while (*t) { if (*t==*s) break;t++;}
+		if (!*t) break;
+		s++;
+	} while (*s);
+	return s-str; /* nr of wchars */
 }
 
 /*********************************************************************
  *                  towupper           (CRTDLL.494)
  */
-WCHAR CRTDLL_towupper(WCHAR x)
+WCHAR __cdecl CRTDLL_towupper(WCHAR x)
 {
     return (WCHAR)toupper((CHAR)x);
 }
 
 /*********************************************************************
- *                  swprintf           (CRTDLL.483)
+ *                  _wcsicmp           (CRTDLL.321)
  */
-DWORD CRTDLL_swprintf(DWORD *args)
+DWORD __cdecl CRTDLL__wcsicmp( LPCWSTR s1, LPCWSTR s2 )
 {
-    return WIN32_wsprintf32W(args);
+    return lstrcmpi32W( s1, s2 );
 }
 
 /*********************************************************************
  *                  _wcsicoll           (CRTDLL.322)
  */
-DWORD CRTDLL__wcsicoll(LPWSTR a1,LPWSTR a2)
+DWORD __cdecl CRTDLL__wcsicoll(LPCWSTR a1,LPCWSTR a2)
 {
     /* FIXME: handle collates */
     return lstrcmpi32W(a1,a2);
 }
 
 /*********************************************************************
+ *                  _wcsnicmp           (CRTDLL.324)
+ */
+DWORD __cdecl CRTDLL__wcsnicmp( LPCWSTR s1, LPCWSTR s2, INT32 len )
+{
+    return lstrncmpi32W( s1, s2, len );
+}
+
+/*********************************************************************
  *                  wcscoll           (CRTDLL.506)
  */
-DWORD CRTDLL_wcscoll(LPWSTR a1,LPWSTR a2)
+DWORD __cdecl CRTDLL_wcscoll(LPWSTR a1,LPWSTR a2)
 {
     /* FIXME: handle collates */
     return lstrcmp32W(a1,a2);
@@ -843,7 +1110,7 @@
 /*********************************************************************
  *                  _wcsrev           (CRTDLL.326)
  */
-VOID CRTDLL__wcsrev(LPWSTR s) {
+VOID __cdecl CRTDLL__wcsrev(LPWSTR s) {
 	LPWSTR	e;
 
 	e=s;
@@ -860,7 +1127,7 @@
 /*********************************************************************
  *                  wcsstr           (CRTDLL.517)
  */
-LPWSTR CRTDLL_wcsstr(LPWSTR s,LPWSTR b)
+LPWSTR __cdecl CRTDLL_wcsstr(LPWSTR s,LPWSTR b)
 {
 	LPWSTR	x,y,c;
 
@@ -878,9 +1145,18 @@
 }
 
 /*********************************************************************
+ *                  wcstombs   (CRTDLL.521)
+ */
+INT32 __cdecl CRTDLL_wcstombs( LPSTR dst, LPCWSTR src, INT32 len )
+{
+    lstrcpynWtoA( dst, src, len );
+    return strlen(dst);  /* FIXME: is this right? */
+}
+
+/*********************************************************************
  *                  wcsrchr           (CRTDLL.515)
  */
-LPWSTR CRTDLL_wcsrchr(LPWSTR str,WCHAR xchar)
+LPWSTR __cdecl CRTDLL_wcsrchr(LPWSTR str,WCHAR xchar)
 {
 	LPWSTR	s;
 
@@ -895,52 +1171,115 @@
 
 /*********************************************************************
  *                  _setmode           (CRTDLL.265)
- * FIXME: dunno what this is.
+ * FIXME: At present we ignore the request to translate CR/LF to LF.
+ *
+ * We allways translate when we read with fgets, we never do with fread
+ *
  */
-DWORD
-CRTDLL__setmode(LPVOID x,INT32 y) {
+INT32 __cdecl CRTDLL__setmode( INT32 fh,INT32 mode)
+{
 	/* FIXME */
-	fprintf(stdnimp,"CRTDLL._setmode(%p,%d), STUB.\n",x,y);
-	return 0;
+#define O_TEXT     0x4000
+#define O_BINARY   0x8000
+
+	dprintf_crtdll(stddeb,
+		       "CRTDLL._setmode on fhandle %d mode %s, STUB.\n",
+		fh,(mode=O_TEXT)?"O_TEXT":
+		(mode=O_BINARY)?"O_BINARY":"UNKNOWN");
+	return -1;
 }
 
 /*********************************************************************
  *                  atexit           (CRTDLL.345)
  */
-INT32
-CRTDLL_atexit(LPVOID x) {
+INT32 __cdecl CRTDLL_atexit(LPVOID x)
+{
 	/* FIXME */
 	fprintf(stdnimp,"CRTDLL.atexit(%p), STUB.\n",x);
 	return 0; /* successful */
 }
 
 /*********************************************************************
+ *                  mblen          (CRTDLL.428)
+ * FIXME: check multibyte support
+ */
+WCHAR  __cdecl CRTDLL_mblen(CHAR *mb,INT32 size)
+{
+
+    int ret=1;
+    
+    if (!mb)
+      ret = 0;
+    else if ((size<1)||(!*(mb+1)))
+      ret = -1;
+    else if (!(*mb))
+      ret =0;
+      
+    dprintf_crtdll(stderr,"CRTDLL_mlen %s for max %d bytes ret %d\n",mb,size,ret);
+
+    return ret;
+}
+
+/*********************************************************************
  *                  mbstowcs           (CRTDLL.429)
  * FIXME: check multibyte support
  */
-INT32
-CRTDLL_mbstowcs(LPWSTR a,LPSTR b,INT32 nr) {
-	int	i;
-	for (i=0;(i<nr) && b[i];i++) {
-		a[i] = (WCHAR)b[i];
+INT32 __cdecl CRTDLL_mbstowcs(LPWSTR wcs, LPCSTR mbs, INT32 size)
+{
+
+/* Slightly modified lstrcpynAtoW functions from memory/strings.c
+ *  We need the numberr of characters transfered 
+ *  FIXME: No multibyte support yet
+ */
+
+    LPWSTR p = wcs;
+    LPCSTR src= mbs;
+    int ret, n=size;
+
+    while ((n-- > 0) && *src) {
+      *p++ = (WCHAR)(unsigned char)*src++;
 	}
-	return i;
+    p++;
+    ret = (p -wcs);
+          
+    dprintf_crtdll(stddeb,"CRTDLL_mbstowcs %s for %d chars put %d wchars\n",
+		   mbs,size,ret);
+    return ret;
 }
 
 /*********************************************************************
  *                  mbtowc           (CRTDLL.430)
  * FIXME: check multibyte support
  */
-WCHAR
-CRTDLL_mbtowc(CHAR a) {
-	return a;
+WCHAR __cdecl CRTDLL_mbtowc(WCHAR* wc,CHAR* mb,INT32 size) 
+{
+   int ret;
+
+   if (!mb)
+     ret = 0;
+   else if (!wc)
+     ret =-1;
+   else 
+     if ( (ret = mblen(mb,size)) != -1 )
+       {
+	 if (ret <= sizeof(char))
+	   *wc = (WCHAR) ((unsigned char)*mb);
+        else
+        ret=   -1;
+        }   
+     else
+       ret = -1;
+   
+   dprintf_crtdll(stderr,"CRTDLL_mbtowc %s for %d chars\n",mb,size);
+         
+   return ret;
 }
 
 /*********************************************************************
  *                  _isctype           (CRTDLL.138)
  */
-BOOL32
-CRTDLL__isctype(CHAR x,CHAR type) {
+BOOL32 __cdecl CRTDLL__isctype(CHAR x,CHAR type)
+{
 	if ((type & CRTDLL_SPACE) && isspace(x))
 		return TRUE;
 	if ((type & CRTDLL_PUNCT) && ispunct(x))
@@ -962,8 +1301,8 @@
 /*********************************************************************
  *                  _chdrive           (CRTDLL.52)
  */
-BOOL32
-CRTDLL__chdrive(INT32 newdrive) {
+BOOL32 __cdecl CRTDLL__chdrive(INT32 newdrive)
+{
 	/* FIXME: generates errnos */
 	return DRIVE_SetCurrentDrive(newdrive);
 }
@@ -971,18 +1310,51 @@
 /*********************************************************************
  *                  _chdir           (CRTDLL.51)
  */
-INT32
-CRTDLL__chdir(LPCSTR newdir) {
+INT32 __cdecl CRTDLL__chdir(LPCSTR newdir)
+{
 	if (!SetCurrentDirectory32A(newdir))
 		return -1;
 	return 0;
 }
 
 /*********************************************************************
+ *                  _getcwd           (CRTDLL.120)
+ */
+CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT32 size)
+{
+  DOS_FULL_NAME full_name;
+  char *ret;
+
+  dprintf_crtdll(stddeb,"CRTDLL_getcwd for buf %p size %d\n",
+		 buf,size);
+  if (buf == NULL)
+    {
+      dprintf_crtdll(stderr,"CRTDLL_getcwd malloc unsupported\n");
+      printf("CRTDLL_getcwd malloc unsupported\n");
+      return 0;
+    }
+  ret = getcwd(buf,size);
+  if (!DOSFS_GetFullName( buf, FALSE, &full_name )) 
+    {
+      dprintf_crtdll(stddeb,"CRTDLL_getcwd failed\n");
+      return 0;
+    }
+  if (strlen(full_name.short_name)>size) 
+    {
+      dprintf_crtdll(stddeb,"CRTDLL_getcwd string too long\n");
+      return 0;
+    }
+  ret=strcpy(buf,full_name.short_name);
+  if (ret) 
+    dprintf_crtdll(stddeb,"CRTDLL_getcwd returned:%s\n",ret);
+  return ret;
+}
+
+/*********************************************************************
  *                  _mkdir           (CRTDLL.234)
  */
-INT32
-CRTDLL__mkdir(LPCSTR newdir) {
+INT32 __cdecl CRTDLL__mkdir(LPCSTR newdir)
+{
 	if (!CreateDirectory32A(newdir,NULL))
 		return -1;
 	return 0;
@@ -992,8 +1364,8 @@
  *                  _errno           (CRTDLL.52)
  * Yes, this is a function.
  */
-LPINT32
-CRTDLL__errno() {
+LPINT32 __cdecl CRTDLL__errno()
+{
 	static	int crtdllerrno;
 	extern int LastErrorToErrno(DWORD);
 
@@ -1001,3 +1373,83 @@
 	crtdllerrno = LastErrorToErrno(GetLastError());
 	return &crtdllerrno;
 }
+
+/*********************************************************************
+ *                  _tempnam           (CRTDLL.305)
+ * 
+ */
+LPSTR __cdecl CRTDLL__tempnam(LPCSTR dir, LPCSTR prefix)
+{
+
+     char *ret;
+     DOS_FULL_NAME tempname;
+     
+     if ((ret = tempnam(dir,prefix))==NULL) {
+       dprintf_crtdll(stddeb,
+		      "CRTDLL_tempnam Unable to get unique filename\n");
+       return NULL;
+     }
+     if (!DOSFS_GetFullName(ret,FALSE,&tempname))
+     {
+       dprintf_crtdll(stddeb,
+		      "CRTDLL_tempnam Wrong path?\n");
+       return NULL;
+     }
+     free(ret);
+     if ((ret = CRTDLL_malloc(strlen(tempname.short_name)+1)) == NULL) {
+	 dprintf_crtdll(stddeb,
+			"CRTDLL_tempnam CRTDL_malloc for shortname failed\n");
+	 return NULL;
+     }
+     if ((ret = strcpy(ret,tempname.short_name)) == NULL) { 
+       dprintf_crtdll(stddeb,
+		      "CRTDLL_tempnam Malloc for shortname failed\n");
+       return NULL;
+     }
+     
+     dprintf_crtdll(stddeb,"CRTDLL_tempnam dir %s prefix %s got %s\n",
+		    dir,prefix,ret);
+     return ret;
+
+}
+/*********************************************************************
+ *                  tmpnam           (CRTDLL.490)
+ *
+ * lcclnk from lcc-win32 relies on a terminating dot in the name returned
+ * 
+ */
+LPSTR __cdecl CRTDLL_tmpnam(LPSTR s)
+{
+     char *ret;
+
+     if ((ret =tmpnam(s))== NULL) {
+       dprintf_crtdll(stddeb,
+		      "CRTDLL_tmpnam Unable to get unique filename\n");
+       return NULL;
+     }
+     if (!DOSFS_GetFullName(ret,FALSE,&CRTDLL_tmpname))
+     {
+       dprintf_crtdll(stddeb,
+		      "CRTDLL_tmpnam Wrong path?\n");
+       return NULL;
+     }
+     strcat(CRTDLL_tmpname.short_name,".");
+     dprintf_crtdll(stddeb,"CRTDLL_tmpnam for buf %p got %s\n",
+		    s,CRTDLL_tmpname.short_name);
+     dprintf_crtdll(stddeb,"CRTDLL_tmpnam long got %s\n",
+		    CRTDLL_tmpname.long_name);
+     if ( s != NULL) 
+       return strcpy(s,CRTDLL_tmpname.short_name);
+     else 
+       return CRTDLL_tmpname.short_name;
+
+}
+
+/*********************************************************************
+ *                  _itoa           (CRTDLL.165)
+ */
+LPSTR  __cdecl CRTDLL__itoa(INT32 x,LPSTR buf,INT32 buflen)
+{
+    wsnprintf32A(buf,buflen,"%d",x);
+    return buf;
+}
diff --git a/misc/lstr.c b/misc/lstr.c
index 64190c3..f2fd7c6 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -137,7 +137,7 @@
     for (p = buffer; *str; str++) if (*str != '\r') *p++ = *str;
     *p = '\0';
     if ((p > buffer) && (p[-1] == '\n')) p[1] = '\0'; /* Remove trailing \n */
-    module = MODULE_GetModuleName( GetExePtr(GetCurrentTask()) );
+    module = MODULE_GetModuleName( GetCurrentTask() );
     fprintf( stderr, "OutputDebugString: %s says '%s'\n",
              module ? module : "???", buffer );
     HeapFree( GetProcessHeap(), 0, buffer );
@@ -475,7 +475,7 @@
 }
 
 /***********************************************************************
- *           FormatMessageA   (KERNEL32.138) Library Version
+ *           FormatMessage32A   (KERNEL32.138)
  * FIXME: missing wrap,FROM_SYSTEM message-loading,
  */
 DWORD WINAPI FormatMessage32A(
@@ -577,10 +577,7 @@
 						if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
 							argliststart=args+insertnr-1;
 						else
-							/* FIXME: not sure that this is
-							 * correct for unix-c-varargs.
-							 */
-							argliststart=((DWORD*)&args)+insertnr-1;
+                                                    argliststart=(*(DWORD**)args)+insertnr-1;
 
 						if (fmtstr[strlen(fmtstr)]=='s')
 							sprintfbuf=HeapAlloc(GetProcessHeap(),0,strlen((LPSTR)argliststart[0])+1);
@@ -643,44 +640,10 @@
 }
 #undef ADD_TO_T
 
+
 /***********************************************************************
- *           FormatMessageA   (KERNEL32.138) Emulator Version
+ *           FormatMessage32W   (KERNEL32.138)
  */
-DWORD WINAPI WIN32_FormatMessage32A(DWORD *args)
-{
-	DWORD	dwFlags		= args[0];
-	LPCVOID	lpSource	= (LPCVOID)args[1];
-	DWORD	dwMessageId	= args[2];
-	DWORD	dwLanguageId	= args[3];
-	LPSTR	lpBuffer	= (LPSTR)args[4];
-	DWORD	nSize		= args[5];
-	DWORD	*xargs;
-
-	/* convert possible varargs to an argument array look-a-like */
-
-	if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) {
-		xargs=(DWORD*)args[6];
-	} else {
-		/* args[6] is a pointer to a pointer to the start of 
-		 * a list of arguments.
-		 */
-		if (args[6])
-			xargs=(DWORD*)(((DWORD*)args[6])[0]);
-		else
-			xargs=NULL;
-		dwFlags|=FORMAT_MESSAGE_ARGUMENT_ARRAY;
-	}
-	return FormatMessage32A(
-		dwFlags,
-		lpSource,
-		dwMessageId,
-		dwLanguageId,
-		lpBuffer,
-		nSize,
-		xargs
-	);
-}
-
 DWORD WINAPI FormatMessage32W(
 	DWORD	dwFlags,
 	LPCVOID	lpSource,
@@ -781,10 +744,7 @@
 					if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
 						argliststart=args+insertnr-1;
 					else
-						/* FIXME: not sure that this is
-						 * correct for unix-c-varargs.
-						 */
-						argliststart=((DWORD*)&args)+insertnr-1;
+						argliststart=(*(DWORD**)args)+insertnr-1;
 
 					if (fmtstr[strlen(fmtstr)]=='s') {
 						DWORD	xarr[3];
@@ -847,41 +807,3 @@
 			lstrlen32W(lpBuffer);
 }
 #undef ADD_TO_T
-
-/***********************************************************************
- *           FormatMessageW   (KERNEL32.138) Emulator Version
- */
-DWORD WINAPI WIN32_FormatMessage32W(DWORD *args)
-{
-	DWORD	dwFlags		= args[0];
-	LPCVOID	lpSource	= (LPCVOID)args[1];
-	DWORD	dwMessageId	= args[2];
-	DWORD	dwLanguageId	= args[3];
-	LPWSTR	lpBuffer	= (LPWSTR)args[4];
-	DWORD	nSize		= args[5];
-	DWORD	*xargs;
-
-	/* convert possible varargs to an argument array look-a-like */
-
-	if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) {
-		xargs=(DWORD*)args[6];
-	} else {
-		/* args[6] is a pointer to a pointer to the start of 
-		 * a list of arguments.
-		 */
-		if (args[6])
-			xargs=(DWORD*)(((DWORD*)args[6])[0]);
-		else
-			xargs=NULL;
-		dwFlags|=FORMAT_MESSAGE_ARGUMENT_ARRAY;
-	}
-	return FormatMessage32W(
-		dwFlags,
-		lpSource,
-		dwMessageId,
-		dwLanguageId,
-		lpBuffer,
-		nSize,
-		xargs
-	);
-}
diff --git a/misc/main.c b/misc/main.c
index 3ef3384..c158941 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -35,31 +35,123 @@
 #include "xmalloc.h"
 
 const char people[] = "Wine is available thanks to the work of "
-"Bob Amstadt, Dag Asheim, Martin Ayotte, Peter Bajusz, Ross Biro, "
-"Uwe Bonnes, Erik Bos, Fons Botman, John Brezak, Andrew Bulhak, "
-"John Burton, Niels de Carpentier, Jimen Ching, Huw D. M. Davies, "
-"Roman Dolejsi, Frans van Dorsselaer, Paul Falstad, David Faure, "
-"Olaf Flebbe, Peter Galbavy, Ramon Garcia, Matthew Ghio, "
-"Hans de Graaff, Charles M. Hannum, John Harvey, Cameron Heide, "
-"Jochen Hoenicke, Onno Hovers, Jeffrey Hsu, Miguel de Icaza, "
-"Jukka Iivonen, Lee Jaekil, Alexandre Julliard, Bang Jun-Young, "
-"Pavel Kankovsky, Jochen Karrer, Andreas Kirschbaum, Albrecht Kleine, "
-"Jon Konrath, Alex Korobka, Greg Kreider, Anand Kumria, Scott A. Laird, "
-"Andrew Lewycky, Martin von Loewis, Kenneth MacDonald, Peter MacDonald, "
-"William Magro, Juergen Marquardt, Ricardo Massaro, Marcus Meissner, "
-"Graham Menhennitt, David Metcalfe, Bruce Milner, Steffen Moeller, "
-"Andreas Mohr, Philippe De Muyter, Itai Nahshon, Michael Patra, "
-"Jim Peterson, Robert Pouliot, Keith Reynolds, Slaven Rezic, "
-"John Richardson, Johannes Ruscheinski, Thomas Sandford, "
-"Constantine Sapuntzakis, Pablo Saratxaga, Daniel Schepler, "
-"Ulrich Schmid, Bernd Schmidt, Yngvi Sigurjonsson, Stephen Simmons, "
-"Rick Sladkey, William Smith, Dominik Strasser, Vadim Strizhevsky, "
-"Erik Svendsen, Tristan Tarrant, Andrew Taylor, Duncan C Thomson, "
-"Goran Thyni, Jimmy Tirtawangsa, Jon Tombs, Linus Torvalds, "
-"Gregory Trubetskoy, Petri Tuomola, Michael Veksler, Sven Verdoolaege, "
-"Ronan Waide, Eric Warnke, Manfred Weichel, Morten Welinder, "
-"Jan Willamowius, Carl Williams, Karl Guenter Wuensch, Eric Youngdale, "
-"James Youngman, Mikolaj Zalewski, and John Zero.";
+"Bob Amstadt, "
+"Dag Asheim, "
+"Martin Ayotte, "
+"Peter Bajusz, "
+"Georg Beyerle, "
+"Ross Biro, "
+"Uwe Bonnes, "
+"Erik Bos, "
+"Fons Botman, "
+"John Brezak, "
+"Andrew Bulhak, "
+"John Burton, "
+"Niels de Carpentier, "
+"Jimen Ching, "
+"David A. Cuthbert, "
+"Huw D. M. Davies, "
+"Roman Dolejsi, "
+"Frans van Dorsselaer, "
+"Chris Faherty, "
+"Paul Falstad, "
+"David Faure, "
+"Claus Fischer, "
+"Olaf Flebbe, "
+"Chad Fraleigh, "
+"Peter Galbavy, "
+"Ramon Garcia, "
+"Matthew Ghio, "
+"Jody Goldberg, "
+"Hans de Graaff, "
+"Charles M. Hannum, "
+"Adrian Harvey, "
+"John Harvey, "
+"Cameron Heide, "
+"Jochen Hoenicke, "
+"Onno Hovers, "
+"Jeffrey Hsu, "
+"Miguel de Icaza, "
+"Jukka Iivonen, "
+"Lee Jaekil, "
+"Alexandre Julliard, "
+"Bang Jun-Young, "
+"Pavel Kankovsky, "
+"Jochen Karrer, "
+"Andreas Kirschbaum, "
+"Albrecht Kleine, "
+"Jon Konrath, "
+"Alex Korobka, "
+"Greg Kreider, "
+"Anand Kumria, "
+"Scott A. Laird, "
+"Andrew Lewycky, "
+"Martin von Loewis, "
+"Michiel van Loon, "
+"Kenneth MacDonald, "
+"Peter MacDonald, "
+"William Magro, "
+"Juergen Marquardt, "
+"Ricardo Massaro, "
+"Marcus Meissner, "
+"Graham Menhennitt, "
+"David Metcalfe, "
+"Bruce Milner, "
+"Steffen Moeller, "
+"Andreas Mohr, "
+"Philippe De Muyter, "
+"Itai Nahshon, "
+"Henrik Olsen, "
+"Michael Patra, "
+"Dimitrie O. Paun, "
+"Jim Peterson, "
+"Robert Pouliot, "
+"Keith Reynolds, "
+"Slaven Rezic, "
+"John Richardson, "
+"Rick Richardson, "
+"Doug Ridgway, "
+"Bernhard Rosenkraenzer, "
+"Johannes Ruscheinski, "
+"Thomas Sandford, "
+"Constantine Sapuntzakis, "
+"Pablo Saratxaga, "
+"Daniel Schepler, "
+"Peter Schlaile, "
+"Ulrich Schmid, "
+"Bernd Schmidt, "
+"Ingo Schneider, "
+"Victor Schneider, "
+"Yngvi Sigurjonsson, "
+"Stephen Simmons, "
+"Rick Sladkey, "
+"William Smith, "
+"Dominik Strasser, "
+"Vadim Strizhevsky, "
+"Erik Svendsen, "
+"Tristan Tarrant, "
+"Andrew Taylor, "
+"Duncan C Thomson, "
+"Goran Thyni, "
+"Jimmy Tirtawangsa, "
+"Jon Tombs, "
+"Linus Torvalds, "
+"Gregory Trubetskoy, "
+"Petri Tuomola, "
+"Michael Veksler, "
+"Sven Verdoolaege, "
+"Ronan Waide, "
+"Eric Warnke, "
+"Manfred Weichel, "
+"Morten Welinder, "
+"Lawson Whitney, "
+"Jan Willamowius, "
+"Carl Williams, "
+"Karl Guenter Wuensch, "
+"Eric Youngdale, "
+"James Youngman, "
+"Mikolaj Zalewski, "
+"and John Zero.";
 
 const WINE_LANGUAGE_DEF Languages[] =
 {
diff --git a/misc/network.c b/misc/network.c
index 3768fc9..4ebd1ff 100644
--- a/misc/network.c
+++ b/misc/network.c
@@ -153,8 +153,8 @@
 /**************************************************************************
  *				WNetGetConnection	[USER.512]
  */
-int WINAPI WNetGetConnection(LPSTR lpLocalName, 
-                             LPSTR lpRemoteName, UINT16 *cbRemoteName)
+int WINAPI WNetGetConnection16(LPSTR lpLocalName, 
+                               LPSTR lpRemoteName, UINT16 *cbRemoteName)
 {
     const char *path;
 
@@ -402,4 +402,11 @@
 }
 
 
-
+DWORD
+WNetGetConnection32A(LPCSTR localname,LPSTR remotename,LPDWORD buflen)
+{
+	UINT16	x;
+	DWORD	ret = WNetGetConnection16(localname,remotename,&x);
+	*buflen = x;
+	return ret;
+}
diff --git a/misc/ntdll.c b/misc/ntdll.c
index 43b6a5d..aeef87a 100644
--- a/misc/ntdll.c
+++ b/misc/ntdll.c
@@ -510,3 +510,27 @@
 	/* returns file io completion status */
 	return 0;
 }
+/*
+These functions were originally in CRTDLL. CRTFLL now call the C-Lib 
+function directly. So they were moved here
+*/
+
+/*********************************************************************
+ *                  atoi          (NDLL.885)
+ */
+INT32 NTDLL_atoi(LPCSTR x)
+{
+    if (!x) return 0;
+    return atoi(x);
+}
+
+/*********************************************************************
+ *                  atol          (NTDLL.886)
+ */
+LONG NTDLL_atol(LPCSTR x)
+{
+    if (!x) return 0;
+    return atol(x);
+}
+
+
diff --git a/misc/ole2.c b/misc/ole2.c
index 5f65195..8996ce9 100644
--- a/misc/ole2.c
+++ b/misc/ole2.c
@@ -17,8 +17,8 @@
  */
 DWORD WINAPI OleBuildVersion()
 {
-	dprintf_ole(stddeb,"OleBuildVersion()\n");
-	return (rmm<<16)+rup;
+    dprintf_ole(stddeb,"OleBuildVersion()\n");
+    return (rmm<<16)+rup;
 }
 
 /***********************************************************************
@@ -35,5 +35,14 @@
  */
 void WINAPI OleUninitialize()
 {
-	dprintf_ole(stdnimp,"OleUninitialize()\n");
+    dprintf_ole(stdnimp,"OleUninitialize()\n");
 }
+
+/***********************************************************************
+ *           OleFlushClipboard   [OLE2.76]
+ */
+HRESULT WINAPI OleFlushClipboard()
+{
+    return S_OK;
+}
+
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index df08c93..5fd924e 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -125,6 +125,7 @@
 	LOCALE_ENTRY(IPOSSEPBYSPACE),
 	LOCALE_ENTRY(INEGSYMPRECEDES),
 	LOCALE_ENTRY(INEGSEPBYSPACE),
+/*	LOCALE_ENTRY(FONTSIGNATURE),*/
 	{NULL,0},
 };
 
@@ -183,7 +184,7 @@
 /***********************************************************************
  *           GetUserDefaultLCID       (OLE2NLS.1)
  */
-DWORD WINAPI GetUserDefaultLCID()
+LCID WINAPI GetUserDefaultLCID()
 {
 /* Default sorting, neutral sublanguage */
     switch(Options.language)
@@ -224,7 +225,7 @@
 /***********************************************************************
  *         GetSystemDefaultLCID       (OLE2NLS.2)
  */
-DWORD WINAPI GetSystemDefaultLCID()
+LCID WINAPI GetSystemDefaultLCID()
 {
 	return GetUserDefaultLCID();
 }
@@ -232,7 +233,7 @@
 /***********************************************************************
  *         GetUserDefaultLangID       (OLE2NLS.3)
  */
-WORD WINAPI GetUserDefaultLangID()
+LANGID WINAPI GetUserDefaultLangID()
 {
 	return (WORD)GetUserDefaultLCID();
 }
@@ -240,7 +241,7 @@
 /***********************************************************************
  *         GetSystemDefaultLangID     (OLE2NLS.4)
  */
-WORD WINAPI GetSystemDefaultLangID()
+LANGID WINAPI GetSystemDefaultLangID()
 {
 	return GetUserDefaultLangID();
 }
@@ -261,6 +262,9 @@
 
 	dprintf_ole(stddeb,"GetLocaleInfo32A(%8lX,%8lX,%p,%4X)\n",
 			lcid,LCType,buf,len);
+
+	LCType &= ~(LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP);
+
 	/* As an option, we could obtain the value from win.ini.
 	   This would not match the Wine compile-time option.
 	   Also, not all identifiers are available from win.ini */
@@ -303,8 +307,8 @@
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Deutschland")
 LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"49")
+LOCVAL(LOCALE_IDEFAULTCODEPAGE,"851")
 /* Dunno
-LOCVAL(LOCALE_IDEFAULTCODEPAGE)
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE)
 */
 LOCVAL(LOCALE_SLIST,";")
@@ -522,8 +526,6 @@
 
     case LANG_En:
     	switch (LCType) {
-/* This definitions apply to Germany only. Users in Austria 
-   or Switzerland might want to modify them */
 LOCVAL(LOCALE_ILANGUAGE,"9")
 LOCVAL(LOCALE_SLANGUAGE,"English")
 LOCVAL(LOCALE_SENGLANGUAGE,"English")
@@ -536,8 +538,8 @@
 LOCVAL(LOCALE_SNATIVECTRYNAME,"Deutschland")
 LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
 LOCVAL(LOCALE_IDEFAULTCOUNTRY,"49")
+LOCVAL(LOCALE_IDEFAULTCODEPAGE,"437")
 /* Dunno
-LOCVAL(LOCALE_IDEFAULTCODEPAGE)
 LOCVAL(LOCALE_IDEFAULTANSICODEPAGE)
 */
 LOCVAL(LOCALE_SLIST,";")
@@ -1685,7 +1687,8 @@
 	if(!found) {
 		fprintf(stderr,"'%s' not supported for your language.\n",
 			retString);
-		return 0;
+		retString = "<WINE-NLS-unknown>";
+		/*return 0;*/
 	}
 	if (buf)
 		lstrcpyn32A(buf,retString,len);
@@ -2029,3 +2032,59 @@
 	return strlen(languages[i].langname); /* same as strlenW(langname); */
 }
 
+
+INT32 WINAPI LCMapString32A(
+	LCID lcid,DWORD mapflags,LPCSTR srcstr,INT32 srclen,LPSTR dststr,
+	INT32 dstlen
+) {
+	int	i,len;
+
+	fprintf(stderr,"LCMapStringA(0x%04lx,0x%08lx,%s,%d,%p,%d)\n",
+		lcid,mapflags,srcstr,srclen,dststr,dstlen
+	);
+	if (!dstlen || !dststr) {
+		dststr = srcstr;
+	}
+	if (!srclen) srclen = strlen(srcstr);
+	if (!dstlen) dstlen = strlen(dststr);
+	len = dstlen;
+	if (srclen < len)
+		len = srclen;
+	if (mapflags & LCMAP_LOWERCASE) {
+		for (i=0;i<len;i++)
+			dststr[i]=tolower(srcstr[i]);
+		mapflags &= ~LCMAP_LOWERCASE;
+	}
+	if (mapflags)
+		fprintf(stderr,"	unimplemented flags: 0x%08lx\n",mapflags);
+	return len;
+}
+
+/* FIXME: implement everyhting & correct */
+
+INT32 WINAPI LCMapString32W(
+	LCID lcid,DWORD mapflags,LPCWSTR srcstr,INT32 srclen,LPWSTR dststr,
+	INT32 dstlen
+) {
+	int	i,len;
+
+	fprintf(stderr,"LCMapStringW(0x%04lx,0x%08lx,%p,%d,%p,%d)\n",
+		lcid,mapflags,srcstr,srclen,dststr,dstlen
+	);
+	if (!dstlen || !dststr) {
+		dststr = srcstr;
+	}
+	if (!srclen) srclen = strlen(srcstr);
+	if (!dstlen) dstlen = strlen(dststr);
+	len = dstlen;
+	if (srclen < len)
+		len = srclen;
+	if (mapflags & LCMAP_LOWERCASE) {
+		for (i=0;i<len;i++)
+			dststr[i]=tolower(srcstr[i]);
+		mapflags &= ~LCMAP_LOWERCASE;
+	}
+	if (mapflags)
+		fprintf(stderr,"	unimplemented flags: 0x%08lx\n",mapflags);
+	return len;
+}
diff --git a/misc/printdrv.c b/misc/printdrv.c
index 2a6cc30..1ad9e09 100644
--- a/misc/printdrv.c
+++ b/misc/printdrv.c
@@ -83,7 +83,7 @@
                                 LPSTR pDeviceName, LPDEVMODE32A pDevModeOutput,
                                   LPDEVMODE32A pDevModeInput,DWORD fMode )
 {
-    fprintf(stderr,"DocumentPropertiesA(%d,%d,%s,%p,%p,%d)\n",
+    fprintf(stderr,"DocumentPropertiesA(%d,%d,%s,%p,%p,%ld)\n",
 	hWnd,hPrinter,pDeviceName,pDevModeOutput,pDevModeInput,fMode
     );
     return 1;
diff --git a/misc/registry.c b/misc/registry.c
index 56dea7d..e14b342 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -2093,11 +2093,33 @@
 		hkey,lpszValueName,lpdwReserved,lpdwType,lpbData,
 		lpcbData?*lpcbData:0
 	);
+	if (lpszValueName)
+		lpszValueNameW=strdupA2W(lpszValueName);
+	else 
+		lpszValueNameW=NULL;
+
+	if (lpdwType)
+		type=*lpdwType;
+
 	if (lpbData) {
-		/* double buffer */
-		buf	= (LPBYTE)xmalloc((*lpcbData)*2);
-		myxlen	= *lpcbData*2;
+		myxlen  = 0;
 		mylen	= &myxlen;
+		buf	= xmalloc(4);
+		ret=RegQueryValueEx32W(
+			hkey,
+			lpszValueNameW,
+			lpdwReserved,
+			&type,
+			buf,
+			mylen
+		);
+		free(buf);
+		if (ret==ERROR_MORE_DATA) {
+			buf	= (LPBYTE)xmalloc(*mylen);
+		} else {
+			buf	= (LPBYTE)xmalloc(2*(*lpcbData));
+			myxlen  = 2*(*lpcbData);
+		}
 	} else {
 		buf=NULL;
 		if (lpcbData) {
@@ -2106,13 +2128,6 @@
 		} else
 			mylen	= NULL;
 	}
-	if (lpszValueName)
-		lpszValueNameW=strdupA2W(lpszValueName);
-	else 
-		lpszValueNameW=NULL;
-
-	if (lpdwType)
-		type=*lpdwType;
 	ret=RegQueryValueEx32W(
 		hkey,
 		lpszValueNameW,
diff --git a/misc/shell.c b/misc/shell.c
index b3a9ffe..63e618a 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -46,7 +46,7 @@
 
 #pragma pack(4)
 
-extern HGLOBAL16 CURSORICON_LoadHandler( HGLOBAL16, HINSTANCE16, BOOL32);
+extern HICON16   LoadIconHandler( HGLOBAL16 hResource, BOOL16 bNew );
 extern WORD 	 GetIconID( HGLOBAL16 hResource, DWORD resType );
 
 static const char*	lpstrMsgWndCreated = "OTHERWINDOWCREATED";
@@ -688,34 +688,40 @@
       if( nIconIndex == (UINT16)-1 ) RetPtr[0] = iconDirCount;
       else if( nIconIndex < iconDirCount )
       {
-	   UINT16   i, icon;
+	  UINT16   i, icon;
 
-	   if( n > iconDirCount - nIconIndex ) n = iconDirCount - nIconIndex;
+	  if( n > iconDirCount - nIconIndex ) n = iconDirCount - nIconIndex;
 
-	   for( i = nIconIndex; i < nIconIndex + n; i++ ) 
-	   {
-	       /* .ICO files have only one icon directory */
+	  for( i = nIconIndex; i < nIconIndex + n; i++ ) 
+	  {
+	      /* .ICO files have only one icon directory */
 
-	       if( lpiID == NULL )
+	      if( lpiID == NULL )
 	           hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + i, 
 							      *(WORD*)pData );
-	       RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 );
-	       GlobalFree16(hIcon); 
-           }
+	      RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 );
+	      GlobalFree16(hIcon); 
+          }
 
-	   for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
-	   {
-	       hIcon = 0;
-	       if( lpiID )
+	  for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
+	  {
+	      hIcon = 0;
+	      if( lpiID )
 		   hIcon = ICO_LoadIcon( hInstance, hFile, 
 					 lpiID->idEntries + RetPtr[icon-nIconIndex]);
-	       else
+	      else
 	         for( i = 0; i < iconCount; i++ )
 		   if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) )
 		     hIcon = SHELL_LoadResource( hInstance, hFile, pIconStorage + i,
 								    *(WORD*)pData );
-	       RetPtr[icon-nIconIndex] = (hIcon)?CURSORICON_LoadHandler( hIcon, hInstance, FALSE ):0;
-	   }
+	      if( hIcon )
+	      {
+		  RetPtr[icon-nIconIndex] = LoadIconHandler( hIcon, TRUE ); 
+		  FarSetOwner( RetPtr[icon-nIconIndex], GetExePtr(hInstance) );
+	      }
+	      else
+		  RetPtr[icon-nIconIndex] = 0;
+	  }
       }
     if( lpiID ) HeapFree( GetProcessHeap(), 0, lpiID);
     else HeapFree( GetProcessHeap(), 0, pData);
@@ -1030,3 +1036,9 @@
 	*numargs=i;
 	return argv;
 }
+
+void WINAPI Control_RunDLL(DWORD a1,DWORD a2,LPSTR a3,DWORD a4) {
+	fprintf(stderr,"Control_RunDLL(0x%08lx,0x%08lx,%s,0x%08lx)\n",
+		a1,a2,a3,a4
+	);
+}
diff --git a/misc/spy.c b/misc/spy.c
index 65490b9..56cebfe 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -9,6 +9,7 @@
 #include <stdio.h>
 #include <string.h>
 #include "windows.h"
+#include "win.h"
 #include "module.h"
 #include "options.h"
 #include "stddebug.h"
@@ -568,6 +569,7 @@
 
 
 static BOOL16 SPY_Exclude[SPY_MAX_MSGNUM+1];
+static BOOL16 SPY_ExcludeDWP = 0;
 static int SPY_IndentLevel  = 0;
 
 #define SPY_EXCLUDE(msg) \
@@ -578,17 +580,56 @@
  */
 const char *SPY_GetMsgName( UINT32 msg )
 {
-    static char buffer[20];
+    static char msg_buffer[20];
 
     if (msg <= SPY_MAX_MSGNUM)
     {
         if (!MessageTypeNames[msg]) return "???";
         return MessageTypeNames[msg];
     }
-    sprintf( buffer, "WM_USER+%04x", msg - WM_USER );
-    return buffer;
+    sprintf( msg_buffer, "WM_USER+%04x", msg - WM_USER );
+    return msg_buffer;
 }
 
+/***********************************************************************
+ *           SPY_GetWndName
+ */
+const char *SPY_GetWndName( HWND32 hwnd )
+{
+    static char wnd_buffer[16];
+
+    WND* pWnd = WIN_FindWndPtr( hwnd );
+    if( pWnd )
+    {
+	INT32 n = sizeof(wnd_buffer) - 6;
+	LPSTR p = wnd_buffer;
+	LPSTR src;
+	
+        char  postfix;
+	
+	if( pWnd->text && pWnd->text[0] != '\0' )
+	{
+	    src = pWnd->text;
+	    *(p++) = postfix = '\"';
+	    while ((n-- > 1) && *src) *p++ = *src++;
+	}
+	else /* get class name */
+	{
+	    INT32 len;
+
+	    *(p++)='{';
+	    GlobalGetAtomName32A( pWnd->class->atomName, p, n + 1);
+	    src = p += (len = lstrlen32A(p));
+	    if( len >= n ) src = wnd_buffer;	/* something nonzero */
+	    postfix = '}';
+	}
+	if( *src ) for( n = 0; n < 3; n++ ) *(p++)='.';
+	*(p++) = postfix;
+	*(p++) = '\0';
+    }
+    else lstrcpy32A( wnd_buffer, "\"NULL\"" );
+    return wnd_buffer;
+}
 
 /***********************************************************************
  *           SPY_EnterMessage
@@ -596,20 +637,24 @@
 void SPY_EnterMessage( INT32 iFlag, HWND32 hWnd, UINT32 msg,
                        WPARAM32 wParam, LPARAM lParam )
 {
+    LPCSTR pname;
+
     if (!debugging_message || SPY_EXCLUDE(msg)) return;
 
     /* each SPY_SENDMESSAGE must be complemented by call to SPY_ExitMessage */
     switch(iFlag)
     {
     case SPY_DISPATCHMESSAGE16:
-        dprintf_message(stddeb,"%*s(%04x) message [%04x] %s dispatched  wp=%04x lp=%08lx\n",
-                        SPY_IndentLevel, "", hWnd, msg, SPY_GetMsgName( msg ),
+	pname = SPY_GetWndName(hWnd);
+        dprintf_message(stddeb,"%*s(%04x) %-16s message [%04x] %s dispatched  wp=%04x lp=%08lx\n",
+                        SPY_IndentLevel, "", hWnd, pname, msg, SPY_GetMsgName( msg ),
                         wParam, lParam);
         break;
 
     case SPY_DISPATCHMESSAGE32:
-        dprintf_message(stddeb,"%*s(%08x) message [%04x] %s dispatched  wp=%08x lp=%08lx\n",
-                        SPY_IndentLevel, "", hWnd, msg, SPY_GetMsgName( msg ),
+	pname = SPY_GetWndName(hWnd);
+        dprintf_message(stddeb,"%*s(%08x) %-16s message [%04x] %s dispatched  wp=%08x lp=%08lx\n",
+                        SPY_IndentLevel, "", hWnd, pname, msg, SPY_GetMsgName( msg ),
                         wParam, lParam);
         break;
 
@@ -618,32 +663,36 @@
         {
             char taskName[30];
             HTASK16 hTask = GetWindowTask16(hWnd);
+
             if (hTask == GetCurrentTask()) strcpy( taskName, "self" );
             else if (!hTask) strcpy( taskName, "Wine" );
             else sprintf( taskName, "task %04x %s",
-                          hTask, MODULE_GetModuleName( GetExePtr(hTask) ) );
+                          hTask, MODULE_GetModuleName(hTask) );
+	    pname = SPY_GetWndName(hWnd);
 
             if (iFlag == SPY_SENDMESSAGE16)
-                dprintf_message(stddeb,"%*s(%04x) message [%04x] %s sent from %s wp=%04x lp=%08lx\n",
-                                SPY_IndentLevel, "", hWnd, msg,
-                                SPY_GetMsgName( msg ), taskName, wParam,
-                                lParam );
+                dprintf_message(stddeb,
+				"%*s(%04x) %-16s message [%04x] %s sent from %s wp=%04x lp=%08lx\n",
+                                SPY_IndentLevel, "", hWnd, pname, msg, SPY_GetMsgName( msg ), 
+				taskName, wParam, lParam );
             else
-                dprintf_message(stddeb,"%*s(%08x) message [%04x] %s sent from %s wp=%08x lp=%08lx\n",
-                                SPY_IndentLevel, "", hWnd, msg,
-                                SPY_GetMsgName( msg ), taskName, wParam,
-                                lParam );
+                dprintf_message(stddeb,
+				"%*s(%08x) %-16s message [%04x] %s sent from %s wp=%08x lp=%08lx\n",
+                                SPY_IndentLevel, "", hWnd, pname, msg, SPY_GetMsgName( msg ), 
+				taskName, wParam, lParam );
         }
         break;   
 
     case SPY_DEFWNDPROC16:
-        dprintf_message(stddeb, "%*s(%04x) DefWindowProc: %s [%04x]  wp=%04x lp=%08lx\n",
+	if( SPY_ExcludeDWP ) return;
+        dprintf_message(stddeb, "%*s(%04x)  DefWindowProc16: %s [%04x]  wp=%04x lp=%08lx\n",
                         SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ),
                         msg, wParam, lParam );
         break;
 
     case SPY_DEFWNDPROC32:
-        dprintf_message(stddeb, "%*s(%08x) DefWindowProc: %s [%04x]  wp=%08x lp=%08lx\n",
+	if( SPY_ExcludeDWP ) return;
+        dprintf_message(stddeb, "%*s(%08x)  DefWindowProc32: %s [%04x]  wp=%08x lp=%08lx\n",
                         SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ),
                         msg, wParam, lParam );
         break;
@@ -657,29 +706,51 @@
  */
 void SPY_ExitMessage( INT32 iFlag, HWND32 hWnd, UINT32 msg, LRESULT lReturn )
 {
-    if (!debugging_message || SPY_EXCLUDE(msg)) return;
+    LPCSTR pname;
+
+    if (!debugging_message || SPY_EXCLUDE(msg) ||
+	(SPY_ExcludeDWP && (iFlag == SPY_RESULT_DEFWND16 || iFlag == SPY_RESULT_DEFWND32)) )
+	return;
+
     if (SPY_IndentLevel) SPY_IndentLevel -= SPY_INDENT_UNIT;
 
     switch(iFlag)
     {
+    case SPY_RESULT_DEFWND16:
+	dprintf_message(stddeb,"%*s(%04x)  DefWindowProc16: %s [%04x] returned %08lx\n",
+			SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ), msg, lReturn );
+	break;
+
+    case SPY_RESULT_DEFWND32:
+	dprintf_message(stddeb,"%*s(%08x)  DefWindowProc32: %s [%04x] returned %08lx\n",
+			SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ), msg, lReturn );
+	break;
+
     case SPY_RESULT_OK16:
-        dprintf_message(stddeb,"%*s(%04x) message [%04x] %s returned %08lx\n",
-                        SPY_IndentLevel, "", hWnd, msg,
+	pname = SPY_GetWndName(hWnd);
+        dprintf_message(stddeb,"%*s(%04x) %-16s message [%04x] %s returned %08lx\n",
+                        SPY_IndentLevel, "", hWnd, pname, msg,
                         SPY_GetMsgName( msg ), lReturn );
         break;
+
     case SPY_RESULT_OK32:
-        dprintf_message(stddeb,"%*s(%08x) message [%04x] %s returned %08lx\n",
-                        SPY_IndentLevel, "", hWnd, msg,
+	pname = SPY_GetWndName(hWnd);
+        dprintf_message(stddeb,"%*s(%08x) %-16s message [%04x] %s returned %08lx\n",
+                        SPY_IndentLevel, "", hWnd, pname, msg,
                         SPY_GetMsgName( msg ), lReturn );
         break; 
+
     case SPY_RESULT_INVALIDHWND16:
-        dprintf_message(stddeb,"%*s(%04x) message [%04x] %s HAS INVALID HWND\n",
-                        SPY_IndentLevel, "", hWnd, msg,
+	pname = SPY_GetWndName(hWnd);
+        dprintf_message(stddeb,"%*s(%04x) %-16s message [%04x] %s HAS INVALID HWND\n",
+                        SPY_IndentLevel, "", hWnd, pname, msg,
                         SPY_GetMsgName( msg ) );
         break;
+
     case SPY_RESULT_INVALIDHWND32:
-        dprintf_message(stddeb,"%*s(%08x) message [%04x] %s HAS INVALID HWND\n",
-                        SPY_IndentLevel, "", hWnd, msg,
+	pname = SPY_GetWndName(hWnd);
+        dprintf_message(stddeb,"%*s(%08x) %-16s message [%04x] %s HAS INVALID HWND\n",
+                        SPY_IndentLevel, "", hWnd, pname, msg,
                         SPY_GetMsgName( msg ) );
         break;
    }
@@ -712,5 +783,8 @@
             for (i = 0; i <= SPY_MAX_MSGNUM; i++)
                 SPY_Exclude[i] = (MessageTypeNames[i] && strstr(buffer,MessageTypeNames[i]));
     }
+
+    SPY_ExcludeDWP = PROFILE_GetWineIniInt( "Spy", "ExcludeDWP", 0 );
+
     return 1;
 }
diff --git a/misc/ver.c b/misc/ver.c
index 89426ca..dc6836c 100644
--- a/misc/ver.c
+++ b/misc/ver.c
@@ -1,7 +1,8 @@
 /* 
  * Implementation of VER.DLL
  * 
- * Copyright 1996 Marcus Meissner
+ * Copyright 1996,1997 Marcus Meissner
+ * Copyright 1997 David Cuthbert
  */
 #include <stdlib.h>
 #include <stdio.h>
@@ -166,8 +167,9 @@
 
 
 int
-read_ne_header(HFILE32 lzfd,LPIMAGE_OS2_HEADER nehd) {
+read_xx_header(HFILE32 lzfd) {
 	IMAGE_DOS_HEADER	mzh;
+	char			magic[2];
 
 	LZSeek32(lzfd,0,SEEK_SET);
 	if (sizeof(mzh)!=LZRead32(lzfd,&mzh,sizeof(mzh)))
@@ -175,22 +177,24 @@
 	if (mzh.e_magic!=IMAGE_DOS_SIGNATURE)
 		return 0;
 	LZSeek32(lzfd,mzh.e_lfanew,SEEK_SET);
-	LZREAD(nehd);
-	if (nehd->ne_magic == IMAGE_OS2_SIGNATURE) {
-		LZSeek32(lzfd,mzh.e_lfanew,SEEK_SET);
-		return 1;
-	}
-	fprintf(stderr,"misc/ver.c:read_ne_header:can't handle PE files yet.\n");
-	/* must handle PE files too. Later. */
+	if (2!=LZRead32(lzfd,magic,2))
+		return 0;
+	LZSeek32(lzfd,mzh.e_lfanew,SEEK_SET);
+	if (magic[0] == 'N' && magic[1] == 'E')
+		return IMAGE_OS2_SIGNATURE;
+	if (magic[0] == 'P' && magic[1] == 'E')
+		return IMAGE_NT_SIGNATURE;
+	fprintf(stderr,"misc/ver.c:read_ne_header:can't handle %*s files.\n",2,magic);
 	return 0;
 }
 
 
 int
 find_ne_resource(
-	HFILE32 lzfd,LPIMAGE_OS2_HEADER nehd,SEGPTR typeid,SEGPTR resid,
+	HFILE32 lzfd,SEGPTR typeid,SEGPTR resid,
 	BYTE **resdata,int *reslen,DWORD *off
 ) {
+	IMAGE_OS2_HEADER nehd;
 	NE_TYPEINFO	ti;
 	NE_NAMEINFO	ni;
 	int		i;
@@ -198,7 +202,12 @@
 	DWORD		nehdoffset;
 
 	nehdoffset = LZTELL(lzfd);
-	LZSeek32(lzfd,nehd->resource_tab_offset,SEEK_CUR);
+	LZREAD(&nehd);
+	if (nehd.resource_tab_offset==nehd.rname_tab_offset) {
+		dprintf_ver(stddeb,"no resources in NE dll\n");
+		return 0;
+	}
+	LZSeek32(lzfd,nehd.resource_tab_offset+nehdoffset,SEEK_SET);
 	LZREAD(&shiftcount);
 	dprintf_ver(stddeb,"shiftcount is %d\n",shiftcount);
 	dprintf_ver(stddeb,"reading resource typeinfo dir.\n");
@@ -212,6 +221,7 @@
 		if (!ti.type_id)
 			return 0;
 		dprintf_ver(stddeb,"    ti.typeid =%04x,count=%d\n",ti.type_id,ti.count);
+
 		skipflag=0;
 		if (!HIWORD(typeid)) {
 			if ((ti.type_id&0x8000)&&(typeid!=ti.type_id))
@@ -227,7 +237,7 @@
 				whereleft = LZTELL(lzfd);
 				LZSeek32(
 					lzfd,
-					nehdoffset+nehd->resource_tab_offset+ti.type_id,
+					nehdoffset+nehd.resource_tab_offset+ti.type_id,
 					SEEK_SET
 				);
 				LZREAD(&len);
@@ -268,7 +278,7 @@
 					whereleft = LZTELL(lzfd);
 					  LZSeek32(
 						lzfd,
-						nehdoffset+nehd->resource_tab_offset+ni.id,
+						nehdoffset+nehd.resource_tab_offset+ni.id,
 						SEEK_SET
 					);
 					LZREAD(&len);
@@ -302,31 +312,135 @@
 	}
 }
 
+extern LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(
+	LPIMAGE_RESOURCE_DIRECTORY resdirptr,LPCWSTR name,DWORD root
+);
+
+/* Loads the specified PE resource.
+ * FIXME: shouldn't load the whole image
+ */
+int
+find_pe_resource(
+	HFILE32 lzfd,LPWSTR typeid,LPWSTR resid,
+	BYTE **resdata,int *reslen,DWORD *off
+) {
+	IMAGE_NT_HEADERS pehd;
+	int		i;
+	UINT32		nrofsections;
+	DWORD		imagesize,pehdoffset;
+	BYTE		*image;
+	IMAGE_DATA_DIRECTORY		resdir;
+	LPIMAGE_RESOURCE_DIRECTORY	resourcedir,xresdir;
+	LPIMAGE_RESOURCE_DATA_ENTRY	xresdata;
+	LPIMAGE_SECTION_HEADER		sections;
+
+	pehdoffset = LZTELL(lzfd);
+	LZREAD(&pehd);
+	resdir = pehd.OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY];
+	dprintf_ver(stddeb,"find_pe_resource(.,%p,%p,....)\n",typeid,resid);
+	if (!resdir.Size) {
+		fprintf(stderr,"misc/ver.c:find_pe_resource() no resource directory found in PE file.\n");
+		return 0;
+	}
+	imagesize = pehd.OptionalHeader.SizeOfImage;
+	image = HeapAlloc(GetProcessHeap(),0,imagesize);
+	nrofsections = pehd.FileHeader.NumberOfSections;
+
+	sections = (LPIMAGE_SECTION_HEADER)HeapAlloc(GetProcessHeap(),0,pehd.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER));
+	LZSeek32(lzfd,
+		pehdoffset+
+		sizeof(DWORD)+	/* Signature */
+		sizeof(IMAGE_FILE_HEADER)+	
+		pehd.FileHeader.SizeOfOptionalHeader,
+		SEEK_SET
+	);
+	if (	nrofsections*sizeof(IMAGE_SECTION_HEADER)!=
+		LZRead32(lzfd,sections,nrofsections*sizeof(IMAGE_SECTION_HEADER))
+	) {
+		HeapFree(GetProcessHeap(),0,image);
+		return 0;
+	}
+	for (i=0;i<nrofsections;i++) {
+		if (sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+			continue;
+		LZSeek32(lzfd,sections[i].PointerToRawData,SEEK_SET);
+		if (	sections[i].SizeOfRawData!=
+			LZRead32(lzfd,image+sections[i].VirtualAddress,sections[i].SizeOfRawData)
+		)
+			continue;
+	}
+	resourcedir = (LPIMAGE_RESOURCE_DIRECTORY)(image+resdir.VirtualAddress);
+	xresdir = GetResDirEntryW(resourcedir,typeid,(DWORD)resourcedir);
+	if (!xresdir) {
+		dprintf_ver(stddeb,"...no typeid entry found for %p\n",typeid);
+		HeapFree(GetProcessHeap(),0,image);
+		return 0;
+	}
+	xresdir = GetResDirEntryW(xresdir,resid,(DWORD)resourcedir);
+	if (!xresdir) {
+		dprintf_ver(stddeb,"...no resid entry found for %p\n",resid);
+		HeapFree(GetProcessHeap(),0,image);
+		return 0;
+	}
+	
+	xresdir = GetResDirEntryW(xresdir,0,(DWORD)resourcedir);
+	if (!xresdir) {
+		dprintf_ver(stddeb,"...no 0 (default language) entry found for %p\n",resid);
+		HeapFree(GetProcessHeap(),0,image);
+		return 0;
+	}
+	xresdata = (LPIMAGE_RESOURCE_DATA_ENTRY)xresdir;
+	*reslen	= xresdata->Size;
+	*resdata= (LPBYTE)xmalloc(*reslen);
+	memcpy(*resdata,image+xresdata->OffsetToData,*reslen);
+	/* find physical address for virtual offset */
+	for (i=0;i<nrofsections;i++) {
+		if (sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+			continue;
+		if (	(xresdata->OffsetToData >= sections[i].VirtualAddress)&&
+			(xresdata->OffsetToData < sections[i].VirtualAddress+sections[i].SizeOfRawData)
+		) {
+			*off = (DWORD)(xresdata->OffsetToData)-(DWORD)(sections[i].VirtualAddress)+(DWORD)(sections[i].PointerToRawData);
+			break;
+		}
+	}
+	HeapFree(GetProcessHeap(),0,image);
+	HeapFree(GetProcessHeap(),0,sections);
+	return 1;
+}
+
 /* GetFileResourceSize				[VER.2] */
 DWORD WINAPI GetFileResourceSize(LPCSTR filename,SEGPTR restype,SEGPTR resid,
                                  LPDWORD off)
 {
 	HFILE32			lzfd;
 	OFSTRUCT		ofs;
-	BYTE			*resdata;
-	int			reslen;
-	IMAGE_OS2_HEADER	nehd;
+	BYTE			*resdata = NULL;
+	int			reslen,res;
 
 	dprintf_ver(stddeb,"GetFileResourceSize(%s,%lx,%lx,%p)\n",
 		filename,(LONG)restype,(LONG)resid,off
 	);
 	lzfd=LZOpenFile32A(filename,&ofs,OF_READ);
-	if (lzfd==0)
+	if (!lzfd)
 		return 0;
-	if (!read_ne_header(lzfd,&nehd)) {
-		LZClose32(lzfd);
-		return 0;
+	switch (read_xx_header(lzfd)) {
+	case 0:
+	    res=0;
+	    break;
+	case IMAGE_OS2_SIGNATURE:
+	    res=find_ne_resource(lzfd,restype,resid,&resdata,&reslen,off);
+	    break;
+	case IMAGE_NT_SIGNATURE:
+	    res=find_pe_resource(lzfd,(LPWSTR)restype,(LPWSTR)resid,&resdata,&reslen,off);
+	    break;
 	}
-	if (!find_ne_resource(lzfd,&nehd,restype,resid,&resdata,&reslen,off)) {
-		LZClose32(lzfd);
-		return 0;
+	if (!res) {
+	    LZClose32(lzfd);
+	    return 0;
 	}
-	free(resdata);
+	if (resdata)
+		free(resdata);
 	LZClose32(lzfd);
 	return reslen;
 }
@@ -337,9 +451,9 @@
 {
 	HFILE32			lzfd;
 	OFSTRUCT		ofs;
-	BYTE			*resdata;
-	int			reslen=datalen;
-	IMAGE_OS2_HEADER	nehd;
+	BYTE			*resdata=NULL;
+	int			res,reslen=datalen;
+
 	dprintf_ver(stddeb,"GetFileResource(%s,%lx,%lx,%ld,%ld,%p)\n",
 		filename,(LONG)restype,(LONG)resid,off,datalen,data
 	);
@@ -348,20 +462,26 @@
 	if (lzfd==0)
 		return 0;
 	if (!off) {
-		if (!read_ne_header(lzfd,&nehd)) {
-			LZClose32(lzfd);
-			return 0;
+		switch (read_xx_header(lzfd)) {
+		case 0:	res=0;
+			break;
+		case IMAGE_OS2_SIGNATURE:
+			res= find_ne_resource(lzfd,restype,resid,&resdata,&reslen,&off);
+			break;
+		case IMAGE_NT_SIGNATURE:
+			res= find_pe_resource(lzfd,restype,resid,&resdata,&reslen,&off);
+			break;
 		}
-		if (!find_ne_resource(lzfd,&nehd,restype,resid,&resdata,&reslen,&off)) {
-			LZClose32(lzfd);
+		LZClose32(lzfd);
+		if (!res)
 			return 0;
-		}
+		if (reslen>datalen) reslen = datalen;
+		memcpy(data,resdata,reslen);
 		free(resdata);
+		return reslen;
 	}
 	LZSeek32(lzfd,off,SEEK_SET);
-	if (reslen>datalen)
-		reslen=datalen;
-	LZRead32(lzfd,data,reslen);
+	reslen = LZRead32(lzfd,data,datalen);
 	LZClose32(lzfd);
 	return reslen;
 }
@@ -369,8 +489,8 @@
 /* GetFileVersionInfoSize			[VER.6] */
 DWORD WINAPI GetFileVersionInfoSize16(LPCSTR filename,LPDWORD handle)
 {
-	DWORD	len,ret;
-	BYTE	buf[72];
+	DWORD	len,ret,isuni=0;
+	BYTE	buf[144];
 	VS_FIXEDFILEINFO *vffi;
 
 	dprintf_ver(stddeb,"GetFileVersionInfoSize16(%s,%p)\n",filename,handle);
@@ -384,15 +504,41 @@
 		return 0;
 
 	vffi=(VS_FIXEDFILEINFO*)(buf+0x14);
-	if (vffi->dwSignature != VS_FFI_SIGNATURE)
-		return 0;
+	if (vffi->dwSignature != VS_FFI_SIGNATURE) {
+		/* unicode resource */
+		if (vffi->dwSignature == 0x004f0049) {
+			isuni = 1;
+			vffi = (VS_FIXEDFILEINFO*)(buf+0x28);
+		} else {
+			fprintf(stderr,"vffi->dwSignature is 0x%08lx, but not 0x%08lx!\n",
+				vffi->dwSignature,VS_FFI_SIGNATURE
+			);
+			return 0;
+		}
+	}
 	if (*(WORD*)buf < len)
 		len = *(WORD*)buf;
-	dprintf_ver(stddeb,"->strucver=%ld.%ld,filever=%ld.%ld,productver=%ld.%ld,flagmask=%lx,flags=%lx,OS=",
+	dprintf_ver(stddeb,"	structversion=0x%lx.0x%lx,\n    fileversion=0x%lx.0x%lx,\n    productversion=0x%lx.0x%lx,\n    flagmask=0x%lx,\n    flags=",
 		(vffi->dwStrucVersion>>16),vffi->dwStrucVersion&0xFFFF,
 		vffi->dwFileVersionMS,vffi->dwFileVersionLS,
 		vffi->dwProductVersionMS,vffi->dwProductVersionLS,
-		vffi->dwFileFlagsMask,vffi->dwFileFlags
+		vffi->dwFileFlagsMask
+	);
+	if (vffi->dwFileFlags & VS_FF_DEBUG) 
+		dprintf_ver(stddeb,"DEBUG,");
+	if (vffi->dwFileFlags & VS_FF_PRERELEASE)
+		dprintf_ver(stddeb,"PRERELEASE,");
+	if (vffi->dwFileFlags & VS_FF_PATCHED)
+		dprintf_ver(stddeb,"PATCHED,");
+	if (vffi->dwFileFlags & VS_FF_PRIVATEBUILD)
+		dprintf_ver(stddeb,"PRIVATEBUILD,");
+	if (vffi->dwFileFlags & VS_FF_INFOINFERRED)
+		dprintf_ver(stddeb,"INFOINFERRED,");
+	if (vffi->dwFileFlags & VS_FF_SPECIALBUILD)
+		dprintf_ver(stddeb,"SPECIALBUILD,");
+	dprintf_ver(stddeb,"\n    OS=0x%lx.0x%lx (",
+		(vffi->dwFileOS&0xFFFF0000)>>16,
+		vffi->dwFileOS&0x0000FFFF
 	);
 	switch (vffi->dwFileOS&0xFFFF0000) {
 	case VOS_DOS:dprintf_ver(stddeb,"DOS,");break;
@@ -401,7 +547,7 @@
 	case VOS_NT:dprintf_ver(stddeb,"NT,");break;
 	case VOS_UNKNOWN:
 	default:
-		dprintf_ver(stddeb,"UNKNOWN(%ld),",vffi->dwFileOS&0xFFFF0000);break;
+		dprintf_ver(stddeb,"UNKNOWN(0x%lx),",vffi->dwFileOS&0xFFFF0000);break;
 	}
 	switch (vffi->dwFileOS & 0xFFFF) {
 	case VOS__BASE:dprintf_ver(stddeb,"BASE");break;
@@ -409,21 +555,22 @@
 	case VOS__WINDOWS32:dprintf_ver(stddeb,"WIN32");break;
 	case VOS__PM16:dprintf_ver(stddeb,"PM16");break;
 	case VOS__PM32:dprintf_ver(stddeb,"PM32");break;
-	default:dprintf_ver(stddeb,"UNKNOWN(%ld)",vffi->dwFileOS&0xFFFF);break;
+	default:dprintf_ver(stddeb,"UNKNOWN(0x%lx)",vffi->dwFileOS&0xFFFF);break;
 	}
+	dprintf_ver(stddeb,")\n    ");
 	switch (vffi->dwFileType) {
 	default:
 	case VFT_UNKNOWN:
-		dprintf_ver(stddeb,"filetype=Unknown(%ld)",vffi->dwFileType);
+		dprintf_ver(stddeb,"filetype=Unknown(0x%lx)",vffi->dwFileType);
 		break;
-	case VFT_APP:dprintf_ver(stddeb,"filetype=APP");break;
-	case VFT_DLL:dprintf_ver(stddeb,"filetype=DLL");break;
+	case VFT_APP:dprintf_ver(stddeb,"filetype=APP,");break;
+	case VFT_DLL:dprintf_ver(stddeb,"filetype=DLL,");break;
 	case VFT_DRV:
 		dprintf_ver(stddeb,"filetype=DRV,");
 		switch(vffi->dwFileSubtype) {
 		default:
 		case VFT2_UNKNOWN:
-			dprintf_ver(stddeb,"UNKNOWN(%ld)",vffi->dwFileSubtype);
+			dprintf_ver(stddeb,"UNKNOWN(0x%lx)",vffi->dwFileSubtype);
 			break;
 		case VFT2_DRV_PRINTER:
 			dprintf_ver(stddeb,"PRINTER");
@@ -464,7 +611,7 @@
 		dprintf_ver(stddeb,"filetype=FONT.");
 		switch (vffi->dwFileSubtype) {
 		default:
-			dprintf_ver(stddeb,"UNKNOWN(%ld)",vffi->dwFileSubtype);
+			dprintf_ver(stddeb,"UNKNOWN(0x%lx)",vffi->dwFileSubtype);
 			break;
 		case VFT2_FONT_RASTER:dprintf_ver(stddeb,"RASTER");break;
 		case VFT2_FONT_VECTOR:dprintf_ver(stddeb,"VECTOR");break;
@@ -474,7 +621,7 @@
 	case VFT_VXD:dprintf_ver(stddeb,"filetype=VXD");break;
 	case VFT_STATIC_LIB:dprintf_ver(stddeb,"filetype=STATIC_LIB");break;
 	}
-	dprintf_ver(stddeb,"filedata=%lx.%lx\n",vffi->dwFileDateMS,vffi->dwFileDateLS);
+	dprintf_ver(stddeb,"\n    filedata=0x%lx.0x%lx\n",vffi->dwFileDateMS,vffi->dwFileDateLS);
 	return len;
 }
 
@@ -749,7 +896,7 @@
 
 /* VerInstallFileA				[VERSION.7] */
 static LPBYTE
-_fetch_versioninfo(LPSTR fn) {
+_fetch_versioninfo(LPSTR fn,VS_FIXEDFILEINFO **vffi) {
     DWORD	alloclen;
     LPBYTE	buf;
     DWORD	ret;
@@ -766,8 +913,14 @@
 	    free(buf);
 	    alloclen = *(WORD*)buf;
 	    buf = xmalloc(alloclen);
-	} else
+	} else {
+	    *vffi = (VS_FIXEDFILEINFO*)(buf+0x14);
+	    if ((*vffi)->dwSignature == 0x004f0049) /* hack to detect unicode */
+	    	*vffi = (VS_FIXEDFILEINFO*)(buf+0x28);
+	    if ((*vffi)->dwSignature != VS_FFI_SIGNATURE)
+	    	fprintf(stderr,"_fetch_versioninfo:bad VS_FIXEDFILEINFO signature 0x%08lx\n",(*vffi)->dwSignature);
 	    return buf;
+	}
     }
 }
 
@@ -868,16 +1021,14 @@
     }
     xret = 0;
     if (!(flags & VIFF_FORCEINSTALL)) {
-    	buf1 = _fetch_versioninfo(destfn);
+	VS_FIXEDFILEINFO *destvffi,*tmpvffi;
+    	buf1 = _fetch_versioninfo(destfn,&destvffi);
 	if (buf1) {
-	    buf2 = _fetch_versioninfo(tmpfn);
+	    buf2 = _fetch_versioninfo(tmpfn,&tmpvffi);
 	    if (buf2) {
 	    	char	*tbuf1,*tbuf2;
-		VS_FIXEDFILEINFO *destvffi,*tmpvffi;
 		UINT32	len1,len2;
 
-		destvffi= (VS_FIXEDFILEINFO*)(buf1+0x14);
-		tmpvffi = (VS_FIXEDFILEINFO*)(buf2+0x14);
 		len1=len2=40;
 
 		/* compare file versions */
@@ -974,7 +1125,7 @@
 
 
 /* FIXME: UNICODE? */
-struct db {
+struct dbA {
 	WORD	nextoff;
 	WORD	datalen;
 /* in memory structure... */
@@ -985,11 +1136,25 @@
  */
 };
 
+/* FIXME: UNICODE? */
+struct dbW {
+	WORD	nextoff;
+	WORD	datalen;
+	WORD	btext;		/* type of data */
+/* in memory structure... */
+	WCHAR	name[1]; 	/* padded to dword alignment */
+/* .... 
+	WCHAR	data[datalen];     padded to dword alignment
+	BYTE	subdirdata[];      until nextoff
+ */
+};
+
+/* this one used for Win16 resources, which are always in ASCII format */
 static BYTE*
-_find_data(BYTE *block,LPCSTR str, WORD buff_remain) {
+_find_dataA(BYTE *block,LPCSTR str, WORD buff_remain) {
 	char	*nextslash;
 	int	substrlen, inc_size;
-	struct	db	*db;
+	struct	dbA	*db;
 
 	while (*str && *str=='\\')
 		str++;
@@ -1006,7 +1171,7 @@
 
 
 	while (1) {
-		db=(struct db*)block;
+		db=(struct dbA*)block;
 		dprintf_ver(stddeb,"db=%p,db->nextoff=%d,db->datalen=%d,db->name=%s,db->data=%s\n",
 			db,db->nextoff,db->datalen,db->name,(char*)((char*)db+4+((strlen(db->name)+4)&~3))
 		);
@@ -1018,7 +1183,7 @@
 			if (nextslash) {
 				inc_size = 4+((strlen(db->name)+4)&~3)+((db->datalen+3)&~3);
 
-				return _find_data( block+inc_size ,nextslash,
+				return _find_dataA( block+inc_size ,nextslash,
 							buff_remain - inc_size);
 			}
 			else
@@ -1030,13 +1195,54 @@
 	}
 }
 
+/* this one used for Win32 resources, which are always in UNICODE format */
+extern LPWSTR CRTDLL_wcschr(LPWSTR str,WCHAR xchar);
+static BYTE*
+_find_dataW(BYTE *block,LPCWSTR str, WORD buff_remain) {
+	LPWSTR	nextslash;
+	int	substrlen, inc_size;
+	struct	dbW	*db;
+
+	while (*str && *str=='\\')
+		str++;
+	if (NULL!=(nextslash=CRTDLL_wcschr(str,'\\')))
+		substrlen=nextslash-str;
+	else
+		substrlen=lstrlen32W(str);
+	if (nextslash!=NULL) {
+		while (*nextslash && *nextslash=='\\')
+			nextslash++;
+		if (!*nextslash)
+			nextslash=NULL;
+	}
+
+
+	while (1) {
+		db=(struct dbW*)block;
+		if ((!db->nextoff) || (!buff_remain)) /* no more entries ? */
+			return NULL;
+
+		if (!lstrncmp32W(db->name,str,substrlen)) {
+			if (nextslash) {
+				inc_size = 8+((lstrlen32W(db->name)*sizeof(WCHAR)+4)&~3)+((db->datalen+3)&~3);
+
+				return _find_dataW( block+inc_size ,nextslash,
+							buff_remain - inc_size);
+			} else
+				return block;
+		}
+		inc_size=((db->nextoff+3)&~3);
+		block=block+inc_size;
+		buff_remain=buff_remain-inc_size;
+	}
+}
+
 /* VerQueryValue 			[VER.11] */
 /* take care, 'buffer' is NOT a SEGPTR, it just points to one */
 DWORD WINAPI VerQueryValue16(SEGPTR segblock,LPCSTR subblock,SEGPTR *buffer,
                              UINT16 *buflen)
 {
 	BYTE	*block=PTR_SEG_TO_LIN(segblock),*b;
-	struct	db	*db;
 	char	*s;
 
 	dprintf_ver(stddeb,"VerQueryValue16(%p,%s,%p,%d)\n",
@@ -1044,16 +1250,36 @@
 	);
 	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(subblock)+1);
 	strcpy(s,"VS_VERSION_INFO\\");strcat(s,subblock);
-	b=_find_data(block, s, *(WORD *)block);
-	if (b==NULL) {
-		*buflen=0;
-		return 0;
+
+	/* check for UNICODE version */
+	if (	(*(DWORD*)(block+0x14) != VS_FFI_SIGNATURE) && 
+		(*(DWORD*)(block+0x28) == VS_FFI_SIGNATURE)
+	) {
+		struct	dbW	*db;
+		LPWSTR	wstr;
+		wstr = HEAP_strdupAtoW(GetProcessHeap(),0,s);
+		b=_find_dataW(block, wstr, *(WORD *)block);
+		HeapFree(GetProcessHeap(),0,wstr);
+		if (!b) {
+			fprintf(stderr,"key %s not found in versionresource.\n",subblock);
+			*buflen=0;
+			return 0;
+		}
+		db=(struct dbW*)b;
+		b	= b+8+((lstrlen32W(db->name)*sizeof(WCHAR)+4)&~3);
+		*buflen	= db->datalen;
+	} else {
+		struct	dbA	*db;
+		b=_find_dataA(block, s, *(WORD *)block);
+		if (!b) {
+			fprintf(stderr,"key %s not found in versionresource.\n",subblock);
+			*buflen=0;
+			return 0;
+		}
+		db=(struct dbA*)b;
+		b	= b+4+((lstrlen32A(db->name)+4)&~3);
+		*buflen	= db->datalen;
 	}
-	db=(struct db*)b;
-	*buflen	= db->datalen;
-	/* let b point to data area */
-	b	= b+4+((strlen(db->name)+4)&~3);
-	/* now look up what the resp. SEGPTR would be ... */
 	*buffer	= (b-block)+segblock;
 	dprintf_ver(stddeb,"	-> %s=%s\n",subblock,b);
 	return 1;
@@ -1063,23 +1289,42 @@
                               LPVOID *vbuffer,UINT32 *buflen)
 {
 	BYTE	*b,*block=(LPBYTE)vblock,**buffer=(LPBYTE*)vbuffer;
-	struct	db	*db;
-	char	*s;
+	LPSTR	s;
 
 	dprintf_ver(stddeb,"VerQueryValue32A(%p,%s,%p,%d)\n",
 		block,subblock,buffer,*buflen
 	);
 	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(subblock)+1);
 	strcpy(s,"VS_VERSION_INFO\\");strcat(s,subblock);
-	b=_find_data(block, s, *(WORD *)block);
-	if (b==NULL) {
-		*buflen=0;
-		return 0;
+	/* check for UNICODE version */
+	if (	(*(DWORD*)(block+0x14) != VS_FFI_SIGNATURE) && 
+		(*(DWORD*)(block+0x28) == VS_FFI_SIGNATURE)
+	) {
+		LPWSTR	wstr;
+		struct	dbW	*db;
+		wstr = HEAP_strdupAtoW(GetProcessHeap(),0,s);
+		b=_find_dataW(block, wstr, *(WORD *)block);
+		HeapFree(GetProcessHeap(),0,wstr);
+		if (!b) {
+			fprintf(stderr,"key %s not found in versionresource.\n",subblock);
+			*buflen=0;
+			return 0;
+		}
+		db=(struct dbW*)b;
+		*buflen	= db->datalen;
+		b	= b+8+((lstrlen32W(db->name)*sizeof(WCHAR)+4)&~3);
+	} else {
+		struct	dbA	*db;
+		b=_find_dataA(block, s, *(WORD *)block);
+		if (!b) {
+			fprintf(stderr,"key %s not found in versionresource.\n",subblock);
+			*buflen=0;
+			return 0;
+		}
+		db=(struct dbA*)b;
+		*buflen	= db->datalen;
+		b	= b+4+((lstrlen32A(db->name)+4)&~3);
 	}
-	db=(struct db*)b;
-	*buflen	= db->datalen;
-	/* let b point to data area */
-	b	= b+4+((strlen(db->name)+4)&~3);
 	*buffer	= b;
 	dprintf_ver(stddeb,"	-> %s=%s\n",subblock,b);
 	return 1;
@@ -1088,30 +1333,11 @@
 DWORD WINAPI VerQueryValue32W(LPVOID vblock,LPCWSTR subblock,LPVOID *vbuffer,
                               UINT32 *buflen)
 {
-	/* FIXME: hmm, we not only need to convert subblock, but also 
-	 *        the content...or?
-	 * And what about UNICODE version info?
-	 * And the NAMES of the values?
-	 */
-	BYTE		*b,**buffer=(LPBYTE*)vbuffer,*block=(LPBYTE)vblock;
-	struct	db	*db;
-	char		*s,*sb;
+	LPSTR		sb;
+	DWORD		ret;
 
 	sb = HEAP_strdupWtoA( GetProcessHeap(), 0, subblock );
-	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(sb)+1);
-	strcpy(s,"VS_VERSION_INFO\\");strcat(s,sb);
-	b=_find_data(block, s, *(WORD *)block);
-	if (b==NULL) {
-		*buflen=0;
-		HeapFree( GetProcessHeap(), 0, sb );
-		return 0;
-	}
-	db=(struct db*)b;
-	*buflen	= db->datalen;
-	/* let b point to data area */
-	b	= b+4+((strlen(db->name)+4)&~3);
-	*buffer	= b;
-	dprintf_ver(stddeb,"	-> %s=%s\n",sb,b);
+	ret = VerQueryValue32A(vblock,sb,vbuffer,buflen);
         HeapFree( GetProcessHeap(), 0, sb );
 	return 1;
 }
diff --git a/misc/winsock.c b/misc/winsock.c
index 3246b41..bec016c 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -342,7 +342,11 @@
 
 INT32 WINSOCK_DeleteTaskWSI( TDB* pTask, LPWSINFO pwsi )
 {
-    /* WSACleanup() backend, called on task termination as well. */
+    /* WSACleanup() backend, called on task termination as well.
+     * Real DLL would have registered its own signal handler with
+     * TaskSetSignalHandler() and waited until USIG_TERMINATION/USIG_GPF
+     * but this scheme is much more straightforward.
+     */
 
     int	i, j, n;
 
diff --git a/misc/wsprintf.c b/misc/wsprintf.c
index f347fd5..9f11e07 100644
--- a/misc/wsprintf.c
+++ b/misc/wsprintf.c
@@ -331,7 +331,7 @@
  *           wvsnprintf32A   (Not a Windows API)
  */
 INT32 WINAPI wvsnprintf32A( LPSTR buffer, UINT32 maxlen, LPCSTR spec,
-                            LPCVOID args )
+                            va_list args )
 {
     WPRINTF_FORMAT format;
     LPSTR p = buffer;
@@ -351,21 +351,24 @@
         switch(format.type)
         {
         case WPR_WCHAR:
-            if ((*p = (CHAR)*(WCHAR *)args)) p++;
+            if ((*p = (CHAR)va_arg( args, WCHAR ))) p++;
             else if (format.width > 1) *p++ = ' ';
             else len = 0;
             break;
         case WPR_CHAR:
-            if ((*p = *(CHAR *)args)) p++;
+            if ((*p = va_arg( args, CHAR ))) p++;
             else if (format.width > 1) *p++ = ' ';
             else len = 0;
             break;
         case WPR_STRING:
-            if (len) memcpy( p, *(LPCSTR *)args, len );
+            if (len) memcpy( p, va_arg( args, LPCSTR ), len );
             p += len;
             break;
         case WPR_WSTRING:
-            for (i = 0; i < len; i++) *p++ = (CHAR)*(*(LPCWSTR *)args + i);
+            {
+                LPCWSTR ptr = va_arg( args, LPCWSTR );
+                for (i = 0; i < len; i++) *p++ = (CHAR)*ptr++;
+            }
             break;
         case WPR_HEXA:
             if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
@@ -383,12 +386,12 @@
             for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
             if (len) memcpy( p, number, len );
             p += len;
+            (void)va_arg( args, INT32 ); /* Go to the next arg */
             break;
         }
         if (format.flags & WPRINTF_LEFTALIGN)
             for (i = format.precision; i < format.width; i++, maxlen--)
                 *p++ = ' ';
-        args = (INT32 *)args + 1;
         maxlen -= len;
     }
     *p = 0;
@@ -400,7 +403,7 @@
  *           wvsnprintf32W   (Not a Windows API)
  */
 INT32 WINAPI wvsnprintf32W( LPWSTR buffer, UINT32 maxlen, LPCWSTR spec,
-                            LPCVOID args )
+                            va_list args )
 {
     WPRINTF_FORMAT format;
     LPWSTR p = buffer;
@@ -420,20 +423,23 @@
         switch(format.type)
         {
         case WPR_WCHAR:
-            if ((*p = *(WCHAR *)args)) p++;
+            if ((*p = va_arg( args, WCHAR ))) p++;
             else if (format.width > 1) *p++ = ' ';
             else len = 0;
             break;
         case WPR_CHAR:
-            if ((*p = (WCHAR)*(CHAR *)args)) p++;
+            if ((*p = (WCHAR)va_arg( args, CHAR ))) p++;
             else if (format.width > 1) *p++ = ' ';
             else len = 0;
             break;
         case WPR_STRING:
-            for (i = 0; i < len; i++) *p++ = (WCHAR)*(*(LPCSTR *)args + i);
+            {
+                LPCSTR ptr = va_arg( args, LPCSTR );
+                for (i = 0; i < len; i++) *p++ = (WCHAR)*ptr++;
+            }
             break;
         case WPR_WSTRING:
-            if (len) memcpy( p, *(LPCWSTR *)args, len * sizeof(WCHAR) );
+            if (len) memcpy( p, va_arg( args, LPCWSTR ), len * sizeof(WCHAR) );
             p += len;
             break;
         case WPR_HEXA:
@@ -451,12 +457,12 @@
         case WPR_UNSIGNED:
             for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
             for (i = 0; i < len; i++) *p++ = (WCHAR)number[i];
+            (void)va_arg( args, INT32 ); /* Go to the next arg */
             break;
         }
         if (format.flags & WPRINTF_LEFTALIGN)
             for (i = format.precision; i < format.width; i++, maxlen--)
                 *p++ = ' ';
-        args = (INT32 *)args + 1;
         maxlen -= len;
     }
     *p = 0;
@@ -476,7 +482,7 @@
 /***********************************************************************
  *           wvsprintf32A   (USER32.586)
  */
-INT32 WINAPI wvsprintf32A( LPSTR buffer, LPCSTR spec, LPCVOID args )
+INT32 WINAPI wvsprintf32A( LPSTR buffer, LPCSTR spec, va_list args )
 {
     return wvsnprintf32A( buffer, 0xffffffff, spec, args );
 }
@@ -485,7 +491,7 @@
 /***********************************************************************
  *           wvsprintf32W   (USER32.587)
  */
-INT32 WINAPI wvsprintf32W( LPWSTR buffer, LPCWSTR spec, LPCVOID args )
+INT32 WINAPI wvsprintf32W( LPWSTR buffer, LPCWSTR spec, va_list args )
 {
     return wvsnprintf32W( buffer, 0xffffffff, spec, args );
 }
@@ -502,7 +508,7 @@
 
     va_start( valist, spec );
     /* Note: we call the 32-bit version, because the args are 32-bit */
-    res = (INT16)wvsprintf32A( buffer, spec, (LPCVOID)valist );
+    res = (INT16)wvsprintf32A( buffer, spec, valist );
     va_end( valist );
     return res;
 }
@@ -519,44 +525,75 @@
 
 
 /***********************************************************************
- *           wsprintf32A   (USER32.584)
+ *           wsprintf32A   (USER32.585)
  */
-/* Winelib version */
 INT32 WINAPIV wsprintf32A( LPSTR buffer, LPCSTR spec, ... )
 {
     va_list valist;
     INT32 res;
 
     va_start( valist, spec );
-    res = wvsprintf32A( buffer, spec, (LPCVOID)valist );
+    res = wvsprintf32A( buffer, spec, valist );
     va_end( valist );
     return res;
 }
 
-/* Emulator version */
-INT32 WINAPIV WIN32_wsprintf32A( DWORD *args )
-{
-    return wvsprintf32A( (LPSTR)args[0], (LPCSTR)args[1], (LPCVOID)&args[2] );
-}
-
 
 /***********************************************************************
- *           wsprintf32W   (USER32.585)
+ *           wsprintf32W   (USER32.586)
  */
-/* Winelib version */
 INT32 WINAPIV wsprintf32W( LPWSTR buffer, LPCWSTR spec, ... )
 {
     va_list valist;
     INT32 res;
 
     va_start( valist, spec );
-    res = wvsprintf32W( buffer, spec, (LPCVOID)valist );
+    res = wvsprintf32W( buffer, spec, valist );
     va_end( valist );
     return res;
 }
 
-/* Emulator version */
-INT32 WINAPIV WIN32_wsprintf32W( DWORD *args )
+
+/***********************************************************************
+ *           wsnprintf16   (Not a Windows API)
+ */
+INT16 WINAPIV wsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec, ... )
 {
-    return wvsprintf32W( (LPWSTR)args[0], (LPCWSTR)args[1], (LPCVOID)&args[2]);
+    va_list valist;
+    INT16 res;
+
+    va_start( valist, spec );
+    res = wvsnprintf16( buffer, maxlen, spec, valist );
+    va_end( valist );
+    return res;
+}
+
+
+/***********************************************************************
+ *           wsnprintf32A   (Not a Windows API)
+ */
+INT32 WINAPIV wsnprintf32A( LPSTR buffer, UINT32 maxlen, LPCSTR spec, ... )
+{
+    va_list valist;
+    INT32 res;
+
+    va_start( valist, spec );
+    res = wvsnprintf32A( buffer, maxlen, spec, valist );
+    va_end( valist );
+    return res;
+}
+
+
+/***********************************************************************
+ *           wsnprintf32W   (Not a Windows API)
+ */
+INT32 WINAPIV wsnprintf32W( LPWSTR buffer, UINT32 maxlen, LPCWSTR spec, ... )
+{
+    va_list valist;
+    INT32 res;
+
+    va_start( valist, spec );
+    res = wvsnprintf32W( buffer, maxlen, spec, valist );
+    va_end( valist );
+    return res;
 }