Release 960324

Sun Mar 24 13:13:11 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [include/win.h] [windows/*.c]
	Replaced next, parent, child and owner handles by pointers in WND
	structure. This should improve performance, and should be
	reasonably safe since Microsoft did the same in Win95.

	* [include/wintypes.h] [*/*]
	Redefined HANDLE to be UINT instead of a pointer for Winelib. This
	allows removing a lot of unnecessary casts and NPFMTs.

	* [windows/caret.c]
	Create the caret brush upon CreateCaret(); use the bitmap
	dimensions for the caret.
	Fixed CARET_DisplayCaret() to use PatBlt().

Fri Mar 22 16:00:00 1996  Anand Kumria <akumria@ozemail.com.au>

	* [misc/winsocket.c]
	More sanity checks, fixup some erroneous return codes.

	* [documentation/winsock]
	Description of how compatible the winsock is currently.

Fri Mar 22 13:05:34 1996  Ulrich Schmid  <uschmid@mail.hh.provi.de>

	* [library/winmain.c]
	Set `lpszCmdParam' by concatenating arguments.

	* [loader/module.c]
	WinExec: accept Unix commands, use Wine emulator.

Mon Mar 18 12:16:27 1996  Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [if1632/kernel32.spec][win32/thread.c][include/kernel32.h]
	DeleteCriticalSection, EnterCriticalSection,
 	InitializeCriticalSection, LeaveCriticalSection, TlsAlloc,
 	TlsFree, TlsGetValue, TlsSetValue: new functions.
	CRITICAL_SECTION: new structure.

	* [if1632/kernel32.spec][win32/code_page.c]
	WideCharToMultiByte: new function.

	* [if1632/kernel32.spec][win32/file.c]
	GetFileAttributesA: new function.

	* [if1632/kernel32.spec][misc/main.c]
	GetEnvironmentStringsW, FreeEnvironmentStringsA,
 	FreeEnvironmentStringsW: new functions.
	
	* [if1632/user.spec][win32/cursoricon32.c][win32/Makefile.in]
	cursoricon32.c: new file.
	LoadCursorA, LoadCursorW: modified implementation from LoadCursor
 	to WIN32_*.
	LoadIconA, LoadIconW: modified implementation from LoadIconA32
	to WIN32_*.

	* [include/struct32.h]
	pragma pack inserted.
	CURSORICON32 structures added.

	* [include/winnls.h]
	Constants CP_* and WC_* added.

	* [loader/pe_image.c]
	PE_LoadModule: call PE_InitDLL with hModule rather than wpnt.

Sun Mar 17 16:59:12 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [misc/commdlg.c]
	Introduced hook function handling in file dialog.
	Removed an unnecessary ShowWindow call in FILEDLG_WMCommand().

Thu Mar 14 10:50:00 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>

	* [if1632/gdi32.spec]
	Added GetNearestColor.

	* [if1632/kernel32.spec]
	Added GlobalAddAtomA.

	* [win32/param32.c]
	Added stackframe.h to includes.
	WIN32_GlobalAddAtomA() - new function.
diff --git a/misc/clipboard.c b/misc/clipboard.c
index 847e891..31049ba 100644
--- a/misc/clipboard.c
+++ b/misc/clipboard.c
@@ -59,7 +59,7 @@
 {
     if (hWndClipboardOwner != 0) return FALSE;
     hWndClipboardOwner = hWnd;
-    dprintf_clipboard(stddeb,"OpenClipboard("NPFMT"); !\n", hWnd);
+    dprintf_clipboard(stddeb,"OpenClipboard(%04x); !\n", hWnd);
     return TRUE;
 }
 
@@ -107,7 +107,7 @@
 HWND GetClipboardOwner()
 {
     dprintf_clipboard(stddeb,
-		"GetClipboardOwner() = "NPFMT" !\n", hWndClipboardOwner);
+		"GetClipboardOwner() = %04x !\n", hWndClipboardOwner);
     return hWndClipboardOwner;
 }
 
@@ -119,7 +119,7 @@
 {
     LPCLIPFORMAT lpFormat = ClipFormats; 
     dprintf_clipboard(stddeb,
-		"SetClipboardDate(%04X, "NPFMT") !\n", wFormat, hData);
+		"SetClipboardDate(%04X, %04x) !\n", wFormat, hData);
     while(TRUE) {
 	if (lpFormat == NULL) return 0;
 	if (lpFormat->wFormatID == wFormat) break;
@@ -173,7 +173,7 @@
 	if (lpFormat == NULL) break;
 	if (lpFormat->hData != 0) {
         dprintf_clipboard(stddeb,
-		"CountClipboardFormats // Find Not Empty ("NPFMT") !\n",
+		"CountClipboardFormats // Find Not Empty (%04x) !\n",
 					lpFormat->hData);
 	    FormatCount++;
 	    }
@@ -211,7 +211,7 @@
 	lpFormat = lpFormat->NextFormat;
 	}
     dprintf_clipboard(stddeb,
-		"EnumClipboardFormats // Find Not Empty Id=%04X hData="NPFMT" !\n",
+		"EnumClipboardFormats // Find Not Empty Id=%04X hData=%04x !\n",
 				lpFormat->wFormatID, lpFormat->hData);
     return lpFormat->wFormatID;
 }
@@ -279,7 +279,7 @@
 HWND SetClipboardViewer(HWND hWnd)
 {
     HWND hwndPrev = hWndViewer;
-    dprintf_clipboard(stddeb,"SetClipboardViewer("NPFMT") !\n", hWnd);
+    dprintf_clipboard(stddeb,"SetClipboardViewer(%04x) !\n", hWnd);
     hWndViewer = hWnd;
     return hwndPrev;
 }
@@ -290,7 +290,7 @@
  */
 HWND GetClipboardViewer()
 {
-    dprintf_clipboard(stddeb,"GetClipboardFormat() = "NPFMT" !\n", hWndViewer);
+    dprintf_clipboard(stddeb,"GetClipboardFormat() = %04x !\n", hWndViewer);
     return hWndViewer;
 }
 
@@ -301,7 +301,7 @@
 BOOL ChangeClipboardChain(HWND hWnd, HWND hWndNext)
 {
     dprintf_clipboard(stdnimp,
-		"ChangeClipboardChain("NPFMT", "NPFMT") !\n", hWnd, hWndNext);
+		"ChangeClipboardChain(%04x, %04x) !\n", hWnd, hWndNext);
 
      return 0;
 }
@@ -331,7 +331,7 @@
 HWND GetOpenClipboardWindow()
 {
     dprintf_clipboard(stddeb,
-		"GetOpenClipboardWindow() = "NPFMT" !\n", hWndClipboardOwner);
+		"GetOpenClipboardWindow() = %04x !\n", hWndClipboardOwner);
     return hWndClipboardOwner;
 }
 
@@ -377,7 +377,7 @@
 	    hText=0;
 	} else {
 	    dprintf_clipboard(stddeb,"Selection is %s\n",val);
-	    hText=GlobalAlloc(GMEM_MOVEABLE, nitems);
+	    hText=GlobalAlloc(GMEM_MOVEABLE, nitems+1);
 	    memcpy(GlobalLock(hText),val,nitems+1);
 	    GlobalUnlock(hText);
 	}
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 9e76ac0..3d242f7 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -295,6 +295,18 @@
 }
 
 /***********************************************************************
+ *                              FILEDLG_HookCallChk             [internal]
+ */
+static int FILEDLG_HookCallChk(LPOPENFILENAME lpofn)
+{
+ if (lpofn)
+  if (lpofn->Flags & OFN_ENABLEHOOK)
+   if (lpofn->lpfnHook)
+    return 1;
+ return 0;   
+} 
+
+/***********************************************************************
  *                              FILEDLG_WMInitDialog            [internal]
  */
 
@@ -372,7 +384,11 @@
     ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
   if (lpofn->Flags & OFN_HIDEREADONLY)
     ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); 
-  return TRUE;
+  if (FILEDLG_HookCallChk(lpofn))
+     return (BOOL)CallWindowProc(lpofn->lpfnHook, 
+               hWnd,  WM_INITDIALOG, wParam,(LPARAM)MAKE_SEGPTR(lpofn));
+  else  
+     return TRUE;
 }
 
 /***********************************************************************
@@ -382,6 +398,7 @@
 {
   LONG lRet;
   LPOPENFILENAME lpofn;
+  OPENFILENAME ofn2;
   char tmpstr[512], tmpstr2[512];
   LPSTR pstr, pstr2;
   UINT control,notification;
@@ -407,6 +424,12 @@
       SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet,
 			 (LPARAM)MAKE_SEGPTR(tmpstr));
       SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
+
+      if (FILEDLG_HookCallChk(lpofn))
+       CallWindowProc (lpofn->lpfnHook, hWnd,
+                  RegisterWindowMessage(MAKE_SEGPTR(LBSELCHSTRING)), 
+                  control, MAKELONG(lRet,CD_LBSELCHANGE));       
+      /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, CD_LBSELNOITEMS */                  
       return TRUE;
     case lst2: /* directory list */
       FILEDLG_StripEditControl(hWnd);
@@ -454,6 +477,7 @@
       return TRUE;
     case IDOK:
     almost_ok:
+      ofn2=*lpofn; /* for later restoring */
       SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(tmpstr));
       pstr = strrchr(tmpstr, '\\');
       if (pstr == NULL)
@@ -507,7 +531,9 @@
 	}
       else 
 	SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
-      ShowWindow(hWnd, SW_HIDE);
+#if 0
+      ShowWindow(hWnd, SW_HIDE);   /* this should not be necessary ?! (%%%) */
+#endif
       {
 	int drive = DRIVE_GetCurrentDrive();
 	tmpstr2[0] = 'A'+ drive;
@@ -535,6 +561,20 @@
           dprintf_commdlg(stddeb,"strcpy'ing '%s'\n",tmpstr); fflush(stdout);
 	  strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), tmpstr);
 	}
+      if (FILEDLG_HookCallChk(lpofn))
+      {
+       lRet= (BOOL)CallWindowProc (lpofn->lpfnHook,
+               hWnd, RegisterWindowMessage(MAKE_SEGPTR(FILEOKSTRING)), 
+               0, (LPARAM)MAKE_SEGPTR(lpofn));                        
+       if (lRet)       
+       {
+         *lpofn=ofn2; /* restore old state */
+#if 0
+         ShowWindow(hWnd, SW_SHOW);               /* only if above (%%%) SW_HIDE used */
+#endif         
+         break;
+       }
+      }
       EndDialog(hWnd, TRUE);
       return TRUE;
     case IDCANCEL:
@@ -550,6 +590,15 @@
  */
 LRESULT FileOpenDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {  
+ LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
+ 
+ if (wMsg!=WM_INITDIALOG)
+  if (FILEDLG_HookCallChk(lpofn))
+  {
+   LRESULT  lRet=(BOOL)CallWindowProc(lpofn->lpfnHook, hWnd, wMsg, wParam, lParam);
+   if (lRet)   
+    return lRet;         /* else continue message processing */
+  }             
   switch (wMsg)
     {
     case WM_INITDIALOG:
@@ -584,6 +633,15 @@
  */
 LRESULT FileSaveDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {
+ LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
+ 
+ if (wMsg!=WM_INITDIALOG)
+  if (FILEDLG_HookCallChk(lpofn))
+  {
+   LRESULT  lRet=(BOOL)CallWindowProc(lpofn->lpfnHook, hWnd, wMsg, wParam, lParam);
+   if (lRet)   
+    return lRet;         /* else continue message processing */
+  }             
   switch (wMsg) {
    case WM_INITDIALOG:
       return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
diff --git a/misc/driver.c b/misc/driver.c
index 7da4990..30567fa 100644
--- a/misc/driver.c
+++ b/misc/driver.c
@@ -33,7 +33,7 @@
         	dprintf_driver(stddeb,"LoadStartupDrivers // str='%s'\n", ptr);
 		hDrv = OpenDriver(ptr, "drivers", 0L);
         	dprintf_driver(stddeb,
-			"LoadStartupDrivers // hDrv="NPFMT"\n", hDrv);
+			"LoadStartupDrivers // hDrv=%04x\n", hDrv);
 		ptr += strlen(ptr) + 1;
 		}
     	dprintf_driver(stddeb,"LoadStartupDrivers // end of list !\n");
@@ -44,7 +44,7 @@
  */
 LRESULT WINAPI SendDriverMessage(HDRVR hDriver, WORD msg, LPARAM lParam1, LPARAM lParam2)
 {
-	dprintf_driver(stdnimp,"SendDriverMessage("NPFMT", %04X, %08lX, %08lX);\n",
+	dprintf_driver(stdnimp,"SendDriverMessage(%04x, %04X, %08lX, %08lX);\n",
 						hDriver, msg, lParam1, lParam2);
         return 0;
 }
@@ -93,7 +93,7 @@
 		lpnewdrv->lpPrevItem = lpdrv;
 		}
 	lpnewdrv->lpDrvProc = NULL;
-    	dprintf_driver(stddeb,"OpenDriver // hDrvr="NPFMT" loaded !\n", hDrvr);
+    	dprintf_driver(stddeb,"OpenDriver // hDrvr=%04x loaded !\n", hDrvr);
 	return hDrvr;
 }
 
@@ -104,7 +104,7 @@
 {
 	LPDRIVERITEM	lpdrv;
     	dprintf_driver(stddeb,
-		"CloseDriver("NPFMT", %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
+		"CloseDriver(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
 	lpdrv = (LPDRIVERITEM) GlobalLock(hDrvr);
 	if (lpdrv != NULL && lpdrv->dis.hDriver == hDrvr) {
 		if (lpdrv->lpPrevItem)
@@ -113,7 +113,7 @@
 			((LPDRIVERITEM)lpdrv->lpNextItem)->lpPrevItem = lpdrv->lpPrevItem;
 		GlobalUnlock(hDrvr);
 		GlobalFree(hDrvr);
-        dprintf_driver(stddeb,"CloseDriver // hDrvr="NPFMT" closed !\n", hDrvr);
+        dprintf_driver(stddeb,"CloseDriver // hDrvr=%04x closed !\n", hDrvr);
 		return TRUE;
 		}
 	return FALSE;
@@ -126,7 +126,7 @@
 {
 	LPDRIVERITEM	lpdrv;
 	HANDLE			hModule = 0;
-    	dprintf_driver(stddeb,"GetDriverModuleHandle("NPFMT");\n", hDrvr);
+    	dprintf_driver(stddeb,"GetDriverModuleHandle(%04x);\n", hDrvr);
 	lpdrv = (LPDRIVERITEM) GlobalLock(hDrvr);
 	if (lpdrv != NULL) {
 		hModule = lpdrv->dis.hModule;
@@ -175,7 +175,7 @@
 BOOL GetDriverInfo(HDRVR hDrvr, LPDRIVERINFOSTRUCT lpDrvInfo)
 {
 	LPDRIVERITEM	lpdrv;
-    	dprintf_driver(stddeb,"GetDriverInfo("NPFMT", %p);\n", hDrvr, lpDrvInfo);
+    	dprintf_driver(stddeb,"GetDriverInfo(%04x, %p);\n", hDrvr, lpDrvInfo);
 	if (lpDrvInfo == NULL) return FALSE;
 	lpdrv = (LPDRIVERITEM) GlobalLock(hDrvr);
 	if (lpdrv == NULL) return FALSE;
@@ -191,7 +191,7 @@
 {
 	LPDRIVERITEM	lpdrv;
 	HDRVR			hRetDrv = 0;
-    	dprintf_driver(stddeb,"GetNextDriver("NPFMT", %08lX);\n", hDrvr, dwFlags);
+    	dprintf_driver(stddeb,"GetNextDriver(%04x, %08lX);\n", hDrvr, dwFlags);
 	if (hDrvr == 0) {
 		if (lpDrvItemList == NULL) {
             		dprintf_driver(stddeb,
@@ -199,7 +199,7 @@
 			LoadStartupDrivers();
 			if (lpDrvItemList == NULL) return 0;
 			}
-        	dprintf_driver(stddeb,"GetNextDriver // return first "NPFMT" !\n",
+        	dprintf_driver(stddeb,"GetNextDriver // return first %04x !\n",
 					lpDrvItemList->dis.hDriver);
 		return lpDrvItemList->dis.hDriver;
 		}
@@ -215,7 +215,7 @@
 			}
 		GlobalUnlock(hDrvr);
 		}
-    	dprintf_driver(stddeb,"GetNextDriver // return "NPFMT" !\n", hRetDrv);
+    	dprintf_driver(stddeb,"GetNextDriver // return %04x !\n", hRetDrv);
 	return hRetDrv;
 }
 
diff --git a/misc/exec.c b/misc/exec.c
index fc0131b..e66f09f 100644
--- a/misc/exec.c
+++ b/misc/exec.c
@@ -55,7 +55,7 @@
  */
 BOOL ExitWindows( DWORD dwReturnCode, WORD wReserved )
 {
-    HWND hwnd, hwndDesktop;
+    HWND hwndDesktop;
     WND *wndPtr;
     HWND *list, *pWnd;
     int count, i;
@@ -70,22 +70,16 @@
 
     hwndDesktop = GetDesktopWindow();
     count = 0;
-    for (hwnd = GetTopWindow(hwndDesktop); hwnd != 0; hwnd = wndPtr->hwndNext)
-    {
-        if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
+    for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
         count++;
-    }
     if (!count) /* No windows, we can exit at once */
         EXEC_ExitWindows( LOWORD(dwReturnCode) );
 
       /* Now build the list of all windows */
 
-    if (!(list = (HWND *)malloc( sizeof(HWND) * count ))) return FALSE;
-    for (hwnd = GetTopWindow(hwndDesktop), pWnd = list; hwnd != 0; hwnd = wndPtr->hwndNext)
-    {
-        wndPtr = WIN_FindWndPtr( hwnd );
-        *pWnd++ = hwnd;
-    }
+    if (!(pWnd = list = (HWND *)malloc( sizeof(HWND) * count ))) return FALSE;
+    for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
+        *pWnd++ = wndPtr->hwndSelf;
 
       /* Now send a WM_QUERYENDSESSION message to every window */
 
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index 57e5c8c..4b4b500 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -263,7 +263,7 @@
 	BYTE	*buf;
 	struct	lzstate	*lzs;
 
-	dprintf_file(stddeb,"LZRead(%d,%08lx,%d)\n",fd,segbuf,toread);
+	dprintf_file(stddeb,"LZRead(%d,%08lx,%d)\n",fd,(DWORD)segbuf,toread);
 	howmuch=toread;
 	for (i=0;i<nroflzstates;i++)
 		if (lzstates[i].lzfd==fd)
diff --git a/misc/main.c b/misc/main.c
index eb19885..34f3b95 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -831,6 +831,66 @@
     return envtable;
 }
 
+
+LPVOID GetEnvironmentStringsW(void)
+{
+    int count,len;
+    LPENVENTRY lpEnv;
+    char *envtable, *envptr;
+	WCHAR *wenvtable;
+
+    /* Count the total number of bytes we'll need for the string
+     * table.  Include the trailing nuls and the final double nul.
+     */
+    count = 1;
+    lpEnv = lpEnvList;
+    while(lpEnv != NULL)
+    {
+        if(lpEnv->Name != NULL)
+        {
+            count += strlen(lpEnv->Name) + 1;
+            count += strlen(lpEnv->Value) + 1;
+        }
+        lpEnv = lpEnv->Next;
+    }
+
+	len=count;
+    envtable = malloc(count);
+    if(envtable)
+    {
+        lpEnv = lpEnvList;
+        envptr = envtable;
+
+        while(lpEnv != NULL)
+        {
+            if(lpEnv->Name != NULL)
+            {
+                count = sprintf(envptr, "%s=%s", lpEnv->Name, lpEnv->Value);
+                envptr += count + 1;
+            }
+            lpEnv = lpEnv->Next;
+        }
+        *envptr = '\0';
+    }
+
+	wenvtable = malloc(2*len);
+	for(count=0;count<len;count++)
+		wenvtable[count]=(WCHAR)envtable[count];
+	free(envtable);
+
+    return envtable;
+}
+
+void FreeEnvironmentStringsA(void *e)
+{
+	free(e);
+}
+
+void FreeEnvironmentStringsW(void* e)
+{
+	free(e);
+}
+
 /***********************************************************************
  *	GetTimerResolution (USER.14)
  */
diff --git a/misc/network.c b/misc/network.c
index 6840755..0713f8d 100644
--- a/misc/network.c
+++ b/misc/network.c
@@ -117,7 +117,7 @@
  */
 int WNetWatchQueue(HWND hWnd,LPSTR szLocal,LPSTR szUser,WORD nQueue)
 {
-	printf("EMPTY STUB !!! WNetWatchQueue("NPFMT",'%s','%s',%x)\n",
+	printf("EMPTY STUB !!! WNetWatchQueue(%04x,'%s','%s',%x)\n",
 		hWnd,szLocal,szUser,nQueue);
 	return WN_NET_ERROR;
 }
@@ -193,7 +193,7 @@
  */
 int WNetDeviceMode(HWND hWndOwner)
 {
-	printf("EMPTY STUB !!! WNetDeviceMode("NPFMT")\n",hWndOwner);
+	printf("EMPTY STUB !!! WNetDeviceMode(%04x)\n",hWndOwner);
 	return WN_NET_ERROR;
 }
 
@@ -202,7 +202,7 @@
  */
 int WNetBrowseDialog(HWND hParent,WORD nType,LPSTR szPath)
 {
-	printf("EMPTY STUB !!! WNetBrowseDialog("NPFMT",%x,'%s')\n",
+	printf("EMPTY STUB !!! WNetBrowseDialog(%04x,%x,'%s')\n",
 		hParent,nType,szPath);
 	return WN_NET_ERROR;
 }
@@ -262,7 +262,7 @@
  */
 int WNetRestoreConnection(HWND hwndOwner,LPSTR lpszDevice)
 {
-	printf("EMPTY STUB !!! WNetRestoreConnection("NPFMT",'%s')\n",
+	printf("EMPTY STUB !!! WNetRestoreConnection(%04x,'%s')\n",
 		hwndOwner,lpszDevice);
 	return WN_NET_ERROR;
 }
@@ -272,7 +272,7 @@
  */
 int WNetWriteJob(HANDLE hJob,void *lpData,LPWORD lpcbData)
 {
-	printf("EMPTY STUB !!! WNetWriteJob("NPFMT",%p,%p)\n",
+	printf("EMPTY STUB !!! WNetWriteJob(%04x,%p,%p)\n",
 		hJob,lpData,lpcbData);
 	return WN_NET_ERROR;
 }
@@ -282,7 +282,7 @@
  */
 UINT WNetConnectDialog(HWND hWndParent, WORD iType)
 {
-	printf("EMPTY STUB !!! WNetConnectDialog("NPFMT", %4X)\n", hWndParent, iType);
+	printf("EMPTY STUB !!! WNetConnectDialog(%04x, %4X)\n", hWndParent, iType);
 	return WN_SUCCESS;
 }
 
@@ -291,7 +291,7 @@
  */
 int WNetDisconnectDialog(HWND hwndOwner, WORD iType)
 {
-	printf("EMPTY STUB !!! WNetDisconnectDialog("NPFMT",%x)\n",
+	printf("EMPTY STUB !!! WNetDisconnectDialog(%04x,%x)\n",
 		hwndOwner,iType);
 	return WN_NET_ERROR;
 }
@@ -301,7 +301,7 @@
  */
 UINT WNetConnectionDialog(HWND hWndParent, WORD iType)
 {
-	printf("EMPTY STUB !!! WNetConnectionDialog("NPFMT", %4X)\n", 
+	printf("EMPTY STUB !!! WNetConnectionDialog(%04x, %4X)\n", 
 		hWndParent, iType);
 	return WN_SUCCESS;
 }
@@ -311,7 +311,7 @@
  */
 int WNetViewQueueDialog(HWND hwndOwner,LPSTR lpszQueue)
 {
-	printf("EMPTY STUB !!! WNetViewQueueDialog("NPFMT",'%s')\n",
+	printf("EMPTY STUB !!! WNetViewQueueDialog(%04x,'%s')\n",
 		hwndOwner,lpszQueue);
 	return WN_NET_ERROR;
 }
@@ -322,7 +322,7 @@
 int WNetPropertyDialog(HWND hwndParent,WORD iButton,
 	WORD nPropSel,LPSTR lpszName,WORD nType)
 {
-	printf("EMPTY STUB !!! WNetPropertyDialog("NPFMT",%x,%x,'%s',%x)\n",
+	printf("EMPTY STUB !!! WNetPropertyDialog(%04x,%x,%x,'%s',%x)\n",
 		hwndParent,iButton,nPropSel,lpszName,nType);
 	return WN_NET_ERROR;
 }
@@ -342,7 +342,7 @@
  */
 int WNetDirectoryNotify(HWND hwndOwner,void *lpDir,WORD wOper)
 {
-	printf("EMPTY STUB !!! WNetDirectoryNotify("NPFMT",%p,%x)\n",
+	printf("EMPTY STUB !!! WNetDirectoryNotify(%04x,%p,%x)\n",
 		hwndOwner,lpDir,wOper);
 	return WN_NET_ERROR;
 }
@@ -353,7 +353,7 @@
 int WNetGetPropertyText(HWND hwndParent,WORD iButton,WORD nPropSel,
 	LPSTR lpszName,WORD nType)
 {
-	printf("EMPTY STUB !!! WNetGetPropertyText("NPFMT",%x,%x,'%s',%x)\n",
+	printf("EMPTY STUB !!! WNetGetPropertyText(%04x,%x,%x,'%s',%x)\n",
 		hwndParent,iButton,nPropSel,lpszName,nType);
 	return WN_NET_ERROR;
 }
@@ -374,7 +374,7 @@
  */
 UINT WNetCloseEnum(HANDLE hEnum)
 {
-	printf("EMPTY STUB !!! WNetCloseEnum("NPFMT");\n", hEnum);
+	printf("EMPTY STUB !!! WNetCloseEnum(%04x);\n", hEnum);
 	return WN_NET_ERROR;
 }
 
@@ -384,7 +384,7 @@
 UINT WNetEnumResource(HANDLE hEnum, DWORD cRequ, 
 				DWORD *lpCount, LPVOID lpBuf)
 {
-	printf("EMPTY STUB !!! WNetEnumResource("NPFMT", %08lX, %p, %p);\n", 
+	printf("EMPTY STUB !!! WNetEnumResource(%04x, %08lX, %p, %p);\n", 
 							hEnum, cRequ, lpCount, lpBuf);
 	return WN_NET_ERROR;
 }
@@ -396,7 +396,7 @@
 	LPNETRESOURCE lpNet, HANDLE FAR *lphEnum)
 {
 	printf("EMPTY STUB !!! WNetOpenEnum(%08lX, %08lX, %p, %p);\n",
-							dwScope, dwType, lpNet, lphEnum);
+               dwScope, dwType, lpNet, lphEnum);
 	return WN_NET_ERROR;
 }
 
diff --git a/misc/olecli.c b/misc/olecli.c
index ca5ca9d..adf9a72 100644
--- a/misc/olecli.c
+++ b/misc/olecli.c
@@ -52,6 +52,6 @@
  */
 BOOL WINAPI OleIsDcMeta(HDC hdc)
 {
-	dprintf_ole(stddeb,"OleIsDCMeta("NPFMT")\n",hdc);
+	dprintf_ole(stddeb,"OleIsDCMeta(%04x)\n",hdc);
 	return GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ) != 0;
 }
diff --git a/misc/rect.c b/misc/rect.c
index 3d2bc8c..68eb462 100644
--- a/misc/rect.c
+++ b/misc/rect.c
@@ -3,8 +3,7 @@
  *
  * Copyright 1993 Alexandre Julliard
  *
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-*/
+ */
 
 #include "windows.h"
 
diff --git a/misc/shell.c b/misc/shell.c
index 2c46817..12aea21 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -229,6 +229,7 @@
 	  lpKey = lphTopKey; break;
         case HKEY_CLASSES_ROOT: /* == 1 */
         case 0x80000000:
+        case 0x80000001:
           lpKey = lphRootKey; break;
         default: 
 	  dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", (DWORD)hKey);
@@ -442,6 +443,7 @@
 	  lpKey = lphTopKey; break;
         case HKEY_CLASSES_ROOT: /* == 1 */
         case 0x80000000:
+        case 0x80000001:
           lpKey = lphRootKey; break;
         default: 
 	  dprintf_reg(stddeb,"RegEnumKey // specific key = %08lX !\n", (DWORD)hKey);
@@ -470,7 +472,7 @@
 void DragAcceptFiles(HWND hWnd, BOOL b)
 {
     /* flips WS_EX_ACCEPTFILES bit according to the value of b */
-    dprintf_reg(stddeb,"DragAcceptFiles("NPFMT", %u) old exStyle %08lx\n",
+    dprintf_reg(stddeb,"DragAcceptFiles(%04x, %u) old exStyle %08lx\n",
 		hWnd,b,GetWindowLong(hWnd,GWL_EXSTYLE));
 
     SetWindowLong(hWnd,GWL_EXSTYLE,
@@ -491,7 +493,7 @@
     LPSTR lpCurrent;
     WORD  i;
     
-    dprintf_reg(stddeb,"DragQueryFile("NPFMT", %i, %p, %u)\n",
+    dprintf_reg(stddeb,"DragQueryFile(%04x, %i, %p, %u)\n",
 		hDrop,wFile,lpszFile,wLength);
     
     lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop); 
@@ -563,7 +565,7 @@
      * we have to pass the parameters. If an instance is already running,
      * we might have to send DDE commands.
      */
-    dprintf_exec(stddeb, "ShellExecute("NPFMT",'%s','%s','%s','%s',%x)\n",
+    dprintf_exec(stddeb, "ShellExecute(%04x,'%s','%s','%s','%s',%x)\n",
 		hWnd, lpOperation ? lpOperation:"<null>", lpFile ? lpFile:"<null>",
 		lpParameters ? lpParameters : "<null>", 
 		lpDirectory ? lpDirectory : "<null>", iShowCmd);
@@ -719,7 +721,7 @@
 {
 	HICON	hIcon = 0;
 	HINSTANCE hInst2 = hInst;
-	dprintf_reg(stddeb, "ExtractIcon("NPFMT", '%s', %d\n", 
+	dprintf_reg(stddeb, "ExtractIcon(%04x, '%s', %d\n", 
 			hInst, lpszExeFileName, nIconIndex);
         return 0;
 	if (lpszExeFileName != NULL) {
diff --git a/misc/spy.c b/misc/spy.c
index 065387c..f42791d 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -432,7 +432,7 @@
     switch(iFlag)
     {
     case SPY_DISPATCHMESSAGE:
-        dprintf_message(stddeb,"("NPFMT") message [%04x] %s dispatched  wp=%04x lp=%08lx\n",
+        dprintf_message(stddeb,"(%04x) message [%04x] %s dispatched  wp=%04x lp=%08lx\n",
                         hWnd, msg, SPY_GetMsgName( msg ),
                         wParam, lParam);
         break;
@@ -443,10 +443,10 @@
             HTASK hTask = GetWindowTask(hWnd);
             if (hTask == GetCurrentTask()) strcpy( taskName, "self" );
             else if (!hTask) strcpy( taskName, "Wine" );
-            else sprintf( taskName, "task "NPFMT" %s",
+            else sprintf( taskName, "task %04x %s",
                           hTask, MODULE_GetModuleName( GetExePtr(hTask) ) );
 
-            dprintf_message(stddeb,"%*s("NPFMT") message [%04x] %s sent from %s wp=%04x lp=%08lx\n",
+            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 );
             SPY_IndentLevel += SPY_INDENT_UNIT;
@@ -454,7 +454,7 @@
         break;   
 
     case SPY_DEFWNDPROC:
-        dprintf_message(stddeb, "%*s("NPFMT") DefWindowProc: %s [%04x]  wp=%04x lp=%08lx\n",
+        dprintf_message(stddeb, "%*s(%04x) DefWindowProc: %s [%04x]  wp=%04x lp=%08lx\n",
                         SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ),
                         msg, wParam, lParam );
         break;
@@ -473,12 +473,12 @@
     switch(iFlag)
     {
     case SPY_RESULT_INVALIDHWND: 
-        dprintf_message(stddeb,"%*s("NPFMT") message [%04x] %s HAS INVALID HWND\n",
+        dprintf_message(stddeb,"%*s(%04x) message [%04x] %s HAS INVALID HWND\n",
                         SPY_IndentLevel, "", hWnd, msg,
                         SPY_GetMsgName( msg ) );
         break;
     case SPY_RESULT_OK:
-        dprintf_message(stddeb,"%*s("NPFMT") message [%04x] %s returned %08lx\n",
+        dprintf_message(stddeb,"%*s(%04x) message [%04x] %s returned %08lx\n",
                         SPY_IndentLevel, "", hWnd, msg,
                         SPY_GetMsgName( msg ), lReturn );
         break;
diff --git a/misc/winsocket.c b/misc/winsocket.c
index 05e1ecf..cd69bc0 100644
--- a/misc/winsocket.c
+++ b/misc/winsocket.c
@@ -49,7 +49,13 @@
 #pragma pack(1)
 #endif
 
-#define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
+#define WINSOCK_MAX_SOCKETS	256
+#define WINSOCK_MAX_UDPDG	1024
+
+/* we are out by two with the following, is it due to byte alignment?
+ * #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long)) 
+ */
+#define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long) - 2)
 /*#define MTYPE 0xb0b0eb05*/
 #define MTYPE 0x30b0eb05
 
@@ -152,8 +158,7 @@
                 fprintf(stderr, "winsock: errno %d, (%s).\n", 
                 			errno, sys_errlist[errno]);
 #else
-                fprintf(stderr, "winsock: errno %d, (%s).\n", 
-					errno, strerror(errno));
+                fprintf(stderr, "winsock: errno %d\n", errno);
 #endif
 #else
                 fprintf(stderr, "winsock: errno %d\n", errno);
@@ -242,8 +247,8 @@
 
         switch(h_errno)
         {
-	case TRY_AGAIN:		return WSATRY_AGAIN;
 	case HOST_NOT_FOUND:	return WSAHOST_NOT_FOUND;
+	case TRY_AGAIN:		return WSATRY_AGAIN;
 	case NO_RECOVERY:	return WSANO_RECOVERY;
 	case NO_DATA:		return WSANO_DATA; 
 /* just in case we ever get here and there are no problems */
@@ -380,6 +385,11 @@
 
 	dprintf_winsock(stddeb, "WSA_accept: socket %d, ptr %8x, length %d\n", s, (int) addr, *addrlen);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return INVALID_SOCKET;
+	}
+
 	if ((sock = accept(s, addr, (int *) addrlen)) < 0) {
         	errno_to_wsaerrno();
         	return INVALID_SOCKET;
@@ -389,11 +399,38 @@
 
 INT WINSOCK_bind(SOCKET s, struct sockaddr *name, INT namelen)
 {
+
 	dprintf_winsock(stddeb, "WSA_bind: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
 	dump_sockaddr(name);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
+	if (namelen < sizeof(*name)) {
+		WSASetLastError(WSAEFAULT);
+		return SOCKET_ERROR;
+	}
+
+	/* check the socket family */
+	if ( ((struct sockaddr_in *)name)->sin_family != AF_INET ) {
+		WSASetLastError(WSAEAFNOSUPPORT);
+		return SOCKET_ERROR;
+	}
+
 	if (bind(s, name, namelen) < 0) {
-        	errno_to_wsaerrno();
+		switch(errno) {
+		case EBADF:
+			WSASetLastError(WSAENOTSOCK);
+			break;
+		case EADDRNOTAVAIL:
+			WSASetLastError(WSAEINVAL);
+			break;
+		default:
+			errno_to_wsaerrno();
+			break;
+		}
         	return SOCKET_ERROR;
 	}
 	return 0;
@@ -403,10 +440,18 @@
 {
 	dprintf_winsock(stddeb, "WSA_closesocket: socket %d\n", s);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	FD_CLR(s, &fd_in_use);
 
 	if (close(s) < 0) {
-        	errno_to_wsaerrno();
+		if (errno == EBADF)
+			WSASetLastError(WSAENOTSOCK);
+		else
+        		errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
@@ -417,6 +462,11 @@
 	dprintf_winsock(stddeb, "WSA_connect: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
 	dump_sockaddr(name);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if (connect(s, name, namelen) < 0) {
         	errno_to_wsaerrno();
         	return SOCKET_ERROR;
@@ -429,6 +479,11 @@
 	dprintf_winsock(stddeb, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, *namelen);
 	dump_sockaddr(name);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if (getpeername(s, name, (int *) namelen) < 0) {
 		if (h_errno < 0) {
         		errno_to_wsaerrno();
@@ -443,6 +498,12 @@
 INT WINSOCK_getsockname(SOCKET s, struct sockaddr *name, INT *namelen)
 {
 	dprintf_winsock(stddeb, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, (int) *namelen);
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if (getsockname(s, name, (int *) namelen) < 0) {
 		if (h_errno < 0) {
         		errno_to_wsaerrno();
@@ -458,10 +519,19 @@
 WINSOCK_getsockopt(SOCKET s, INT level, INT optname, char *optval, INT *optlen)
 {
 	dprintf_winsock(stddeb, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s, level, (int) optval, (int) *optlen);
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	convert_sockopt(&level, &optname);
 
 	if (getsockopt(s, (int) level, optname, optval, (int *) optlen) < 0) {
-        	errno_to_wsaerrno();
+		if (errno == EBADF)
+			WSASetLastError(WSAENOTSOCK);
+		else
+        		errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
@@ -505,6 +575,11 @@
 	char *ctlname;
 	dprintf_winsock(stddeb, "WSA_ioctl: socket %d, cmd %lX, ptr %8x\n", s, cmd, (int) argp);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	/* Why can't they all use the same ioctl numbers */
 	newcmd=cmd;
 	newargp=argp;
@@ -532,7 +607,10 @@
 	
 
 	if (ioctl(s, newcmd, newargp) < 0) {
-        	errno_to_wsaerrno();
+		if (errno == EBADF)
+			WSASetLastError(WSAENOTSOCK);
+		else
+        		errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
@@ -542,6 +620,11 @@
 {
 	dprintf_winsock(stddeb, "WSA_listen: socket %d, backlog %d\n", s, backlog);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if (listen(s, backlog) < 0) {
         	errno_to_wsaerrno();
         	return SOCKET_ERROR;
@@ -565,6 +648,11 @@
 
 	dprintf_winsock(stddeb, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s, (int) buf, len, flags);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if ((length = recv(s, buf, len, flags)) < 0) {
         	errno_to_wsaerrno();
         	return SOCKET_ERROR;
@@ -579,6 +667,11 @@
 
 	dprintf_winsock(stddeb, "WSA_recvfrom: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long)buf, len, flags);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if ((length = recvfrom(s, buf, len, flags, from, fromlen)) < 0) {
         	errno_to_wsaerrno();
         	return SOCKET_ERROR;
@@ -591,6 +684,11 @@
 {
 	dprintf_winsock(stddeb, "WSA_select: fd # %d, ptr %8lx, ptr %8lx, ptr %8lX\n", nfds, (unsigned long) readfds, (unsigned long) writefds, (unsigned long) exceptfds);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+/* FIXME */
 	return(select(nfds, readfds, writefds, exceptfds, timeout));
 }
 
@@ -600,6 +698,11 @@
 
 	dprintf_winsock(stddeb, "WSA_send: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long) buf, len, flags);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if ((length = send(s, buf, len, flags)) < 0) {
         	errno_to_wsaerrno();
         	return SOCKET_ERROR;
@@ -614,6 +717,11 @@
 
 	dprintf_winsock(stddeb, "WSA_sendto: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long) buf, len, flags);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if ((length = sendto(s, buf, len, flags, to, tolen)) < 0) {
         	errno_to_wsaerrno();
         	return SOCKET_ERROR;
@@ -627,6 +735,11 @@
 	dprintf_winsock(stddeb, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s, level, optname, (int) optval, optlen);
 	convert_sockopt(&level, &optname);
 	
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if (setsockopt(s, level, optname, optval, optlen) < 0) {
         	errno_to_wsaerrno();
         	return SOCKET_ERROR;
@@ -638,6 +751,11 @@
 {
 	dprintf_winsock(stddeb, "WSA_shutdown: socket s %d, how %d\n", s, how);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	if (shutdown(s, how) < 0) {
         	errno_to_wsaerrno();
         	return SOCKET_ERROR;
@@ -651,24 +769,73 @@
 
     dprintf_winsock(stddeb, "WSA_socket: af=%d type=%d protocol=%d\n", af, type, protocol);
 
-    if ((sock = socket(af, type, protocol)) < 0) {
-        if (errno != EPERM) {
-            errno_to_wsaerrno();
-        } else {
-             /* NOTE: EPERM does not always map to WSAESOCKTNOSUPPORT
-              * so this is done as a special case
-              */
-             /* non super-user wants a raw socket */
-             dprintf_winsock(stderr, "WSA_socket: not enough privileges\n");
-             WSASetLastError(WSAESOCKTNOSUPPORT);
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return INVALID_SOCKET;
+	}
+
+    /* check the socket family */
+    switch(af) {
+    case AF_INET:
+    case AF_UNSPEC:
+        break;
+    default:
+        WSASetLastError(WSAEAFNOSUPPORT);
+        return INVALID_SOCKET;
+        break;
+    }
+
+    /* check the socket type */
+    switch(type) {
+    case SOCK_STREAM:
+    case SOCK_DGRAM:
+    case SOCK_RAW:
+        break;
+    default:
+        WSASetLastError(WSAESOCKTNOSUPPORT);
+        return INVALID_SOCKET;
+        break;
+    }
+
+    /* check the protocol type */
+    if ( protocol < 0 ) { /* don't support negative values */
+        WSASetLastError(WSAEPROTONOSUPPORT);
+        return INVALID_SOCKET;
+    }
+
+    if ( af == AF_UNSPEC) { /* did they not specify the address family? */
+        switch(protocol) {
+        case IPPROTO_TCP:
+             if (type == SOCK_STREAM) {
+                 af = AF_INET;
+                 break;
+             }
+        case IPPROTO_UDP:
+             if (type == SOCK_DGRAM) {
+                 af = AF_INET;
+                 break;
+             }
+        default:
+             WSASetLastError(WSAEPROTOTYPE);
+             return INVALID_SOCKET;
+             break;
         }
-            dprintf_winsock(stddeb, "WSA_socket: failed !\n");
-            return INVALID_SOCKET;
+    }
+
+    if ((sock = socket(af, type, protocol)) < 0) {
+        if (errno == EPERM) {
+            /* non super-user wants a raw socket */
+            fprintf(stderr, "WSA_socket: not enough privileges\n");
+            WSASetLastError(WSAESOCKTNOSUPPORT);
+        } else
+            errno_to_wsaerrno();
+        dprintf_winsock(stddeb, "WSA_socket: failed !\n");
+        return INVALID_SOCKET;
     }
     
-    if (sock > 0xffff) {
-	/* we only support socket numbers up to 0xffff. The return
-	 * value indicates there are no more descriptors available
+    if (sock > WINSOCK_MAX_SOCKETS) {
+	/* we only support socket numbers up to WINSOCK_MAX_SOCKETS.
+	 * The return value indicates no more descriptors are available
 	 */
         WSASetLastError(WSAEMFILE);
 	return INVALID_SOCKET;
@@ -689,6 +856,11 @@
 
 	dprintf_winsock(stddeb, "WSA_gethostbyaddr: ptr %8x, len %d, type %d\n", (int) addr, len, type);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return NULL;
+	}
+
 	if ((host = gethostbyaddr(addr, len, type)) == NULL) {
 		if (h_errno < 0) {
         		errno_to_wsaerrno();
@@ -711,6 +883,11 @@
 
 	dprintf_winsock(stddeb, "WSA_gethostbyname: %s\n", name);
 
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return NULL;
+	}
+
 	if ((host = gethostbyname(name)) == NULL) {
 		if (h_errno < 0) {
         		errno_to_wsaerrno();
@@ -728,12 +905,16 @@
 {
 	dprintf_winsock(stddeb, "WSA_gethostname: name %s, len %d\n", name, namelen);
 
+	if (!wsa_initted) {
+		WSASetLastError(WSANOTINITIALISED);
+        	return SOCKET_ERROR;
+	}
+
 	if (gethostname(name, namelen) < 0) {
-		if (h_errno < 0) {
-        		errno_to_wsaerrno();
-		} else {
-			herrno_to_wsaerrno();
-		}
+		if (errno == EINVAL)
+			WSASetLastError(WSAEFAULT);
+		else
+			errno_to_wsaerrno();
         	return SOCKET_ERROR;
 	}
 	return 0;
@@ -748,6 +929,11 @@
 
 	dprintf_winsock(stddeb, "WSA_getprotobyname: name %s\n", name);
 
+	if (!wsa_initted) {
+		WSASetLastError(WSANOTINITIALISED);
+        	return NULL;
+	}
+
 	if ((proto = getprotobyname(name)) == NULL) {
 		if (h_errno < 0) {
         		errno_to_wsaerrno();
@@ -770,12 +956,20 @@
 
 	dprintf_winsock(stddeb, "WSA_getprotobynumber: num %d\n", number);
 
+	if (!wsa_initted) {
+		WSASetLastError(WSANOTINITIALISED);
+        	return NULL;
+	}
+
 	if ((proto = getprotobynumber(number)) == NULL) {
+#if 0
 		if (h_errno < 0) {
         		errno_to_wsaerrno();
 		} else {
 			herrno_to_wsaerrno();
 		}
+#endif
+		WSASetLastError(WSANO_DATA);
         	return NULL;
 	}
 	CONVERT_PROTOENT(&Heap->protoent_number, proto);
@@ -795,6 +989,11 @@
 
 	dprintf_winsock(stddeb, "WSA_getservbyname: name %s, proto %s\n", name, proto);
 
+	if (!wsa_initted) {
+		WSASetLastError(WSANOTINITIALISED);
+        	return NULL;
+	}
+
 	if ((service = getservbyname(name, proto)) == NULL) {
 		if (h_errno < 0) {
         		errno_to_wsaerrno();
@@ -817,6 +1016,11 @@
 
 	dprintf_winsock(stddeb, "WSA_getservbyport: port %d, name %s\n", port, proto);
 
+	if (!wsa_initted) {
+		WSASetLastError(WSANOTINITIALISED);
+        	return NULL;
+	}
+
 	if ((service = getservbyport(port, proto)) == NULL) {
 		if (h_errno < 0) {
         		errno_to_wsaerrno();
@@ -833,7 +1037,7 @@
 /******************** winsock specific functions ************************
  *
  */
-static HANDLE new_handle = 0;
+static HANDLE new_handle = 1;
 
 static HANDLE AllocWSAHandle(void)
 {
@@ -843,15 +1047,17 @@
 static void recv_message(int sig)
 {
 	static struct ipc_packet message;
-	static int message_is_valid = 0;
+	int message_is_valid = 0;
 	BOOL result;
 
+	message.mtype = MTYPE;
+
 	signal(SIGUSR1, recv_message);
 	while (1) {
 
 		if (!message_is_valid) {
 			if (msgrcv(wine_key, (struct msgbuf*)&(message), 
-				   IPC_PACKET_SIZE, MTYPE, IPC_NOWAIT) == -1) {
+				   IPC_PACKET_SIZE, 0 /*MTYPE*/, IPC_NOWAIT) == -1) {
 				perror("wine: winsock: msgrcv");
 				break;
 			}
@@ -859,7 +1065,7 @@
 
 		result = PostMessage(message.hWnd, message.wMsg,
 				     (WPARAM)message.handle, message.lParam);
-		if (result == FALSE) {
+		if (result != FALSE) {
 			message_is_valid = 1;
 			break;
 		}
@@ -868,6 +1074,8 @@
 		
 	}
 		
+    if ((wine_key = msgget(IPC_PRIVATE, 0600)) == -1)
+	perror("wine: winsock: msgget"); 
 }
 
 
@@ -884,7 +1092,7 @@
 	if (msgsnd(wine_key, (struct msgbuf*)&(message),  
 		   IPC_PACKET_SIZE, 0/*IPC_NOWAIT*/) == -1)
 		perror("wine: winsock: msgsnd");
-		
+
 	kill(getppid(), SIGUSR1);
 }
 
@@ -894,10 +1102,18 @@
 {
 	HANDLE handle;
 	struct hostent *host;
+	int newpid;
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return 0;
+	}
 
 	handle = AllocWSAHandle();
 
-	if (fork()) {
+	newpid = fork();
+	if (newpid) {
+		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
 		return handle;
 	} else {
 		if ((host = gethostbyaddr(addr, len, type)) == NULL) {
@@ -921,10 +1137,18 @@
 {
 	HANDLE handle;
 	struct hostent *host;
+	int newpid;
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return 0;
+	}
 
 	handle = AllocWSAHandle();
 
-	if (fork()) {
+	newpid = fork();
+	if (newpid) {
+		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
 		return handle;
 	} else {
 		if ((host = gethostbyname(name)) == NULL) {
@@ -948,10 +1172,18 @@
 {
 	HANDLE handle;
 	struct protoent *proto;
+	int newpid;
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return 0;
+	}
 
 	handle = AllocWSAHandle();
 
-	if (fork()) {
+	newpid = fork();
+	if (newpid) {
+		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
 		return handle;
 	} else {
 		if ((proto = getprotobyname(name)) == NULL) {
@@ -975,10 +1207,18 @@
 {
 	HANDLE handle;
 	struct protoent *proto;
+	int newpid;
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return 0;
+	}
 
 	handle = AllocWSAHandle();
 
-	if (fork()) {
+	newpid = fork();
+	if (newpid) {
+		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
 		return handle;
 	} else {
 		if ((proto = getprotobynumber(number)) == NULL) {
@@ -1002,10 +1242,18 @@
 {
 	HANDLE handle;
 	struct servent *service;
+	int newpid;
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return 0;
+	}
 
 	handle = AllocWSAHandle();
 
-	if (fork()) {
+	newpid = fork();
+	if (newpid) {
+		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
 		return handle;
 	} else {
 		if ((service = getservbyname(name, proto)) == NULL) {
@@ -1029,10 +1277,18 @@
 {
 	HANDLE handle;
 	struct servent *service;
+	int newpid;
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return 0;
+	}
 
 	handle = AllocWSAHandle();
 
-	if (fork()) {
+	newpid = fork();
+	if (newpid) {
+		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
 		return handle;
 	} else {
 		if ((service = getservbyport(port, proto)) == NULL) {
@@ -1055,8 +1311,14 @@
     long event;
     fd_set read_fds, write_fds, except_fds;
     int errors = 0;
+    int newpid;
 
-    dprintf_winsock(stddeb, "WSA_AsyncSelect: socket %d, HWND "NPFMT", wMsg %d, event %ld\n", s, hWnd, wMsg, lEvent);
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
+    dprintf_winsock(stddeb, "WSA_AsyncSelect: socket %d, HWND %04x, wMsg %d, event %ld\n", s, hWnd, wMsg, lEvent);
 
     /* remove outstanding asyncselect() processes */
     /* kill */
@@ -1064,7 +1326,9 @@
     if (wMsg == 0 && lEvent == 0) 
         return 0;
 
-    if (fork()) {
+    newpid = fork();
+    if (newpid) {
+        dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
         return 0;
     } else {
         while (1) {
@@ -1099,7 +1363,12 @@
 
 INT WSACancelAsyncRequest(HANDLE hAsyncTaskHandle)
 {
-	dprintf_winsock(stddeb, "WSA_AsyncRequest: handle "NPFMT"\n", hAsyncTaskHandle);
+	dprintf_winsock(stddeb, "WSA_AsyncRequest: handle %04x\n", hAsyncTaskHandle);
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
 
 	return 0;
 }
@@ -1107,6 +1376,12 @@
 INT WSACancelBlockingCall(void)
 {
 	dprintf_winsock(stddeb, "WSA_CancelBlockCall\n");
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
+
 	return 0;
 }
           
@@ -1114,14 +1389,24 @@
 {
 	dprintf_winsock(stddeb, "WSA_GetLastError = %x\n", wsa_errno);
 
-    return wsa_errno;
+	return wsa_errno;
 }
 
 void WSASetLastError(INT iError)
 {
 	dprintf_winsock(stddeb, "WSA_SetLastErorr %d\n", iError);
 
-    wsa_errno = iError;
+	/* technically, we should make sure that WINESockets 
+	* has been started up correctly. But since this function
+	* is also used internally, it makes no sense.
+	*
+	*if (!wsa_initted) { 
+	*	WSASetLastError(WSANOTINITIALISED);
+	*	return SOCKET_ERROR;
+	*}
+	*/
+
+	wsa_errno = iError;
 }
 
 BOOL WSAIsBlocking(void)
@@ -1134,6 +1419,12 @@
 FARPROC WSASetBlockingHook(FARPROC lpBlockFunc)
 {
 	dprintf_winsock(stddeb, "WSA_SetBlockHook %8lx, STUB!\n", (unsigned long) lpBlockFunc);
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return NULL;
+	}
+
 	BlockFunction = lpBlockFunc;
 
 	return (FARPROC) lpBlockFunc;
@@ -1142,11 +1433,18 @@
 INT WSAUnhookBlockingHook(void)
 {
 	dprintf_winsock(stddeb, "WSA_UnhookBlockingHook\n");
+
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return NULL;
+	}
+
 	BlockFunction = NULL;
 
 	return 0;
 }
 
+#ifdef 0
 WSADATA WINSOCK_data = {
         0x0101,
         0x0101,
@@ -1162,14 +1460,35 @@
 #else
 	"Unknown",
 #endif
-        128,
-	1024,
+        WINSOCK_MAX_SOCKETS,
+	WINSOCK_MAX_UDPDG,
         NULL
 };
+#endif
 
 INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
 {
 
+	WSADATA WINSOCK_data = {
+        			0x0101,
+        			0x0101,
+        			"WINE Sockets",
+			#ifdef linux
+        			"Linux/i386",
+			#elif defined(__NetBSD__)
+        			"NetBSD/i386",
+			#elif defined(sunos)
+				"SunOS",
+			#elif defined(__FreeBSD__)
+				"FreeBSD",
+			#else
+				"Unknown",
+			#endif
+        			WINSOCK_MAX_SOCKETS,
+				WINSOCK_MAX_UDPDG,
+				NULL
+				};
+
     dprintf_winsock(stddeb, "WSAStartup: verReq=%x\n", wVersionRequested);
 
     if (LOBYTE(wVersionRequested) < 1 ||
@@ -1186,7 +1505,9 @@
 	return WSASYSNOTREADY;
 
     Heap = (struct WinSockHeap *) GlobalLock(HeapHandle);
-    memcpy(lpWSAData, &WINSOCK_data, sizeof(WINSOCK_data));
+
+    /* return winsock information */
+    memcpy(lpWSAData, &WINSOCK_data, sizeof(WINSOCK_data)); 
 
     /* ipc stuff */
 
@@ -1199,7 +1520,9 @@
     
     FD_ZERO(&fd_in_use);
 
-    wsa_initted = 1;
+    /* increment our usage count */
+    wsa_initted++;
+    dprintf_winsock(stddeb, "WSAStartup: succeeded\n");
     return(0);
 }
 
@@ -1207,14 +1530,25 @@
 {
 	int fd;
 
-	if (wine_key)
-		if (msgctl(wine_key, IPC_RMID, NULL) == -1)
-			perror("wine: winsock: shmctl");
+	dprintf_winsock(stddeb, "WSACleanup (%d)\n",getpid());
 
-	for (fd = 0; fd != FD_SETSIZE; fd++)
-		if (FD_ISSET(fd, &fd_in_use))
-			close(fd);
+	if (!wsa_initted) { 
+		WSASetLastError(WSANOTINITIALISED);
+		return SOCKET_ERROR;
+	}
 
-	wsa_initted = 0;
+	/* decrement usage count */
+	wsa_initted--;
+
+	if (wsa_initted == 0) {
+		if (wine_key)
+			if (msgctl(wine_key, IPC_RMID, NULL) == -1)
+				perror("wine: winsock: msgctl");
+
+		for (fd = 0; fd != FD_SETSIZE; fd++)
+			if (FD_ISSET(fd, &fd_in_use))
+				close(fd);
+
+	}
 	return 0;
 }