1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/loader/resource.c
Alexandre Julliard 641ee76ace Release 970804
Sun Aug  3 14:03:43 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [documentation/Makefile.in]
	Create links for files included from wine.texinfo.

	* [wine.man]
	Moved to documentation dir.

	* [if1632/builtin.c]
	Made SYSTEM.DLL always loaded by default.

	* [loader/signal.c] [if1632/signal.c]
	Split signal.c in generic/emulator-specific parts.

	* [misc/system.c] [if1632/thunk.c]
	Implemented system timer functions.
	Fixed InquireSystem parameters.

	* [msdos/ioports.c]
	Defined inb/outb functions to avoid including asm/io.h.
	Use the right instruction for word and dword direct access.

	* [multimedia/mmsystem.c]
	Fixed CallTo16 usage.

Sat Aug 2 13:05:23 1997  Andreas Mohr <100.30936@germany.net>

	* [controls/edit.c]
	When text is inserted into a newly created editline, the caret
	is placed after the text. Should be placed before the text. Fixed.

	* [files/file.c]
	Removed O_TRUNC flag from OF_WRITE mode in _lopen32().
	According to doc _lopen() never truncates files.

	* [if1632/user.spec] [misc/comm.c]
	Added stub for EnableCommNotification().

	* [misc/ver.c]
	Fixed problem with VerQueryValue*() running over end of name table
	in rare cases.

	* [msdos/int21.c]
	Enhanced ioctlGetDeviceInfo() to correctly return the current drive.

	* [multimedia/joystick.c] [windows/message.c]
	Added joystick support !!!
	Needs Linux >= 2.1.45 or joystick-0.8.0.tar.gz.

Fri Aug  1 18:02:09 1997  Morten Welinder  <terra@diku.dk>

	* [if1632/user32.spec]
	Define DrawAnimatedRects32.

	* [graphics/painting.c]
	(DrawAnimatedRects32): Create stub.

	* [misc/registry.c]
	Cope with NULL class in RegQueryInfoKey32A.

	* [if1632/user32.spec]
	Add GetMenuItemInfo32[AW].

	* [controls/menu.c]
	(InsertMenu32A): Upgrade flags to 8 hex-digits.
	(MENUEX_ParseResource): First shot at implementation.
	(LoadMenuIndirect32A): Handle extended menus.
	(GetMenuItemInfo32[AW]): First shot at implementation.

	* [include/windows.h]
	Define MFT_*, MFS_*, MIIM_* macros.  Define MENUITEMINFO[AW]
 	structures and pointers.

	* [Makefile.in]
	(etags): Add TAGS as target.

	* [if1632/comctl32.spec]
	Use Windows 95's ordinals.  Add a few missing stubs.

Thu Jul 31 14:01:13 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [objects/color.c]
	Fix for 16 color mode of XFree.

	* [if1632/kernel32.spec][win32/ordinals.c]
	Moved/added some ordinal only exported functions from kernel32.dll
	(mostly thunking preparation stuff).

Wed Jul 30 09:16:38 1997  John Harvey <john@division.co.uk>

	* [graphics/win16drv/init.c] [include/win16drv.h]
        Escape(SETABORTPROC) returns success to keep pbrush.exe happy.
        Escape(NEXTBAND) implemented to make HP PCL printer driver work in
 	word.  Stub for PATBLT added to start work on printing more than
 	text.

Mon Jul 28 13:14:28 1997  Victor Schneider <vischne@ibm.net>

	* [libtest/expand.c]
	New Winelib test program.

Wed Jul 23 09:37:13 1997  Adrian Harvey <adrian@select.com.au>

	* [tools/build.c] [tools/build-spec.txt] [if1632/kernel.spec]
	  [if1632/user.spec]
	Added ability to set filename wine considers the built-in DLLs 
	to be in  to something other than name.DLL with new "file" key
	in .spec files.
	Made kernel filename KRNL386.EXE (some programs use this name 
	explicitly - ChemOffice install now starts up).
	Made user filename USER.EXE (just to be tidy).

Sun Jul 20 23:51:02 1997  David A. Cuthbert <dacut@henry.ece.cmu.edu>

	* [controls/menu.c] [misc/tweak.c] [include/tweak.h]
	Fixed MENU_KeyLeft and MENU_KeyRight to handle multiple-column
	menus.  Misc menu drawing issues for Win95 tweaks fixed.  Misc
	warnings fixed.

	* [loader/module.c]
	Spaces are now permitted in file/path names on the command line.
	If multiple matches can be made, the preferred match is the
	path/file with fewer spaces.

Tue Jul 29 02:21:15 1997  Bruce Milner <Bruce.Milner@genetics.utah.edu>

	* [misc/compobj.c]
	Added CLSIDFromString and StringFromCLSID.
1997-08-04 16:34:36 +00:00

808 lines
23 KiB
C

/*
* Resources
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "arch.h"
#include "windows.h"
#include "gdi.h"
#include "global.h"
#include "heap.h"
#include "neexe.h"
#include "accel.h"
#include "module.h"
#include "resource.h"
#include "stddebug.h"
#include "debug.h"
#include "libres.h"
#define PrintId(name) \
if (HIWORD((DWORD)name)) \
dprintf_resource( stddeb, "'%s'", (char *)PTR_SEG_TO_LIN(name)); \
else \
dprintf_resource( stddeb, "#%04x", LOWORD(name));
extern WORD WINE_LanguageId;
/**********************************************************************
* FindResource16 (KERNEL.60)
*/
HRSRC16 FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type )
{
NE_MODULE *pModule;
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
dprintf_resource(stddeb, "FindResource16: module=%04x type=", hModule );
PrintId( type );
if (HIWORD(name)) /* Check for '#xxx' name */
{
char *ptr = PTR_SEG_TO_LIN( name );
if (ptr[0] == '#') {
if (!(name = (SEGPTR)atoi( ptr + 1 ))) return 0;
}
}
dprintf_resource( stddeb, " name=" );
PrintId( name );
dprintf_resource( stddeb, "\n" );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
#ifndef WINELIB
if (pModule->flags & NE_FFLAGS_WIN32)
{
fprintf(stderr,"Don't know how to FindResource16() for Win32 module\n");
return 0;
}
return NE_FindResource( hModule, type, name );
#else
return LIBRES_FindResource16( hModule, name, type );
#endif
}
/**********************************************************************
* FindResource32A (KERNEL32.128)
*/
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;
if (HIWORD((DWORD)name))
xname = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
else
xname = (LPWSTR)name;
if (HIWORD((DWORD)type))
xtype = HEAP_strdupAtoW( GetProcessHeap(), 0, type);
else
xtype = (LPWSTR)type;
ret = FindResourceEx32W( hModule, xname, xtype, lang );
if (HIWORD((DWORD)name)) HeapFree( GetProcessHeap(), 0, xname );
if (HIWORD((DWORD)type)) HeapFree( GetProcessHeap(), 0, xtype );
return ret;
}
/**********************************************************************
* FindResourceEx32W (KERNEL32.130)
*/
HRSRC32 FindResourceEx32W(
HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type, WORD lang
) {
#ifndef WINELIB
NE_MODULE *pModule;
if (!hModule) hModule = GetTaskDS();
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
dprintf_resource(stddeb, "FindResource32W: module=%08x type=", hModule );
if (HIWORD(type))
dprintf_resource(stddeb,"%p",type);
else
dprintf_resource(stddeb,"#%p",type);
dprintf_resource( stddeb, " name=" );
if (HIWORD(name))
dprintf_resource(stddeb,"%p",name);
else
dprintf_resource(stddeb,"#%p",name);
dprintf_resource( stddeb, "\n" );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
return PE_FindResourceEx32W(hModule,name,type,lang);
#else
return LIBRES_FindResource32( 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)
*/
HGLOBAL16 LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc )
{
NE_MODULE *pModule;
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
dprintf_resource(stddeb, "LoadResource16: module=%04x res=%04x\n",
hModule, hRsrc );
if (!hRsrc) return 0;
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
#ifndef WINELIB
if (pModule->flags & NE_FFLAGS_WIN32)
{
fprintf(stderr,"Don't know how to LoadResource16() for Win32 module\n");
return 0;
}
return NE_LoadResource( hModule, hRsrc );
#else
return LIBRES_LoadResource( hModule, hRsrc );
#endif
}
/**********************************************************************
* LoadResource32 (KERNEL32.370)
*/
HGLOBAL32 LoadResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
{
#ifndef WINELIB
NE_MODULE *pModule;
if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
dprintf_resource(stddeb, "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))
{
fprintf(stderr,"LoadResource32: tried to load a non win32 resource.\n");
return 0; /* FIXME? */
}
return PE_LoadResource32(hModule,hRsrc);
#else
return LIBRES_LoadResource( hModule, hRsrc );
#endif
}
/**********************************************************************
* LockResource (KERNEL.62)
*/
/* 16-bit version */
SEGPTR WIN16_LockResource16(HGLOBAL16 handle)
{
#ifndef WINELIB
HMODULE16 hModule;
NE_MODULE *pModule;
dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
if (!handle) return (SEGPTR)0;
hModule = GetExePtr( handle );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
if (pModule->flags & NE_FFLAGS_WIN32)
{
fprintf(stderr,"Don't know how to LockResource() for Win32 module\n");
return 0;
}
return NE_LockResource( hModule, handle );
#else
return LIBRES_LockResource( handle );
#endif
}
/* WINELIB 16-bit version */
LPVOID LockResource16( HGLOBAL16 handle )
{
#ifndef WINELIB
HMODULE16 hModule;
NE_MODULE *pModule;
dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
if (!handle) return NULL;
hModule = GetExePtr( handle );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
if (pModule->flags & NE_FFLAGS_WIN32)
{
fprintf(stderr,"Don't know how to LockResource16() for Win32 module\n");
return 0;
}
return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) );
#else
return LIBRES_LockResource( handle );
#endif
}
/**********************************************************************
* LockResource32 (KERNEL32.384)
*/
LPVOID LockResource32( HGLOBAL32 handle )
{
return (LPVOID)handle;
}
/**********************************************************************
* FreeResource16 (KERNEL.63)
*/
BOOL16 FreeResource16( HGLOBAL16 handle )
{
#ifndef WINELIB
HMODULE16 hModule;
NE_MODULE *pModule;
dprintf_resource(stddeb, "FreeResource16: handle=%04x\n", handle );
if (!handle) return FALSE;
hModule = GetExePtr( handle );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
if (pModule->flags & NE_FFLAGS_WIN32)
{
fprintf(stderr,"Don't know how to FreeResource16() for Win32 module\n");
return 0;
}
return NE_FreeResource( hModule, handle );
#else
return LIBRES_FreeResource( handle );
#endif
}
/**********************************************************************
* FreeResource32 (KERNEL32.145)
*/
BOOL32 FreeResource32( HGLOBAL32 handle )
{
/* no longer used in Win32 */
return TRUE;
}
/**********************************************************************
* AccessResource16 (KERNEL.64)
*/
INT16 AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc )
{
NE_MODULE *pModule;
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
dprintf_resource(stddeb, "AccessResource16: module=%04x res=%04x\n",
hModule, hRsrc );
if (!hRsrc) return 0;
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
#ifndef WINELIB
if (pModule->flags & NE_FFLAGS_WIN32)
{
fprintf(stderr,"Don't know how to AccessResource16() for Win32 module\n");
return 0;
}
return NE_AccessResource( hModule, hRsrc );
#else
return LIBRES_AccessResource( hModule, hRsrc );
#endif
}
/**********************************************************************
* AccessResource32 (KERNEL32.64)
*/
INT32 AccessResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
{
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n",
hModule, hRsrc );
if (!hRsrc) return 0;
fprintf(stderr,"AccessResource32: not implemented\n");
return 0;
}
/**********************************************************************
* SizeofResource16 (KERNEL.65)
*/
DWORD SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc )
{
NE_MODULE *pModule;
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
dprintf_resource(stddeb, "SizeofResource16: module=%04x res=%04x\n",
hModule, hRsrc );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
#ifndef WINELIB
if (pModule->flags & NE_FFLAGS_WIN32)
{
fprintf(stderr,"Don't know how to SizeOfResource16() for Win32 module\n");
return 0;
}
return NE_SizeofResource( hModule, hRsrc );
#else
return LIBRES_SizeofResource( hModule, hRsrc );
#endif
}
/**********************************************************************
* SizeofResource32 (KERNEL32.522)
*/
DWORD SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
{
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
dprintf_resource(stddeb, "SizeofResource32: module=%04x res=%04x\n",
hModule, hRsrc );
#ifndef WINELIB
return PE_SizeofResource32(hModule,hRsrc);
#else
fprintf(stderr,"SizeofResource32: not implemented\n");
return 0;
#endif
}
/**********************************************************************
* AllocResource16 (KERNEL.66)
*/
HGLOBAL16 AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size )
{
NE_MODULE *pModule;
hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
dprintf_resource(stddeb, "AllocResource: module=%04x res=%04x size=%ld\n",
hModule, hRsrc, size );
if (!hRsrc) return 0;
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
#ifndef WINELIB
if (pModule->flags & NE_FFLAGS_WIN32)
{
fprintf(stderr,"Don't know how to AllocResource() for Win32 module\n");
return 0;
}
return NE_AllocResource( hModule, hRsrc, size );
#else
return LIBRES_AllocResource( hModule, hRsrc, size );
#endif
}
/**********************************************************************
* DirectResAlloc (KERNEL.168)
*
* Check Schulman, p. 232 for details
*/
HGLOBAL16 DirectResAlloc( HINSTANCE16 hInstance, WORD wType, UINT16 wSize )
{
dprintf_resource(stddeb,"DirectResAlloc(%04x,%04x,%04x)\n",
hInstance, wType, wSize );
hInstance = GetExePtr(hInstance);
if(!hInstance)return 0;
if(wType != 0x10) /* 0x10 is the only observed value, passed from
CreateCursorIndirect. */
fprintf(stderr, "DirectResAlloc: wType = %x\n", wType);
return GLOBAL_Alloc(GMEM_MOVEABLE, wSize, hInstance, FALSE, FALSE, FALSE);
}
/**********************************************************************
* LoadAccelerators16 [USER.177]
*/
HACCEL16 LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
{
HACCEL16 hAccel;
HGLOBAL16 rsc_mem;
HRSRC16 hRsrc;
BYTE *lp;
ACCELHEADER *lpAccelTbl;
int i, n;
if (HIWORD(lpTableName))
dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
else
dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
instance, LOWORD(lpTableName) );
if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR )))
return 0;
if (!(rsc_mem = LoadResource16( instance, hRsrc ))) return 0;
lp = (BYTE *)LockResource16(rsc_mem);
n = SizeofResource16(instance,hRsrc)/sizeof(ACCELENTRY);
hAccel = GlobalAlloc16(GMEM_MOVEABLE,
sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
lpAccelTbl->wCount = 0;
for (i = 0; i < n; i++) {
lpAccelTbl->tbl[i].type = *(lp++);
lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
lp += 2;
lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
lp += 2;
if (lpAccelTbl->tbl[i].wEvent == 0) break;
dprintf_accel(stddeb,
"Accelerator #%u / event=%04X id=%04X type=%02X \n",
i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
lpAccelTbl->tbl[i].type);
lpAccelTbl->wCount++;
}
GlobalUnlock16(hAccel);
FreeResource16( rsc_mem );
return hAccel;
}
/**********************************************************************
* LoadAccelerators32W [USER.177]
* The image layout seems to look like this (not 100% sure):
* 00: BYTE type type of accelerator
* 01: BYTE pad (to WORD boundary)
* 02: WORD event
* 04: WORD IDval
* 06: WORD pad (to DWORD boundary)
*/
HACCEL32 LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
{
HACCEL32 hAccel;
HGLOBAL32 rsc_mem;
HRSRC32 hRsrc;
BYTE *lp;
ACCELHEADER *lpAccelTbl;
int i, n;
if (HIWORD(lpTableName))
dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
instance, (char *)( lpTableName ) );
else
dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
instance, LOWORD(lpTableName) );
if (!(hRsrc = FindResource32W( instance, lpTableName,
(LPCWSTR)RT_ACCELERATOR )))
return 0;
if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0;
lp = (BYTE *)LockResource32(rsc_mem);
n = SizeofResource32(instance,hRsrc)/sizeof(ACCELENTRY);
hAccel = GlobalAlloc16(GMEM_MOVEABLE,
sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
lpAccelTbl->wCount = 0;
for (i = 0; i < n; i++) {
lpAccelTbl->tbl[i].type = *lp;
lp += 2;
lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
lp += 2;
lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
lp += 4;
if (lpAccelTbl->tbl[i].wEvent == 0) break;
dprintf_accel(stddeb,
"Accelerator #%u / event=%04X id=%04X type=%02X \n",
i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
lpAccelTbl->tbl[i].type);
lpAccelTbl->wCount++;
}
GlobalUnlock16(hAccel);
FreeResource32(rsc_mem);
return hAccel;
}
HACCEL32 LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
{
LPWSTR uni;
HACCEL32 result;
if (HIWORD(lpTableName))
uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
else
uni = (LPWSTR)lpTableName;
result = LoadAccelerators32W(instance,uni);
if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
return result;
}
/**********************************************************************
* LoadString16
*/
INT16
LoadString16(HINSTANCE16 instance,UINT16 resource_id,LPSTR buffer,INT16 buflen)
{
HGLOBAL16 hmem;
HRSRC16 hrsrc;
unsigned char *p;
int string_num;
int i;
dprintf_resource(stddeb,"LoadString: inst=%04x id=%04x buff=%08x len=%d\n",
instance, resource_id, (int) buffer, buflen);
hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING );
if (!hrsrc) return 0;
hmem = LoadResource16( instance, hrsrc );
if (!hmem) return 0;
p = LockResource16(hmem);
string_num = resource_id & 0x000f;
for (i = 0; i < string_num; i++)
p += *p + 1;
dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
i = MIN(buflen - 1, *p);
if (buffer == NULL)
return i;
if (i > 0) {
memcpy(buffer, p + 1, i);
buffer[i] = '\0';
} else {
if (buflen > 1) {
buffer[0] = '\0';
return 0;
}
fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
}
FreeResource16( hmem );
dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
return i;
}
/**********************************************************************
* LoadString32W (USER32.375)
*/
INT32
LoadString32W(HINSTANCE32 instance,UINT32 resource_id,LPWSTR buffer,int buflen)
{
HGLOBAL32 hmem;
HRSRC32 hrsrc;
WCHAR *p;
int string_num;
int i;
dprintf_resource(stddeb, "LoadString: instance = %04x, id = %04x, buffer = %08x, "
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
(LPCWSTR)RT_STRING );
if (!hrsrc) return 0;
hmem = LoadResource32( instance, hrsrc );
if (!hmem) return 0;
p = LockResource32(hmem);
string_num = resource_id & 0x000f;
for (i = 0; i < string_num; i++)
p += *p + 1;
dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
i = MIN(buflen - 1, *p);
if (buffer == NULL)
return i;
if (i > 0) {
memcpy(buffer, p + 1, i * sizeof (WCHAR));
buffer[i] = (WCHAR) 0;
} else {
if (buflen > 1) {
buffer[0] = (WCHAR) 0;
return 0;
}
#if 0
fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
#endif
}
#if 0
dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
#endif
return i;
}
/**********************************************************************
* LoadString32A (USER32.374)
*/
INT32
LoadString32A(HINSTANCE32 instance,UINT32 resource_id,LPSTR buffer,int buflen)
{
INT32 retval;
LPWSTR buffer2 = NULL;
if (buffer) buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
retval = LoadString32W(instance,resource_id,buffer2,buflen);
if (buffer2)
{
lstrcpynWtoA( buffer, buffer2, buflen );
HeapFree( GetProcessHeap(), 0, 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 )
{
INT32 retval;
LPSTR buffer2 = NULL;
if (buffer) buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen );
retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
if (buffer)
{
lstrcpynAtoW( buffer, buffer2, buflen );
HeapFree( GetProcessHeap(), 0, buffer2 );
}
return retval;
}
/**********************************************************************
* SetResourceHandler (KERNEL.43)
*/
FARPROC16
SetResourceHandler(HINSTANCE16 instance,SEGPTR s,FARPROC16 farproc)
{
if (HIWORD(s))
fprintf(stderr,"SetResourceHandler(%04x,%s,%p), empty STUB!\n",
instance,(char*)PTR_SEG_TO_LIN(s),farproc);
else
fprintf(stderr,"SetResourceHandler(%04x,0x%04x,%p), empty STUB!\n",
instance,LOWORD(s),farproc);
return NULL;
}
#ifndef WINELIB
/**********************************************************************
* EnumResourceTypesA (KERNEL32.90)
*/
BOOL32
EnumResourceTypes32A(HMODULE32 hmodule,ENUMRESTYPEPROC32A lpfun,LONG lParam) {
return PE_EnumResourceTypes32A(hmodule,lpfun,lParam);
}
/**********************************************************************
* EnumResourceTypesW (KERNEL32.91)
*/
BOOL32
EnumResourceTypes32W(HMODULE32 hmodule,ENUMRESTYPEPROC32W lpfun,LONG lParam) {
return PE_EnumResourceTypes32W(hmodule,lpfun,lParam);
}
/**********************************************************************
* EnumResourceNamesA (KERNEL32.88)
*/
BOOL32
EnumResourceNames32A(HMODULE32 hmodule,LPCSTR type,ENUMRESNAMEPROC32A lpfun,LONG lParam) {
return PE_EnumResourceNames32A(hmodule,type,lpfun,lParam);
}
/**********************************************************************
* EnumResourceNamesW (KERNEL32.89)
*/
BOOL32
EnumResourceNames32W(HMODULE32 hmodule,LPCWSTR type,ENUMRESNAMEPROC32W lpfun,LONG lParam) {
return PE_EnumResourceNames32W(hmodule,type,lpfun,lParam);
}
/**********************************************************************
* EnumResourceLanguagesA (KERNEL32.86)
*/
BOOL32
EnumResourceLanguages32A(HMODULE32 hmodule,LPCSTR type,LPCSTR name,ENUMRESLANGPROC32A lpfun,LONG lParam) {
return PE_EnumResourceLanguages32A(hmodule,type,name,lpfun,lParam);
}
/**********************************************************************
* EnumResourceLanguagesW (KERNEL32.87)
*/
BOOL32
EnumResourceLanguages32W(HMODULE32 hmodule,LPCWSTR type,LPCWSTR name,ENUMRESLANGPROC32W lpfun,LONG lParam) {
return PE_EnumResourceLanguages32W(hmodule,type,name,lpfun,lParam);
}
#endif /* WINELIB */