Coverage Report

Created: 2025-06-13 07:22

/src/libexe/libexe/libexe_file.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File 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 <narrow_string.h>
25
#include <types.h>
26
#include <wide_string.h>
27
28
#include "libexe_data_directory_descriptor.h"
29
#include "libexe_codepage.h"
30
#include "libexe_debug.h"
31
#include "libexe_debug_data.h"
32
#include "libexe_definitions.h"
33
#include "libexe_export_table.h"
34
#include "libexe_import_table.h"
35
#include "libexe_io_handle.h"
36
#include "libexe_file.h"
37
#include "libexe_libbfio.h"
38
#include "libexe_libcdata.h"
39
#include "libexe_libcerror.h"
40
#include "libexe_libcnotify.h"
41
#include "libexe_section.h"
42
#include "libexe_section_descriptor.h"
43
44
/* Creates a file
45
 * Make sure the value file is referencing, is set to NULL
46
 * Returns 1 if successful or -1 on error
47
 */
48
int libexe_file_initialize(
49
     libexe_file_t **file,
50
     libcerror_error_t **error )
51
899
{
52
899
  libexe_internal_file_t *internal_file = NULL;
53
899
  static char *function                 = "libexe_file_initialize";
54
55
899
  if( file == NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
60
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
61
0
     "%s: invalid file.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
899
  if( *file != NULL )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
71
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
72
0
     "%s: invalid file value already set.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
899
  internal_file = memory_allocate_structure(
78
899
                   libexe_internal_file_t );
79
80
899
  if( internal_file == NULL )
81
0
  {
82
0
    libcerror_error_set(
83
0
     error,
84
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
85
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
86
0
     "%s: unable to create file.",
87
0
     function );
88
89
0
    goto on_error;
90
0
  }
91
899
  if( memory_set(
92
899
       internal_file,
93
899
       0,
94
899
       sizeof( libexe_internal_file_t ) ) == NULL )
95
0
  {
96
0
    libcerror_error_set(
97
0
     error,
98
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
99
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
100
0
     "%s: unable to clear file.",
101
0
     function );
102
103
0
    memory_free(
104
0
     internal_file );
105
106
0
    return( -1 );
107
0
  }
108
899
  if( libcdata_array_initialize(
109
899
       &( internal_file->sections_array ),
110
899
       0,
111
899
       error ) != 1 )
112
0
  {
113
0
    libcerror_error_set(
114
0
     error,
115
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
116
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
117
0
     "%s: unable to create sections array.",
118
0
     function );
119
120
0
    goto on_error;
121
0
  }
122
899
  if( libexe_io_handle_initialize(
123
899
       &( internal_file->io_handle ),
124
899
       error ) != 1 )
125
0
  {
126
0
    libcerror_error_set(
127
0
     error,
128
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
129
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
130
0
     "%s: unable to create IO handle.",
131
0
     function );
132
133
0
    goto on_error;
134
0
  }
135
899
  *file = (libexe_file_t *) internal_file;
136
137
899
  return( 1 );
138
139
0
on_error:
140
0
  if( internal_file != NULL )
141
0
  {
142
0
    if( internal_file->sections_array != NULL )
143
0
    {
144
0
      libcdata_array_free(
145
0
       &( internal_file->sections_array ),
146
0
       NULL,
147
0
       NULL );
148
0
    }
149
0
    memory_free(
150
0
     internal_file );
151
0
  }
152
0
  return( -1 );
153
899
}
154
155
/* Frees a file
156
 * Returns 1 if successful or -1 on error
157
 */
158
int libexe_file_free(
159
     libexe_file_t **file,
160
     libcerror_error_t **error )
161
899
{
162
899
  libexe_internal_file_t *internal_file = NULL;
163
899
  static char *function                 = "libexe_file_free";
164
899
  int result                            = 1;
165
166
899
  if( file == NULL )
167
0
  {
168
0
    libcerror_error_set(
169
0
     error,
170
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
171
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
172
0
     "%s: invalid file.",
173
0
     function );
174
175
0
    return( -1 );
176
0
  }
177
899
  if( *file != NULL )
178
899
  {
179
899
    internal_file = (libexe_internal_file_t *) *file;
180
181
899
    if( internal_file->file_io_handle != NULL )
182
0
    {
183
0
      if( libexe_file_close(
184
0
           *file,
185
0
           error ) != 0 )
186
0
      {
187
0
        libcerror_error_set(
188
0
         error,
189
0
         LIBCERROR_ERROR_DOMAIN_IO,
190
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
191
0
         "%s: unable to close file.",
192
0
         function );
193
194
0
        result = -1;
195
0
      }
196
0
    }
197
899
    *file = NULL;
198
199
899
    if( libcdata_array_free(
200
899
         &( internal_file->sections_array ),
201
899
         (int (*)(intptr_t **, libcerror_error_t **)) &libexe_section_descriptor_free,
202
899
         error ) != 1 )
203
0
    {
204
0
      libcerror_error_set(
205
0
       error,
206
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
207
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
208
0
       "%s: unable to free sections array.",
209
0
       function );
210
211
0
      result = -1;
212
0
    }
213
899
    if( libexe_io_handle_free(
214
899
         &( internal_file->io_handle ),
215
899
         error ) != 1 )
216
0
    {
217
0
      libcerror_error_set(
218
0
       error,
219
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
220
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
221
0
       "%s: unable to free IO handle.",
222
0
       function );
223
224
0
      result = -1;
225
0
    }
226
899
    memory_free(
227
899
     internal_file );
228
899
  }
229
899
  return( result );
230
899
}
231
232
/* Signals the file to abort its current activity
233
 * Returns 1 if successful or -1 on error
234
 */
235
int libexe_file_signal_abort(
236
     libexe_file_t *file,
237
     libcerror_error_t **error )
238
0
{
239
0
  libexe_internal_file_t *internal_file = NULL;
240
0
  static char *function                 = "libexe_file_signal_abort";
241
242
0
  if( file == NULL )
243
0
  {
244
0
    libcerror_error_set(
245
0
     error,
246
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
247
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
248
0
     "%s: invalid file.",
249
0
     function );
250
251
0
    return( -1 );
252
0
  }
253
0
  internal_file = (libexe_internal_file_t *) file;
254
255
0
  if( internal_file->io_handle == NULL )
256
0
  {
257
0
    libcerror_error_set(
258
0
     error,
259
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
260
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
261
0
     "%s: invalid file - missing IO handle.",
262
0
     function );
263
264
0
    return( -1 );
265
0
  }
266
0
  internal_file->io_handle->abort = 1;
267
268
0
  return( 1 );
269
0
}
270
271
/* Opens a file
272
 * Returns 1 if successful or -1 on error
273
 */
274
int libexe_file_open(
275
     libexe_file_t *file,
276
     const char *filename,
277
     int access_flags,
278
     libcerror_error_t **error )
279
0
{
280
0
  libbfio_handle_t *file_io_handle      = NULL;
281
0
  libexe_internal_file_t *internal_file = NULL;
282
0
  static char *function                 = "libexe_file_open";
283
0
  size_t filename_length                = 0;
284
285
0
  if( file == NULL )
286
0
  {
287
0
    libcerror_error_set(
288
0
     error,
289
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
290
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
291
0
     "%s: invalid file.",
292
0
     function );
293
294
0
    return( -1 );
295
0
  }
296
0
  internal_file = (libexe_internal_file_t *) file;
297
298
0
  if( filename == NULL )
299
0
  {
300
0
    libcerror_error_set(
301
0
     error,
302
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
303
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
304
0
     "%s: invalid filename.",
305
0
     function );
306
307
0
    return( -1 );
308
0
  }
309
0
  if( ( ( access_flags & LIBEXE_ACCESS_FLAG_READ ) == 0 )
310
0
   && ( ( access_flags & LIBEXE_ACCESS_FLAG_WRITE ) == 0 ) )
311
0
  {
312
0
    libcerror_error_set(
313
0
     error,
314
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
315
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
316
0
     "%s: unsupported access flags.",
317
0
     function );
318
319
0
    return( -1 );
320
0
  }
321
0
  if( ( access_flags & LIBEXE_ACCESS_FLAG_WRITE ) != 0 )
322
0
  {
323
0
    libcerror_error_set(
324
0
     error,
325
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
326
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
327
0
     "%s: write access currently not supported.",
328
0
     function );
329
330
0
    return( -1 );
331
0
  }
332
0
  if( libbfio_file_initialize(
333
0
       &file_io_handle,
334
0
       error ) != 1 )
335
0
  {
336
0
    libcerror_error_set(
337
0
     error,
338
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
339
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
340
0
     "%s: unable to create file IO handle.",
341
0
     function );
342
343
0
    goto on_error;
344
0
  }
345
#if defined( HAVE_DEBUG_OUTPUT )
346
  if( libbfio_handle_set_track_offsets_read(
347
       file_io_handle,
348
       1,
349
       error ) != 1 )
350
  {
351
                libcerror_error_set(
352
                 error,
353
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
354
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
355
                 "%s: unable to set track offsets read in file IO handle.",
356
                 function );
357
358
    goto on_error;
359
  }
360
#endif
361
0
  filename_length = narrow_string_length(
362
0
                     filename );
363
364
0
  if( libbfio_file_set_name(
365
0
       file_io_handle,
366
0
       filename,
367
0
       filename_length + 1,
368
0
       error ) != 1 )
369
0
  {
370
0
                libcerror_error_set(
371
0
                 error,
372
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
373
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
374
0
                 "%s: unable to set filename in file IO handle.",
375
0
                 function );
376
377
0
    goto on_error;
378
0
  }
379
0
  if( libexe_file_open_file_io_handle(
380
0
       file,
381
0
       file_io_handle,
382
0
       access_flags,
383
0
       error ) != 1 )
384
0
  {
385
0
    libcerror_error_set(
386
0
     error,
387
0
     LIBCERROR_ERROR_DOMAIN_IO,
388
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
389
0
     "%s: unable to open file: %s.",
390
0
     function,
391
0
     filename );
392
393
0
    goto on_error;
394
0
  }
395
0
  internal_file->file_io_handle_created_in_library = 1;
396
397
0
  return( 1 );
398
399
0
on_error:
400
0
  if( file_io_handle != NULL )
401
0
  {
402
0
    libbfio_handle_free(
403
0
     &file_io_handle,
404
0
     NULL );
405
0
  }
406
0
  return( -1 );
407
0
}
408
409
#if defined( HAVE_WIDE_CHARACTER_TYPE )
410
411
/* Opens a file
412
 * Returns 1 if successful or -1 on error
413
 */
414
int libexe_file_open_wide(
415
     libexe_file_t *file,
416
     const wchar_t *filename,
417
     int access_flags,
418
     libcerror_error_t **error )
419
{
420
  libbfio_handle_t *file_io_handle      = NULL;
421
  libexe_internal_file_t *internal_file = NULL;
422
  static char *function                 = "libexe_file_open_wide";
423
  size_t filename_length                = 0;
424
425
  if( file == NULL )
426
  {
427
    libcerror_error_set(
428
     error,
429
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
430
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
431
     "%s: invalid file.",
432
     function );
433
434
    return( -1 );
435
  }
436
  internal_file = (libexe_internal_file_t *) file;
437
438
  if( filename == NULL )
439
  {
440
    libcerror_error_set(
441
     error,
442
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
443
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
444
     "%s: invalid filename.",
445
     function );
446
447
    return( -1 );
448
  }
449
  if( ( ( access_flags & LIBEXE_ACCESS_FLAG_READ ) == 0 )
450
   && ( ( access_flags & LIBEXE_ACCESS_FLAG_WRITE ) == 0 ) )
451
  {
452
    libcerror_error_set(
453
     error,
454
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
455
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
456
     "%s: unsupported access flags.",
457
     function );
458
459
    return( -1 );
460
  }
461
  if( ( access_flags & LIBEXE_ACCESS_FLAG_WRITE ) != 0 )
462
  {
463
    libcerror_error_set(
464
     error,
465
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
466
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
467
     "%s: write access currently not supported.",
468
     function );
469
470
    return( -1 );
471
  }
472
  if( libbfio_file_initialize(
473
       &file_io_handle,
474
       error ) != 1 )
475
  {
476
    libcerror_error_set(
477
     error,
478
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
479
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
480
     "%s: unable to create file IO handle.",
481
     function );
482
483
    goto on_error;
484
  }
485
#if defined( HAVE_DEBUG_OUTPUT )
486
  if( libbfio_handle_set_track_offsets_read(
487
       file_io_handle,
488
       1,
489
       error ) != 1 )
490
  {
491
                libcerror_error_set(
492
                 error,
493
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
494
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
495
                 "%s: unable to set track offsets read in file IO handle.",
496
                 function );
497
498
    goto on_error;
499
  }
500
#endif
501
  filename_length = wide_string_length(
502
                     filename );
503
504
  if( libbfio_file_set_name_wide(
505
       file_io_handle,
506
       filename,
507
       filename_length + 1,
508
       error ) != 1 )
509
  {
510
                libcerror_error_set(
511
                 error,
512
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
513
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
514
                 "%s: unable to set filename in file IO handle.",
515
                 function );
516
517
    goto on_error;
518
  }
519
  if( libexe_file_open_file_io_handle(
520
       file,
521
       file_io_handle,
522
       access_flags,
523
       error ) != 1 )
524
  {
525
    libcerror_error_set(
526
     error,
527
     LIBCERROR_ERROR_DOMAIN_IO,
528
     LIBCERROR_IO_ERROR_OPEN_FAILED,
529
     "%s: unable to open file: %ls.",
530
     function,
531
     filename );
532
533
    goto on_error;
534
  }
535
  internal_file->file_io_handle_created_in_library = 1;
536
537
  return( 1 );
538
539
on_error:
540
  if( file_io_handle != NULL )
541
  {
542
    libbfio_handle_free(
543
     &file_io_handle,
544
     NULL );
545
  }
546
  return( -1 );
547
}
548
549
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
550
551
/* Opens a file using a Basic File IO (bfio) handle
552
 * Returns 1 if successful or -1 on error
553
 */
554
int libexe_file_open_file_io_handle(
555
     libexe_file_t *file,
556
     libbfio_handle_t *file_io_handle,
557
     int access_flags,
558
     libcerror_error_t **error )
559
899
{
560
899
  libexe_internal_file_t *internal_file = NULL;
561
899
  static char *function                 = "libexe_file_open_file_io_handle";
562
899
  int bfio_access_flags                 = 0;
563
899
  int file_io_handle_is_open            = 0;
564
565
899
  if( file == NULL )
566
0
  {
567
0
    libcerror_error_set(
568
0
     error,
569
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
570
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
571
0
     "%s: invalid file.",
572
0
     function );
573
574
0
    return( -1 );
575
0
  }
576
899
  internal_file = (libexe_internal_file_t *) file;
577
578
899
  if( internal_file->file_io_handle != NULL )
579
0
  {
580
0
    libcerror_error_set(
581
0
     error,
582
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
583
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
584
0
     "%s: invalid file - file IO handle already set.",
585
0
     function );
586
587
0
    return( -1 );
588
0
  }
589
899
  if( file_io_handle == NULL )
590
0
  {
591
0
    libcerror_error_set(
592
0
     error,
593
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
594
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
595
0
     "%s: invalid file IO handle.",
596
0
     function );
597
598
0
    return( -1 );
599
0
  }
600
899
  if( ( ( access_flags & LIBEXE_ACCESS_FLAG_READ ) == 0 )
601
899
   && ( ( access_flags & LIBEXE_ACCESS_FLAG_WRITE ) == 0 ) )
602
0
  {
603
0
    libcerror_error_set(
604
0
     error,
605
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
606
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
607
0
     "%s: unsupported access flags.",
608
0
     function );
609
610
0
    return( -1 );
611
0
  }
612
899
  if( ( access_flags & LIBEXE_ACCESS_FLAG_WRITE ) != 0 )
613
0
  {
614
0
    libcerror_error_set(
615
0
     error,
616
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
617
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
618
0
     "%s: write access currently not supported.",
619
0
     function );
620
621
0
    return( -1 );
622
0
  }
623
899
  if( ( access_flags & LIBEXE_ACCESS_FLAG_READ ) != 0 )
624
899
  {
625
899
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
626
899
  }
627
899
  file_io_handle_is_open = libbfio_handle_is_open(
628
899
                            file_io_handle,
629
899
                            error );
630
631
899
  if( file_io_handle_is_open == -1 )
632
0
  {
633
0
    libcerror_error_set(
634
0
     error,
635
0
     LIBCERROR_ERROR_DOMAIN_IO,
636
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
637
0
     "%s: unable to determine if file IO handle is open.",
638
0
     function );
639
640
0
    goto on_error;
641
0
  }
642
899
  else if( file_io_handle_is_open == 0 )
643
899
  {
644
899
    if( libbfio_handle_open(
645
899
         file_io_handle,
646
899
         bfio_access_flags,
647
899
         error ) != 1 )
648
0
    {
649
0
      libcerror_error_set(
650
0
       error,
651
0
       LIBCERROR_ERROR_DOMAIN_IO,
652
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
653
0
       "%s: unable to open file IO handle.",
654
0
       function );
655
656
0
      goto on_error;
657
0
    }
658
899
    internal_file->file_io_handle_opened_in_library = 1;
659
899
  }
660
899
  if( libexe_file_open_read(
661
899
       internal_file,
662
899
       file_io_handle,
663
899
       error ) != 1 )
664
814
  {
665
814
    libcerror_error_set(
666
814
     error,
667
814
     LIBCERROR_ERROR_DOMAIN_IO,
668
814
     LIBCERROR_IO_ERROR_READ_FAILED,
669
814
     "%s: unable to read from file handle.",
670
814
     function );
671
672
814
    goto on_error;
673
814
  }
674
85
  internal_file->file_io_handle = file_io_handle;
675
676
85
  return( 1 );
677
678
814
on_error:
679
814
  if( ( file_io_handle_is_open == 0 )
680
814
   && ( internal_file->file_io_handle_opened_in_library != 0 ) )
681
814
  {
682
814
    libbfio_handle_close(
683
814
     file_io_handle,
684
814
     error );
685
686
814
    internal_file->file_io_handle_opened_in_library = 0;
687
814
  }
688
814
  internal_file->file_io_handle = NULL;
689
690
814
  return( -1 );
691
899
}
692
693
/* Closes a file
694
 * Returns 0 if successful or -1 on error
695
 */
696
int libexe_file_close(
697
     libexe_file_t *file,
698
     libcerror_error_t **error )
699
85
{
700
85
  libexe_internal_file_t *internal_file = NULL;
701
85
  static char *function                 = "libexe_file_close";
702
85
  int result                            = 0;
703
704
85
  if( file == NULL )
705
0
  {
706
0
    libcerror_error_set(
707
0
     error,
708
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
709
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
710
0
     "%s: invalid file.",
711
0
     function );
712
713
0
    return( -1 );
714
0
  }
715
85
  internal_file = (libexe_internal_file_t *) file;
716
717
85
  if( internal_file->file_io_handle == NULL )
718
0
  {
719
0
    libcerror_error_set(
720
0
     error,
721
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
722
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
723
0
     "%s: invalid file - missing file IO handle.",
724
0
     function );
725
726
0
    return( -1 );
727
0
  }
728
#if defined( HAVE_DEBUG_OUTPUT )
729
  if( libcnotify_verbose != 0 )
730
  {
731
    if( internal_file->file_io_handle_created_in_library != 0 )
732
    {
733
      if( libexe_debug_print_read_offsets(
734
           internal_file->file_io_handle,
735
           error ) != 1 )
736
      {
737
        libcerror_error_set(
738
         error,
739
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
740
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
741
         "%s: unable to print the read offsets.",
742
         function );
743
744
        result = -1;
745
      }
746
    }
747
  }
748
#endif
749
85
  if( internal_file->file_io_handle_opened_in_library != 0 )
750
85
  {
751
85
    if( libbfio_handle_close(
752
85
         internal_file->file_io_handle,
753
85
         error ) != 0 )
754
0
    {
755
0
      libcerror_error_set(
756
0
       error,
757
0
       LIBCERROR_ERROR_DOMAIN_IO,
758
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
759
0
       "%s: unable to close file IO handle.",
760
0
       function );
761
762
0
      result = -1;
763
0
    }
764
85
    internal_file->file_io_handle_opened_in_library = 0;
765
85
  }
766
85
  if( internal_file->file_io_handle_created_in_library != 0 )
767
0
  {
768
0
    if( libbfio_handle_free(
769
0
         &( internal_file->file_io_handle ),
770
0
         error ) != 1 )
771
0
    {
772
0
      libcerror_error_set(
773
0
       error,
774
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
775
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
776
0
       "%s: unable to free file IO handle.",
777
0
       function );
778
779
0
      result = -1;
780
0
    }
781
0
    internal_file->file_io_handle_created_in_library = 0;
782
0
  }
783
85
  internal_file->file_io_handle = NULL;
784
785
85
  if( libexe_io_handle_clear(
786
85
       internal_file->io_handle,
787
85
       error ) != 1 )
788
0
  {
789
0
    libcerror_error_set(
790
0
     error,
791
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
792
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
793
0
     "%s: unable to clear IO handle.",
794
0
     function );
795
796
0
    result = -1;
797
0
  }
798
85
  if( libcdata_array_resize(
799
85
       internal_file->sections_array,
800
85
       0,
801
85
       (int (*)(intptr_t **, libcerror_error_t **)) &libexe_section_descriptor_free,
802
85
       error ) != 1 )
803
0
  {
804
0
    libcerror_error_set(
805
0
     error,
806
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
807
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
808
0
     "%s: unable to resize sections array.",
809
0
     function );
810
811
0
    result = -1;
812
0
  }
813
85
  return( result );
814
85
}
815
816
/* Opens a file for reading
817
 * Returns 1 if successful or -1 on error
818
 */
819
int libexe_file_open_read(
820
     libexe_internal_file_t *internal_file,
821
     libbfio_handle_t *file_io_handle,
822
     libcerror_error_t **error )
823
899
{
824
899
  libexe_data_directory_descriptor_t *data_directory_descriptor = NULL;
825
899
  libexe_debug_data_t *debug_data                               = NULL;
826
899
  libexe_export_table_t *export_table                           = NULL;
827
899
  libexe_import_table_t *import_table                           = NULL;
828
899
  static char *function                                         = "libexe_file_open_read";
829
899
  off64_t file_offset                                           = 0;
830
899
  uint16_t number_of_sections                                   = 0;
831
832
899
  if( internal_file == NULL )
833
0
  {
834
0
    libcerror_error_set(
835
0
     error,
836
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
837
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
838
0
     "%s: invalid file.",
839
0
     function );
840
841
0
    return( -1 );
842
0
  }
843
899
  if( internal_file->io_handle == NULL )
844
0
  {
845
0
    libcerror_error_set(
846
0
     error,
847
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
848
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
849
0
     "%s: invalid file - missing IO handle.",
850
0
     function );
851
852
0
    return( -1 );
853
0
  }
854
899
  if( internal_file->io_handle->abort != 0 )
855
0
  {
856
0
    internal_file->io_handle->abort = 0;
857
0
  }
858
#if defined( HAVE_DEBUG_OUTPUT )
859
  if( libcnotify_verbose != 0 )
860
  {
861
    libcnotify_printf(
862
     "Reading file header:\n" );
863
  }
864
#endif
865
899
  if( libexe_io_handle_read_file_header(
866
899
       internal_file->io_handle,
867
899
       file_io_handle,
868
899
       &number_of_sections,
869
899
       error ) != 1 )
870
296
  {
871
296
    libcerror_error_set(
872
296
     error,
873
296
     LIBCERROR_ERROR_DOMAIN_IO,
874
296
     LIBCERROR_IO_ERROR_READ_FAILED,
875
296
     "%s: unable to read file header.",
876
296
     function );
877
878
296
    goto on_error;
879
296
  }
880
603
  if( number_of_sections > 0 )
881
517
  {
882
#if defined( HAVE_DEBUG_OUTPUT )
883
    if( libcnotify_verbose != 0 )
884
    {
885
      libcnotify_printf(
886
       "Reading section table:\n" );
887
    }
888
#endif
889
517
    if( libexe_io_handle_read_section_table(
890
517
         internal_file->io_handle,
891
517
         file_io_handle,
892
517
         number_of_sections,
893
517
         internal_file->sections_array,
894
517
         error ) != 1 )
895
75
    {
896
75
      libcerror_error_set(
897
75
       error,
898
75
       LIBCERROR_ERROR_DOMAIN_IO,
899
75
       LIBCERROR_IO_ERROR_READ_FAILED,
900
75
       "%s: unable to read section table.",
901
75
       function );
902
903
75
      goto on_error;
904
75
    }
905
517
  }
906
528
  if( internal_file->io_handle->coff_optional_header != NULL )
907
454
  {
908
454
    data_directory_descriptor = &( internal_file->io_handle->coff_optional_header->data_directories[ LIBEXE_DATA_DIRECTORY_EXPORT_TABLE ] );
909
910
454
    if( data_directory_descriptor->size > 0 )
911
233
    {
912
233
      if( libexe_file_get_offset_by_relative_virtual_address(
913
233
           internal_file,
914
233
           data_directory_descriptor->virtual_address,
915
233
           &file_offset,
916
233
           error ) != 1 )
917
29
      {
918
29
        libcerror_error_set(
919
29
         error,
920
29
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
921
29
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
922
29
         "%s: unable to retrieve offset for relative virtual address: 0x%08" PRIx32 ".",
923
29
         function,
924
29
         data_directory_descriptor->virtual_address );
925
926
29
        goto on_error;
927
29
      }
928
204
      if( libexe_export_table_initialize(
929
204
           &export_table,
930
204
           error ) != 1 )
931
0
      {
932
0
        libcerror_error_set(
933
0
         error,
934
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
935
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
936
0
         "%s: unable to create export table.",
937
0
         function );
938
939
0
        goto on_error;
940
0
      }
941
204
      if( libexe_export_table_read(
942
204
           export_table,
943
204
           file_io_handle,
944
204
           file_offset,
945
204
           data_directory_descriptor->size,
946
204
           error ) != 1 )
947
120
      {
948
120
        libcerror_error_set(
949
120
         error,
950
120
         LIBCERROR_ERROR_DOMAIN_IO,
951
120
         LIBCERROR_IO_ERROR_READ_FAILED,
952
120
         "%s: unable to read export table.",
953
120
         function );
954
955
120
        goto on_error;
956
120
      }
957
84
      if( libexe_export_table_free(
958
84
           &export_table,
959
84
           error ) != 1 )
960
0
      {
961
0
        libcerror_error_set(
962
0
         error,
963
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
964
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
965
0
         "%s: unable to free export table.",
966
0
         function );
967
968
0
        goto on_error;
969
0
      }
970
84
    }
971
305
    data_directory_descriptor = &( internal_file->io_handle->coff_optional_header->data_directories[ LIBEXE_DATA_DIRECTORY_IMPORT_TABLE ] );
972
973
305
    if( data_directory_descriptor->size > 0 )
974
176
    {
975
176
      if( libexe_file_get_offset_by_relative_virtual_address(
976
176
           internal_file,
977
176
           data_directory_descriptor->virtual_address,
978
176
           &file_offset,
979
176
           error ) != 1 )
980
41
      {
981
41
        libcerror_error_set(
982
41
         error,
983
41
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
984
41
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
985
41
         "%s: unable to retrieve offset for relative virtual address: 0x%08" PRIx32 ".",
986
41
         function,
987
41
         data_directory_descriptor->virtual_address );
988
989
41
        goto on_error;
990
41
      }
991
135
      if( libexe_import_table_initialize(
992
135
           &import_table,
993
135
           error ) != 1 )
994
0
      {
995
0
        libcerror_error_set(
996
0
         error,
997
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
998
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
999
0
         "%s: unable to create import table.",
1000
0
         function );
1001
1002
0
        goto on_error;
1003
0
      }
1004
135
      if( libexe_import_table_read(
1005
135
           import_table,
1006
135
           file_io_handle,
1007
135
           file_offset,
1008
135
           data_directory_descriptor->size,
1009
135
           error ) != 1 )
1010
93
      {
1011
93
        libcerror_error_set(
1012
93
         error,
1013
93
         LIBCERROR_ERROR_DOMAIN_IO,
1014
93
         LIBCERROR_IO_ERROR_READ_FAILED,
1015
93
         "%s: unable to read import table.",
1016
93
         function );
1017
1018
93
        goto on_error;
1019
93
      }
1020
42
      if( libexe_import_table_free(
1021
42
           &import_table,
1022
42
           error ) != 1 )
1023
0
      {
1024
0
        libcerror_error_set(
1025
0
         error,
1026
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1027
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1028
0
         "%s: unable to free import table.",
1029
0
         function );
1030
1031
0
        goto on_error;
1032
0
      }
1033
42
    }
1034
171
    data_directory_descriptor = &( internal_file->io_handle->coff_optional_header->data_directories[ LIBEXE_DATA_DIRECTORY_DEBUG_DATA ] );
1035
1036
171
    if( data_directory_descriptor->size > 0 )
1037
162
    {
1038
162
      if( libexe_file_get_offset_by_relative_virtual_address(
1039
162
           internal_file,
1040
162
           data_directory_descriptor->virtual_address,
1041
162
           &file_offset,
1042
162
           error ) != 1 )
1043
44
      {
1044
44
        libcerror_error_set(
1045
44
         error,
1046
44
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1047
44
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1048
44
         "%s: unable to retrieve offset for relative virtual address: 0x%08" PRIx32 ".",
1049
44
         function,
1050
44
         data_directory_descriptor->virtual_address );
1051
1052
44
        goto on_error;
1053
44
      }
1054
118
      if( libexe_debug_data_initialize(
1055
118
           &debug_data,
1056
118
           error ) != 1 )
1057
0
      {
1058
0
        libcerror_error_set(
1059
0
         error,
1060
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1061
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1062
0
         "%s: unable to create debug data.",
1063
0
         function );
1064
1065
0
        goto on_error;
1066
0
      }
1067
118
      if( libexe_debug_data_read(
1068
118
           debug_data,
1069
118
           file_io_handle,
1070
118
           file_offset,
1071
118
           data_directory_descriptor->size,
1072
118
           error ) != 1 )
1073
116
      {
1074
116
        libcerror_error_set(
1075
116
         error,
1076
116
         LIBCERROR_ERROR_DOMAIN_IO,
1077
116
         LIBCERROR_IO_ERROR_READ_FAILED,
1078
116
         "%s: unable to read debug data.",
1079
116
         function );
1080
1081
116
        goto on_error;
1082
116
      }
1083
2
      if( libexe_debug_data_free(
1084
2
           &debug_data,
1085
2
           error ) != 1 )
1086
0
      {
1087
0
        libcerror_error_set(
1088
0
         error,
1089
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1090
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1091
0
         "%s: unable to free debug data.",
1092
0
         function );
1093
1094
0
        goto on_error;
1095
0
      }
1096
2
    }
1097
171
  }
1098
85
  return( 1 );
1099
1100
814
on_error:
1101
814
  if( debug_data != NULL )
1102
116
  {
1103
116
    libexe_debug_data_free(
1104
116
     &debug_data,
1105
116
     NULL );
1106
116
  }
1107
814
  if( import_table != NULL )
1108
93
  {
1109
93
    libexe_import_table_free(
1110
93
     &import_table,
1111
93
     NULL );
1112
93
  }
1113
814
  if( export_table != NULL )
1114
120
  {
1115
120
    libexe_export_table_free(
1116
120
     &export_table,
1117
120
     NULL );
1118
120
  }
1119
814
  return( -1 );
1120
528
}
1121
1122
/* Retrieves the file ASCII codepage
1123
 * Returns 1 if successful or -1 on error
1124
 */
1125
int libexe_file_get_ascii_codepage(
1126
     libexe_file_t *file,
1127
     int *ascii_codepage,
1128
     libcerror_error_t **error )
1129
0
{
1130
0
  libexe_internal_file_t *internal_file = NULL;
1131
0
  static char *function                 = "libexe_file_get_ascii_codepage";
1132
1133
0
  if( file == NULL )
1134
0
  {
1135
0
    libcerror_error_set(
1136
0
     error,
1137
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1138
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1139
0
     "%s: invalid file.",
1140
0
     function );
1141
1142
0
    return( -1 );
1143
0
  }
1144
0
  internal_file = (libexe_internal_file_t *) file;
1145
1146
0
  if( internal_file->io_handle == NULL )
1147
0
  {
1148
0
    libcerror_error_set(
1149
0
     error,
1150
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1151
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1152
0
     "%s: invalid file - missing IO handle.",
1153
0
     function );
1154
1155
0
    return( -1 );
1156
0
  }
1157
0
  if( ascii_codepage == NULL )
1158
0
  {
1159
0
    libcerror_error_set(
1160
0
     error,
1161
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1162
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1163
0
     "%s: invalid ASCII codepage.",
1164
0
     function );
1165
1166
0
    return( -1 );
1167
0
  }
1168
0
  *ascii_codepage = internal_file->io_handle->ascii_codepage;
1169
1170
0
  return( 1 );
1171
0
}
1172
1173
/* Sets the file ASCII codepage
1174
 * Returns 1 if successful or -1 on error
1175
 */
1176
int libexe_file_set_ascii_codepage(
1177
     libexe_file_t *file,
1178
     int ascii_codepage,
1179
     libcerror_error_t **error )
1180
0
{
1181
0
  libexe_internal_file_t *internal_file = NULL;
1182
0
  static char *function                 = "libexe_file_set_ascii_codepage";
1183
1184
0
  if( file == NULL )
1185
0
  {
1186
0
    libcerror_error_set(
1187
0
     error,
1188
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1189
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1190
0
     "%s: invalid file.",
1191
0
     function );
1192
1193
0
    return( -1 );
1194
0
  }
1195
0
  internal_file = (libexe_internal_file_t *) file;
1196
1197
0
  if( internal_file->io_handle == NULL )
1198
0
  {
1199
0
    libcerror_error_set(
1200
0
     error,
1201
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1202
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1203
0
     "%s: invalid file - missing IO handle.",
1204
0
     function );
1205
1206
0
    return( -1 );
1207
0
  }
1208
0
  if( ( ascii_codepage != LIBEXE_CODEPAGE_ASCII )
1209
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_874 )
1210
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_932 )
1211
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_936 )
1212
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_949 )
1213
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_950 )
1214
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_1250 )
1215
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_1251 )
1216
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_1252 )
1217
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_1253 )
1218
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_1254 )
1219
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_1255 )
1220
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_1256 )
1221
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_1257 )
1222
0
   && ( ascii_codepage != LIBEXE_CODEPAGE_WINDOWS_1258 ) )
1223
0
  {
1224
0
    libcerror_error_set(
1225
0
     error,
1226
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1227
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1228
0
     "%s: unsupported ASCII codepage.",
1229
0
     function );
1230
1231
0
    return( -1 );
1232
0
  }
1233
0
  internal_file->io_handle->ascii_codepage = ascii_codepage;
1234
1235
0
  return( 1 );
1236
0
}
1237
1238
/* Retrieves offset of a relative virtual address
1239
 * Returns 1 if successful, 0 if no such section or -1 on error
1240
 */
1241
int libexe_file_get_offset_by_relative_virtual_address(
1242
     libexe_internal_file_t *internal_file,
1243
     uint32_t virtual_address,
1244
     off64_t *offset,
1245
     libcerror_error_t **error )
1246
571
{
1247
571
  libexe_section_descriptor_t *section_descriptor = NULL;
1248
571
  static char *function                           = "libexe_file_get_offset_by_relative_virtual_address";
1249
571
  size64_t section_size                           = 0;
1250
571
  int number_of_sections                          = 0;
1251
571
  int section_index                               = 0;
1252
1253
571
  if( internal_file == NULL )
1254
0
  {
1255
0
    libcerror_error_set(
1256
0
     error,
1257
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1258
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1259
0
     "%s: invalid file.",
1260
0
     function );
1261
1262
0
    return( -1 );
1263
0
  }
1264
571
  if( offset == NULL )
1265
0
  {
1266
0
    libcerror_error_set(
1267
0
     error,
1268
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1269
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1270
0
     "%s: invalid offset.",
1271
0
     function );
1272
1273
0
    return( -1 );
1274
0
  }
1275
571
  if( libcdata_array_get_number_of_entries(
1276
571
       internal_file->sections_array,
1277
571
       &number_of_sections,
1278
571
       error ) != 1 )
1279
0
  {
1280
0
    libcerror_error_set(
1281
0
     error,
1282
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1283
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1284
0
     "%s: unable to retrieve number of sections.",
1285
0
     function );
1286
1287
0
    return( -1 );
1288
0
  }
1289
571
  for( section_index = 0;
1290
37.4k
       section_index < number_of_sections;
1291
36.9k
       section_index++ )
1292
37.3k
  {
1293
37.3k
    if( libcdata_array_get_entry_by_index(
1294
37.3k
         internal_file->sections_array,
1295
37.3k
         section_index,
1296
37.3k
         (intptr_t **) &section_descriptor,
1297
37.3k
         error ) != 1 )
1298
0
    {
1299
0
      libcerror_error_set(
1300
0
       error,
1301
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1302
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1303
0
       "%s: unable to retrieve section descriptor: %d.",
1304
0
       function,
1305
0
       section_index );
1306
1307
0
      return( -1 );
1308
0
    }
1309
37.3k
    if( libexe_section_descriptor_get_data_range(
1310
37.3k
         section_descriptor,
1311
37.3k
         offset,
1312
37.3k
         &section_size,
1313
37.3k
         error ) != 1 )
1314
0
    {
1315
0
      libcerror_error_set(
1316
0
       error,
1317
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1318
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1319
0
       "%s: unable to retrieve section descriptor: %d data range.",
1320
0
       function,
1321
0
       section_index );
1322
1323
0
      return( -1 );
1324
0
    }
1325
37.3k
    if( ( virtual_address >= section_descriptor->virtual_address )
1326
37.3k
     && ( ( virtual_address - section_descriptor->virtual_address ) < section_size ) )
1327
457
    {
1328
457
      *offset += virtual_address - section_descriptor->virtual_address;
1329
1330
457
      return( 1 );
1331
457
    }
1332
37.3k
  }
1333
114
  *offset = 0;
1334
1335
114
  return( 0 );
1336
571
}
1337
1338
/* Retrieves the number of sections
1339
 * Returns 1 if successful or -1 on error
1340
 */
1341
int libexe_file_get_number_of_sections(
1342
     libexe_file_t *file,
1343
     int *number_of_sections,
1344
     libcerror_error_t **error )
1345
0
{
1346
0
  libexe_internal_file_t *internal_file = NULL;
1347
0
  static char *function                 = "libexe_file_get_number_of_sections";
1348
1349
0
  if( file == NULL )
1350
0
  {
1351
0
    libcerror_error_set(
1352
0
     error,
1353
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1354
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1355
0
     "%s: invalid file.",
1356
0
     function );
1357
1358
0
    return( -1 );
1359
0
  }
1360
0
  internal_file = (libexe_internal_file_t *) file;
1361
1362
0
  if( libcdata_array_get_number_of_entries(
1363
0
       internal_file->sections_array,
1364
0
       number_of_sections,
1365
0
       error ) != 1 )
1366
0
  {
1367
0
    libcerror_error_set(
1368
0
     error,
1369
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1370
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1371
0
     "%s: unable to retrieve number of sections.",
1372
0
     function );
1373
1374
0
    return( -1 );
1375
0
  }
1376
0
  return( 1 );
1377
0
}
1378
1379
/* Retrieves a specific section
1380
 * Returns 1 if successful or -1 on error
1381
 */
1382
int libexe_file_get_section(
1383
     libexe_file_t *file,
1384
     int section_index,
1385
     libexe_section_t **section,
1386
     libcerror_error_t **error )
1387
0
{
1388
0
  libexe_internal_file_t *internal_file           = NULL;
1389
0
  libexe_section_descriptor_t *section_descriptor = NULL;
1390
0
  static char *function                           = "libexe_file_get_section";
1391
1392
0
  if( file == NULL )
1393
0
  {
1394
0
    libcerror_error_set(
1395
0
     error,
1396
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1397
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1398
0
     "%s: invalid file.",
1399
0
     function );
1400
1401
0
    return( -1 );
1402
0
  }
1403
0
  internal_file = (libexe_internal_file_t *) file;
1404
1405
0
  if( section == NULL )
1406
0
  {
1407
0
    libcerror_error_set(
1408
0
     error,
1409
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1410
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1411
0
     "%s: invalid section.",
1412
0
     function );
1413
1414
0
    return( -1 );
1415
0
  }
1416
0
  if( *section != NULL )
1417
0
  {
1418
0
    libcerror_error_set(
1419
0
     error,
1420
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1421
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1422
0
     "%s: invalid section value already set.",
1423
0
     function );
1424
1425
0
    return( -1 );
1426
0
  }
1427
0
  if( libcdata_array_get_entry_by_index(
1428
0
       internal_file->sections_array,
1429
0
       section_index,
1430
0
       (intptr_t **) &section_descriptor,
1431
0
       error ) != 1 )
1432
0
  {
1433
0
    libcerror_error_set(
1434
0
     error,
1435
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1436
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1437
0
     "%s: unable to retrieve section descriptor: %d.",
1438
0
     function,
1439
0
     section_index );
1440
1441
0
    return( -1 );
1442
0
  }
1443
0
  if( libexe_section_initialize(
1444
0
       section,
1445
0
       internal_file->io_handle,
1446
0
       internal_file->file_io_handle,
1447
0
       section_descriptor,
1448
0
       error ) != 1 )
1449
0
  {
1450
0
    libcerror_error_set(
1451
0
     error,
1452
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1453
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1454
0
     "%s: unable to create section.",
1455
0
     function );
1456
1457
0
    return( -1 );
1458
0
  }
1459
0
  return( 1 );
1460
0
}
1461
1462
/* Retrieves a specific section
1463
 * Returns 1 if successful or -1 on error
1464
 */
1465
int libexe_file_get_section_by_index(
1466
     libexe_file_t *file,
1467
     int section_index,
1468
     libexe_section_t **section,
1469
     libcerror_error_t **error )
1470
0
{
1471
0
  libexe_internal_file_t *internal_file           = NULL;
1472
0
  libexe_section_descriptor_t *section_descriptor = NULL;
1473
0
  static char *function                           = "libexe_file_get_section_by_index";
1474
1475
0
  if( file == NULL )
1476
0
  {
1477
0
    libcerror_error_set(
1478
0
     error,
1479
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1480
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1481
0
     "%s: invalid file.",
1482
0
     function );
1483
1484
0
    return( -1 );
1485
0
  }
1486
0
  internal_file = (libexe_internal_file_t *) file;
1487
1488
0
  if( section == NULL )
1489
0
  {
1490
0
    libcerror_error_set(
1491
0
     error,
1492
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1493
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1494
0
     "%s: invalid section.",
1495
0
     function );
1496
1497
0
    return( -1 );
1498
0
  }
1499
0
  if( *section != NULL )
1500
0
  {
1501
0
    libcerror_error_set(
1502
0
     error,
1503
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1504
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1505
0
     "%s: invalid section value already set.",
1506
0
     function );
1507
1508
0
    return( -1 );
1509
0
  }
1510
0
  if( libcdata_array_get_entry_by_index(
1511
0
       internal_file->sections_array,
1512
0
       section_index,
1513
0
       (intptr_t **) &section_descriptor,
1514
0
       error ) != 1 )
1515
0
  {
1516
0
    libcerror_error_set(
1517
0
     error,
1518
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1519
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1520
0
     "%s: unable to retrieve section descriptor: %d.",
1521
0
     function,
1522
0
     section_index );
1523
1524
0
    return( -1 );
1525
0
  }
1526
0
  if( libexe_section_initialize(
1527
0
       section,
1528
0
       internal_file->io_handle,
1529
0
       internal_file->file_io_handle,
1530
0
       section_descriptor,
1531
0
       error ) != 1 )
1532
0
  {
1533
0
    libcerror_error_set(
1534
0
     error,
1535
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1536
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1537
0
     "%s: unable to create section.",
1538
0
     function );
1539
1540
0
    return( -1 );
1541
0
  }
1542
0
  return( 1 );
1543
0
}
1544
1545
/* Retrieves a specific section by an ASCII formatted name
1546
 * Returns 1 if successful, 0 if no such section or -1 on error
1547
 */
1548
int libexe_file_get_section_by_name(
1549
     libexe_file_t *file,
1550
     const char *string,
1551
     size_t string_length,
1552
     libexe_section_t **section,
1553
     libcerror_error_t **error )
1554
0
{
1555
0
  libexe_internal_file_t *internal_file           = NULL;
1556
0
  libexe_section_descriptor_t *section_descriptor = NULL;
1557
0
  static char *function                           = "libexe_file_get_section_by_name";
1558
0
  int number_of_sections                          = 0;
1559
0
  int section_index                               = 0;
1560
1561
0
  if( file == NULL )
1562
0
  {
1563
0
    libcerror_error_set(
1564
0
     error,
1565
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1566
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1567
0
     "%s: invalid file.",
1568
0
     function );
1569
1570
0
    return( -1 );
1571
0
  }
1572
0
  internal_file = (libexe_internal_file_t *) file;
1573
1574
0
  if( string == NULL )
1575
0
  {
1576
0
    libcerror_error_set(
1577
0
     error,
1578
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1579
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1580
0
     "%s: invalid string.",
1581
0
     function );
1582
1583
0
    return( -1 );
1584
0
  }
1585
0
  if( string_length > (size_t) SSIZE_MAX )
1586
0
  {
1587
0
    libcerror_error_set(
1588
0
     error,
1589
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1590
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1591
0
     "%s: invalid string length value exceeds maximum.",
1592
0
     function );
1593
1594
0
    return( -1 );
1595
0
  }
1596
0
  if( section == NULL )
1597
0
  {
1598
0
    libcerror_error_set(
1599
0
     error,
1600
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1601
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1602
0
     "%s: invalid section.",
1603
0
     function );
1604
1605
0
    return( -1 );
1606
0
  }
1607
0
  if( *section != NULL )
1608
0
  {
1609
0
    libcerror_error_set(
1610
0
     error,
1611
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1612
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1613
0
     "%s: invalid section value already set.",
1614
0
     function );
1615
1616
0
    return( -1 );
1617
0
  }
1618
0
  if( libcdata_array_get_number_of_entries(
1619
0
       internal_file->sections_array,
1620
0
       &number_of_sections,
1621
0
       error ) != 1 )
1622
0
  {
1623
0
    libcerror_error_set(
1624
0
     error,
1625
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1626
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1627
0
     "%s: unable to retrieve number of sections.",
1628
0
     function );
1629
1630
0
    return( -1 );
1631
0
  }
1632
0
  for( section_index = 0;
1633
0
       section_index < number_of_sections;
1634
0
       section_index++ )
1635
0
  {
1636
0
    if( libcdata_array_get_entry_by_index(
1637
0
         internal_file->sections_array,
1638
0
         section_index,
1639
0
         (intptr_t **) &section_descriptor,
1640
0
         error ) != 1 )
1641
0
    {
1642
0
      libcerror_error_set(
1643
0
       error,
1644
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1645
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1646
0
       "%s: unable to retrieve section descriptor: %d.",
1647
0
       function,
1648
0
       section_index );
1649
1650
0
      return( -1 );
1651
0
    }
1652
0
    if( section_descriptor == NULL )
1653
0
    {
1654
0
      libcerror_error_set(
1655
0
       error,
1656
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1657
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1658
0
       "%s: missing section descriptor: %d.",
1659
0
       function,
1660
0
       section_index );
1661
1662
0
      return( -1 );
1663
0
    }
1664
0
    if( ( string_length + 1 ) == section_descriptor->name_size )
1665
0
    {
1666
0
      if( narrow_string_compare(
1667
0
           section_descriptor->name,
1668
0
           string,
1669
0
           string_length ) == 0 )
1670
0
      {
1671
0
        if( libexe_section_initialize(
1672
0
             section,
1673
0
             internal_file->io_handle,
1674
0
             internal_file->file_io_handle,
1675
0
             section_descriptor,
1676
0
             error ) != 1 )
1677
0
        {
1678
0
          libcerror_error_set(
1679
0
           error,
1680
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1681
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1682
0
           "%s: unable to create section.",
1683
0
           function );
1684
1685
0
          return( -1 );
1686
0
        }
1687
0
        return( 1 );
1688
0
      }
1689
0
    }
1690
0
  }
1691
0
  return( 0 );
1692
0
}
1693