Release 941030
[wine/hacks.git] / loader / pe_resource.c
blob41fa92d1c1b166c5a925e556cbd45b5c3a6b910f
1 /*
2 * (c) 1994 Erik Bos <erik@hacktic.nl>
4 * based on Eric Youndale's pe-test and:
6 * ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
7 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include "windows.h"
17 #include "neexe.h"
18 #include "peexe.h"
19 #include "dlls.h"
20 #include "resource.h"
21 #include "stddebug.h"
22 /* #define DEBUG_RESOURCE */
23 /* #undef DEBUG_RESOURCE */
24 #include "debug.h"
27 static int
28 find_lang(char *root, struct PE_Resource_Directory *resource, RESOURCE *r)
30 struct PE_Directory_Entry *type_dir;
31 struct PE_Resource_Leaf_Entry *leaf;
33 type_dir = (struct PE_Directory_Entry *)(resource + 1);
34 type_dir += resource->NumberOfNamedEntries;
36 /* grab the 1st resource available */
37 leaf = (struct PE_Resource_Leaf_Entry *) (root + type_dir->OffsetToData);
38 dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n", (int) type_dir->Name);
39 dprintf_resource(stddeb, "\t\taddress %ld, size %ld, language id %ld\n", leaf->OffsetToData, leaf->Size, leaf->CodePage);
40 r->offset = leaf->OffsetToData - r->wpnt->pe->resource_offset;
41 r->size = leaf->Size;
42 printf("\t\toffset %d, size %d\n", r->offset, r->size);
43 return 1;
45 /* for(i=0; i< resource->NumberOfIdEntries; i++) {
46 leaf = (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY));
47 dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n",
48 (int) type_dir->Name);
49 dprintf_resource(stddeb, "\t\t%x %x %x\n", leaf->OffsetToData,
50 leaf->Size, leaf->CodePage);
51 type_dir++;
52 } */
55 static int
56 find_resource(char *root, struct PE_Resource_Directory *resource,
57 LPSTR resource_name, RESOURCE *r)
59 int i;
60 char res_name[256];
61 struct PE_Directory_Entry *type_dir;
62 struct PE_Directory_Name_String_U *name;
64 type_dir = (struct PE_Directory_Entry *)(resource + 1);
66 if (HIWORD((DWORD)resource_name)) {
67 for(i=0; i< resource->NumberOfNamedEntries; i++) {
68 name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING));
69 memset(res_name, 0, sizeof(res_name));
70 my_wcstombs(res_name, name->NameString, name->Length);
71 dprintf_resource(stddeb, "\tPE_findresource: name %s\n", res_name);
72 if (strcasecmp(res_name, resource_name) == 0)
73 return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r);
74 type_dir++;
76 } else {
77 type_dir += resource->NumberOfNamedEntries;
78 for(i=0; i< resource->NumberOfIdEntries; i++) {
79 dprintf_resource(stddeb, "\tPE_findresource: name %8x\n", (int) type_dir->Name);
80 if (type_dir->Name == ((int) resource_name & 0xff))
81 return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r);
82 type_dir++;
85 return 0;
88 static int
89 find_type(struct PE_Resource_Directory *resource, LPSTR resource_name,
90 LPSTR type_name, RESOURCE *r)
92 int i;
93 char *root, res_name[256];
94 struct PE_Directory_Entry *type_dir;
95 struct PE_Directory_Name_String_U *name;
97 root = (char *) resource;
98 type_dir = (struct PE_Directory_Entry *)(resource + 1);
100 if (HIWORD((DWORD)type_name)) {
101 for(i=0; i< resource->NumberOfNamedEntries; i++) {
102 name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING));
103 memset(res_name, 0, sizeof(res_name));
104 my_wcstombs(res_name, name->NameString, name->Length);
105 dprintf_resource(stddeb, "PE_findtype: type %s\n",
106 res_name);
107 if (strcasecmp(res_name, type_name) == 0)
108 return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r);
109 type_dir++;
111 } else {
112 type_dir += resource->NumberOfNamedEntries;
113 for(i=0; i< resource->NumberOfIdEntries; i++) {
114 dprintf_resource(stddeb, "PE_findtype: type %8x\n", (int) type_dir->Name);
115 if (type_dir->Name == ((int) type_name & 0xff))
116 return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r);
117 type_dir++;
120 return 0;
123 /**********************************************************************
124 * PE_FindResource [KERNEL.60]
127 PE_FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name,
128 RESOURCE *r)
130 dprintf_resource(stddeb, "PE_FindResource hInst=%04X typename=%08X resname=%08X\n",
131 instance, (int) type_name, (int) resource_name);
132 if (HIWORD((DWORD)resource_name))
133 if (resource_name[0] == '#')
134 resource_name = (LPSTR) atoi(resource_name + 1);
136 if (HIWORD((DWORD)type_name))
137 if (type_name[0] == '#')
138 type_name = (LPSTR) atoi(type_name + 1);
140 return find_type(r->wpnt->pe->pe_resource, resource_name, type_name,r);