1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/loader/ne_resource.c
Alexandre Julliard ade697e88a Release 951124
Tue Nov 21 18:49:10 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>

	* [configure.in] [Makefile] [misc/dos_fs.c]
	Got rid of autoconf.h file.

	* [debugger/dbg.y]
	More logical behavior upon syntax errors.

	* [include/hook.h] [windows/hook.c]
	Changed hook structure and rewrote most of the hook functions for
	better compatibility, based on investigations by Alex Korobka.

	* [include/message.h] [windows/message.c]
	Added hooks to message queue structure and made the structure
	layout Windows-compatible.
	Added support for WH_MOUSE, WH_KEYBOARD, WH_HARDWARE and
	WH_JOURNALRECORD hooks.

	* [misc/main.c]
	Added command-line option for changing the language at run-time
 	(not implemented yet), based on a suggestion from Michael Patra.

	* [objects/cursoricon.c]
	Fixed silly SEGPTR bug in DumpIcon().

Mon Nov 20 22:22:22 1995  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [controls/listbox.c] [controls/combo.c] [include/listbox.h]
	Partial implementaion of LBS_EXTENDEDSEL style,
	yet more updates for drag & drop support. Now works.

	* [windows/defwnd.c]
	More message handlers.

	* [windows/win.c]
	DragObject, DragDetect, AnyPopup functions. 

	* [controls/listbox.c]
	More kludgy fixes (WM_...TOITEM, etc.).

	* [objects/cursoricon.c] [objects/oembitmap.c]
	IconToCursor skeleton, patch for OBM_LoadCursorIcon to handle new
	cursor.

	* [include/bitmaps/ocr*]
	New OEM cursors.

Mon Nov 20 11:05:20 EST 1995  Jim Peterson <jspeter@birch.ee.vt.edu>

	* [toolkit/heap.c]
	Swapped flags and size arguments to LocalRealloc as per changes in
	memory/local.c by William Magro in previous release.

	* [include/wintypes.h]
	Reinstated the #define's for 'min' and 'max', since they're part of
	the Windows API.  I really don't think it's a wise idea, so I put
	a '#ifndef DONT_DEFINE_min_AND_max' around them.  I think the actual
	WINE code should never use these (it should use 'MIN' and 'MAX'
	instead).

	* [loader/*]
	Put '#ifndef WINELIB' around many things that WINElib should not need.

	* [controls/edit.c]
	Took out many '#if defined(WINELIB)' sections with the associated
	comment 'temporary fix, until Local memory is correctly implemented in
	WINELIB', since the effective translations are now in 
	toolkit/miscstubs.c.
	Took out the #ifndef's I put in EDIT_ClearText.  Whoever modified this
	file fixed (or at least postponed) the bug I had encountered.

	* [loader/task.c]
	Put an #ifdef in TASK_CreateTask() that hardwires the current drive to
	C:  This will probably cause a lot of trouble if this change is
	forgotten in the future, but it will let things like the OpenFileName
	dialog work for now.

	* [toolkit/libres.c] [toolkit/Makefile.in] [toolkit/Makefile]
	  [include/libres.h]
	Made new libres.c file, which will contain functions for supporting
	accessing resources by name in WINElib.  'winerc' will need to be
	changed.

	* [toolkit/heap.c]
	Refined memory routines to allow for differences between LocalAlloc
	and GlobalAlloc and between LocalSize and GlobalSize.

	* [windows/message.c] [include/windows.h]
	Defined the GetCurrentTime routine in windows/message.c, and removed
	the #define in windows.h.

Mon Nov 20 00:36:42 MET 1995 Sven Verdoolaege <skimo@dns.ufsia.ac.be>

	* [*/*]
	Added new debugging type DEBUG_WIN32 and DEBUG_ENV.

	* [loader/module.c]
	Added undocumented GetExpWinVer.

	* [tools/build.c]
	Previous code didn't pop possibly changed %esi, %edi and %edx
	from the stack.
	
	* [win32/advapi.c]
	Added GetUserNameA.

	* [win32/code_page.c]
	Added stub for MultiByteToWideChar.

	* [win32/console.c]
	Added SetConsoleCtrlHandler stub.

	* [win32/file.c]
	Added ReadFile CreateFileA GetFileInformationByHandle stubs.
	Added CloseHandle.

	* [win32/memory.c]
	Changed VirtualAlloc and VirtualFree.

	* [win32/process.c]
	Added ExitProcess.

Sun Nov 19 17:54:42 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

	* [include/windows.h]
	Fixed a few broken structure definitions.

	* [loader/resource.c]
	FindResource(): Need to check for '#xxx' strings here.

	* [miscemu/int21.c]
	FindNext(): Return MS-DOS filenames uppercase.

	* [objects/cursoricon.c]
	CreateIcon(), CreateCursor(): Added missing element to CURSORICONINFO
	initializers.
	
	* [misc/file.c]
	_lopen(): Files opened in OF_WRITE mode are truncated.
	OpenFile(): Ignore OF_READ/OF_WRITE/OF_READWRITE when files are
	created; use read/write mode.
	
	* [misc/profile.c]
	load(): Rewritten.
	
	* [misc/commdlg.c]
	Fixed bad call to strncpy() that smashed the stack.

	* [controls/combo.c] [windows/winpos.c] [memory/selector.c]
	Operator precedence fixes. People who use gcc 2.7.1 don't need a
	debugger :-)
	
	* [if1632/gdi.spec] [objects/palette.c]
	Add ResizePalette() and AnimatePalette() stubs. They don't do anything,
	but sometimes that's good enough.

Fri Nov 17 09:10:35 GMT 1995  John Harvey <john@division.co.uk>

	* [include/wine.h] [include/registers.h] [include/winsock.h]
        Added definitions for Unixware.

	* [loader/signal.c] [misc/comm.c] [misc/winsocket.c]
	Misc. fixes for Unixware.

	* [loader/task.c]
        Made assignemts to context in InitTask for registers use the macros
        from registers.h to make them more portable. (Needed for Unixware)

	* [tools/build.c]
	Fixed register acces routines to work on Unixware. Bit grubby but
 	it seems to work.

	* [controls/edit.c]
	EDIT_WM_NCCreate allocates local heap if hasn't been previously
	allocated.
	
	* [miscemu/int21.c]
	mkdir now creates directory with permission to access it.

	* [misc/dos_fs.c]
	mkdir now creates directory with permission to access it.
	DOS_opendir now uses linked list of dirents to avoid problems with 
	realloc changing address of malloced memory.

Thu Nov 16 12:47:13 1995  Michael Patra  <patra@itp1.Physik.TU-Berlin.DE>

	* [controls/menu.c]
	MENU_CalcItemSize(): Fixed handling of empty menu items.

Sat Nov 11 21:46:54 1995  Hans de Graaff  <graaff@twi72.twi.tudelft.nl>

	* [misc/file.c]
	In OpenFile, unlink should be done on the unix filename.

Sat Nov 11 16:43:29 1995  Cameron Heide  (heide@ee.ualberta.ca)

        * [include/handle32.h]
        New header file containing internal Win32 kernel handle
        information.

        * [win32/file.c]
        Added ReadFile, CreateFile, and CloseFileHandle, and did
        some reorganizing to match the new handle allocation scheme.

        * [win32/init.c]
        Added CloseHandle and the creation of standard I/O handles.

        * [win32/object_mgt.c]
        New module for allocating and freeing Win32 kernel handles.
1995-11-26 13:59:11 +00:00

362 lines
11 KiB
C

#ifndef WINELIB
/*
*
* 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 "windows.h"
#include "arch.h"
#include "dos_fs.h"
#include "global.h"
#include "ldt.h"
#include "module.h"
#include "neexe.h"
#include "resource.h"
#include "stddebug.h"
#include "debug.h"
typedef struct resource_typeinfo_s NE_TYPEINFO;
typedef struct resource_nameinfo_s NE_NAMEINFO;
/***********************************************************************
* NE_FindNameTableId
*
* Find the type and resource id from their names.
* Return value is MAKELONG( typeId, resId ), or 0 if not found.
*/
static DWORD NE_FindNameTableId( HMODULE hModule, SEGPTR typeId, SEGPTR resId )
{
NE_MODULE *pModule;
NE_TYPEINFO *pTypeInfo;
NE_NAMEINFO *pNameInfo;
HGLOBAL handle;
WORD *p;
DWORD ret = 0;
int count;
pModule = (NE_MODULE *)GlobalLock( hModule );
pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
for (; pTypeInfo->type_id != 0;
pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo+1) +
pTypeInfo->count * sizeof(NE_NAMEINFO)))
{
if (pTypeInfo->type_id != 0x800f) continue;
pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1);
for (count = pTypeInfo->count; count > 0; count--, pNameInfo++)
{
dprintf_resource( stddeb, "NameTable entry: type=%04x id=%04x\n",
pTypeInfo->type_id, pNameInfo->id );
handle = LoadResource( hModule,
(HANDLE)((int)pNameInfo - (int)pModule) );
for(p = (WORD*)LockResource(handle); *p; p = (WORD *)((char*)p+*p))
{
dprintf_resource( stddeb," type=%04x '%s' id=%04x '%s'\n",
p[1], (char *)(p+3), p[2],
(char *)(p+3)+strlen((char *)(p+3))+1 );
/* Check for correct type */
if (p[1] & 0x8000)
{
if (!HIWORD(typeId)) continue;
if (strcasecmp( (char *)PTR_SEG_TO_LIN(typeId),
(char *)(p + 3) )) continue;
}
else if (HIWORD(typeId) || ((typeId & ~0x8000)!= p[1]))
continue;
/* Now check for the id */
if (p[2] & 0x8000)
{
if (!HIWORD(resId)) continue;
if (strcasecmp( (char *)PTR_SEG_TO_LIN(resId),
(char*)(p+3)+strlen((char*)(p+3))+1 )) continue;
}
else if (HIWORD(resId) || ((resId & ~0x8000) != p[2]))
continue;
/* If we get here, we've found the entry */
dprintf_resource( stddeb, " Found!\n" );
ret = MAKELONG( p[1], p[2] );
break;
}
FreeResource( handle );
if (ret) return ret;
}
}
return 0;
}
/***********************************************************************
* NE_FindResourceFromType
*
* Find a resource once the type info structure has been found.
*/
static HRSRC NE_FindResourceFromType( NE_MODULE *pModule,
NE_TYPEINFO *pTypeInfo, SEGPTR resId )
{
BYTE *p;
int count;
NE_NAMEINFO *pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1);
if (HIWORD(resId) != 0) /* Named resource */
{
char *str = (char *)PTR_SEG_TO_LIN( resId );
BYTE len = strlen( str );
for (count = pTypeInfo->count; count > 0; count--, pNameInfo++)
{
if (pNameInfo->id & 0x8000) continue;
p = (BYTE *)pModule + pModule->res_table + pNameInfo->id;
if ((*p == len) && !strncasecmp( p+1, str, len ))
return (HRSRC)((int)pNameInfo - (int)pModule);
}
}
else /* Numeric resource id */
{
WORD id = LOWORD(resId) | 0x8000;
for (count = pTypeInfo->count; count > 0; count--, pNameInfo++)
if (pNameInfo->id == id)
return (HRSRC)((int)pNameInfo - (int)pModule);
}
return 0;
}
/***********************************************************************
* NE_FindResource
*/
HRSRC NE_FindResource( HMODULE hModule, SEGPTR typeId, SEGPTR resId )
{
NE_MODULE *pModule;
NE_TYPEINFO *pTypeInfo;
HRSRC hRsrc;
pModule = (NE_MODULE *)GlobalLock( hModule );
if (!pModule || !pModule->res_table) return 0;
pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
if (HIWORD(typeId) || HIWORD(resId))
{
/* Search the names in the nametable */
DWORD id = NE_FindNameTableId( hModule, typeId, resId );
if (id) /* found */
{
typeId = LOWORD(id);
resId = HIWORD(id);
}
}
if (HIWORD(typeId) != 0) /* Named type */
{
char *str = (char *)PTR_SEG_TO_LIN( typeId );
BYTE len = strlen( str );
while (pTypeInfo->type_id)
{
if (!(pTypeInfo->type_id & 0x8000))
{
BYTE *p = (BYTE*)pModule+pModule->res_table+pTypeInfo->type_id;
if ((*p == len) && !strncasecmp( p+1, str, len ))
{
dprintf_resource( stddeb, " Found type '%s'\n", str );
hRsrc = NE_FindResourceFromType(pModule, pTypeInfo, resId);
if (hRsrc)
{
dprintf_resource( stddeb, " Found id %08lx\n", resId );
return hRsrc;
}
dprintf_resource( stddeb, " Not found, going on\n" );
}
}
dprintf_resource( stddeb, " Skipping type %04x\n",
pTypeInfo->type_id );
pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo+1) +
pTypeInfo->count * sizeof(NE_NAMEINFO));
}
}
else /* Numeric type id */
{
WORD id = LOWORD(typeId) | 0x8000;
while (pTypeInfo->type_id)
{
if (pTypeInfo->type_id == id)
{
dprintf_resource( stddeb, " Found type %04x\n", id );
hRsrc = NE_FindResourceFromType( pModule, pTypeInfo, resId );
if (hRsrc)
{
dprintf_resource( stddeb, " Found id %08lx\n", resId );
return hRsrc;
}
dprintf_resource( stddeb, " Not found, going on\n" );
}
dprintf_resource( stddeb, " Skipping type %04x\n",
pTypeInfo->type_id );
pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo+1) +
pTypeInfo->count * sizeof(NE_NAMEINFO));
}
}
return 0;
}
/***********************************************************************
* NE_AllocResource
*/
HGLOBAL NE_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size )
{
NE_MODULE *pModule;
NE_NAMEINFO *pNameInfo=NULL;
WORD sizeShift;
pModule = (NE_MODULE *)GlobalLock( hModule );
if (!pModule || !pModule->res_table) return 0;
sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
#ifndef WINELIB
pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
#endif
if (size < (DWORD)pNameInfo->length << sizeShift)
size = (DWORD)pNameInfo->length << sizeShift;
return GLOBAL_Alloc( GMEM_FIXED, size, hModule, FALSE, FALSE, FALSE );
}
/***********************************************************************
* NE_AccessResource
*/
int NE_AccessResource( HMODULE hModule, HRSRC hRsrc )
{
NE_MODULE *pModule;
NE_NAMEINFO *pNameInfo=NULL;
WORD sizeShift;
char *name;
int fd;
pModule = (NE_MODULE *)GlobalLock( hModule );
if (!pModule || !pModule->res_table) return 0;
#ifndef WINELIB
pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
#endif
name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
fd = open( DOS_GetUnixFileName(name), O_RDONLY );
sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
lseek( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET );
return fd;
}
/***********************************************************************
* NE_SizeofResource
*/
DWORD NE_SizeofResource( HMODULE hModule, HRSRC hRsrc )
{
NE_MODULE *pModule;
NE_NAMEINFO *pNameInfo=NULL;
WORD sizeShift;
pModule = (NE_MODULE *)GlobalLock( hModule );
if (!pModule || !pModule->res_table) return 0;
sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
#ifndef WINELIB
pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
#endif
return (DWORD)pNameInfo->length << sizeShift;
}
/***********************************************************************
* NE_LoadResource
*/
HGLOBAL NE_LoadResource( HMODULE hModule, HRSRC hRsrc )
{
NE_MODULE *pModule;
NE_NAMEINFO *pNameInfo=NULL;
WORD sizeShift;
int fd;
pModule = (NE_MODULE *)GlobalLock( hModule );
if (!pModule || !pModule->res_table) return 0;
#ifndef WINELIB
pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
#endif
if (pNameInfo->handle)
{
pNameInfo->usage++;
dprintf_resource( stddeb, " Already loaded, new count=%d\n",
pNameInfo->usage );
return pNameInfo->handle;
}
sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
dprintf_resource( stddeb, " Loading, pos=%d, len=%d\n",
(int)pNameInfo->offset << sizeShift,
(int)pNameInfo->length << sizeShift );
if ((fd = MODULE_OpenFile( hModule )) == -1) return 0;
pNameInfo->handle = NE_AllocResource( hModule, hRsrc, 0 );
pNameInfo->usage = 1;
lseek( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET );
read( fd, GlobalLock( pNameInfo->handle ),
(int)pNameInfo->length << sizeShift );
return pNameInfo->handle;
}
/***********************************************************************
* NE_LockResource
*/
SEGPTR NE_LockResource( HMODULE hModule, HGLOBAL handle )
{
/* May need to reload the resource if discarded */
return (SEGPTR)WIN16_GlobalLock( handle );
}
/***********************************************************************
* NE_FreeResource
*/
BOOL NE_FreeResource( HMODULE hModule, HGLOBAL handle )
{
NE_MODULE *pModule;
NE_TYPEINFO *pTypeInfo;
NE_NAMEINFO *pNameInfo;
WORD count;
pModule = (NE_MODULE *)GlobalLock( hModule );
if (!pModule || !pModule->res_table) return FALSE;
pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
while (pTypeInfo->type_id)
{
pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1);
for (count = pTypeInfo->count; count > 0; count--)
{
if (pNameInfo->handle == handle)
{
if (pNameInfo->usage > 0) pNameInfo->usage--;
if (pNameInfo->usage == 0)
{
GlobalFree( pNameInfo->handle );
pNameInfo->handle = 0;
}
return TRUE;
}
pNameInfo++;
}
pTypeInfo = (NE_TYPEINFO *)pNameInfo;
}
fprintf( stderr, "FreeResource: "NPFMT" "NPFMT" not found!\n", hModule, handle );
return FALSE;
}
#endif /* WINELIB */