Release 970202
Sun Feb 2 12:31:03 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
* [files/drive.c]
Fixed SetCurrentDirectory() to also change the current drive.
* [win32/except.c] [tools/build.c]
Use Win32 register functions to implement exception handling.
Fixed UnhandledExceptionFilter.
Fri Jan 31 15:42:41 1997 David Faure <david.faure@ihamy.insa-lyon.fr>
* [windows/keyboard.c]
Added KEYBOARD_GenerateMsg to generate Caps Lock and NumLock events
Added calls to KEYBOARD_GenerateMsg when the key is pressed/released
or when the state has changed, out of wine.
Changed type 3-state 'ToggleKeyState' to boolean. The On/Off is given
by InputKeyStateTable.
Wed Jan 29 21:53:04 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [loader/*resource.c][if1632/thunk.c]
EnumResource* added.
* [loader/pe_resource.] [loader/resource.c]
SizeofResource32(), LoadAccelerators32() added.
* [misc/lstr.c]
FormatMessage %n added.
* [misc/crtdll.c][include/ctrdll.h][if1632/crtdll.spec]
_chdrive,_errno,_isctype added.
* [misc/cpu.c]
Replaced runtime_cpu by GetSystemInfo().
* [windows/hook.c][include/hook.h]
Fixed mapping of hooks to win32/unicode.
* [windows/keyboard.c] [windows/defwnd.c]
Updated to win32 standard.
ALT-<Menukey> fixed.
* [windows/queue.c]
GetWindowThreadProcessId() implemented.
Mon Jan 27 16:42:49 1997 John Harvey <john@division.co.uk>
* [graphics/metafiledrv/*] [graphics/x11drv/*]
[objects/bitmap.c] [objects/brush.c] [objects/font.c]
[objects/gdiobj.c] [objects/pen.c]
Moved SelectObject to graphics drivers. Printer support now works
in a few cases but is definitely not complete. Generic/text driver
works. The postscript driver works if true type fonts are disabled
from the control panel. To enable printer support add Printer=on
to the wine section of your wine.conf file. This causes write not
to work properly. I know that several other printer drivers do not
work.
* [tools/build.c]
Make .stabs not used for svr4 since it doesn't use GNU assembler.
* [misc/fontengine.c]
Make sure a printf doesn't crash the system.
Sat Jan 25 15:53:35 1997 Huw D M Davies <h.davies1@physics.oxford.ac.uk>
* [objects/metafile.c]
Fixed some problems with PlayMetaFileRecord().
* [objects/dc.c]
hClipRgn gets initialized in GetDCState().
Fri Jan 24 21:22:26 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
* [debugger/stabs.c]
Handle file names beginning with '/'.
Fri Jan 24 18:33:04 1997 Robert Pouliot <krynos@clic.net>
* [*/*]
Some more patches for OS/2 support.
Fri Jan 24 11:30:41 1997 Bang Jun-Young <bangjy@nownuri.nowcom.co.kr>
* [resources/sysres_Ko.rc]
Updated support for Korean (Ko) language.
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index 7c7e6af..08655d0 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -8,8 +8,7 @@
* 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!
+ * Copyright 1997 Marcus Meissner
*/
#include <sys/types.h>
@@ -18,22 +17,28 @@
#include "pe_image.h"
#include "module.h"
#include "heap.h"
-#include "handle32.h"
#include "libres.h"
#include "stackframe.h"
#include "neexe.h"
-#include "accel.h"
-#include "xmalloc.h"
#include "stddebug.h"
#include "debug.h"
-#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)
+/**********************************************************************
+ * HMODULE32toPE_MODULE
+ *
+ * small helper function to get a PE_MODULE from a passed HMODULE32
+ */
+static PE_MODULE*
+HMODULE32toPE_MODULE(HMODULE32 hmod) {
+ NE_MODULE *pModule;
+
+ if (!hmod) hmod = GetTaskDS(); /* FIXME: correct? */
+ hmod = GetExePtr( hmod ); /* In case we were passed an hInstance */
+
+ if (!(pModule = MODULE_GetPtr( hmod ))) return 0;
+ if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
+ return pModule->pe_module;
+}
/**********************************************************************
* GetResDirEntryW
@@ -87,50 +92,18 @@
}
/**********************************************************************
- * GetResDirEntryA
- *
- * Helper function - goes down one level of PE resource tree
- *
- */
-LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(LPIMAGE_RESOURCE_DIRECTORY resdirptr,
- LPCSTR name,
- DWORD root)
-{
- LPWSTR xname;
- LPIMAGE_RESOURCE_DIRECTORY ret;
-
- if (HIWORD((DWORD)name))
- xname = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
- else
- xname = (LPWSTR)name;
-
- ret=GetResDirEntryW(resdirptr,xname,root);
- if (HIWORD((DWORD)name))
- HeapFree( GetProcessHeap(), 0, xname );
- return ret;
-}
-
-/**********************************************************************
* PE_FindResourceEx32W
*/
HANDLE32 PE_FindResourceEx32W(
HINSTANCE32 hModule,LPCWSTR name,LPCWSTR type,WORD lang
) {
- PE_MODULE *pe;
- NE_MODULE *pModule;
LPIMAGE_RESOURCE_DIRECTORY resdirptr;
DWORD root;
HANDLE32 result;
+ PE_MODULE *pe = HMODULE32toPE_MODULE(hModule);
- 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;
+ if (!pe || !pe->pe_resource)
+ return 0;
resdirptr = pe->pe_resource;
root = (DWORD) resdirptr;
@@ -151,18 +124,287 @@
*/
HANDLE32 PE_LoadResource32( HINSTANCE32 hModule, HANDLE32 hRsrc )
{
- NE_MODULE *pModule;
- PE_MODULE *pe;
+ PE_MODULE *pe = HMODULE32toPE_MODULE(hModule);
- 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 (!pe || !pe->pe_resource)
+ return 0;
+ if (!hRsrc)
+ return 0;
+ return (HANDLE32) (pe->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
+}
+
+
+/**********************************************************************
+ * PE_SizeofResource32
+ */
+void
+_check_ptr(DWORD x,DWORD start,LPDWORD lastmax) {
+ if ((x>start) && (x<*lastmax))
+ *lastmax=x;
+}
+
+static void
+walk_resdir(DWORD loadaddr,DWORD rootresdir,DWORD xres,DWORD data,DWORD lvl,LPDWORD max){
+ LPIMAGE_RESOURCE_DIRECTORY resdir;
+ LPIMAGE_RESOURCE_DATA_ENTRY dataent;
+ LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ int i;
+
+ if (lvl==3) {
+ dataent = (LPIMAGE_RESOURCE_DATA_ENTRY)(rootresdir+xres);
+ _check_ptr(loadaddr+dataent->OffsetToData,data,max);
+ return;
+ }
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)(rootresdir+xres);
+ et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++)
+ walk_resdir(loadaddr,rootresdir,(lvl==2)?et[i].u2.OffsetToData:et[i].u2.s.OffsetToDirectory,data,lvl+1,max);
+}
+
+DWORD PE_SizeofResource32( HINSTANCE32 hModule, HANDLE32 hRsrc )
+{
+ PE_MODULE *pe = HMODULE32toPE_MODULE(hModule);
+ DWORD max,data;
+ IMAGE_DATA_DIRECTORY dir;
+
+ if (!pe || !pe->pe_resource)
+ return 0;
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+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
+ max=(DWORD)-1;
+ dir=pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
+ if(dir.Size)
+ max=(DWORD)pe->pe_resource+dir.Size;
+
+ data=((DWORD)pe->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
+ walk_resdir(pe->load_addr,(DWORD)pe->pe_resource,0,data,0,&max);
+ return max-data;
+}
+
+/**********************************************************************
+ * PE_EnumResourceTypes32A
+ */
+BOOL32
+PE_EnumResourceTypes32A(HMODULE32 hmod,ENUMRESTYPEPROC32A lpfun,LONG lparam) {
+ PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ int i;
+ LPIMAGE_RESOURCE_DIRECTORY resdir;
+ LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ BOOL32 ret;
+ HANDLE32 heap = GetProcessHeap();
+
+ if (!pe || !pe->pe_resource)
+ return FALSE;
+
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ LPSTR name;
+
+ if (HIWORD(et[i].u1.Name))
+ name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name));
+ else
+ name = (LPSTR)et[i].u1.Name;
+ ret = lpfun(hmod,name,lparam);
+ if (HIWORD(name))
+ HeapFree(heap,0,name);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceTypes32W
+ */
+BOOL32
+PE_EnumResourceTypes32W(HMODULE32 hmod,ENUMRESTYPEPROC32W lpfun,LONG lparam) {
+ PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ int i;
+ LPIMAGE_RESOURCE_DIRECTORY resdir;
+ LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ BOOL32 ret;
+
+ if (!pe || !pe->pe_resource)
+ return FALSE;
+
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ LPWSTR type;
+ if (HIWORD(et[i].u1.Name))
+ type = (LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name);
+ else
+ type = (LPWSTR)et[i].u1.Name;
+
+ ret = lpfun(hmod,type,lparam);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceNames32A
+ */
+BOOL32
+PE_EnumResourceNames32A(
+ HMODULE32 hmod,LPCSTR type,ENUMRESNAMEPROC32A lpfun,LONG lparam
+) {
+ PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ int i;
+ LPIMAGE_RESOURCE_DIRECTORY resdir;
+ LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ BOOL32 ret;
+ HANDLE32 heap = GetProcessHeap();
+ LPWSTR typeW;
+
+ if (!pe || !pe->pe_resource)
+ return FALSE;
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ if (HIWORD(type))
+ typeW = HEAP_strdupAtoW(heap,0,type);
+ else
+ typeW = (LPWSTR)type;
+ resdir = GetResDirEntryW(resdir,typeW,(DWORD)pe->pe_resource);
+ if (HIWORD(typeW))
+ HeapFree(heap,0,typeW);
+ if (!resdir)
+ return FALSE;
+ et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ LPSTR name;
+
+ if (HIWORD(et[i].u1.Name))
+ name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name));
+ else
+ name = (LPSTR)et[i].u1.Name;
+ ret = lpfun(hmod,type,name,lparam);
+ if (HIWORD(name)) HeapFree(heap,0,name);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceNames32W
+ */
+BOOL32
+PE_EnumResourceNames32W(
+ HMODULE32 hmod,LPCWSTR type,ENUMRESNAMEPROC32W lpfun,LONG lparam
+) {
+ PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ int i;
+ LPIMAGE_RESOURCE_DIRECTORY resdir;
+ LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ BOOL32 ret;
+
+ if (!pe || !pe->pe_resource)
+ return FALSE;
+
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ resdir = GetResDirEntryW(resdir,type,(DWORD)pe->pe_resource);
+ if (!resdir)
+ return FALSE;
+ et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ LPWSTR name;
+ if (HIWORD(et[i].u1.Name))
+ name = (LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name);
+ else
+ name = (LPWSTR)et[i].u1.Name;
+ ret = lpfun(hmod,type,name,lparam);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceNames32A
+ */
+BOOL32
+PE_EnumResourceLanguages32A(
+ HMODULE32 hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROC32A lpfun,
+ LONG lparam
+) {
+ PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ int i;
+ LPIMAGE_RESOURCE_DIRECTORY resdir;
+ LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ BOOL32 ret;
+ HANDLE32 heap = GetProcessHeap();
+ LPWSTR nameW,typeW;
+
+ if (!pe || !pe->pe_resource)
+ return FALSE;
+
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ if (HIWORD(name))
+ nameW = HEAP_strdupAtoW(heap,0,name);
+ else
+ nameW = (LPWSTR)name;
+ resdir = GetResDirEntryW(resdir,nameW,(DWORD)pe->pe_resource);
+ if (HIWORD(nameW))
+ HeapFree(heap,0,nameW);
+ if (!resdir)
+ return FALSE;
+ if (HIWORD(type))
+ typeW = HEAP_strdupAtoW(heap,0,type);
+ else
+ typeW = (LPWSTR)type;
+ resdir = GetResDirEntryW(resdir,typeW,(DWORD)pe->pe_resource);
+ if (HIWORD(typeW))
+ HeapFree(heap,0,typeW);
+ if (!resdir)
+ return FALSE;
+ et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ /* languages are just ids... I hope */
+ ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceLanguages32W
+ */
+BOOL32
+PE_EnumResourceLanguages32W(
+ HMODULE32 hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROC32W lpfun,
+ LONG lparam
+) {
+ PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ int i;
+ LPIMAGE_RESOURCE_DIRECTORY resdir;
+ LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ BOOL32 ret;
+
+ if (!pe || !pe->pe_resource)
+ return FALSE;
+
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ resdir = GetResDirEntryW(resdir,name,(DWORD)pe->pe_resource);
+ if (!resdir)
+ return FALSE;
+ resdir = GetResDirEntryW(resdir,type,(DWORD)pe->pe_resource);
+ if (!resdir)
+ return FALSE;
+ et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
+ if (!ret)
+ break;
+ }
+ return ret;
}
#endif