blob: 9efec3424882c5ad168240b7b84c02f656ff0861 [file] [log] [blame]
/*
* (c) 1994 Erik Bos <erik@xs4all.nl>
*
* based on Eric Youndale's pe-test and:
*
* ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
*/
#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 "dlls.h"
#include "pe_image.h"
#include "resource.h"
#include "stddebug.h"
/* #define DEBUG_RESOURCE */
#include "debug.h"
static int
find_lang(char *root, struct PE_Resource_Directory *resource, RESOURCE *r)
{
struct PE_Directory_Entry *type_dir;
struct PE_Resource_Leaf_Entry *leaf;
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 (strcasecmp(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++;
}
}
return 0;
}
static int
find_type(struct PE_Resource_Directory *resource, LPSTR resource_name,
LPSTR type_name, RESOURCE *r)
{
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 (strcasecmp(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;
}
/**********************************************************************
* PE_FindResource [KERNEL.60]
*/
int
PE_FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name,
RESOURCE *r)
{
dprintf_resource(stddeb, "PE_FindResource hInst=%04X typename=%08X resname=%08X\n",
instance, (int) type_name, (int) resource_name);
if (HIWORD((DWORD)resource_name))
if (resource_name[0] == '#')
resource_name = (LPSTR) atoi(resource_name + 1);
if (HIWORD((DWORD)type_name))
if (type_name[0] == '#')
type_name = (LPSTR) atoi(type_name + 1);
return find_type(r->wpnt->pe->pe_resource, resource_name, type_name,r);
}