1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "loaders/dir_load.hh"
|
---|
10 | #include "checksum/checksum.hh"
|
---|
11 | #include "memory/malloc.hh"
|
---|
12 | #include "file/buf_file.hh"
|
---|
13 | #include "file/sub_section.hh"
|
---|
14 | #include <stdlib.h>
|
---|
15 |
|
---|
16 | #include <string.h>
|
---|
17 |
|
---|
18 |
|
---|
19 | i4_bool i4_insert_sections(i4_file_class *in, i4_file_class *out,
|
---|
20 | int total_sections_to_insert,
|
---|
21 | i4_file_class **section_data,
|
---|
22 | char **section_names)
|
---|
23 | {
|
---|
24 | w32 sig=in->read_32();
|
---|
25 | if (sig!=i4_check_sum32("GOLG_SECTION_ID=32",17))
|
---|
26 | i4_error("doesn't work on this");
|
---|
27 |
|
---|
28 | w32 t_sections=in->read_32();
|
---|
29 | int copy_size=in->size()-8+t_sections*8;
|
---|
30 |
|
---|
31 | out->write_32(sig);
|
---|
32 | out->write_32(t_sections + total_sections_to_insert);
|
---|
33 |
|
---|
34 | int i;
|
---|
35 | for (i=0; i<t_sections; i++)
|
---|
36 | {
|
---|
37 | out->write_32(in->read_32()); // copy id unchanged
|
---|
38 | int offset=in->read_32();
|
---|
39 | out->write_32(offset + total_sections_to_insert * 8);
|
---|
40 | }
|
---|
41 |
|
---|
42 | int offset2 = copy_size + out->tell() + total_sections_to_insert*8;
|
---|
43 |
|
---|
44 | for (i=0; i<total_sections_to_insert; i++)
|
---|
45 | {
|
---|
46 | out->write_32(i4_check_sum32(section_names[i], strlen(section_names[i])));
|
---|
47 | out->write_32(offset2);
|
---|
48 | offset2+=section_data[i]->size();
|
---|
49 | }
|
---|
50 |
|
---|
51 | w8 buf[4096];
|
---|
52 | while (copy_size)
|
---|
53 | {
|
---|
54 | int rs=sizeof(buf) > copy_size ? copy_size : sizeof(buf);
|
---|
55 | in->read(buf, rs);
|
---|
56 | out->write(buf, rs);
|
---|
57 | copy_size-=rs;
|
---|
58 | }
|
---|
59 |
|
---|
60 |
|
---|
61 | for (i=0; i<total_sections_to_insert; i++)
|
---|
62 | {
|
---|
63 | int fsize=section_data[i]->size();
|
---|
64 | while (fsize)
|
---|
65 | {
|
---|
66 | int rs=sizeof(buf) > fsize ? fsize : sizeof(buf);
|
---|
67 | section_data[i]->read(buf, rs);
|
---|
68 | out->write(buf, rs);
|
---|
69 | fsize-=rs;
|
---|
70 | }
|
---|
71 | }
|
---|
72 |
|
---|
73 | return i4_T;
|
---|
74 | }
|
---|
75 |
|
---|
76 |
|
---|
77 | i4_loader_class *i4_open_save_file(i4_file_class *in, i4_bool close_on_delete_or_fail)
|
---|
78 | {
|
---|
79 | i4_loader_class *l=new i4_loader_class(in, close_on_delete_or_fail);
|
---|
80 |
|
---|
81 | if (l->error())
|
---|
82 | {
|
---|
83 | delete l;
|
---|
84 | return 0;
|
---|
85 | }
|
---|
86 |
|
---|
87 | return l;
|
---|
88 | }
|
---|
89 |
|
---|
90 |
|
---|
91 | int i4_loader_section_compare(const i4_loader_section_type *a, const i4_loader_section_type *b)
|
---|
92 | {
|
---|
93 | return a->section_id>b->section_id ? 1 : (a->section_id<b->section_id ? -1 : 0);
|
---|
94 | }
|
---|
95 |
|
---|
96 | i4_loader_class::i4_loader_class(i4_file_class *_in, i4_bool close_on_delete)
|
---|
97 | : close_on_delete(close_on_delete),
|
---|
98 | sections(512,512)
|
---|
99 | {
|
---|
100 | seek_to_before_using=-1;
|
---|
101 |
|
---|
102 |
|
---|
103 | in=new i4_buffered_file_class(_in, 0x1000, _in->tell());
|
---|
104 |
|
---|
105 | _error=0;
|
---|
106 |
|
---|
107 | w32 sig=in->read_32();
|
---|
108 | int use_16;
|
---|
109 |
|
---|
110 | if (sig==i4_check_sum32("GOLG",4))
|
---|
111 | use_16=1;
|
---|
112 | else if (sig==i4_check_sum32("GOLG_SECTION_ID=32",17))
|
---|
113 | use_16=0;
|
---|
114 | else // this is not a directoried file
|
---|
115 | {
|
---|
116 | _error=1;
|
---|
117 | return ;
|
---|
118 | }
|
---|
119 |
|
---|
120 | w32 t_sections=in->read_32(), i;
|
---|
121 |
|
---|
122 | last=0x7fffffff;
|
---|
123 |
|
---|
124 | for (i=0; i<t_sections; i++)
|
---|
125 | {
|
---|
126 | i4_loader_section_type *t=sections.add();
|
---|
127 | if (use_16)
|
---|
128 | t->section_id=in->read_16();
|
---|
129 | else
|
---|
130 | t->section_id=in->read_32();
|
---|
131 |
|
---|
132 | t->section_offset=in->read_32();
|
---|
133 | }
|
---|
134 |
|
---|
135 |
|
---|
136 | if (t_sections)
|
---|
137 | {
|
---|
138 | int offset=sections[0].section_offset;
|
---|
139 | for (i=0; i<t_sections-1; i++)
|
---|
140 | sections[i].section_size=sections[i+1].section_offset-sections[i].section_offset;
|
---|
141 |
|
---|
142 | sections[t_sections-1].section_size=in->size()-sections[t_sections-1].section_offset;
|
---|
143 | }
|
---|
144 |
|
---|
145 |
|
---|
146 | sections.sort(i4_loader_section_compare);
|
---|
147 | }
|
---|
148 |
|
---|
149 | int i4_loader_class::find_section(w32 section_id)
|
---|
150 | {
|
---|
151 | sw32 lo=0,hi=sections.size()-1,mid;
|
---|
152 |
|
---|
153 | mid=(lo+hi+1)/2;
|
---|
154 | if (last<hi && sections[last+1].section_id==section_id)
|
---|
155 | mid=last+1;
|
---|
156 | else
|
---|
157 | {
|
---|
158 | while (sections[mid].section_id!=section_id)
|
---|
159 | {
|
---|
160 | if (sections[mid].section_id>section_id)
|
---|
161 | hi=mid-1;
|
---|
162 | else
|
---|
163 | lo=mid+1;
|
---|
164 |
|
---|
165 |
|
---|
166 | w32 last_mid=mid;
|
---|
167 | mid=(hi+lo)/2;
|
---|
168 |
|
---|
169 | if (last_mid==mid)
|
---|
170 | return -1;
|
---|
171 |
|
---|
172 | }
|
---|
173 | }
|
---|
174 |
|
---|
175 | last=mid;
|
---|
176 |
|
---|
177 | return mid;
|
---|
178 | }
|
---|
179 |
|
---|
180 |
|
---|
181 | i4_bool i4_loader_class::goto_section(w32 section_id)
|
---|
182 | {
|
---|
183 | int mid=find_section(section_id);
|
---|
184 | if (mid==-1)
|
---|
185 | return i4_F;
|
---|
186 |
|
---|
187 | if (in->tell()!=sections[mid].section_offset)
|
---|
188 | {
|
---|
189 | i4_warning("goto section : non-linear %d", section_id);
|
---|
190 | in->seek(sections[mid].section_offset);
|
---|
191 | }
|
---|
192 | return i4_T;
|
---|
193 | }
|
---|
194 |
|
---|
195 | i4_bool i4_loader_class::get_section_info(char *section_name, w32 &offset, w32 &size)
|
---|
196 | {
|
---|
197 | w32 id=i4_check_sum32(section_name, strlen(section_name));
|
---|
198 | int mid=find_section(id);
|
---|
199 | if (mid!=-1)
|
---|
200 | {
|
---|
201 | offset=sections[mid].section_offset;
|
---|
202 | size=sections[mid].section_size;
|
---|
203 | return i4_T;
|
---|
204 | }
|
---|
205 | else return i4_F;
|
---|
206 |
|
---|
207 | }
|
---|
208 |
|
---|
209 | i4_bool i4_loader_class::goto_section(char *section_name)
|
---|
210 | {
|
---|
211 | return goto_section(i4_check_sum32(section_name, strlen(section_name)));
|
---|
212 | }
|
---|
213 |
|
---|
214 | static w32 i4_check_end=0;
|
---|
215 | void i4_loader_class::get_version(w16 &version, w16 &data_size)
|
---|
216 | {
|
---|
217 | version = in->read_16();
|
---|
218 | data_size = in->read_16();
|
---|
219 |
|
---|
220 |
|
---|
221 | //data_size is the size of the data + 4 bytes for the version and data size variables
|
---|
222 | //since data_size is used to seek past the data, and we already read 4 bytes for
|
---|
223 | //the version and data_size, return the data_size - 4
|
---|
224 | data_size -= 4;
|
---|
225 |
|
---|
226 | i4_check_end=in->tell() + data_size;
|
---|
227 | }
|
---|
228 |
|
---|
229 |
|
---|
230 | i4_bool i4_loader_class::check_version(w16 version)
|
---|
231 | {
|
---|
232 | w16 ver,add;
|
---|
233 | ver=in->read_16();
|
---|
234 | add=in->read_16();
|
---|
235 |
|
---|
236 | i4_check_end=in->tell()+add-4;
|
---|
237 |
|
---|
238 | if (ver!=version)
|
---|
239 | {
|
---|
240 | in->seek(i4_check_end);
|
---|
241 | return i4_F;
|
---|
242 | }
|
---|
243 | return i4_T;
|
---|
244 | }
|
---|
245 |
|
---|
246 |
|
---|
247 | void i4_loader_class::end_version(I4_LF_ARGS)
|
---|
248 | {
|
---|
249 | if (in->tell()!=i4_check_end)
|
---|
250 | i4_warning("end_check_version did not read proper amount %s:%d", I4_FILE, I4_LINE);
|
---|
251 | }
|
---|
252 |
|
---|
253 | w32 i4_loader_class::size ()
|
---|
254 | { return in->size(); }
|
---|
255 |
|
---|
256 | w32 i4_loader_class::tell ()
|
---|
257 | { return in->tell(); }
|
---|
258 |
|
---|
259 |
|
---|
260 | w32 i4_loader_class::seek(w32 offset)
|
---|
261 | {
|
---|
262 | return in->seek(offset);
|
---|
263 | }
|
---|
264 |
|
---|
265 |
|
---|
266 | w32 i4_loader_class::read (void *buffer, w32 size)
|
---|
267 | {
|
---|
268 | return in->read(buffer, size);
|
---|
269 | }
|
---|
270 |
|
---|
271 |
|
---|
272 | w32 i4_loader_class::write(const void *buffer, w32 size)
|
---|
273 | {
|
---|
274 | i4_error("Bad bad");
|
---|
275 | return 0;
|
---|
276 | }
|
---|
277 |
|
---|
278 | i4_loader_class::~i4_loader_class()
|
---|
279 | {
|
---|
280 | if (close_on_delete && in)
|
---|
281 | delete in;
|
---|
282 | }
|
---|