-
Notifications
You must be signed in to change notification settings - Fork 17
/
resldexe.cpp
235 lines (202 loc) · 6.59 KB
/
resldexe.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
* Copyright (c) 2001, 2002 Michael J. Roberts. All Rights Reserved.
*
* Please see the accompanying license file, LICENSE.TXT, for information
* on using and copying this software.
*/
/*
Name
resldexe.cpp - resource loader - executable file loader
Function
Loads resources from the executable file, if possible.
Notes
This module is separated from the main resload.cpp module to allow
the executable resource loader to be omitted from the link. If the
program doesn't want to be able to load from the executable, the link
can substitute resnoexe.cpp for this module.
Modified
11/03/01 MJRoberts - Creation
*/
#include <stddef.h>
#include <string.h>
#include "t3std.h"
#include "resload.h"
#include "vmimage.h"
/* ------------------------------------------------------------------------ */
/*
* Resource loader interface implementation
*/
class CVmImageLoaderMres_resload: public CVmImageLoaderMres
{
public:
CVmImageLoaderMres_resload(const char *respath)
{
/* remember the path of the resource we're trying to find */
respath_ = respath;
respath_len_ = strlen(respath);
/* we haven't found it yet */
found_ = FALSE;
link_ = 0;
}
~CVmImageLoaderMres_resload()
{
lib_free_str(link_);
}
/* add a resource */
void add_resource(uint32_t seek_ofs, uint32_t siz,
const char *res_name, size_t res_name_len)
{
/*
* if we've already found a match, there's no need to consider
* anything else
*/
if (found_)
return;
/* check to see if this is the one we're looking for */
if (res_name_len == respath_len_
&& memicmp(respath_, res_name, res_name_len) == 0)
{
/* we found it */
found_ = TRUE;
/* remember the seek location */
res_seek_ = seek_ofs;
res_size_ = siz;
}
}
/* add a resource link */
void add_resource(const char *fname, size_t fnamelen,
const char *res_name, size_t res_name_len)
{
/*
* if we've already found a match, there's no need to consider
* anything else
*/
if (found_)
return;
/* check to see if this is the one we're looking for */
if (res_name_len == respath_len_
&& memicmp(respath_, res_name, res_name_len) == 0)
{
/* we found it */
found_ = TRUE;
/* remember the link */
link_ = lib_copy_str(fname, fnamelen);
}
}
/* did we find the resource? */
int found_resource() const { return found_; }
/* get the seek location and size of the resource we found */
uint32_t get_resource_seek() const { return res_seek_; }
uint32_t get_resource_size() const { return res_size_; }
/* get the local filename link, if it's given as a link */
const char *get_link_fname() const { return link_; }
private:
/* name of the resource we're looking for */
const char *respath_;
size_t respath_len_;
/* flag: we found the resource we're looking for */
int found_;
/* seek location and size of the resource we found */
uint32_t res_seek_;
uint32_t res_size_;
/* local filename link, if the resource is given as a link */
char *link_;
};
/* ------------------------------------------------------------------------ */
/*
* Try loading a resource from the executable file
*/
osfildef *CResLoader::open_exe_res(const char *respath,
const char *restype)
{
osfildef *exe_fp;
/*
* if we don't have an executable filename stored, or we don't have an
* executable resource type ID, we can't load the resource
*/
if (exe_filename_ == 0 || restype == 0)
return 0;
/* find the executable file's resources */
exe_fp = os_exeseek(exe_filename_, restype);
/* if we found something, try loading from that file */
if (exe_fp != 0)
{
CVmImageLoaderMres_resload res_ifc(respath);
/* try loading the resources */
CVmImageLoader::
load_resources_from_fp(exe_fp, exe_filename_, &res_ifc);
/* check to see if we found it */
if (res_ifc.found_resource())
{
/* check the type */
if (res_ifc.get_link_fname() != 0)
{
/*
* it's a linked local file - close the exe file and open
* the local file instead
*/
osfcls(exe_fp);
exe_fp = osfoprb(res_ifc.get_link_fname(), OSFOPRB);
}
else
{
/* we got an exe resource - seek to the starting byte */
osfseek(exe_fp, res_ifc.get_resource_seek(), OSFSK_SET);
}
}
else
{
/* didn't find it - close and forget the executable file */
osfcls(exe_fp);
exe_fp = 0;
}
}
/* return the executable file pointer, if we found the resource */
return exe_fp;
}
/* ------------------------------------------------------------------------ */
/*
* Try loading a resource from a resource library
*/
osfildef *CResLoader::open_lib_res(const char *libfile,
const char *respath)
{
osfildef *fp;
/* try opening the file */
fp = osfoprb(libfile, OSFTT3IMG);
/* if we couldn't open the file, we can't load the resource */
if (fp == 0)
return 0;
/* set up a resource finder for our resource */
CVmImageLoaderMres_resload res_ifc(respath);
/* load the file, so that we can try finding the resource */
CVmImageLoader::load_resources_from_fp(fp, libfile, &res_ifc);
/* check to see if we found it */
if (res_ifc.found_resource())
{
/* we got it - check the type */
if (res_ifc.get_link_fname() != 0)
{
/*
* linked local file - close the library file and open the
* local file instead
*/
osfcls(fp);
fp = osfoprb(res_ifc.get_link_fname(), OSFOPRB);
}
else
{
/* embedded resource - seek to the first byte */
osfseek(fp, res_ifc.get_resource_seek(), OSFSK_SET);
}
/* return the library file handle */
return fp;
}
else
{
/* didn't find the resource - close the library */
osfcls(fp);
/* tell the caller we didn't find the resource */
return 0;
}
}