Release 951003
[wine] / loader / pe_resource.c
1 /*
2  *      (c) 1994        Erik Bos        <erik@xs4all.nl>
3  *
4  *      based on Eric Youndale's pe-test and:
5  *
6  *      ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
7  */
8
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 "ldt.h"
18 #include "neexe.h"
19 #include "peexe.h"
20 #include "dlls.h"
21 #include "pe_image.h"
22 #include "resource.h"
23 #include "stddebug.h"
24 /* #define DEBUG_RESOURCE */
25 #include "debug.h"
26
27 #if 0
28
29 static int
30 find_lang(char *root, struct PE_Resource_Directory *resource, RESOURCE *r)
31 {
32         struct PE_Directory_Entry *type_dir;
33         struct PE_Resource_Leaf_Entry *leaf;
34
35         type_dir = (struct PE_Directory_Entry *)(resource + 1);
36         type_dir += resource->NumberOfNamedEntries;
37
38         /* grab the 1st resource available */
39         leaf = (struct PE_Resource_Leaf_Entry *) (root + type_dir->OffsetToData);
40                 dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n", (int) type_dir->Name);
41                 dprintf_resource(stddeb, "\t\taddress %ld, size %ld, language id %ld\n", leaf->OffsetToData, leaf->Size, leaf->CodePage);
42         r->offset = leaf->OffsetToData - r->wpnt->pe->resource_offset;
43         r->size = leaf->Size;
44         printf("\t\toffset %d, size %d\n", r->offset, r->size);
45         return 1;
46
47 /*      for(i=0; i< resource->NumberOfIdEntries; i++) {
48                 leaf = (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY));
49                 dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n", 
50                         (int) type_dir->Name);
51                 dprintf_resource(stddeb, "\t\t%x %x %x\n", leaf->OffsetToData, 
52                         leaf->Size, leaf->CodePage);
53                 type_dir++;
54         } */
55 }
56
57 static int 
58 find_resource(char *root, struct PE_Resource_Directory *resource, 
59                 LPSTR resource_name, RESOURCE *r)
60 {
61         int i;
62         char res_name[256];
63         struct PE_Directory_Entry *type_dir;
64         struct PE_Directory_Name_String_U *name;
65         
66         type_dir = (struct PE_Directory_Entry *)(resource + 1);
67
68         if (HIWORD((DWORD)resource_name)) {
69                 for(i=0; i< resource->NumberOfNamedEntries; i++) {
70                         name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING));
71                         memset(res_name, 0, sizeof(res_name));
72                         my_wcstombs(res_name, name->NameString, name->Length);
73                         dprintf_resource(stddeb, "\tPE_findresource: name %s\n", res_name);
74                         if (strcasecmp(res_name, resource_name) == 0) 
75                                 return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r);
76                         type_dir++;
77                 }
78         } else {
79                 type_dir += resource->NumberOfNamedEntries;
80                 for(i=0; i< resource->NumberOfIdEntries; i++) {
81                         dprintf_resource(stddeb, "\tPE_findresource: name %8x\n", (int) type_dir->Name);
82                         if (type_dir->Name == ((int) resource_name & 0xff))
83                                 return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r);
84                         type_dir++;
85                 }
86         }
87         return 0;
88 }
89
90 static int 
91 find_type(struct PE_Resource_Directory *resource, LPSTR resource_name,
92                 LPSTR type_name)
93 {
94         int i;
95         char *root, res_name[256];
96         struct PE_Directory_Entry *type_dir;
97         struct PE_Directory_Name_String_U *name;
98         
99         root = (char *) resource;
100         type_dir = (struct PE_Directory_Entry *)(resource + 1);
101
102         if (HIWORD((DWORD)type_name)) {
103                 for(i=0; i< resource->NumberOfNamedEntries; i++) {
104                         name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING));
105                         memset(res_name, 0, sizeof(res_name));
106                         my_wcstombs(res_name, name->NameString, name->Length);
107                         dprintf_resource(stddeb, "PE_findtype: type %s\n", 
108                                 res_name);
109                         if (strcasecmp(res_name, type_name) == 0) 
110                                 return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r);
111                         type_dir++;
112                 }
113         } else {
114                 type_dir += resource->NumberOfNamedEntries;
115                 for(i=0; i< resource->NumberOfIdEntries; i++) {
116                         dprintf_resource(stddeb, "PE_findtype: type %8x\n", (int) type_dir->Name);
117                         if (type_dir->Name == ((int) type_name & 0xff))
118                                 return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r);
119                         type_dir++;
120                 }
121         }
122         return 0;
123 }
124
125 /**********************************************************************
126  *                      PE_FindResource [KERNEL.60]
127  */
128 int
129 PE_FindResource(HANDLE instance, SEGPTR resource_name, SEGPTR type_name,
130                 RESOURCE *r)
131 {
132         dprintf_resource(stddeb, "PE_FindResource hInst=%04X typename=%08X resname=%08X\n", 
133                 instance, (int) type_name, (int) resource_name);
134         if (HIWORD(resource_name))
135         {
136                 char *resource_name_ptr = PTR_SEG_TO_LIN( resource_name );
137                 if (resource_name_ptr[0] == '#')
138                         resource_name = (SEGPTR) atoi(resource_name_ptr + 1);
139                 else
140                     resource_name = (SEGPTR)resource_name_ptr;
141         }
142         if (HIWORD(type_name)) 
143         {
144                 char *type_name_ptr = PTR_SEG_TO_LIN( type_name );
145                 if (type_name_ptr[0] == '#')
146                         type_name = (SEGPTR) atoi(type_name_ptr + 1);
147                 else
148                         type_name = (SEGPTR) type_name_ptr;
149         }
150         return find_type(r->wpnt->pe->pe_resource, resource_name, type_name);
151 }
152 #endif