Release 960717

Wed Jul 17 16:10:16 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [configure.in]
	Generate include/config.h instead of putting everything on the
	command-line.
	Removed -with-malloc-debug option (not useful for end users
	anyway).
	Added check for memmove().

	* [include/wintypes.h] [*/Makefile.in]
	Added definition of __WINE__ symbol when compiling Wine code
	(emulator or library) as opposed to user programs.

	* [debugger/editline.c] [debugger/readline/*]
	Moved all the readline code into debugger/editline.c. Removed the
	readline subdirectory.

	* [files/profile.c]
	Added PROFILE_GetWineIniInt().

	* [include/stackframe.h] [loader/task.c]
	The 16-bit stackframe now also exists for Winelib (even though it
	only ever contains one frame).

	* [loader/module.c]
	Added function MODULE_CreateDummyModule() to create a dummy Win16
	module for Winelib and Win32.

	* [memory/ldt.c]
	Make sure the ldt entry contents will be acceptable for the Linux
	kernel.

	* [memory/selector.c]
	Fixed SetSelectorLimit() when the limit is in pages.

	* [misc/port.c]
	Added memmove().

	* [miscemu/dpmi.c]
	Clear the segment registers that contain the selector being freed
	in int31/ax=0001.
	Added missing break after SelectorAccessRights call.

	* [win32/struct32.c]
	Added conversions for MDICREATESTRUCT.

	* [windows/winproc.c]
	Added message conversions for WM_MDICREATE.

Tue Jul 16 19:46:24 1996  Pavel Kankovsky <KAN@frode.dcit.cz>

	* [windows/class.c]
	Added GetExePtr() call in CLASS_FindClassByAtom().

Mon Jul 15 17:49:38 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [if1632/*.spec]
	Some more trivial specs added.

	* [if1632/gdi32.spec] [objects/font.c][windows/dialog.c]
	CreateFont32* added, changed to new naming std.

	* [include/windows.h] [include/mmsystem.h] [include/wintypes.h]
	Some defines/types added.

	* [win32/thread.c]
	TlsSetValue() returns boolean.

	* [win32/resource.c] [loader/pe_resource.c] [loader/resource.c]
 	  [controls/menu.c] [objects/bitmap.c]
	Cleanup of the resource functions, mostly changes to new naming
 	standard and fixing of argument types so that they agree with the
 	win16/win32 API.

Thu Jul 11 15:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/winpos.c]
	ShowWindow() fixes.

	* [windows/mdi.c]
	Fix reversed LPARAM in WM_MDIACTIVATE.

	* [wine.ini]
	New option AllocSystemColors tells Wine how many colors to grab
	from the system colormap.

	* [objects/bitblt.c] [objects/dc.c]
	Fixed pink garbage over Word buttons in PseudoColor. Added
	optional DSTINVERT shortcut for faster text selection.

	* [misc/wsprintf.c]
	Skip bogus segmented pointers in wsvnprintf16(). 

	* [objects/gdiobj.c]
	Added palette handling to UnrealizeObject(). 

	* [objects/color.c] [objects/palette.c] [windows/dce.c]
	Wine gets palette manager with support for more than 20 colors. 
	Only PseudoColor and TrueColor visuals tested so far.

	* [windows/winpos.c] [windows/win.c] 
	Set X size hints for WS_EX_DLGMODALFRAME windows (no resize) and
	use XReconfigureWMWindows() instead of XConfigureWindow() in
	managed mode.

	* [memory/global.c]
	Do not allocate more than 640K of DOS memory.

	* [misc/main.c]
	Do not allow -desktop and -managed together.
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index da19a65..9178772 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -1,154 +1,167 @@
 #ifndef WINELIB
 /*
- *	(c) 1994	Erik Bos	<erik@xs4all.nl>
+ * PE (Portable Execute) File Resources
  *
- *	based on Eric Youndale's pe-test and:
+ * Copyright 1995 Thomas Sandford
+ * Copyright 1996 Martin von Loewis
  *
- *	ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
+ * Based on the Win16 resource handling code in loader/resource.c
+ * Copyright 1993 Robert J. Amstadt
+ * Copyright 1995 Alexandre Julliard
+ *
+ * This is not even at ALPHA level yet. Don't expect it to work!
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 #include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
+#include "wintypes.h"
 #include "windows.h"
-#include "ldt.h"
-#include "neexe.h"
-#include "peexe.h"
+#include "kernel32.h"
 #include "pe_image.h"
-#include "resource.h"
+#include "module.h"
+#include "handle32.h"
+#include "libres.h"
+#include "resource32.h"
+#include "stackframe.h"
+#include "neexe.h"
+#include "accel.h"
+#include "xmalloc.h"
+#include "string32.h"
 #include "stddebug.h"
-/* #define DEBUG_RESOURCE */
 #include "debug.h"
 
-#if 0
+int language = 0x0409;
 
-static int
-find_lang(char *root, struct PE_Resource_Directory *resource, RESOURCE *r)
+#define PrintIdA(name) \
+    if (HIWORD((DWORD)name)) \
+        dprintf_resource( stddeb, "'%s'", name); \
+    else \
+        dprintf_resource( stddeb, "#%04x", LOWORD(name)); 
+#define PrintIdW(name)
+#define PrintId(name)
+
+/**********************************************************************
+ *	    GetResDirEntryW
+ *
+ *	Helper function - goes down one level of PE resource tree
+ *
+ */
+PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
+					 LPCWSTR name,
+					 DWORD root)
 {
-	struct PE_Directory_Entry *type_dir;
-	struct PE_Resource_Leaf_Entry *leaf;
+    int entrynum;
+    PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
+	int namelen;
 
-	type_dir = (struct PE_Directory_Entry *)(resource + 1);
-	type_dir += resource->NumberOfNamedEntries;
-
-	/* grab the 1st resource available */
-	leaf = (struct PE_Resource_Leaf_Entry *) (root + type_dir->OffsetToData);
-		dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n", (int) type_dir->Name);
-		dprintf_resource(stddeb, "\t\taddress %ld, size %ld, language id %ld\n", leaf->OffsetToData, leaf->Size, leaf->CodePage);
-	r->offset = leaf->OffsetToData - r->wpnt->pe->resource_offset;
-	r->size = leaf->Size;
-	printf("\t\toffset %d, size %d\n", r->offset, r->size);
-	return 1;
-
-/*	for(i=0; i< resource->NumberOfIdEntries; i++) {
-		leaf = (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY));
-		dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n", 
-			(int) type_dir->Name);
-		dprintf_resource(stddeb, "\t\t%x %x %x\n", leaf->OffsetToData, 
-			leaf->Size, leaf->CodePage);
-		type_dir++;
-	} */
-}
-
-static int 
-find_resource(char *root, struct PE_Resource_Directory *resource, 
-		LPSTR resource_name, RESOURCE *r)
-{
-	int i;
-	char res_name[256];
-	struct PE_Directory_Entry *type_dir;
-	struct PE_Directory_Name_String_U *name;
-	
-	type_dir = (struct PE_Directory_Entry *)(resource + 1);
-
-	if (HIWORD((DWORD)resource_name)) {
-		for(i=0; i< resource->NumberOfNamedEntries; i++) {
-			name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING));
-			memset(res_name, 0, sizeof(res_name));
-			my_wcstombs(res_name, name->NameString, name->Length);
-			dprintf_resource(stddeb, "\tPE_findresource: name %s\n", res_name);
-			if (lstrcmpi(res_name, resource_name) == 0) 
-				return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r);
-			type_dir++;
-		}
-	} else {
-		type_dir += resource->NumberOfNamedEntries;
-		for(i=0; i< resource->NumberOfIdEntries; i++) {
-			dprintf_resource(stddeb, "\tPE_findresource: name %8x\n", (int) type_dir->Name);
-			if (type_dir->Name == ((int) resource_name & 0xff))
-				return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r);
-			type_dir++;
-		}
+    if (HIWORD(name)) {
+    /* FIXME: what about #xxx names? */
+	entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
+			(BYTE *) resdirptr + 
+                        sizeof(IMAGE_RESOURCE_DIRECTORY));
+	namelen = lstrlen32W(name);
+	for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
+	{
+		PIMAGE_RESOURCE_DIR_STRING_U str =
+		(PIMAGE_RESOURCE_DIR_STRING_U) (root + 
+			(entryTable[entrynum].Name & 0x7fffffff));
+		if(namelen != str->Length)
+			continue;
+		if(lstrncmpi32W(name,str->NameString,str->Length)==0)
+			return (PIMAGE_RESOURCE_DIRECTORY) (
+				root +
+				(entryTable[entrynum].OffsetToData & 0x7fffffff));
 	}
-	return 0;
-}
-
-static int 
-find_type(struct PE_Resource_Directory *resource, LPSTR resource_name,
-		LPSTR type_name)
-{
-	int i;
-	char *root, res_name[256];
-	struct PE_Directory_Entry *type_dir;
-	struct PE_Directory_Name_String_U *name;
-	
-	root = (char *) resource;
-	type_dir = (struct PE_Directory_Entry *)(resource + 1);
-
-	if (HIWORD((DWORD)type_name)) {
-		for(i=0; i< resource->NumberOfNamedEntries; i++) {
-			name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING));
-			memset(res_name, 0, sizeof(res_name));
-			my_wcstombs(res_name, name->NameString, name->Length);
-			dprintf_resource(stddeb, "PE_findtype: type %s\n", 
-				res_name);
-			if (lstrcmpi(res_name, type_name) == 0) 
-				return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r);
-			type_dir++;
-		}
-	} else {
-		type_dir += resource->NumberOfNamedEntries;
-		for(i=0; i< resource->NumberOfIdEntries; i++) {
-			dprintf_resource(stddeb, "PE_findtype: type %8x\n", (int) type_dir->Name);
-			if (type_dir->Name == ((int) type_name & 0xff))
-				return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r);
-			type_dir++;
-		}
-	}
-	return 0;
+	return NULL;
+    } else {
+	entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
+			(BYTE *) resdirptr + 
+                        sizeof(IMAGE_RESOURCE_DIRECTORY) +
+			resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
+	for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
+	    if ((DWORD)entryTable[entrynum].Name == (DWORD)name)
+		return (PIMAGE_RESOURCE_DIRECTORY) (
+			root +
+			(entryTable[entrynum].OffsetToData & 0x7fffffff));
+	return NULL;
+    }
 }
 
 /**********************************************************************
- *			PE_FindResource	[KERNEL.60]
+ *	    GetResDirEntryA
+ *
+ *	Helper function - goes down one level of PE resource tree
+ *
  */
-int
-PE_FindResource(HANDLE instance, SEGPTR resource_name, SEGPTR type_name,
-		RESOURCE *r)
+PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY resdirptr,
+					 LPCSTR name,
+					 DWORD root)
 {
-	dprintf_resource(stddeb, "PE_FindResource hInst=%04X typename=%08X resname=%08X\n", 
-		instance, (int) type_name, (int) resource_name);
-	if (HIWORD(resource_name))
-        {
-                char *resource_name_ptr = PTR_SEG_TO_LIN( resource_name );
-		if (resource_name_ptr[0] == '#')
-			resource_name = (SEGPTR) atoi(resource_name_ptr + 1);
-                else
-                    resource_name = (SEGPTR)resource_name_ptr;
-        }
-	if (HIWORD(type_name)) 
-        {
-                char *type_name_ptr = PTR_SEG_TO_LIN( type_name );
-		if (type_name_ptr[0] == '#')
-			type_name = (SEGPTR) atoi(type_name_ptr + 1);
-                else
-                        type_name = (SEGPTR) type_name_ptr;
-        }
-	return find_type(r->wpnt->pe->pe_resource, resource_name, type_name);
+	LPWSTR				xname;
+	PIMAGE_RESOURCE_DIRECTORY	ret;
+
+	if (HIWORD((DWORD)name))
+		xname	= STRING32_DupAnsiToUni(name);
+	else
+		xname	= (LPWSTR)name;
+
+	ret=GetResDirEntryW(resdirptr,xname,root);
+	if (HIWORD((DWORD)name))
+		free(xname);
+	return ret;
+}
+
+/**********************************************************************
+ *	    PE_FindResource32W
+ */
+HANDLE32 PE_FindResource32W( HINSTANCE hModule, LPCWSTR name, LPCWSTR type )
+{
+    PE_MODULE *pe;
+    NE_MODULE *pModule;
+    PIMAGE_RESOURCE_DIRECTORY resdirptr;
+    DWORD root;
+    HANDLE32 result;
+
+    hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
+    dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule );
+    PrintId( type );
+    dprintf_resource( stddeb, " name=" );
+    PrintId( name );
+    dprintf_resource( stddeb, "\n" );
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
+    if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;  /* FIXME? */
+    if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
+
+    resdirptr = (PIMAGE_RESOURCE_DIRECTORY) pe->pe_resource;
+    root = (DWORD) resdirptr;
+    if ((resdirptr = GetResDirEntryW(resdirptr, type, root)) == NULL)
+	return 0;
+    if ((resdirptr = GetResDirEntryW(resdirptr, name, root)) == NULL)
+	return 0;
+    result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)language, root);
+	/* Try LANG_NEUTRAL, too */
+    if(!result)
+        return (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)0, root);
+    return result;
+}
+
+
+/**********************************************************************
+ *	    PE_LoadResource32
+ */
+HANDLE32 PE_LoadResource32( HINSTANCE hModule, HANDLE32 hRsrc )
+{
+    NE_MODULE *pModule;
+    PE_MODULE *pe;
+
+    if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
+    hModule = GetExePtr( hModule );  /* In case we were passed an hInstance */
+    dprintf_resource(stddeb, "PE_LoadResource32: module=%04x res=%04x\n",
+                     hModule, hRsrc );
+    if (!hRsrc) return 0;
+
+    if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
+    if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;  /* FIXME? */
+    if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0;
+    return (HANDLE32) (pe->load_addr+((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
 }
 #endif
-
-#endif /* WINELIB */