mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 13:16:12 +00:00
234bc24db1
Wed Dec 7 14:52:25 1994 Alexandre Julliard (julliard@lamisun.epfl.ch) * [controls/listbox.c] Fixed problems due to new scroll-bar code. * [loader/signal.c] [miscemu/ioports.c] Handle I/O opcodes that use an absolute address. * [objects/text.c] Implemented TabbedTextOut(). Sat Dec 3 18:53:08 1994 Kenneth MacDonald <K.MacDonald@ed.ac.uk> * [objects/metafile.c] Implemented GetMetafile(). Fixed bug in PlayMetaFile() when reading disc based metafile records. Added META_POLYPOLYGON, META_DELETEOBJECT and META_EOF to PlayMetaFileRecord(). Wed Nov 30 06:32:25 1994 Martin von Loewis (martin@cs.csufresno.edu) * [Imakefile] wine.sym: Remove gcc2_compiled and friends * [controls/listbox.c][if1632/relay.c][if1632/relay.c] [loader/resource.c][memory/heap.c][objects/dib.c][windows/dialog.c] Replace #ifdef DEBUG_XXX with if(debugging_xxx){ * [if1632/call.S] CallToLibMain: New function * [if1632/relay.c][include/options.h][misc/main.c] [miscemu/int1a.c][miscemu/int21.c][miscemu/kernel.c] removed Options.relay_debug * [include/heap.h] HEAP_OWNER: Use ds instead of cs:ip * [loader/ne_image.c] LoadNEImage: Remember current exe, handle nodata dlls InitNEDLL: handle nodata dlls, call CallToLibMain * [loader/selector.c] CreateSelectors: Initialize auto_data_sel with 0 * [memory/heap.c] HEAP_CheckHeap: Check prev HEAP_CheckLocalHeaps: new function * [misc/profile] Remember and dump only changed profiles * [tools/makedebug] Introduce debugging_xxx flags Sun Nov 27 23:13:22 MET 1994 <erik@xs4all.nl> * [clipboard.h color.h dc.h dos_fs.h event.h font.h graphics.h if1632.h kernel.h library.h miscemu.h ne_image.h nonclient.h pe_image.h selectors.h wintypes.h] Added. * [*/*] - Commented all 'static char copyright statements', see misc/main.c - moved prototypes to headers files, fixed wrong prototypes. - *please* add a header file for each .c if you need to export things. * [misc/main.c] Added one static string which list the names of the contributors. Fri Nov 25 16:24:27 MET 1994 Dag Asheim (dash@ifi.uio.no) * [Configure] Made the support for multiple languages more automatic. Added a [fonts] section to the wine.conf file. Made the defaults better. Generally cleaned it up. * [rc/sysres_No.rc] [rc/sysres_De.rc] [rc/sysres.c] Norwegian resources and small fixes to the german resources. Wed Nov 23 20:28:59 1994 Martin von Loewis (martin@cs.csufresno.edu) * [debugger/break.c] bark(), toggle_next(), should_continue(): New functions insert_break(): Fixed, adds write access to page before writing wine_bp.next_addr: new structure field * [debugger/dbg.y] Changed symbol's value to be it's value instead of the value pointed to by the symbol. Changed SIGTRAP handling to allow continuation after break point * [misc/shell.c] ShellAbout(): Load resource from memory
381 lines
11 KiB
C
381 lines
11 KiB
C
/*
|
||
static char RCSId[] = "$Id: ne_resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $";
|
||
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
|
||
*/
|
||
#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 "neexe.h"
|
||
#include "peexe.h"
|
||
#include "arch.h"
|
||
#include "dlls.h"
|
||
#include "library.h"
|
||
#include "heap.h"
|
||
#include "resource.h"
|
||
#include "stddebug.h"
|
||
#include "debug.h"
|
||
|
||
/**********************************************************************
|
||
* NE_LoadNameTable
|
||
*/
|
||
static void NE_LoadNameTable(struct w_files *wpnt)
|
||
{
|
||
struct resource_typeinfo_s typeinfo;
|
||
struct resource_nameinfo_s nameinfo;
|
||
unsigned short size_shift;
|
||
RESNAMTAB *top, *new;
|
||
char read_buf[1024];
|
||
char *p;
|
||
int i;
|
||
unsigned short len;
|
||
off_t saved_pos;
|
||
|
||
top = NULL;
|
||
/*
|
||
* Move to beginning of resource table.
|
||
*/
|
||
lseek(wpnt->fd, wpnt->mz_header->ne_offset +
|
||
wpnt->ne->ne_header->resource_tab_offset, SEEK_SET);
|
||
|
||
/*
|
||
* Read block size.
|
||
*/
|
||
if (read(wpnt->fd, &size_shift, sizeof(size_shift)) != sizeof(size_shift))
|
||
return;
|
||
|
||
size_shift = CONV_SHORT(size_shift);
|
||
|
||
/*
|
||
* Find resource.
|
||
*/
|
||
typeinfo.type_id = 0xffff;
|
||
while (typeinfo.type_id != 0)
|
||
{
|
||
if (read(wpnt->fd, &typeinfo, sizeof(typeinfo)) != sizeof(typeinfo))
|
||
break;
|
||
|
||
if (typeinfo.type_id == 0)
|
||
break;
|
||
|
||
if (typeinfo.type_id == 0x800f)
|
||
{
|
||
for (i = 0; i < typeinfo.count; i++)
|
||
{
|
||
if (read(wpnt->fd, &nameinfo, sizeof(nameinfo)) != sizeof(nameinfo))
|
||
break;
|
||
|
||
saved_pos = lseek(wpnt->fd, 0, SEEK_CUR);
|
||
lseek(wpnt->fd, (long) nameinfo.offset << size_shift,
|
||
SEEK_SET);
|
||
read(wpnt->fd, &len, sizeof(len));
|
||
while (len)
|
||
{
|
||
new = (RESNAMTAB *) GlobalQuickAlloc(sizeof(*new));
|
||
new->next = top;
|
||
top = new;
|
||
|
||
read(wpnt->fd, &new->type_ord, 2);
|
||
read(wpnt->fd, &new->id_ord, 2);
|
||
read(wpnt->fd, read_buf, len - 6);
|
||
|
||
p = read_buf + strlen(read_buf) + 1;
|
||
strncpy(new->id, p, MAX_NAME_LENGTH);
|
||
new->id[MAX_NAME_LENGTH - 1] = '\0';
|
||
|
||
read(wpnt->fd, &len, sizeof(len));
|
||
}
|
||
lseek(wpnt->fd, saved_pos, SEEK_SET);
|
||
}
|
||
} else
|
||
lseek(wpnt->fd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
|
||
}
|
||
wpnt->ne->resnamtab = top;
|
||
}
|
||
|
||
static int type_match(int type_id1, int type_id2, int fd, off_t off)
|
||
{
|
||
off_t old_pos;
|
||
unsigned char c;
|
||
size_t nbytes;
|
||
char name[256];
|
||
|
||
if (type_id1 == -1)
|
||
return 1;
|
||
if ((type_id1 & 0xffff0000) == 0) {
|
||
if ((type_id2 & 0x8000) == 0)
|
||
return 0;
|
||
return (type_id1 & 0x000f) == (type_id2 & 0x000f);
|
||
}
|
||
if ((type_id2 & 0x8000) != 0)
|
||
return 0;
|
||
dprintf_resource(stddeb, "type_compare: type_id2=%04X !\n", type_id2);
|
||
|
||
old_pos = lseek(fd, 0, SEEK_CUR);
|
||
lseek(fd, off + type_id2, SEEK_SET);
|
||
read(fd, &c, 1);
|
||
nbytes = CONV_CHAR_TO_LONG(c);
|
||
|
||
dprintf_resource(stddeb, "type_compare: namesize=%d\n", nbytes);
|
||
read(fd, name, nbytes);
|
||
lseek(fd, old_pos, SEEK_SET);
|
||
name[nbytes] = '\0';
|
||
dprintf_resource(stddeb, "type_compare: name=`%s'\n", name);
|
||
return strcasecmp((char *) type_id1, name) == 0;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* FindResourceByNumber
|
||
*/
|
||
static int FindResourceByNumber(RESOURCE *r, int type_id, int resource_id)
|
||
{
|
||
struct resource_typeinfo_s typeinfo;
|
||
struct resource_nameinfo_s nameinfo;
|
||
unsigned short size_shift;
|
||
int i;
|
||
off_t rtoff;
|
||
|
||
dprintf_resource(stddeb, "FindResourceByNumber: type_id =%x,m res_id = %x\n",
|
||
type_id, resource_id);
|
||
|
||
/* Move to beginning of resource table */
|
||
rtoff = (r->wpnt->mz_header->ne_offset +
|
||
r->wpnt->ne->ne_header->resource_tab_offset);
|
||
lseek(r->wpnt->fd, rtoff, SEEK_SET);
|
||
|
||
/* Read block size */
|
||
if (read(r->wpnt->fd, &size_shift, sizeof(size_shift)) != sizeof(size_shift)) {
|
||
printf("FindResourceByNumber (%d) bad block size !\n",(int) resource_id);
|
||
return -1;
|
||
}
|
||
size_shift = CONV_SHORT(size_shift);
|
||
|
||
/* Find resource */
|
||
for (;;) {
|
||
if (read(r->wpnt->fd, &typeinfo, sizeof(typeinfo)) != sizeof(typeinfo)) {
|
||
printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id);
|
||
return -1;
|
||
}
|
||
dprintf_resource(stddeb, "FindResourceByNumber type=%X count=%d ?=%ld searched=%08X\n",
|
||
typeinfo.type_id, typeinfo.count, typeinfo.reserved, type_id);
|
||
if (typeinfo.type_id == 0)
|
||
break;
|
||
if (type_match(type_id, typeinfo.type_id, r->wpnt->fd, rtoff)) {
|
||
|
||
for (i = 0; i < typeinfo.count; i++) {
|
||
#ifndef WINELIB
|
||
if (read(r->wpnt->fd, &nameinfo, sizeof(nameinfo)) != sizeof(nameinfo))
|
||
#else
|
||
if (!load_nameinfo(r->wpnt->fd, &nameinfo))
|
||
#endif
|
||
{
|
||
printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id);
|
||
return -1;
|
||
}
|
||
dprintf_resource(stddeb, "FindResource: search type=%X id=%X // type=%X id=%X\n",
|
||
type_id, resource_id, typeinfo.type_id, nameinfo.id);
|
||
if (nameinfo.id == resource_id) {
|
||
r->size = nameinfo.length << size_shift;
|
||
r->offset = nameinfo.offset << size_shift;
|
||
return size_shift;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
lseek(r->wpnt->fd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* FindResourceByName
|
||
*/
|
||
static int FindResourceByName(RESOURCE *r, int type_id, char *resource_name)
|
||
{
|
||
struct resource_typeinfo_s typeinfo;
|
||
struct resource_nameinfo_s nameinfo;
|
||
unsigned short size_shift;
|
||
off_t old_pos, new_pos;
|
||
unsigned char nbytes;
|
||
char name[256];
|
||
int i;
|
||
off_t rtoff;
|
||
|
||
/* Check for loaded name table */
|
||
if (r->wpnt->ne->resnamtab != NULL) {
|
||
RESNAMTAB *e;
|
||
|
||
for (e = r->wpnt->ne->resnamtab; e != NULL; e = e->next)
|
||
if (e->type_ord == (type_id & 0x000f) &&
|
||
strcasecmp(e->id, resource_name) == 0)
|
||
{
|
||
return FindResourceByNumber(r, type_id, e->id_ord);
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/* Move to beginning of resource table */
|
||
rtoff = (r->wpnt->mz_header->ne_offset +
|
||
r->wpnt->ne->ne_header->resource_tab_offset);
|
||
lseek(r->wpnt->fd, rtoff, SEEK_SET);
|
||
|
||
/* Read block size */
|
||
if (read(r->wpnt->fd, &size_shift, sizeof(size_shift)) != sizeof(size_shift))
|
||
{
|
||
printf("FindResourceByName (%s) bad block size !\n", resource_name);
|
||
return -1;
|
||
}
|
||
size_shift = CONV_SHORT (size_shift);
|
||
|
||
/* Find resource */
|
||
for (;;)
|
||
{
|
||
if (read(r->wpnt->fd, &typeinfo, sizeof(typeinfo)) != sizeof(typeinfo)) {
|
||
printf("FindResourceByName (%s) bad typeinfo size !\n", resource_name);
|
||
return -1;
|
||
}
|
||
dprintf_resource(stddeb, "FindResourceByName typeinfo.type_id=%X count=%d type_id=%X\n",
|
||
typeinfo.type_id, typeinfo.count, type_id);
|
||
if (typeinfo.type_id == 0)
|
||
break;
|
||
if (type_match(type_id, typeinfo.type_id, r->wpnt->fd, rtoff))
|
||
{
|
||
for (i = 0; i < typeinfo.count; i++)
|
||
{
|
||
#ifndef WINELIB
|
||
if (read(r->wpnt->fd, &nameinfo, sizeof(nameinfo)) != sizeof(nameinfo))
|
||
#else
|
||
if (!load_nameinfo (r->wpnt->fd, &nameinfo))
|
||
#endif
|
||
{
|
||
printf("FindResourceByName (%s) bad nameinfo size !\n", resource_name);
|
||
return -1;
|
||
}
|
||
/*
|
||
if ((nameinfo.id & 0x8000) != 0) continue;
|
||
*/
|
||
dprintf_resource(stddeb, "FindResourceByName // nameinfo.id=%04X !\n", nameinfo.id);
|
||
old_pos = lseek(r->wpnt->fd, 0, SEEK_CUR);
|
||
new_pos = rtoff + nameinfo.id;
|
||
lseek(r->wpnt->fd, new_pos, SEEK_SET);
|
||
read(r->wpnt->fd, &nbytes, 1);
|
||
dprintf_resource(stddeb, "FindResourceByName // namesize=%d !\n", nbytes);
|
||
nbytes = CONV_CHAR_TO_LONG (nbytes);
|
||
read(r->wpnt->fd, name, nbytes);
|
||
lseek(r->wpnt->fd, old_pos, SEEK_SET);
|
||
name[nbytes] = '\0';
|
||
dprintf_resource(stddeb, "FindResourceByName type_id=%X (%d of %d) name='%s' resource_name='%s'\n",
|
||
typeinfo.type_id, i + 1, typeinfo.count,
|
||
name, resource_name);
|
||
if (strcasecmp(name, resource_name) == 0) {
|
||
r->size = nameinfo.length << size_shift;
|
||
r->offset = nameinfo.offset << size_shift;
|
||
return size_shift;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
lseek(r->wpnt->fd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* GetRsrcCount [internal]
|
||
*/
|
||
int GetRsrcCount(HINSTANCE hInst, int type_id)
|
||
{
|
||
struct w_files *wpnt;
|
||
struct resource_typeinfo_s typeinfo;
|
||
struct resource_nameinfo_s nameinfo;
|
||
unsigned short size_shift;
|
||
off_t rtoff;
|
||
|
||
if (hInst == 0)
|
||
return 0;
|
||
dprintf_resource(stddeb, "GetRsrcCount hInst=%04X typename=%08X\n",
|
||
hInst, type_id);
|
||
|
||
if ((wpnt = GetFileInfo(hInst)) == NULL)
|
||
return 0;
|
||
/*
|
||
* Move to beginning of resource table.
|
||
*/
|
||
rtoff = (wpnt->mz_header->ne_offset +
|
||
wpnt->ne->ne_header->resource_tab_offset);
|
||
lseek(wpnt->fd, rtoff, SEEK_SET);
|
||
/*
|
||
* Read block size.
|
||
*/
|
||
if (read(wpnt->fd, &size_shift, sizeof(size_shift)) != sizeof(size_shift)) {
|
||
printf("GetRsrcCount // bad block size !\n");
|
||
return -1;
|
||
}
|
||
size_shift = CONV_SHORT (size_shift);
|
||
for (;;) {
|
||
if (read(wpnt->fd, &typeinfo, sizeof(typeinfo)) != sizeof(typeinfo)) {
|
||
printf("GetRsrcCount // bad typeinfo size !\n");
|
||
return 0;
|
||
}
|
||
dprintf_resource(stddeb, "GetRsrcCount // typeinfo.type_id=%X count=%d type_id=%X\n",
|
||
typeinfo.type_id, typeinfo.count, type_id);
|
||
if (typeinfo.type_id == 0)
|
||
break;
|
||
if (type_match(type_id, typeinfo.type_id, wpnt->fd, rtoff))
|
||
return typeinfo.count;
|
||
else
|
||
lseek(wpnt->fd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* NE_FindResource [KERNEL.60]
|
||
*/
|
||
int NE_FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name,
|
||
RESOURCE *r)
|
||
{
|
||
int type, x;
|
||
|
||
dprintf_resource(stddeb, "NE_FindResource hInst=%04X typename=%p resname=%p\n",
|
||
instance, type_name, resource_name);
|
||
|
||
r->size = r->offset = 0;
|
||
|
||
/* nametable loaded ? */
|
||
if (r->wpnt->ne->resnamtab == NULL)
|
||
NE_LoadNameTable(r->wpnt);
|
||
|
||
if (((int) type_name & 0xffff0000) == 0)
|
||
type = (int) type_name;
|
||
else {
|
||
if (type_name[0] == '\0')
|
||
type = -1;
|
||
if (type_name[0] == '#')
|
||
type = atoi(type_name + 1);
|
||
else
|
||
type = (int) type_name;
|
||
}
|
||
|
||
if (((int) resource_name & 0xffff0000) == 0)
|
||
x = FindResourceByNumber(r, type, (int) resource_name | 0x8000);
|
||
else {
|
||
if (resource_name[0] == '\0')
|
||
x = FindResourceByNumber(r, type, -1);
|
||
if (resource_name[0] == '#')
|
||
x = FindResourceByNumber(r, type, atoi(resource_name + 1));
|
||
else
|
||
x = FindResourceByName(r, type, resource_name);
|
||
}
|
||
if (x == -1) {
|
||
printf("NE_FindResource hInst=%04X typename=%08X resname=%08X not found!\n",
|
||
instance, (int) type_name, (int) resource_name);
|
||
return 0;
|
||
}
|
||
return 1;
|
||
}
|