Release 960811

Sun Aug 11 13:00:20 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [configure.in] [include/acconfig.h] [tools/build.c]
	Added check for underscore on external symbols.

	* [memory/selector.c] [memory/global.c]
	Fixed FreeSelector() to free only one selector.
	Added SELECTOR_FreeBlock() to free an array of selectors.

	* [objects/color.c]
	Fixed a bug in COLOR_ToLogical() that caused GetPixel() to fail on
	hi-color displays.

	* [tools/build.c] [if1632/crtdll.spec]
	Added 'extern' type, used for external variables or functions.

	* [windows/winpos.c]
	Allow de-activating a window in WINPOS_ChangeActiveWindow().

	* [windows/winproc.c]
	Added 32-to-16 translation for button messages.
	Fixed WINPROC_GetPtr() to avoid crashes on 32-bit procedures that
	happen to be valid SEGPTRs.

Sat Aug 10 18:22:25 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [windows/message.c]
	Removed a FIXME in MSG_PeekHardwareMsg(): produces correct 
	data for the JOURNALRECORD-hook (using EVENTMSG16 structure).

	* [if1632/gdi.spec] [include/windows.h] [objects/metafile.c]
	Introduced undocumented API function IsValidMetaFile(), plus a
 	minor fix in last patch of CopyMetaFile().

	* [objects/gdiobj.c]
	Removed a FIXME in IsGDIObject(): added magic word check.

Sun Aug 10 18:10:10 1996  Bruce Milner <Bruce.Milner@genetics.utah.edu>

	* [controls/statuswin.c]
	First pass at implementing the StatusWindow class.

	* [include/commctrl.h]
	Header file for common controls.

	* [controls/widgets.c]
	Added InitCommonControls().

	* [if1632/comctl32.spec]
	Add DrawStatusTextA, CreateStatusWindowA, InitCommonControls.

	* [win32/findfile.c] [if1632/kernel32.spec]
	Add FindNextFile32A, FindClose.
	Modified FindFirstFile32A so it works with FindNextFile32A.

	* [include/winbase.h]
	Fixed WIN32_FIND_DATA structure member names.

Sat Aug 10 09:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/scroll.c]
	Changed scrolling routines to benefit from DCE code update.

Thu Aug  8 18:05:09 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/file.c]
	SearchPath* could get NULL for lastpart argument.

	* [if1632/build-spec.txt] [documentation/debugging]
	Varargs documentation added, debugging hints updated.

	* [if1632/crtdll.spec][misc/crtdll.c][misc/Makefile.in]
	Started to implement CRTDLL.

	* [if1632/wsock32.spec]
	Some thunks to standard libc functions (structures have the same
 	elements, but perhaps wrong offset due to packing).

	* [include/kernel32.h][include/windows.h][win32/*.c][loader/main.c]
	Merged kernel32.h into windows.h.

	* [misc/lstr.c]
	Enhanced FormatMessage().

	* [misc/main.c] [if1632/kernel.spec] [include/windows.h]
	GetVersion() updated to new naming standard.
	Changed language handling to support language ids.

	* [misc/shell.c]
	Enhanced FindExecutable, so it finds files in the search path too.

	* [win32/environment.c]
	GetCommandLine* updated.

	* [loader/resource.c] [loader/pe_resource.c]
	FindResourceEx32* added.
	Loading of messagetables added.
	Language handling now uses Wine default language id.
diff --git a/loader/main.c b/loader/main.c
index 235faea..28f9987 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -16,7 +16,6 @@
 #include "comm.h"
 #include "win.h"
 #include "menu.h"
-#include "kernel32.h"
 #include "atom.h"
 #include "dialog.h"
 #include "directory.h"
@@ -59,6 +58,7 @@
     extern BOOL32 RELAY_Init(void);
     extern BOOL32 SIGNAL_Init(void);
     extern BOOL32 WIDGETS_Init(void);
+    extern int KERN32_Init(void);
 
     int queueSize;
 
diff --git a/loader/ne_image.c b/loader/ne_image.c
index a32007e..a900e83 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -20,6 +20,7 @@
 #include "arch.h"
 #include "selectors.h"
 #include "callback.h"
+#include "file.h"
 #include "module.h"
 #include "stackframe.h"
 #include "stddebug.h"
diff --git a/loader/ne_resource.c b/loader/ne_resource.c
index bd74e65..99e32b7 100644
--- a/loader/ne_resource.c
+++ b/loader/ne_resource.c
@@ -35,7 +35,7 @@
     NE_MODULE *pModule;
     NE_TYPEINFO *pTypeInfo;
     NE_NAMEINFO *pNameInfo;
-    HGLOBAL handle;
+    HGLOBAL16 handle;
     WORD *p;
     DWORD ret = 0;
     int count;
@@ -101,8 +101,8 @@
  *
  * Find a resource once the type info structure has been found.
  */
-static HRSRC NE_FindResourceFromType( NE_MODULE *pModule,
-                                      NE_TYPEINFO *pTypeInfo, SEGPTR resId )
+static HRSRC16 NE_FindResourceFromType( NE_MODULE *pModule,
+                                        NE_TYPEINFO *pTypeInfo, SEGPTR resId )
 {
     BYTE *p;
     int count;
@@ -117,7 +117,7 @@
             if (pNameInfo->id & 0x8000) continue;
             p = (BYTE *)pModule + pModule->res_table + pNameInfo->id;
             if ((*p == len) && !lstrncmpi32A( p+1, str, len ))
-                return (HRSRC)((int)pNameInfo - (int)pModule);
+                return (HRSRC16)((int)pNameInfo - (int)pModule);
         }
     }
     else  /* Numeric resource id */
@@ -125,7 +125,7 @@
         WORD id = LOWORD(resId) | 0x8000;
         for (count = pTypeInfo->count; count > 0; count--, pNameInfo++)
             if (pNameInfo->id == id) 
-	      return (HRSRC)((int)pNameInfo - (int)pModule);
+	      return (HRSRC16)((int)pNameInfo - (int)pModule);
     }
     return 0;
 }
@@ -134,10 +134,10 @@
 /***********************************************************************
  *           NE_FindResource
  */
-HRSRC NE_FindResource( HMODULE16 hModule, SEGPTR typeId, SEGPTR resId )
+HRSRC16 NE_FindResource( HMODULE16 hModule, SEGPTR typeId, SEGPTR resId )
 {
     NE_TYPEINFO *pTypeInfo;
-    HRSRC hRsrc;
+    HRSRC16 hRsrc;
 
     NE_MODULE *pModule = MODULE_GetPtr( hModule );
     if (!pModule || !pModule->res_table) return 0;
@@ -211,7 +211,7 @@
 /***********************************************************************
  *           NE_AllocResource
  */
-HGLOBAL NE_AllocResource( HMODULE16 hModule, HRSRC hRsrc, DWORD size )
+HGLOBAL16 NE_AllocResource( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size )
 {
     NE_NAMEINFO *pNameInfo=NULL;
     WORD sizeShift;
@@ -231,7 +231,7 @@
 /***********************************************************************
  *           NE_AccessResource
  */
-int NE_AccessResource( HMODULE16 hModule, HRSRC hRsrc )
+int NE_AccessResource( HMODULE16 hModule, HRSRC16 hRsrc )
 {
     NE_NAMEINFO *pNameInfo=NULL;
     int fd;
@@ -254,7 +254,7 @@
 /***********************************************************************
  *           NE_SizeofResource
  */
-DWORD NE_SizeofResource( HMODULE16 hModule, HRSRC hRsrc )
+DWORD NE_SizeofResource( HMODULE16 hModule, HRSRC16 hRsrc )
 {
     NE_NAMEINFO *pNameInfo=NULL;
     WORD sizeShift;
@@ -272,7 +272,7 @@
 /***********************************************************************
  *           NE_LoadResource
  */
-HGLOBAL NE_LoadResource( HMODULE16 hModule,  HRSRC hRsrc )
+HGLOBAL16 NE_LoadResource( HMODULE16 hModule,  HRSRC16 hRsrc )
 {
     NE_NAMEINFO *pNameInfo=NULL;
     WORD sizeShift;
@@ -307,7 +307,7 @@
 /***********************************************************************
  *           NE_LockResource
  */
-SEGPTR NE_LockResource( HMODULE16 hModule, HGLOBAL handle )
+SEGPTR NE_LockResource( HMODULE16 hModule, HGLOBAL16 handle )
 {
     /* May need to reload the resource if discarded */
 
@@ -318,7 +318,7 @@
 /***********************************************************************
  *           NE_FreeResource
  */
-BOOL NE_FreeResource( HMODULE16 hModule, HGLOBAL handle )
+BOOL NE_FreeResource( HMODULE16 hModule, HGLOBAL16 handle )
 {
     NE_TYPEINFO *pTypeInfo;
     NE_NAMEINFO *pNameInfo;
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index fd3a302..1f9fa13 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -15,7 +15,6 @@
 #include <sys/types.h>
 #include "wintypes.h"
 #include "windows.h"
-#include "kernel32.h"
 #include "pe_image.h"
 #include "module.h"
 #include "handle32.h"
@@ -29,8 +28,6 @@
 #include "stddebug.h"
 #include "debug.h"
 
-int language = 0x0409;
-
 #define PrintIdA(name) \
     if (HIWORD((DWORD)name)) \
         dprintf_resource( stddeb, "'%s'", name); \
@@ -116,9 +113,11 @@
 }
 
 /**********************************************************************
- *	    PE_FindResource32W
+ *	    PE_FindResourceEx32W
  */
-HANDLE32 PE_FindResource32W( HINSTANCE hModule, LPCWSTR name, LPCWSTR type )
+HANDLE32 PE_FindResourceEx32W( 
+	HINSTANCE hModule, LPCWSTR name, LPCWSTR type, WORD lang
+)
 {
     PE_MODULE *pe;
     NE_MODULE *pModule;
@@ -142,7 +141,7 @@
 	return 0;
     if ((resdirptr = GetResDirEntryW(resdirptr, name, root)) == NULL)
 	return 0;
-    result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)language, root);
+    result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT32)lang, root);
 	/* Try LANG_NEUTRAL, too */
     if(!result)
         return (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)0, root);
diff --git a/loader/resource.c b/loader/resource.c
index cea0057..d96398a 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -32,6 +32,7 @@
     else \
         dprintf_resource( stddeb, "#%04x", LOWORD(name)); 
 
+extern WORD WINE_LanguageId;
 
 /**********************************************************************
  *	    FindResource16    (KERNEL.60)
@@ -72,6 +73,15 @@
  */
 HANDLE32 FindResource32A( HINSTANCE32 hModule, LPCSTR name, LPCSTR type )
 {
+    return FindResourceEx32A(hModule,name,type,WINE_LanguageId);
+}
+
+/**********************************************************************
+ *	    FindResourceEx32A    (KERNEL32.129)
+ */
+HANDLE32 FindResourceEx32A(
+	HINSTANCE32 hModule,LPCSTR name,LPCSTR type,WORD lang
+) {
     LPWSTR xname,xtype;
     HANDLE32 ret;
 
@@ -79,7 +89,7 @@
     else xname = (LPWSTR)name;
     if (HIWORD((DWORD)type)) xtype = STRING32_DupAnsiToUni(type);
     else xtype = (LPWSTR)type;
-    ret = FindResource32W(hModule,xname,xtype);
+    ret = FindResourceEx32W(hModule,xname,xtype,lang);
     if (HIWORD((DWORD)name)) free(xname);
     if (HIWORD((DWORD)type)) free(xtype);
     return ret;
@@ -87,16 +97,14 @@
 
 
 /**********************************************************************
- *	    FindResource32W    (KERNEL32.131)
+ *	    FindResourceEx32W    (KERNEL32.130)
  */
-HRSRC32 FindResource32W( HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type )
-{
+HRSRC32 FindResourceEx32W(
+	HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type, WORD lang
+) {
 #ifndef WINELIB
     NE_MODULE *pModule;
 
-    /* Sometimes we get passed hModule = 0x00000000. FIXME: is GetTaskDS()
-     * ok?
-     */
     if (!hModule) hModule = GetTaskDS();
     hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
     dprintf_resource(stddeb, "FindResource32W: module=%08x type=", hModule );
@@ -106,12 +114,20 @@
     dprintf_resource( stddeb, "\n" );
     if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
     if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
-    return PE_FindResource32W(hModule,name,type);
+    return PE_FindResourceEx32W(hModule,name,type,lang);
 #else
     return LIBRES_FindResource( hModule, name, type );
 #endif
 }
 
+/**********************************************************************
+ *	    FindResource32W    (KERNEL32.131)
+ */
+HRSRC32 FindResource32W( HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type )
+{
+    return FindResourceEx32W(hModule,name,type,WINE_LanguageId);
+}
+
 
 /**********************************************************************
  *	    LoadResource16    (KERNEL.61)
@@ -642,11 +658,121 @@
 INT32
 LoadString32A(HINSTANCE32 instance,UINT32 resource_id,LPSTR buffer,int buflen)
 {
-    LPWSTR buffer2 = (LPWSTR)xmalloc(buflen*2);
+    LPWSTR buffer2 = buffer?(LPWSTR)xmalloc(buflen*2):NULL;
     INT32 retval = LoadString32W(instance,resource_id,buffer2,buflen);
 
-    STRING32_UniToAnsi(buffer,buffer2);
-    free(buffer2);
+    if (buffer) {
+	STRING32_UniToAnsi(buffer,buffer2);
+	free(buffer2);
+    }
+    return retval;
+}
+
+/* Messages...used by FormatMessage32* (KERNEL32.something)
+ * 
+ * They can be specified either directly or using a message ID and
+ * loading them from the resource.
+ * 
+ * The resourcedata has following format:
+ * start:
+ * 0: DWORD nrofentries
+ * nrofentries * subentry:
+ *	0: DWORD firstentry
+ *	4: DWORD lastentry
+ *      8: DWORD offset from start to the stringentries
+ *
+ * (lastentry-firstentry) * stringentry:
+ * 0: WORD len (0 marks end)
+ * 2: WORD unknown (flags?)
+ * 4: CHAR[len-4]
+ * 	(stringentry i of a subentry refers to the ID 'firstentry+i')
+ *
+ * Yes, ANSI strings in win32 resources. Go figure.
+ */
+
+/**********************************************************************
+ *	LoadMessage32A		(internal)
+ */
+INT32
+LoadMessage32A(
+	HINSTANCE32 instance,UINT32 id,WORD lang,LPSTR buffer,int buflen
+) {
+    HGLOBAL32	hmem;
+    HRSRC32	hrsrc;
+    BYTE	*p;
+    int		nrofentries,i,slen;
+    struct	_subentry {
+    	DWORD	firstentry;
+	DWORD	lastentry;
+	DWORD	offset;
+    } *se;
+    struct	_stringentry {
+    	WORD	len;
+	WORD	unknown;
+	CHAR	str[1];
+    } *stre;
+
+    dprintf_resource(stddeb, "LoadMessage: instance = %04x, id = %04x, buffer = %08x, "
+	   "length = %d\n", instance, (int)id, (int) buffer, buflen);
+
+    /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
+    hrsrc = FindResourceEx32W(instance,(LPWSTR)1,(LPCWSTR)RT_MESSAGELIST,lang);
+    if (!hrsrc) return 0;
+    hmem = LoadResource32( instance, hrsrc );
+    if (!hmem) return 0;
+    
+    p = LockResource32(hmem);
+    nrofentries = *(DWORD*)p;
+    stre = NULL;
+    se = (struct _subentry*)(p+4);
+    for (i=nrofentries;i--;) {
+    	if ((id>=se->firstentry) && (id<se->lastentry)) {
+	    stre = (struct _stringentry*)(p+se->offset);
+	    id	-= se->firstentry;
+	    break;
+	}
+	se++;
+    }
+    if (!stre)
+    	return 0;
+    for (i=id;i--;) {
+    	if (!(slen=stre->len))
+		return 0;
+    	stre = (struct _stringentry*)(((char*)stre)+slen);
+    }
+    slen=stre->len;
+    dprintf_resource(stddeb,"	- strlen=%d\n",slen);
+    i = MIN(buflen - 1, slen);
+    if (buffer == NULL)
+	return slen; /* different to LoadString */
+    if (i>0) {
+	lstrcpyn32A(buffer,stre->str,i);
+	buffer[i]=0;
+    } else {
+	if (buflen>1) {
+	    buffer[0]=0;
+	    return 0;
+	}
+    }
+    if (buffer)
+	    dprintf_resource(stddeb,"LoadMessage // '%s' copied !\n", buffer);
+    return i;
+}
+
+/**********************************************************************
+ *	LoadMessage32W	(internal)
+ */
+INT32
+LoadMessage32W(
+	HINSTANCE32 instance,UINT32 id,WORD lang,LPWSTR buffer,int buflen
+) {
+    LPSTR buffer2 = buffer?(LPSTR)xmalloc(buflen):NULL;
+    INT32 retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
+
+    if (buffer) {
+	STRING32_AnsiToUni(buffer,buffer2);
+	free(buffer2);
+    }
     return retval;
 }
 
diff --git a/loader/task.c b/loader/task.c
index b1bea0d..4eb6234 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -38,7 +38,7 @@
   /* Must not be greater than 64k, or MAKE_SEGPTR won't work */
 #define STACK32_SIZE 0x10000
 
-extern void USER_AppExit(HTASK, HINSTANCE, HQUEUE );
+extern void USER_AppExit( HTASK16, HINSTANCE16, HQUEUE16 );
 
   /* Saved 16-bit stack for current process (Win16 only) */
 WORD IF1632_Saved16_ss = 0;
@@ -254,7 +254,7 @@
  * Create a thunk free-list in segment 'handle', starting from offset 'offset'
  * and containing 'count' entries.
  */
-static void TASK_CreateThunks( HGLOBAL handle, WORD offset, WORD count )
+static void TASK_CreateThunks( HGLOBAL16 handle, WORD offset, WORD count )
 {
     int i;
     WORD free;
@@ -1030,9 +1030,9 @@
 /***********************************************************************
  *           SetTaskQueue  (KERNEL.34)
  */
-HQUEUE SetTaskQueue( HANDLE hTask, HQUEUE hQueue )
+HQUEUE16 SetTaskQueue( HTASK16 hTask, HQUEUE16 hQueue )
 {
-    HQUEUE hPrev;
+    HQUEUE16 hPrev;
     TDB *pTask;
 
     if (!hTask) hTask = hCurrentTask;