/src/libwrc/libwrc/libwrc_resource_node_tree.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Resource node tree functions |
3 | | * |
4 | | * Copyright (C) 2011-2024, Joachim Metz <joachim.metz@gmail.com> |
5 | | * |
6 | | * Refer to AUTHORS for acknowledgements. |
7 | | * |
8 | | * This program is free software: you can redistribute it and/or modify |
9 | | * it under the terms of the GNU Lesser General Public License as published by |
10 | | * the Free Software Foundation, either version 3 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public License |
19 | | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
20 | | */ |
21 | | |
22 | | #include <common.h> |
23 | | #include <memory.h> |
24 | | #include <types.h> |
25 | | |
26 | | #include "libwrc_definitions.h" |
27 | | #include "libwrc_io_handle.h" |
28 | | #include "libwrc_libbfio.h" |
29 | | #include "libwrc_libcdata.h" |
30 | | #include "libwrc_libcerror.h" |
31 | | #include "libwrc_libcnotify.h" |
32 | | #include "libwrc_resource_node_entry.h" |
33 | | #include "libwrc_resource_node_header.h" |
34 | | #include "libwrc_resource_node_tree.h" |
35 | | |
36 | | #include "wrc_resource_node.h" |
37 | | |
38 | | const uint8_t libwrc_resource_name_mui[ 6 ] = { |
39 | | 'M', 0, 'U', 0, 'I', 0 }; |
40 | | |
41 | | const uint8_t libwrc_resource_name_wevt_template[ 26 ] = { |
42 | | 'W', 0, 'E', 0, 'V', 0, 'T', 0, '_', 0, 'T', 0, 'E', 0, 'M', 0, |
43 | | 'P', 0, 'L', 0, 'A', 0, 'T', 0, 'E', 0 }; |
44 | | |
45 | | /* Reads the node of a resource node tree |
46 | | * Returns 1 if successful or -1 on error |
47 | | */ |
48 | | int libwrc_resource_node_tree_read_node( |
49 | | libcdata_tree_node_t *node, |
50 | | libwrc_io_handle_t *io_handle, |
51 | | libbfio_handle_t *file_io_handle, |
52 | | off64_t file_offset, |
53 | | int node_level, |
54 | | libcerror_error_t **error ) |
55 | 4.02k | { |
56 | 4.02k | libcdata_tree_node_t *sub_node = NULL; |
57 | 4.02k | libwrc_resource_node_entry_t *resource_node_entry = NULL; |
58 | 4.02k | libwrc_resource_node_entry_t *sub_resource_node_entry = NULL; |
59 | 4.02k | libwrc_resource_node_header_t *resource_node_header = NULL; |
60 | 4.02k | static char *function = "libwrc_resource_node_tree_read_node"; |
61 | 4.02k | off64_t resource_node_entry_data_offset = 0; |
62 | 4.02k | uint32_t entry_index = 0; |
63 | 4.02k | uint32_t number_of_entries = 0; |
64 | 4.02k | uint32_t resource_node_entry_offset = 0; |
65 | 4.02k | int number_of_sub_nodes = 0; |
66 | 4.02k | int resource_node_entry_index = 0; |
67 | 4.02k | int result = 0; |
68 | 4.02k | int sub_node_index = 0; |
69 | | |
70 | 4.02k | if( io_handle == NULL ) |
71 | 0 | { |
72 | 0 | libcerror_error_set( |
73 | 0 | error, |
74 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
75 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
76 | 0 | "%s: invalid IO handle.", |
77 | 0 | function ); |
78 | |
|
79 | 0 | return( -1 ); |
80 | 0 | } |
81 | 4.02k | if( ( node_level < 1 ) |
82 | 4.02k | || ( node_level > LIBWRC_MAXIMUM_RESOURCE_NODE_RECURSION_DEPTH ) ) |
83 | 19 | { |
84 | 19 | libcerror_error_set( |
85 | 19 | error, |
86 | 19 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
87 | 19 | LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, |
88 | 19 | "%s: invalid node level value out of bounds.", |
89 | 19 | function ); |
90 | | |
91 | 19 | return( -1 ); |
92 | 19 | } |
93 | 4.00k | if( node == NULL ) |
94 | 0 | { |
95 | 0 | libcerror_error_set( |
96 | 0 | error, |
97 | 0 | LIBCERROR_ERROR_DOMAIN_ARGUMENTS, |
98 | 0 | LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, |
99 | 0 | "%s: invalid node.", |
100 | 0 | function ); |
101 | |
|
102 | 0 | return( -1 ); |
103 | 0 | } |
104 | 4.00k | if( libwrc_resource_node_header_initialize( |
105 | 4.00k | &resource_node_header, |
106 | 4.00k | error ) == -1 ) |
107 | 0 | { |
108 | 0 | libcerror_error_set( |
109 | 0 | error, |
110 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
111 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
112 | 0 | "%s: unable to create resource node header.", |
113 | 0 | function ); |
114 | |
|
115 | 0 | goto on_error; |
116 | 0 | } |
117 | 4.00k | if( libwrc_resource_node_header_read_file_io_handle( |
118 | 4.00k | resource_node_header, |
119 | 4.00k | file_io_handle, |
120 | 4.00k | file_offset, |
121 | 4.00k | error ) != 1 ) |
122 | 110 | { |
123 | 110 | libcerror_error_set( |
124 | 110 | error, |
125 | 110 | LIBCERROR_ERROR_DOMAIN_IO, |
126 | 110 | LIBCERROR_IO_ERROR_READ_FAILED, |
127 | 110 | "%s: unable to read resource node header at offset: %" PRIi64 " (0x%08" PRIx64 ").", |
128 | 110 | function, |
129 | 110 | file_offset, |
130 | 110 | file_offset ); |
131 | | |
132 | 110 | goto on_error; |
133 | 110 | } |
134 | 3.89k | file_offset += sizeof( wrc_resource_node_header_t ); |
135 | | |
136 | 3.89k | number_of_entries = (uint32_t) resource_node_header->number_of_named_entries + (uint32_t) resource_node_header->number_of_unnamed_entries; |
137 | | |
138 | 3.89k | if( libwrc_resource_node_header_free( |
139 | 3.89k | &resource_node_header, |
140 | 3.89k | error ) == -1 ) |
141 | 0 | { |
142 | 0 | libcerror_error_set( |
143 | 0 | error, |
144 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
145 | 0 | LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, |
146 | 0 | "%s: unable to free resource node header.", |
147 | 0 | function ); |
148 | |
|
149 | 0 | goto on_error; |
150 | 0 | } |
151 | 3.89k | resource_node_entry_data_offset = sizeof( wrc_resource_node_header_t ) + ( number_of_entries * sizeof( wrc_resource_node_entry_t ) ); |
152 | | |
153 | 3.89k | if( (size64_t) resource_node_entry_data_offset > io_handle->stream_size ) |
154 | 25 | { |
155 | 25 | libcerror_error_set( |
156 | 25 | error, |
157 | 25 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
158 | 25 | LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, |
159 | 25 | "%s: invalid number of entries value out of bounds.", |
160 | 25 | function ); |
161 | | |
162 | 25 | goto on_error; |
163 | 25 | } |
164 | 3.86k | for( entry_index = 0; |
165 | 10.9k | entry_index < number_of_entries; |
166 | 7.10k | entry_index++ ) |
167 | 7.31k | { |
168 | 7.31k | if( libwrc_resource_node_entry_initialize( |
169 | 7.31k | &resource_node_entry, |
170 | 7.31k | error ) == -1 ) |
171 | 0 | { |
172 | 0 | libcerror_error_set( |
173 | 0 | error, |
174 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
175 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
176 | 0 | "%s: unable to create resource node entry: %d.", |
177 | 0 | function, |
178 | 0 | entry_index ); |
179 | |
|
180 | 0 | goto on_error; |
181 | 0 | } |
182 | 7.31k | if( libwrc_resource_node_entry_read_file_io_handle( |
183 | 7.31k | resource_node_entry, |
184 | 7.31k | file_io_handle, |
185 | 7.31k | file_offset, |
186 | 7.31k | node_level, |
187 | 7.31k | error ) != 1 ) |
188 | 5 | { |
189 | 5 | libcerror_error_set( |
190 | 5 | error, |
191 | 5 | LIBCERROR_ERROR_DOMAIN_IO, |
192 | 5 | LIBCERROR_IO_ERROR_READ_FAILED, |
193 | 5 | "%s: unable to read resource node entry: %d at offset: %" PRIi64 " (0x%08" PRIx64 ").", |
194 | 5 | function, |
195 | 5 | entry_index, |
196 | 5 | file_offset, |
197 | 5 | file_offset ); |
198 | | |
199 | 5 | goto on_error; |
200 | 5 | } |
201 | 7.30k | file_offset += sizeof( wrc_resource_node_entry_t ); |
202 | | |
203 | 7.30k | result = libwrc_resource_node_entry_read_name_file_io_handle( |
204 | 7.30k | resource_node_entry, |
205 | 7.30k | file_io_handle, |
206 | 7.30k | error ); |
207 | | |
208 | 7.30k | if( result == -1 ) |
209 | 126 | { |
210 | 126 | libcerror_error_set( |
211 | 126 | error, |
212 | 126 | LIBCERROR_ERROR_DOMAIN_IO, |
213 | 126 | LIBCERROR_IO_ERROR_READ_FAILED, |
214 | 126 | "%s: unable to read resource node entry: %d name.", |
215 | 126 | function, |
216 | 126 | entry_index ); |
217 | | |
218 | 126 | goto on_error; |
219 | 126 | } |
220 | 7.18k | resource_node_entry_offset = resource_node_entry->offset & 0x7fffffffUL; |
221 | | |
222 | | /* Check the bounds here to fail fast on corrupt data |
223 | | */ |
224 | 7.18k | if( ( resource_node_entry_offset < resource_node_entry_data_offset ) |
225 | 7.18k | || ( resource_node_entry_offset >= io_handle->stream_size ) ) |
226 | 74 | { |
227 | 74 | libcerror_error_set( |
228 | 74 | error, |
229 | 74 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
230 | 74 | LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, |
231 | 74 | "%s: invalid resource node entry: %d - offset value out of bounds.", |
232 | 74 | function, |
233 | 74 | entry_index ); |
234 | | |
235 | 74 | goto on_error; |
236 | 74 | } |
237 | 7.10k | if( node_level == 1 ) |
238 | 1.64k | { |
239 | 1.64k | if( ( resource_node_entry->identifier & LIBWRC_RESOURCE_IDENTIFIER_FLAG_HAS_NAME ) == 0 ) |
240 | 1.02k | { |
241 | 1.02k | switch( resource_node_entry->identifier ) |
242 | 1.02k | { |
243 | 7 | case LIBWRC_RESOURCE_IDENTIFIER_CURSOR: |
244 | 7 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_CURSOR; |
245 | 7 | break; |
246 | | |
247 | 5 | case LIBWRC_RESOURCE_IDENTIFIER_BITMAP: |
248 | 5 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_BITMAP; |
249 | 5 | break; |
250 | | |
251 | 2 | case LIBWRC_RESOURCE_IDENTIFIER_ICON: |
252 | 2 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_ICON; |
253 | 2 | break; |
254 | | |
255 | 2 | case LIBWRC_RESOURCE_IDENTIFIER_MENU: |
256 | 2 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_MENU; |
257 | 2 | break; |
258 | | |
259 | 5 | case LIBWRC_RESOURCE_IDENTIFIER_DIALOG: |
260 | 5 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_DIALOG; |
261 | 5 | break; |
262 | | |
263 | 5 | case LIBWRC_RESOURCE_IDENTIFIER_STRING: |
264 | 5 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_STRING; |
265 | 5 | break; |
266 | | |
267 | 1 | case LIBWRC_RESOURCE_IDENTIFIER_FONT_DIRECTORY: |
268 | 1 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_FONT_DIRECTORY; |
269 | 1 | break; |
270 | | |
271 | 11 | case LIBWRC_RESOURCE_IDENTIFIER_FONT: |
272 | 11 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_FONT; |
273 | 11 | break; |
274 | | |
275 | 4 | case LIBWRC_RESOURCE_IDENTIFIER_ACCELERATOR: |
276 | 4 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_ACCELERATOR; |
277 | 4 | break; |
278 | | |
279 | 2 | case LIBWRC_RESOURCE_IDENTIFIER_RAW_DATA: |
280 | 2 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_RAW_DATA; |
281 | 2 | break; |
282 | | |
283 | 2 | case LIBWRC_RESOURCE_IDENTIFIER_MESSAGE_TABLE: |
284 | 2 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_MESSAGE_TABLE; |
285 | 2 | break; |
286 | | |
287 | 36 | case LIBWRC_RESOURCE_IDENTIFIER_GROUP_CURSOR: |
288 | 36 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_GROUP_CURSOR; |
289 | 36 | break; |
290 | | |
291 | 4 | case LIBWRC_RESOURCE_IDENTIFIER_GROUP_ICON: |
292 | 4 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_GROUP_ICON; |
293 | 4 | break; |
294 | | |
295 | 19 | case LIBWRC_RESOURCE_IDENTIFIER_VERSION: |
296 | 19 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_VERSION; |
297 | 19 | break; |
298 | | |
299 | 7 | case LIBWRC_RESOURCE_IDENTIFIER_DIALOG_INCLUDE: |
300 | 7 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_DIALOG_INCLUDE; |
301 | 7 | break; |
302 | | |
303 | 3 | case LIBWRC_RESOURCE_IDENTIFIER_PLUG_AND_PLAY: |
304 | 3 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_PLUG_AND_PLAY; |
305 | 3 | break; |
306 | | |
307 | 3 | case LIBWRC_RESOURCE_IDENTIFIER_VXD: |
308 | 3 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_VXD; |
309 | 3 | break; |
310 | | |
311 | 2 | case LIBWRC_RESOURCE_IDENTIFIER_ANIMATED_CURSOR: |
312 | 2 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_ANIMATED_CURSOR; |
313 | 2 | break; |
314 | | |
315 | 7 | case LIBWRC_RESOURCE_IDENTIFIER_ANIMATED_ICON: |
316 | 7 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_ANIMATED_ICON; |
317 | 7 | break; |
318 | | |
319 | 6 | case LIBWRC_RESOURCE_IDENTIFIER_HTML: |
320 | 6 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_HTML; |
321 | 6 | break; |
322 | | |
323 | 27 | case LIBWRC_RESOURCE_IDENTIFIER_MANIFEST: |
324 | 27 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_MANIFEST; |
325 | 27 | break; |
326 | 1.02k | } |
327 | 1.02k | } |
328 | 626 | else |
329 | 626 | { |
330 | 626 | if( resource_node_entry->name_string_size == 6 ) |
331 | 227 | { |
332 | 227 | if( memory_compare( |
333 | 227 | resource_node_entry->name_string, |
334 | 227 | libwrc_resource_name_mui, |
335 | 227 | 6 ) == 0 ) |
336 | 70 | { |
337 | 70 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_MUI; |
338 | 70 | } |
339 | 227 | } |
340 | 399 | else if( resource_node_entry->name_string_size == 26 ) |
341 | 246 | { |
342 | 246 | if( memory_compare( |
343 | 246 | resource_node_entry->name_string, |
344 | 246 | libwrc_resource_name_wevt_template, |
345 | 246 | 26 ) == 0 ) |
346 | 77 | { |
347 | 77 | resource_node_entry->type = LIBWRC_RESOURCE_TYPE_WEVT_TEMPLATE; |
348 | 77 | } |
349 | 246 | } |
350 | 626 | } |
351 | 1.64k | } |
352 | 7.10k | if( libcdata_tree_node_insert_value( |
353 | 7.10k | node, |
354 | 7.10k | (intptr_t *) resource_node_entry, |
355 | 7.10k | (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libwrc_resource_node_entry_compare, |
356 | 7.10k | LIBCDATA_INSERT_FLAG_NON_UNIQUE_ENTRIES, |
357 | 7.10k | error ) == -1 ) |
358 | 0 | { |
359 | 0 | libcerror_error_set( |
360 | 0 | error, |
361 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
362 | 0 | LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, |
363 | 0 | "%s: unable to insert resource node: %d.", |
364 | 0 | function, |
365 | 0 | resource_node_entry_index ); |
366 | |
|
367 | 0 | goto on_error; |
368 | 0 | } |
369 | 7.10k | resource_node_entry = NULL; |
370 | | |
371 | 7.10k | resource_node_entry_index++; |
372 | | |
373 | | #if defined( HAVE_DEBUG_OUTPUT ) |
374 | | if( libcnotify_verbose != 0 ) |
375 | | { |
376 | | libcnotify_printf( |
377 | | "\n" ); |
378 | | } |
379 | | #endif |
380 | 7.10k | } |
381 | 3.66k | if( libcdata_tree_node_get_number_of_sub_nodes( |
382 | 3.66k | node, |
383 | 3.66k | &number_of_sub_nodes, |
384 | 3.66k | error ) != 1 ) |
385 | 0 | { |
386 | 0 | libcerror_error_set( |
387 | 0 | error, |
388 | 0 | LIBCERROR_ERROR_DOMAIN_IO, |
389 | 0 | LIBCERROR_IO_ERROR_READ_FAILED, |
390 | 0 | "%s: unable to retrieve number of sub nodes.", |
391 | 0 | function ); |
392 | |
|
393 | 0 | goto on_error; |
394 | 0 | } |
395 | 3.66k | if( libcdata_tree_node_get_sub_node_by_index( |
396 | 3.66k | node, |
397 | 3.66k | 0, |
398 | 3.66k | &sub_node, |
399 | 3.66k | error ) != 1 ) |
400 | 28 | { |
401 | 28 | libcerror_error_set( |
402 | 28 | error, |
403 | 28 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
404 | 28 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
405 | 28 | "%s: unable to retrieve first sub node.", |
406 | 28 | function ); |
407 | | |
408 | 28 | goto on_error; |
409 | 28 | } |
410 | 3.63k | for( sub_node_index = 0; |
411 | 5.89k | sub_node_index < number_of_sub_nodes; |
412 | 3.63k | sub_node_index++ ) |
413 | 5.19k | { |
414 | 5.19k | if( libcdata_tree_node_get_value( |
415 | 5.19k | sub_node, |
416 | 5.19k | (intptr_t **) &sub_resource_node_entry, |
417 | 5.19k | error ) != 1 ) |
418 | 0 | { |
419 | 0 | libcerror_error_set( |
420 | 0 | error, |
421 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
422 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
423 | 0 | "%s: unable to retrieve resource sub node: %d entry.", |
424 | 0 | function, |
425 | 0 | sub_node_index ); |
426 | |
|
427 | 0 | goto on_error; |
428 | 0 | } |
429 | 5.19k | if( sub_resource_node_entry == NULL ) |
430 | 0 | { |
431 | 0 | libcerror_error_set( |
432 | 0 | error, |
433 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
434 | 0 | LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, |
435 | 0 | "%s: invalid resource sub node: %d entry.", |
436 | 0 | function, |
437 | 0 | sub_node_index ); |
438 | |
|
439 | 0 | goto on_error; |
440 | 0 | } |
441 | 5.19k | if( ( sub_resource_node_entry->offset & 0x80000000UL ) != 0 ) |
442 | 3.26k | { |
443 | 3.26k | resource_node_entry_offset = sub_resource_node_entry->offset & 0x7fffffffUL; |
444 | | |
445 | 3.26k | if( libwrc_resource_node_tree_read_node( |
446 | 3.26k | sub_node, |
447 | 3.26k | io_handle, |
448 | 3.26k | file_io_handle, |
449 | 3.26k | (off64_t) resource_node_entry_offset, |
450 | 3.26k | node_level + 1, |
451 | 3.26k | error ) != 1 ) |
452 | 2.60k | { |
453 | 2.60k | libcerror_error_set( |
454 | 2.60k | error, |
455 | 2.60k | LIBCERROR_ERROR_DOMAIN_IO, |
456 | 2.60k | LIBCERROR_IO_ERROR_READ_FAILED, |
457 | 2.60k | "%s: unable to read sub resource node: %d at offset: %" PRIu32 " (0x%08" PRIx32 ").", |
458 | 2.60k | function, |
459 | 2.60k | sub_node_index, |
460 | 2.60k | resource_node_entry_offset, |
461 | 2.60k | resource_node_entry_offset ); |
462 | | |
463 | 2.60k | goto on_error; |
464 | 2.60k | } |
465 | 3.26k | } |
466 | 1.92k | else |
467 | 1.92k | { |
468 | 1.92k | if( libwrc_data_descriptor_initialize( |
469 | 1.92k | &( sub_resource_node_entry->data_descriptor ), |
470 | 1.92k | error ) == -1 ) |
471 | 0 | { |
472 | 0 | libcerror_error_set( |
473 | 0 | error, |
474 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
475 | 0 | LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, |
476 | 0 | "%s: unable to create data descriptor: %d.", |
477 | 0 | function, |
478 | 0 | sub_node_index ); |
479 | |
|
480 | 0 | goto on_error; |
481 | 0 | } |
482 | 1.92k | if( libwrc_data_descriptor_read_file_io_handle( |
483 | 1.92k | sub_resource_node_entry->data_descriptor, |
484 | 1.92k | file_io_handle, |
485 | 1.92k | (off64_t) sub_resource_node_entry->offset, |
486 | 1.92k | error ) != 1 ) |
487 | 154 | { |
488 | 154 | libcerror_error_set( |
489 | 154 | error, |
490 | 154 | LIBCERROR_ERROR_DOMAIN_IO, |
491 | 154 | LIBCERROR_IO_ERROR_READ_FAILED, |
492 | 154 | "%s: unable to read data descriptor: %d at offset: %" PRIu32 " (0x%08" PRIx32 ").", |
493 | 154 | function, |
494 | 154 | sub_node_index, |
495 | 154 | sub_resource_node_entry->offset, |
496 | 154 | sub_resource_node_entry->offset ); |
497 | | |
498 | 154 | goto on_error; |
499 | 154 | } |
500 | 1.77k | if( ( sub_resource_node_entry->data_descriptor->virtual_address < io_handle->virtual_address ) |
501 | 1.77k | || ( (size64_t) sub_resource_node_entry->data_descriptor->virtual_address >= ( io_handle->virtual_address + io_handle->stream_size ) ) ) |
502 | 134 | { |
503 | 134 | libcerror_error_set( |
504 | 134 | error, |
505 | 134 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
506 | 134 | LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, |
507 | 134 | "%s: invalid data descriptor: %d - virtual address value out of bounds.", |
508 | 134 | function, |
509 | 134 | sub_node_index ); |
510 | | |
511 | 134 | goto on_error; |
512 | 134 | } |
513 | 1.64k | if( (size64_t) ( sub_resource_node_entry->data_descriptor->virtual_address + sub_resource_node_entry->data_descriptor->size ) > ( io_handle->virtual_address + io_handle->stream_size ) ) |
514 | 37 | { |
515 | 37 | libcerror_error_set( |
516 | 37 | error, |
517 | 37 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
518 | 37 | LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, |
519 | 37 | "%s: invalid data descriptor: %d - size value out of bounds.", |
520 | 37 | function, |
521 | 37 | sub_node_index ); |
522 | | |
523 | 37 | goto on_error; |
524 | 37 | } |
525 | 1.64k | } |
526 | 2.26k | if( libcdata_tree_node_get_next_node( |
527 | 2.26k | sub_node, |
528 | 2.26k | &sub_node, |
529 | 2.26k | error ) != 1 ) |
530 | 0 | { |
531 | 0 | libcerror_error_set( |
532 | 0 | error, |
533 | 0 | LIBCERROR_ERROR_DOMAIN_RUNTIME, |
534 | 0 | LIBCERROR_RUNTIME_ERROR_GET_FAILED, |
535 | 0 | "%s: unable to retrieve next node of sub node: %d.", |
536 | 0 | function, |
537 | 0 | sub_node_index ); |
538 | |
|
539 | 0 | goto on_error; |
540 | 0 | } |
541 | 2.26k | } |
542 | 706 | return( 1 ); |
543 | | |
544 | 3.29k | on_error: |
545 | 3.29k | if( resource_node_entry != NULL ) |
546 | 205 | { |
547 | 205 | libwrc_resource_node_entry_free( |
548 | 205 | &resource_node_entry, |
549 | 205 | NULL ); |
550 | 205 | } |
551 | 3.29k | if( resource_node_header != NULL ) |
552 | 110 | { |
553 | 110 | libwrc_resource_node_header_free( |
554 | 110 | &resource_node_header, |
555 | 110 | NULL ); |
556 | 110 | } |
557 | 3.29k | return( -1 ); |
558 | 3.63k | } |
559 | | |