cfad47cfa3/tads3/resldexe.cpp

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