Coverage Report

Created: 2025-06-13 07:22

/src/libevt/libevt/libevt_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 "libevt_codepage.h"
29
#include "libevt_debug.h"
30
#include "libevt_definitions.h"
31
#include "libevt_io_handle.h"
32
#include "libevt_file.h"
33
#include "libevt_file_header.h"
34
#include "libevt_libbfio.h"
35
#include "libevt_libcerror.h"
36
#include "libevt_libcnotify.h"
37
#include "libevt_libcthreads.h"
38
#include "libevt_libfcache.h"
39
#include "libevt_libfdata.h"
40
#include "libevt_record.h"
41
#include "libevt_record_values.h"
42
43
#include "evt_file_header.h"
44
45
/* Creates a file
46
 * Make sure the value file is referencing, is set to NULL
47
 * Returns 1 if successful or -1 on error
48
 */
49
int libevt_file_initialize(
50
     libevt_file_t **file,
51
     libcerror_error_t **error )
52
1.81k
{
53
1.81k
  libevt_internal_file_t *internal_file = NULL;
54
1.81k
  static char *function                 = "libevt_file_initialize";
55
56
1.81k
  if( file == NULL )
57
0
  {
58
0
    libcerror_error_set(
59
0
     error,
60
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
61
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
62
0
     "%s: invalid file.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
1.81k
  if( *file != NULL )
68
0
  {
69
0
    libcerror_error_set(
70
0
     error,
71
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
72
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
73
0
     "%s: invalid file value already set.",
74
0
     function );
75
76
0
    return( -1 );
77
0
  }
78
1.81k
  internal_file = memory_allocate_structure(
79
1.81k
                   libevt_internal_file_t );
80
81
1.81k
  if( internal_file == NULL )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
86
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
87
0
     "%s: unable to create file.",
88
0
     function );
89
90
0
    goto on_error;
91
0
  }
92
1.81k
  if( memory_set(
93
1.81k
       internal_file,
94
1.81k
       0,
95
1.81k
       sizeof( libevt_internal_file_t ) ) == NULL )
96
0
  {
97
0
    libcerror_error_set(
98
0
     error,
99
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
100
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
101
0
     "%s: unable to clear file.",
102
0
     function );
103
104
0
    memory_free(
105
0
     internal_file );
106
107
0
    return( -1 );
108
0
  }
109
1.81k
  if( libevt_io_handle_initialize(
110
1.81k
       &( internal_file->io_handle ),
111
1.81k
       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 IO handle.",
118
0
     function );
119
120
0
    goto on_error;
121
0
  }
122
1.81k
  if( libfdata_list_initialize(
123
1.81k
       &( internal_file->records_list ),
124
1.81k
       (intptr_t *) internal_file->io_handle,
125
1.81k
       NULL,
126
1.81k
       NULL,
127
1.81k
       (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevt_record_values_read_element_data,
128
1.81k
       NULL,
129
1.81k
       LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
130
1.81k
       error ) != 1 )
131
0
  {
132
0
    libcerror_error_set(
133
0
     error,
134
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
135
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
136
0
     "%s: unable to create records list.",
137
0
     function );
138
139
0
    goto on_error;
140
0
  }
141
1.81k
  if( libfdata_list_initialize(
142
1.81k
       &( internal_file->recovered_records_list ),
143
1.81k
       (intptr_t *) internal_file->io_handle,
144
1.81k
       NULL,
145
1.81k
       NULL,
146
1.81k
       (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevt_record_values_read_element_data,
147
1.81k
       NULL,
148
1.81k
       LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
149
1.81k
       error ) != 1 )
150
0
  {
151
0
    libcerror_error_set(
152
0
     error,
153
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
154
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
155
0
     "%s: unable to create recovered records list.",
156
0
     function );
157
158
0
    goto on_error;
159
0
  }
160
1.81k
  if( libfcache_cache_initialize(
161
1.81k
       &( internal_file->records_cache ),
162
1.81k
       LIBEVT_MAXIMUM_CACHE_ENTRIES_RECORDS,
163
1.81k
       error ) != 1 )
164
0
  {
165
0
    libcerror_error_set(
166
0
     error,
167
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
168
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
169
0
     "%s: unable to create records cache.",
170
0
     function );
171
172
0
    goto on_error;
173
0
  }
174
1.81k
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
175
1.81k
  if( libcthreads_read_write_lock_initialize(
176
1.81k
       &( internal_file->read_write_lock ),
177
1.81k
       error ) != 1 )
178
0
  {
179
0
    libcerror_error_set(
180
0
     error,
181
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
182
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
183
0
     "%s: unable to initialize read/write lock.",
184
0
     function );
185
186
0
    goto on_error;
187
0
  }
188
1.81k
#endif
189
1.81k
  *file = (libevt_file_t *) internal_file;
190
191
1.81k
  return( 1 );
192
193
0
on_error:
194
0
  if( internal_file != NULL )
195
0
  {
196
0
    if( internal_file->recovered_records_list != NULL )
197
0
    {
198
0
      libfdata_list_free(
199
0
       &( internal_file->recovered_records_list ),
200
0
       NULL );
201
0
    }
202
0
    if( internal_file->records_list != NULL )
203
0
    {
204
0
      libfdata_list_free(
205
0
       &( internal_file->records_list ),
206
0
       NULL );
207
0
    }
208
0
    if( internal_file->io_handle != NULL )
209
0
    {
210
0
      libevt_io_handle_free(
211
0
       &( internal_file->io_handle ),
212
0
       NULL );
213
0
    }
214
0
    memory_free(
215
0
     internal_file );
216
0
  }
217
0
  return( -1 );
218
1.81k
}
219
220
/* Frees a file
221
 * Returns 1 if successful or -1 on error
222
 */
223
int libevt_file_free(
224
     libevt_file_t **file,
225
     libcerror_error_t **error )
226
1.81k
{
227
1.81k
  libevt_internal_file_t *internal_file = NULL;
228
1.81k
  static char *function                 = "libevt_file_free";
229
1.81k
  int result                            = 1;
230
231
1.81k
  if( file == NULL )
232
0
  {
233
0
    libcerror_error_set(
234
0
     error,
235
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
236
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
237
0
     "%s: invalid file.",
238
0
     function );
239
240
0
    return( -1 );
241
0
  }
242
1.81k
  if( *file != NULL )
243
1.81k
  {
244
1.81k
    internal_file = (libevt_internal_file_t *) *file;
245
246
1.81k
    if( internal_file->file_io_handle != NULL )
247
0
    {
248
0
      if( libevt_file_close(
249
0
           *file,
250
0
           error ) != 0 )
251
0
      {
252
0
        libcerror_error_set(
253
0
         error,
254
0
         LIBCERROR_ERROR_DOMAIN_IO,
255
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
256
0
         "%s: unable to close file.",
257
0
         function );
258
259
0
        result = -1;
260
0
      }
261
0
    }
262
1.81k
    *file = NULL;
263
264
1.81k
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
265
1.81k
    if( libcthreads_read_write_lock_free(
266
1.81k
         &( internal_file->read_write_lock ),
267
1.81k
         error ) != 1 )
268
0
    {
269
0
      libcerror_error_set(
270
0
       error,
271
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
272
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
273
0
       "%s: unable to free read/write lock.",
274
0
       function );
275
276
0
      result = -1;
277
0
    }
278
1.81k
#endif
279
1.81k
    if( libfcache_cache_free(
280
1.81k
         &( internal_file->records_cache ),
281
1.81k
         error ) != 1 )
282
0
    {
283
0
      libcerror_error_set(
284
0
       error,
285
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
286
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
287
0
       "%s: unable to free records cache.",
288
0
       function );
289
290
0
      result = -1;
291
0
    }
292
1.81k
    if( libfdata_list_free(
293
1.81k
         &( internal_file->recovered_records_list ),
294
1.81k
         error ) != 1 )
295
0
    {
296
0
      libcerror_error_set(
297
0
       error,
298
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
299
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
300
0
       "%s: unable to free recovered records list.",
301
0
       function );
302
303
0
      result = -1;
304
0
    }
305
1.81k
    if( libfdata_list_free(
306
1.81k
         &( internal_file->records_list ),
307
1.81k
         error ) != 1 )
308
0
    {
309
0
      libcerror_error_set(
310
0
       error,
311
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
312
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
313
0
       "%s: unable to free records list.",
314
0
       function );
315
316
0
      result = -1;
317
0
    }
318
1.81k
    if( libevt_io_handle_free(
319
1.81k
         &( internal_file->io_handle ),
320
1.81k
         error ) != 1 )
321
0
    {
322
0
      libcerror_error_set(
323
0
       error,
324
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
325
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
326
0
       "%s: unable to free IO handle.",
327
0
       function );
328
329
0
      result = -1;
330
0
    }
331
1.81k
    memory_free(
332
1.81k
     internal_file );
333
1.81k
  }
334
1.81k
  return( result );
335
1.81k
}
336
337
/* Signals the file to abort its current activity
338
 * Returns 1 if successful or -1 on error
339
 */
340
int libevt_file_signal_abort(
341
     libevt_file_t *file,
342
     libcerror_error_t **error )
343
0
{
344
0
  libevt_internal_file_t *internal_file = NULL;
345
0
  static char *function                 = "libevt_file_signal_abort";
346
347
0
  if( file == NULL )
348
0
  {
349
0
    libcerror_error_set(
350
0
     error,
351
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
352
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
353
0
     "%s: invalid file.",
354
0
     function );
355
356
0
    return( -1 );
357
0
  }
358
0
  internal_file = (libevt_internal_file_t *) file;
359
360
0
  if( internal_file->io_handle == NULL )
361
0
  {
362
0
    libcerror_error_set(
363
0
     error,
364
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
365
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
366
0
     "%s: invalid file - missing IO handle.",
367
0
     function );
368
369
0
    return( -1 );
370
0
  }
371
0
  internal_file->io_handle->abort = 1;
372
373
0
  return( 1 );
374
0
}
375
376
/* Opens a file
377
 * Returns 1 if successful or -1 on error
378
 */
379
int libevt_file_open(
380
     libevt_file_t *file,
381
     const char *filename,
382
     int access_flags,
383
     libcerror_error_t **error )
384
0
{
385
0
  libbfio_handle_t *file_io_handle      = NULL;
386
0
  libevt_internal_file_t *internal_file = NULL;
387
0
  static char *function                 = "libevt_file_open";
388
0
  size_t filename_length                = 0;
389
390
0
  if( file == NULL )
391
0
  {
392
0
    libcerror_error_set(
393
0
     error,
394
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
395
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
396
0
     "%s: invalid file.",
397
0
     function );
398
399
0
    return( -1 );
400
0
  }
401
0
  internal_file = (libevt_internal_file_t *) file;
402
403
0
  if( filename == NULL )
404
0
  {
405
0
    libcerror_error_set(
406
0
     error,
407
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
408
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
409
0
     "%s: invalid filename.",
410
0
     function );
411
412
0
    return( -1 );
413
0
  }
414
0
  if( ( ( access_flags & LIBEVT_ACCESS_FLAG_READ ) == 0 )
415
0
   && ( ( access_flags & LIBEVT_ACCESS_FLAG_WRITE ) == 0 ) )
416
0
  {
417
0
    libcerror_error_set(
418
0
     error,
419
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
420
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
421
0
     "%s: unsupported access flags.",
422
0
     function );
423
424
0
    return( -1 );
425
0
  }
426
0
  if( ( access_flags & LIBEVT_ACCESS_FLAG_WRITE ) != 0 )
427
0
  {
428
0
    libcerror_error_set(
429
0
     error,
430
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
431
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
432
0
     "%s: write access currently not supported.",
433
0
     function );
434
435
0
    return( -1 );
436
0
  }
437
0
  if( libbfio_file_initialize(
438
0
       &file_io_handle,
439
0
       error ) != 1 )
440
0
  {
441
0
    libcerror_error_set(
442
0
     error,
443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
444
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
445
0
     "%s: unable to create file IO handle.",
446
0
     function );
447
448
0
    goto on_error;
449
0
  }
450
#if defined( HAVE_DEBUG_OUTPUT )
451
  if( libbfio_handle_set_track_offsets_read(
452
       file_io_handle,
453
       1,
454
       error ) != 1 )
455
  {
456
                libcerror_error_set(
457
                 error,
458
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
459
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
460
                 "%s: unable to set track offsets read in file IO handle.",
461
                 function );
462
463
    goto on_error;
464
  }
465
#endif
466
0
  filename_length = narrow_string_length(
467
0
                     filename );
468
469
0
  if( libbfio_file_set_name(
470
0
       file_io_handle,
471
0
       filename,
472
0
       filename_length + 1,
473
0
       error ) != 1 )
474
0
  {
475
0
                libcerror_error_set(
476
0
                 error,
477
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
478
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
479
0
                 "%s: unable to set filename in file IO handle.",
480
0
                 function );
481
482
0
    goto on_error;
483
0
  }
484
0
  if( libevt_file_open_file_io_handle(
485
0
       file,
486
0
       file_io_handle,
487
0
       access_flags,
488
0
       error ) != 1 )
489
0
  {
490
0
    libcerror_error_set(
491
0
     error,
492
0
     LIBCERROR_ERROR_DOMAIN_IO,
493
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
494
0
     "%s: unable to open file: %s.",
495
0
     function,
496
0
     filename );
497
498
0
    goto on_error;
499
0
  }
500
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
501
0
  if( libcthreads_read_write_lock_grab_for_write(
502
0
       internal_file->read_write_lock,
503
0
       error ) != 1 )
504
0
  {
505
0
    libcerror_error_set(
506
0
     error,
507
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
508
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
509
0
     "%s: unable to grab read/write lock for writing.",
510
0
     function );
511
512
0
    goto on_error;
513
0
  }
514
0
#endif
515
0
  internal_file->file_io_handle_created_in_library = 1;
516
517
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
518
0
  if( libcthreads_read_write_lock_release_for_write(
519
0
       internal_file->read_write_lock,
520
0
       error ) != 1 )
521
0
  {
522
0
    libcerror_error_set(
523
0
     error,
524
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
525
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
526
0
     "%s: unable to release read/write lock for writing.",
527
0
     function );
528
529
0
    internal_file->file_io_handle_created_in_library = 0;
530
531
0
    goto on_error;
532
0
  }
533
0
#endif
534
0
  return( 1 );
535
536
0
on_error:
537
0
  if( file_io_handle != NULL )
538
0
  {
539
0
    libbfio_handle_free(
540
0
     &file_io_handle,
541
0
     NULL );
542
0
  }
543
0
  return( -1 );
544
0
}
545
546
#if defined( HAVE_WIDE_CHARACTER_TYPE )
547
548
/* Opens a file
549
 * Returns 1 if successful or -1 on error
550
 */
551
int libevt_file_open_wide(
552
     libevt_file_t *file,
553
     const wchar_t *filename,
554
     int access_flags,
555
     libcerror_error_t **error )
556
{
557
  libbfio_handle_t *file_io_handle      = NULL;
558
  libevt_internal_file_t *internal_file = NULL;
559
  static char *function                 = "libevt_file_open_wide";
560
  size_t filename_length                = 0;
561
562
  if( file == NULL )
563
  {
564
    libcerror_error_set(
565
     error,
566
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
567
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
568
     "%s: invalid file.",
569
     function );
570
571
    return( -1 );
572
  }
573
  internal_file = (libevt_internal_file_t *) file;
574
575
  if( filename == NULL )
576
  {
577
    libcerror_error_set(
578
     error,
579
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
580
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
581
     "%s: invalid filename.",
582
     function );
583
584
    return( -1 );
585
  }
586
  if( ( ( access_flags & LIBEVT_ACCESS_FLAG_READ ) == 0 )
587
   && ( ( access_flags & LIBEVT_ACCESS_FLAG_WRITE ) == 0 ) )
588
  {
589
    libcerror_error_set(
590
     error,
591
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
592
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
593
     "%s: unsupported access flags.",
594
     function );
595
596
    return( -1 );
597
  }
598
  if( ( access_flags & LIBEVT_ACCESS_FLAG_WRITE ) != 0 )
599
  {
600
    libcerror_error_set(
601
     error,
602
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
603
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
604
     "%s: write access currently not supported.",
605
     function );
606
607
    return( -1 );
608
  }
609
  if( libbfio_file_initialize(
610
       &file_io_handle,
611
       error ) != 1 )
612
  {
613
    libcerror_error_set(
614
     error,
615
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
616
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
617
     "%s: unable to create file IO handle.",
618
     function );
619
620
    goto on_error;
621
  }
622
#if defined( HAVE_DEBUG_OUTPUT )
623
  if( libbfio_handle_set_track_offsets_read(
624
       file_io_handle,
625
       1,
626
       error ) != 1 )
627
  {
628
                libcerror_error_set(
629
                 error,
630
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
631
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
632
                 "%s: unable to set track offsets read in file IO handle.",
633
                 function );
634
635
    goto on_error;
636
  }
637
#endif
638
  filename_length = wide_string_length(
639
                     filename );
640
641
  if( libbfio_file_set_name_wide(
642
       file_io_handle,
643
       filename,
644
       filename_length + 1,
645
       error ) != 1 )
646
  {
647
                libcerror_error_set(
648
                 error,
649
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
650
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
651
                 "%s: unable to set filename in file IO handle.",
652
                 function );
653
654
    goto on_error;
655
  }
656
  if( libevt_file_open_file_io_handle(
657
       file,
658
       file_io_handle,
659
       access_flags,
660
       error ) != 1 )
661
  {
662
    libcerror_error_set(
663
     error,
664
     LIBCERROR_ERROR_DOMAIN_IO,
665
     LIBCERROR_IO_ERROR_OPEN_FAILED,
666
     "%s: unable to open file: %ls.",
667
     function,
668
     filename );
669
670
    goto on_error;
671
  }
672
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
673
  if( libcthreads_read_write_lock_grab_for_write(
674
       internal_file->read_write_lock,
675
       error ) != 1 )
676
  {
677
    libcerror_error_set(
678
     error,
679
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
680
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
681
     "%s: unable to grab read/write lock for writing.",
682
     function );
683
684
    goto on_error;
685
  }
686
#endif
687
  internal_file->file_io_handle_created_in_library = 1;
688
689
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
690
  if( libcthreads_read_write_lock_release_for_write(
691
       internal_file->read_write_lock,
692
       error ) != 1 )
693
  {
694
    libcerror_error_set(
695
     error,
696
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
697
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
698
     "%s: unable to release read/write lock for writing.",
699
     function );
700
701
    internal_file->file_io_handle_created_in_library = 0;
702
703
    goto on_error;
704
  }
705
#endif
706
  return( 1 );
707
708
on_error:
709
  if( file_io_handle != NULL )
710
  {
711
    libbfio_handle_free(
712
     &file_io_handle,
713
     NULL );
714
  }
715
  return( -1 );
716
}
717
718
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
719
720
/* Opens a file using a Basic File IO (bfio) handle
721
 * Returns 1 if successful or -1 on error
722
 */
723
int libevt_file_open_file_io_handle(
724
     libevt_file_t *file,
725
     libbfio_handle_t *file_io_handle,
726
     int access_flags,
727
     libcerror_error_t **error )
728
1.81k
{
729
1.81k
  libevt_internal_file_t *internal_file    = NULL;
730
1.81k
  static char *function                    = "libevt_file_open_file_io_handle";
731
1.81k
  uint8_t file_io_handle_opened_in_library = 0;
732
1.81k
  int bfio_access_flags                    = 0;
733
1.81k
  int file_io_handle_is_open               = 0;
734
735
1.81k
  if( file == NULL )
736
0
  {
737
0
    libcerror_error_set(
738
0
     error,
739
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
740
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
741
0
     "%s: invalid file.",
742
0
     function );
743
744
0
    return( -1 );
745
0
  }
746
1.81k
  internal_file = (libevt_internal_file_t *) file;
747
748
1.81k
  if( internal_file->file_io_handle != NULL )
749
0
  {
750
0
    libcerror_error_set(
751
0
     error,
752
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
753
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
754
0
     "%s: invalid file - file IO handle already set.",
755
0
     function );
756
757
0
    return( -1 );
758
0
  }
759
1.81k
  if( file_io_handle == NULL )
760
0
  {
761
0
    libcerror_error_set(
762
0
     error,
763
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
764
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
765
0
     "%s: invalid file IO handle.",
766
0
     function );
767
768
0
    return( -1 );
769
0
  }
770
1.81k
  if( ( ( access_flags & LIBEVT_ACCESS_FLAG_READ ) == 0 )
771
1.81k
   && ( ( access_flags & LIBEVT_ACCESS_FLAG_WRITE ) == 0 ) )
772
0
  {
773
0
    libcerror_error_set(
774
0
     error,
775
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
776
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
777
0
     "%s: unsupported access flags.",
778
0
     function );
779
780
0
    return( -1 );
781
0
  }
782
1.81k
  if( ( access_flags & LIBEVT_ACCESS_FLAG_WRITE ) != 0 )
783
0
  {
784
0
    libcerror_error_set(
785
0
     error,
786
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
787
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
788
0
     "%s: write access currently not supported.",
789
0
     function );
790
791
0
    return( -1 );
792
0
  }
793
1.81k
  if( ( access_flags & LIBEVT_ACCESS_FLAG_READ ) != 0 )
794
1.81k
  {
795
1.81k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
796
1.81k
  }
797
1.81k
  file_io_handle_is_open = libbfio_handle_is_open(
798
1.81k
                            file_io_handle,
799
1.81k
                            error );
800
801
1.81k
  if( file_io_handle_is_open == -1 )
802
0
  {
803
0
    libcerror_error_set(
804
0
     error,
805
0
     LIBCERROR_ERROR_DOMAIN_IO,
806
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
807
0
     "%s: unable to determine if file IO handle is open.",
808
0
     function );
809
810
0
    goto on_error;
811
0
  }
812
1.81k
  else if( file_io_handle_is_open == 0 )
813
1.81k
  {
814
1.81k
    if( libbfio_handle_open(
815
1.81k
         file_io_handle,
816
1.81k
         bfio_access_flags,
817
1.81k
         error ) != 1 )
818
0
    {
819
0
      libcerror_error_set(
820
0
       error,
821
0
       LIBCERROR_ERROR_DOMAIN_IO,
822
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
823
0
       "%s: unable to open file IO handle.",
824
0
       function );
825
826
0
      goto on_error;
827
0
    }
828
1.81k
    file_io_handle_opened_in_library = 1;
829
1.81k
  }
830
1.81k
  if( libevt_file_open_read(
831
1.81k
       internal_file,
832
1.81k
       file_io_handle,
833
1.81k
       error ) != 1 )
834
18
  {
835
18
    libcerror_error_set(
836
18
     error,
837
18
     LIBCERROR_ERROR_DOMAIN_IO,
838
18
     LIBCERROR_IO_ERROR_READ_FAILED,
839
18
     "%s: unable to read from file handle.",
840
18
     function );
841
842
18
    goto on_error;
843
18
  }
844
1.79k
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
845
1.79k
  if( libcthreads_read_write_lock_grab_for_write(
846
1.79k
       internal_file->read_write_lock,
847
1.79k
       error ) != 1 )
848
0
  {
849
0
    libcerror_error_set(
850
0
     error,
851
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
852
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
853
0
     "%s: unable to grab read/write lock for writing.",
854
0
     function );
855
856
0
    goto on_error;
857
0
  }
858
1.79k
#endif
859
1.79k
  internal_file->file_io_handle                   = file_io_handle;
860
1.79k
  internal_file->file_io_handle_opened_in_library = file_io_handle_opened_in_library;
861
862
1.79k
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
863
1.79k
  if( libcthreads_read_write_lock_release_for_write(
864
1.79k
       internal_file->read_write_lock,
865
1.79k
       error ) != 1 )
866
0
  {
867
0
    libcerror_error_set(
868
0
     error,
869
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
870
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
871
0
     "%s: unable to release read/write lock for writing.",
872
0
     function );
873
874
0
    internal_file->file_io_handle                   = NULL;
875
0
    internal_file->file_io_handle_opened_in_library = 0;
876
877
0
    goto on_error;
878
0
  }
879
1.79k
#endif
880
1.79k
  return( 1 );
881
882
18
on_error:
883
18
  if( file_io_handle_opened_in_library != 0 )
884
18
  {
885
18
    libbfio_handle_close(
886
18
     file_io_handle,
887
18
     error );
888
18
  }
889
18
  return( -1 );
890
1.79k
}
891
892
/* Closes a file
893
 * Returns 0 if successful or -1 on error
894
 */
895
int libevt_file_close(
896
     libevt_file_t *file,
897
     libcerror_error_t **error )
898
1.79k
{
899
1.79k
  libevt_internal_file_t *internal_file = NULL;
900
1.79k
  static char *function                 = "libevt_file_close";
901
1.79k
  int result                            = 0;
902
903
1.79k
  if( file == NULL )
904
0
  {
905
0
    libcerror_error_set(
906
0
     error,
907
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
908
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
909
0
     "%s: invalid file.",
910
0
     function );
911
912
0
    return( -1 );
913
0
  }
914
1.79k
  internal_file = (libevt_internal_file_t *) file;
915
916
1.79k
  if( internal_file->file_io_handle == NULL )
917
0
  {
918
0
    libcerror_error_set(
919
0
     error,
920
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
921
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
922
0
     "%s: invalid file - missing file IO handle.",
923
0
     function );
924
925
0
    return( -1 );
926
0
  }
927
1.79k
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
928
1.79k
  if( libcthreads_read_write_lock_grab_for_write(
929
1.79k
       internal_file->read_write_lock,
930
1.79k
       error ) != 1 )
931
0
  {
932
0
    libcerror_error_set(
933
0
     error,
934
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
935
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
936
0
     "%s: unable to grab read/write lock for writing.",
937
0
     function );
938
939
0
    return( -1 );
940
0
  }
941
1.79k
#endif
942
#if defined( HAVE_DEBUG_OUTPUT )
943
  if( libcnotify_verbose != 0 )
944
  {
945
    if( internal_file->file_io_handle_created_in_library != 0 )
946
    {
947
      if( libevt_debug_print_read_offsets(
948
           internal_file->file_io_handle,
949
           error ) != 1 )
950
      {
951
        libcerror_error_set(
952
         error,
953
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
954
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
955
         "%s: unable to print the read offsets.",
956
         function );
957
958
        result = -1;
959
      }
960
    }
961
  }
962
#endif
963
1.79k
  if( internal_file->file_io_handle_opened_in_library != 0 )
964
1.79k
  {
965
1.79k
    if( libbfio_handle_close(
966
1.79k
         internal_file->file_io_handle,
967
1.79k
         error ) != 0 )
968
0
    {
969
0
      libcerror_error_set(
970
0
       error,
971
0
       LIBCERROR_ERROR_DOMAIN_IO,
972
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
973
0
       "%s: unable to close file IO handle.",
974
0
       function );
975
976
0
      result = -1;
977
0
    }
978
1.79k
    internal_file->file_io_handle_opened_in_library = 0;
979
1.79k
  }
980
1.79k
  if( internal_file->file_io_handle_created_in_library != 0 )
981
0
  {
982
0
    if( libbfio_handle_free(
983
0
         &( internal_file->file_io_handle ),
984
0
         error ) != 1 )
985
0
    {
986
0
      libcerror_error_set(
987
0
       error,
988
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
989
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
990
0
       "%s: unable to free file IO handle.",
991
0
       function );
992
993
0
      result = -1;
994
0
    }
995
0
    internal_file->file_io_handle_created_in_library = 0;
996
0
  }
997
1.79k
  internal_file->file_io_handle = NULL;
998
999
1.79k
  if( libevt_io_handle_clear(
1000
1.79k
       internal_file->io_handle,
1001
1.79k
       error ) != 1 )
1002
0
  {
1003
0
    libcerror_error_set(
1004
0
     error,
1005
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1006
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1007
0
     "%s: unable to clear IO handle.",
1008
0
     function );
1009
1010
0
    result = -1;
1011
0
  }
1012
1.79k
  if( libevt_file_header_free(
1013
1.79k
       &( internal_file->file_header ),
1014
1.79k
       error ) != 1 )
1015
0
  {
1016
0
    libcerror_error_set(
1017
0
     error,
1018
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1019
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1020
0
     "%s: unable to free file header.",
1021
0
     function );
1022
1023
0
    result = -1;
1024
0
  }
1025
1.79k
  if( libfdata_list_empty(
1026
1.79k
       internal_file->records_list,
1027
1.79k
       error ) != 1 )
1028
0
  {
1029
0
    libcerror_error_set(
1030
0
     error,
1031
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1032
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1033
0
     "%s: unable to empty records list.",
1034
0
     function );
1035
1036
0
    result = -1;
1037
0
  }
1038
1.79k
  if( libfdata_list_empty(
1039
1.79k
       internal_file->recovered_records_list,
1040
1.79k
       error ) != 1 )
1041
0
  {
1042
0
    libcerror_error_set(
1043
0
     error,
1044
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1045
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1046
0
     "%s: unable to empty recovered records list.",
1047
0
     function );
1048
1049
0
    result = -1;
1050
0
  }
1051
1.79k
  if( libfcache_cache_empty(
1052
1.79k
       internal_file->records_cache,
1053
1.79k
       error ) != 1 )
1054
0
  {
1055
0
    libcerror_error_set(
1056
0
     error,
1057
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1058
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1059
0
     "%s: unable to empty records cache.",
1060
0
     function );
1061
1062
0
    result = -1;
1063
0
  }
1064
1.79k
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1065
1.79k
  if( libcthreads_read_write_lock_release_for_write(
1066
1.79k
       internal_file->read_write_lock,
1067
1.79k
       error ) != 1 )
1068
0
  {
1069
0
    libcerror_error_set(
1070
0
     error,
1071
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1072
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1073
0
     "%s: unable to release read/write lock for writing.",
1074
0
     function );
1075
1076
0
    return( -1 );
1077
0
  }
1078
1.79k
#endif
1079
1.79k
  return( result );
1080
1.79k
}
1081
1082
/* Opens a file for reading
1083
 * Returns 1 if successful or -1 on error
1084
 */
1085
int libevt_file_open_read(
1086
     libevt_internal_file_t *internal_file,
1087
     libbfio_handle_t *file_io_handle,
1088
     libcerror_error_t **error )
1089
1.81k
{
1090
1.81k
  static char *function      = "libevt_file_open_read";
1091
1.81k
  off64_t last_record_offset = 0;
1092
1.81k
  uint32_t header_size       = 0;
1093
1.81k
  int result_record_read     = 0;
1094
1.81k
  int result_record_recovery = 0;
1095
1096
1.81k
  if( internal_file == NULL )
1097
0
  {
1098
0
    libcerror_error_set(
1099
0
     error,
1100
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1101
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1102
0
     "%s: invalid file.",
1103
0
     function );
1104
1105
0
    return( -1 );
1106
0
  }
1107
1.81k
  if( internal_file->io_handle == NULL )
1108
0
  {
1109
0
    libcerror_error_set(
1110
0
     error,
1111
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1112
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1113
0
     "%s: invalid file - missing IO handle.",
1114
0
     function );
1115
1116
0
    return( -1 );
1117
0
  }
1118
1.81k
  if( internal_file->file_header != NULL )
1119
0
  {
1120
0
    libcerror_error_set(
1121
0
     error,
1122
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1123
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1124
0
     "%s: invalid file - file header already set.",
1125
0
     function );
1126
1127
0
    return( -1 );
1128
0
  }
1129
1.81k
  internal_file->io_handle->abort = 0;
1130
1131
1.81k
  if( libbfio_handle_get_size(
1132
1.81k
       file_io_handle,
1133
1.81k
       &( internal_file->io_handle->file_size ),
1134
1.81k
       error ) != 1 )
1135
0
  {
1136
0
    libcerror_error_set(
1137
0
     error,
1138
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1139
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1140
0
     "%s: unable to retrieve file size.",
1141
0
     function );
1142
1143
0
    goto on_error;
1144
0
  }
1145
#if defined( HAVE_DEBUG_OUTPUT )
1146
  if( libcnotify_verbose != 0 )
1147
  {
1148
    libcnotify_printf(
1149
     "Reading file header:\n" );
1150
  }
1151
#endif
1152
1.81k
  if( libevt_file_header_initialize(
1153
1.81k
       &( internal_file->file_header ),
1154
1.81k
       error ) != 1 )
1155
0
  {
1156
0
    libcerror_error_set(
1157
0
     error,
1158
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1159
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1160
0
     "%s: unable to create file header.",
1161
0
     function );
1162
1163
0
    goto on_error;
1164
0
  }
1165
1.81k
  if( libevt_file_header_read_file_io_handle(
1166
1.81k
       internal_file->file_header,
1167
1.81k
       file_io_handle,
1168
1.81k
       0,
1169
1.81k
       error ) != 1 )
1170
18
  {
1171
18
    libcerror_error_set(
1172
18
     error,
1173
18
     LIBCERROR_ERROR_DOMAIN_IO,
1174
18
     LIBCERROR_IO_ERROR_READ_FAILED,
1175
18
     "%s: unable to read file header.",
1176
18
     function );
1177
1178
18
    goto on_error;
1179
18
  }
1180
1.79k
  header_size = internal_file->file_header->size;
1181
1182
1.79k
  if( header_size != internal_file->file_header->copy_of_size )
1183
1.78k
  {
1184
#if defined( HAVE_DEBUG_OUTPUT )
1185
    if( libcnotify_verbose != 0 )
1186
    {
1187
      libcnotify_printf(
1188
       "%s: value mismatch for size and copy of size ( %" PRIu32 " != %" PRIu32 " ).\n",
1189
       function,
1190
       header_size,
1191
       internal_file->file_header->copy_of_size );
1192
    }
1193
#endif
1194
    /* If the size does not match the header size assume size copy contains
1195
     * the correct value for the next validation check
1196
     */
1197
1.78k
    if( header_size != sizeof( evt_file_header_t ) )
1198
1.76k
    {
1199
1.76k
      header_size = internal_file->file_header->copy_of_size;
1200
1.76k
    }
1201
1.78k
    internal_file->io_handle->flags |= LIBEVT_IO_HANDLE_FLAG_IS_CORRUPTED;
1202
1.78k
  }
1203
1.79k
  if( (size_t) header_size != sizeof( evt_file_header_t ) )
1204
1.77k
  {
1205
#if defined( HAVE_DEBUG_OUTPUT )
1206
    if( libcnotify_verbose != 0 )
1207
    {
1208
      libcnotify_printf(
1209
       "%s: header size: %" PRIu32 " does not match known value.\n",
1210
       function,
1211
       header_size );
1212
    }
1213
#endif
1214
1.77k
    internal_file->io_handle->flags |= LIBEVT_IO_HANDLE_FLAG_IS_CORRUPTED;
1215
1.77k
  }
1216
#if defined( HAVE_DEBUG_OUTPUT )
1217
  if( libcnotify_verbose != 0 )
1218
  {
1219
    libcnotify_printf(
1220
     "Reading records:\n" );
1221
  }
1222
#endif
1223
1.79k
  result_record_read = libevt_io_handle_read_records(
1224
1.79k
                        internal_file->io_handle,
1225
1.79k
                        file_io_handle,
1226
1.79k
                        internal_file->file_header->first_record_offset,
1227
1.79k
                        internal_file->file_header->end_of_file_record_offset,
1228
1.79k
                        internal_file->records_list,
1229
1.79k
                        &last_record_offset,
1230
1.79k
                        error );
1231
1232
1.79k
  if( result_record_read != 1 )
1233
1.74k
  {
1234
1.74k
    libcerror_error_set(
1235
1.74k
     error,
1236
1.74k
     LIBCERROR_ERROR_DOMAIN_IO,
1237
1.74k
     LIBCERROR_IO_ERROR_READ_FAILED,
1238
1.74k
     "%s: unable to read records.",
1239
1.74k
     function );
1240
1241
#if defined( HAVE_DEBUG_OUTPUT )
1242
    if( libcnotify_verbose != 0 )
1243
    {
1244
      if( ( error != NULL )
1245
       && ( *error != NULL ) )
1246
      {
1247
        libcnotify_print_error_backtrace(
1248
         *error );
1249
      }
1250
    }
1251
#endif
1252
1.74k
  }
1253
1.79k
  if( internal_file->io_handle->abort == 0 )
1254
1.79k
  {
1255
1.79k
    result_record_recovery = libevt_io_handle_recover_records(
1256
1.79k
                              internal_file->io_handle,
1257
1.79k
                              file_io_handle,
1258
1.79k
                              internal_file->file_header->first_record_offset,
1259
1.79k
                              internal_file->file_header->end_of_file_record_offset,
1260
1.79k
                              last_record_offset,
1261
1.79k
                              internal_file->records_list,
1262
1.79k
                              internal_file->recovered_records_list,
1263
1.79k
                              error );
1264
1265
1.79k
    if( result_record_recovery != 1 )
1266
0
    {
1267
#if defined( HAVE_DEBUG_OUTPUT )
1268
      if( result_record_read != 1 )
1269
      {
1270
        libcerror_error_free(
1271
         error );
1272
      }
1273
#endif
1274
0
      libcerror_error_set(
1275
0
       error,
1276
0
       LIBCERROR_ERROR_DOMAIN_IO,
1277
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1278
0
       "%s: unable to recover records.",
1279
0
       function );
1280
1281
#if defined( HAVE_DEBUG_OUTPUT )
1282
      if( libcnotify_verbose != 0 )
1283
      {
1284
        if( ( error != NULL )
1285
         && ( *error != NULL ) )
1286
        {
1287
          libcnotify_print_error_backtrace(
1288
           *error );
1289
        }
1290
      }
1291
#endif
1292
0
    }
1293
1.79k
  }
1294
1.79k
  if( ( result_record_read != 1 )
1295
1.79k
   && ( result_record_recovery != 1 ) )
1296
0
  {
1297
0
    goto on_error;
1298
0
  }
1299
1.79k
  if( ( error != NULL )
1300
1.79k
   && ( *error != NULL ) )
1301
0
  {
1302
0
    libcerror_error_free(
1303
0
     error );
1304
0
  }
1305
1.79k
  internal_file->io_handle->abort = 0;
1306
1307
1.79k
  return( 1 );
1308
1309
18
on_error:
1310
18
  if( internal_file->file_header != NULL )
1311
18
  {
1312
18
    libevt_file_header_free(
1313
18
     &( internal_file->file_header ),
1314
18
     NULL );
1315
18
  }
1316
18
  return( -1 );
1317
1.79k
}
1318
1319
/* Determine if the file corrupted
1320
 * Returns 1 if corrupted, 0 if not or -1 on error
1321
 */
1322
int libevt_file_is_corrupted(
1323
     libevt_file_t *file,
1324
     libcerror_error_t **error )
1325
0
{
1326
0
  libevt_internal_file_t *internal_file = NULL;
1327
0
  static char *function                 = "libevt_file_is_corrupted";
1328
0
  int result                            = 0;
1329
1330
0
  if( file == NULL )
1331
0
  {
1332
0
    libcerror_error_set(
1333
0
     error,
1334
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1335
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1336
0
     "%s: invalid file.",
1337
0
     function );
1338
1339
0
    return( -1 );
1340
0
  }
1341
0
  internal_file = (libevt_internal_file_t *) file;
1342
1343
0
  if( internal_file->io_handle == NULL )
1344
0
  {
1345
0
    libcerror_error_set(
1346
0
     error,
1347
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1348
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1349
0
     "%s: invalid file - missing IO handle.",
1350
0
     function );
1351
1352
0
    return( -1 );
1353
0
  }
1354
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1355
0
  if( libcthreads_read_write_lock_grab_for_read(
1356
0
       internal_file->read_write_lock,
1357
0
       error ) != 1 )
1358
0
  {
1359
0
    libcerror_error_set(
1360
0
     error,
1361
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1362
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1363
0
     "%s: unable to grab read/write lock for reading.",
1364
0
     function );
1365
1366
0
    return( -1 );
1367
0
  }
1368
0
#endif
1369
0
  if( ( internal_file->io_handle->flags & LIBEVT_IO_HANDLE_FLAG_IS_CORRUPTED ) != 0 )
1370
0
  {
1371
0
    result = 1;
1372
0
  }
1373
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1374
0
  if( libcthreads_read_write_lock_release_for_read(
1375
0
       internal_file->read_write_lock,
1376
0
       error ) != 1 )
1377
0
  {
1378
0
    libcerror_error_set(
1379
0
     error,
1380
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1381
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1382
0
     "%s: unable to release read/write lock for reading.",
1383
0
     function );
1384
1385
0
    return( -1 );
1386
0
  }
1387
0
#endif
1388
0
  return( result );
1389
0
}
1390
1391
/* Retrieves the file ASCII codepage
1392
 * Returns 1 if successful or -1 on error
1393
 */
1394
int libevt_file_get_ascii_codepage(
1395
     libevt_file_t *file,
1396
     int *ascii_codepage,
1397
     libcerror_error_t **error )
1398
0
{
1399
0
  libevt_internal_file_t *internal_file = NULL;
1400
0
  static char *function                 = "libevt_file_get_ascii_codepage";
1401
1402
0
  if( file == NULL )
1403
0
  {
1404
0
    libcerror_error_set(
1405
0
     error,
1406
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1407
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1408
0
     "%s: invalid file.",
1409
0
     function );
1410
1411
0
    return( -1 );
1412
0
  }
1413
0
  internal_file = (libevt_internal_file_t *) file;
1414
1415
0
  if( internal_file->io_handle == NULL )
1416
0
  {
1417
0
    libcerror_error_set(
1418
0
     error,
1419
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1420
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1421
0
     "%s: invalid file - missing IO handle.",
1422
0
     function );
1423
1424
0
    return( -1 );
1425
0
  }
1426
0
  if( ascii_codepage == NULL )
1427
0
  {
1428
0
    libcerror_error_set(
1429
0
     error,
1430
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1431
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1432
0
     "%s: invalid ASCII codepage.",
1433
0
     function );
1434
1435
0
    return( -1 );
1436
0
  }
1437
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1438
0
  if( libcthreads_read_write_lock_grab_for_read(
1439
0
       internal_file->read_write_lock,
1440
0
       error ) != 1 )
1441
0
  {
1442
0
    libcerror_error_set(
1443
0
     error,
1444
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1445
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1446
0
     "%s: unable to grab read/write lock for reading.",
1447
0
     function );
1448
1449
0
    return( -1 );
1450
0
  }
1451
0
#endif
1452
0
  *ascii_codepage = internal_file->io_handle->ascii_codepage;
1453
1454
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1455
0
  if( libcthreads_read_write_lock_release_for_read(
1456
0
       internal_file->read_write_lock,
1457
0
       error ) != 1 )
1458
0
  {
1459
0
    libcerror_error_set(
1460
0
     error,
1461
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1462
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1463
0
     "%s: unable to release read/write lock for reading.",
1464
0
     function );
1465
1466
0
    return( -1 );
1467
0
  }
1468
0
#endif
1469
0
  return( 1 );
1470
0
}
1471
1472
/* Sets the file ASCII codepage
1473
 * Returns 1 if successful or -1 on error
1474
 */
1475
int libevt_file_set_ascii_codepage(
1476
     libevt_file_t *file,
1477
     int ascii_codepage,
1478
     libcerror_error_t **error )
1479
0
{
1480
0
  libevt_internal_file_t *internal_file = NULL;
1481
0
  static char *function                 = "libevt_file_set_ascii_codepage";
1482
1483
0
  if( file == NULL )
1484
0
  {
1485
0
    libcerror_error_set(
1486
0
     error,
1487
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1488
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1489
0
     "%s: invalid file.",
1490
0
     function );
1491
1492
0
    return( -1 );
1493
0
  }
1494
0
  internal_file = (libevt_internal_file_t *) file;
1495
1496
0
  if( internal_file->io_handle == NULL )
1497
0
  {
1498
0
    libcerror_error_set(
1499
0
     error,
1500
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1501
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1502
0
     "%s: invalid file - missing IO handle.",
1503
0
     function );
1504
1505
0
    return( -1 );
1506
0
  }
1507
0
  if( ( ascii_codepage != LIBEVT_CODEPAGE_ASCII )
1508
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_874 )
1509
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_932 )
1510
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_936 )
1511
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_949 )
1512
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_950 )
1513
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_1250 )
1514
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_1251 )
1515
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_1252 )
1516
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_1253 )
1517
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_1254 )
1518
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_1255 )
1519
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_1256 )
1520
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_1257 )
1521
0
   && ( ascii_codepage != LIBEVT_CODEPAGE_WINDOWS_1258 ) )
1522
0
  {
1523
0
    libcerror_error_set(
1524
0
     error,
1525
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1526
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1527
0
     "%s: unsupported ASCII codepage.",
1528
0
     function );
1529
1530
0
    return( -1 );
1531
0
  }
1532
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1533
0
  if( libcthreads_read_write_lock_grab_for_write(
1534
0
       internal_file->read_write_lock,
1535
0
       error ) != 1 )
1536
0
  {
1537
0
    libcerror_error_set(
1538
0
     error,
1539
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1540
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1541
0
     "%s: unable to grab read/write lock for writing.",
1542
0
     function );
1543
1544
0
    return( -1 );
1545
0
  }
1546
0
#endif
1547
0
  internal_file->io_handle->ascii_codepage = ascii_codepage;
1548
1549
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1550
0
  if( libcthreads_read_write_lock_release_for_write(
1551
0
       internal_file->read_write_lock,
1552
0
       error ) != 1 )
1553
0
  {
1554
0
    libcerror_error_set(
1555
0
     error,
1556
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1557
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1558
0
     "%s: unable to release read/write lock for writing.",
1559
0
     function );
1560
1561
0
    return( -1 );
1562
0
  }
1563
0
#endif
1564
0
  return( 1 );
1565
0
}
1566
1567
/* Retrieves the format version
1568
 * Returns 1 if successful or -1 on error
1569
 */
1570
int libevt_file_get_format_version(
1571
     libevt_file_t *file,
1572
     uint32_t *major_format_version,
1573
     uint32_t *minor_format_version,
1574
     libcerror_error_t **error )
1575
0
{
1576
0
  libevt_internal_file_t *internal_file = NULL;
1577
0
  static char *function                 = "libevt_file_get_format_version";
1578
1579
0
  if( file == NULL )
1580
0
  {
1581
0
    libcerror_error_set(
1582
0
     error,
1583
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1584
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1585
0
     "%s: invalid file.",
1586
0
     function );
1587
1588
0
    return( -1 );
1589
0
  }
1590
0
  internal_file = (libevt_internal_file_t *) file;
1591
1592
0
  if( internal_file->file_header == NULL )
1593
0
  {
1594
0
    libcerror_error_set(
1595
0
     error,
1596
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1597
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1598
0
     "%s: invalid file - missing file header.",
1599
0
     function );
1600
1601
0
    return( -1 );
1602
0
  }
1603
0
  if( major_format_version == NULL )
1604
0
  {
1605
0
    libcerror_error_set(
1606
0
     error,
1607
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1608
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1609
0
     "%s: invalid major format version.",
1610
0
     function );
1611
1612
0
    return( -1 );
1613
0
  }
1614
0
  if( minor_format_version == NULL )
1615
0
  {
1616
0
    libcerror_error_set(
1617
0
     error,
1618
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1619
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1620
0
     "%s: invalid minor format version.",
1621
0
     function );
1622
1623
0
    return( -1 );
1624
0
  }
1625
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1626
0
  if( libcthreads_read_write_lock_grab_for_read(
1627
0
       internal_file->read_write_lock,
1628
0
       error ) != 1 )
1629
0
  {
1630
0
    libcerror_error_set(
1631
0
     error,
1632
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1633
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1634
0
     "%s: unable to grab read/write lock for reading.",
1635
0
     function );
1636
1637
0
    return( -1 );
1638
0
  }
1639
0
#endif
1640
0
  *major_format_version = internal_file->file_header->major_format_version;
1641
0
  *minor_format_version = internal_file->file_header->minor_format_version;
1642
1643
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1644
0
  if( libcthreads_read_write_lock_release_for_read(
1645
0
       internal_file->read_write_lock,
1646
0
       error ) != 1 )
1647
0
  {
1648
0
    libcerror_error_set(
1649
0
     error,
1650
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1651
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1652
0
     "%s: unable to release read/write lock for reading.",
1653
0
     function );
1654
1655
0
    return( -1 );
1656
0
  }
1657
0
#endif
1658
0
  return( 1 );
1659
0
}
1660
1661
/* Retrieves the version
1662
 * Returns 1 if successful or -1 on error
1663
 */
1664
int libevt_file_get_version(
1665
     libevt_file_t *file,
1666
     uint32_t *major_version,
1667
     uint32_t *minor_version,
1668
     libcerror_error_t **error )
1669
0
{
1670
0
  libevt_internal_file_t *internal_file = NULL;
1671
0
  static char *function                 = "libevt_file_get_version";
1672
1673
0
  if( file == NULL )
1674
0
  {
1675
0
    libcerror_error_set(
1676
0
     error,
1677
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1678
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1679
0
     "%s: invalid file.",
1680
0
     function );
1681
1682
0
    return( -1 );
1683
0
  }
1684
0
  internal_file = (libevt_internal_file_t *) file;
1685
1686
0
  if( internal_file->file_header == NULL )
1687
0
  {
1688
0
    libcerror_error_set(
1689
0
     error,
1690
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1691
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1692
0
     "%s: invalid file - missing file header.",
1693
0
     function );
1694
1695
0
    return( -1 );
1696
0
  }
1697
0
  if( major_version == NULL )
1698
0
  {
1699
0
    libcerror_error_set(
1700
0
     error,
1701
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1702
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1703
0
     "%s: invalid major version.",
1704
0
     function );
1705
1706
0
    return( -1 );
1707
0
  }
1708
0
  if( minor_version == NULL )
1709
0
  {
1710
0
    libcerror_error_set(
1711
0
     error,
1712
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1713
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1714
0
     "%s: invalid minor version.",
1715
0
     function );
1716
1717
0
    return( -1 );
1718
0
  }
1719
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1720
0
  if( libcthreads_read_write_lock_grab_for_read(
1721
0
       internal_file->read_write_lock,
1722
0
       error ) != 1 )
1723
0
  {
1724
0
    libcerror_error_set(
1725
0
     error,
1726
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1727
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1728
0
     "%s: unable to grab read/write lock for reading.",
1729
0
     function );
1730
1731
0
    return( -1 );
1732
0
  }
1733
0
#endif
1734
0
  *major_version = internal_file->file_header->major_format_version;
1735
0
  *minor_version = internal_file->file_header->minor_format_version;
1736
1737
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1738
0
  if( libcthreads_read_write_lock_release_for_read(
1739
0
       internal_file->read_write_lock,
1740
0
       error ) != 1 )
1741
0
  {
1742
0
    libcerror_error_set(
1743
0
     error,
1744
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1745
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1746
0
     "%s: unable to release read/write lock for reading.",
1747
0
     function );
1748
1749
0
    return( -1 );
1750
0
  }
1751
0
#endif
1752
0
  return( 1 );
1753
0
}
1754
1755
/* Retrieves the flags
1756
 * Returns 1 if successful or -1 on error
1757
 */
1758
int libevt_file_get_flags(
1759
     libevt_file_t *file,
1760
     uint32_t *flags,
1761
     libcerror_error_t **error )
1762
0
{
1763
0
  libevt_internal_file_t *internal_file = NULL;
1764
0
  static char *function                 = "libevt_file_get_flags";
1765
1766
0
  if( file == NULL )
1767
0
  {
1768
0
    libcerror_error_set(
1769
0
     error,
1770
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1771
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1772
0
     "%s: invalid file.",
1773
0
     function );
1774
1775
0
    return( -1 );
1776
0
  }
1777
0
  internal_file = (libevt_internal_file_t *) file;
1778
1779
0
  if( internal_file->file_header == NULL )
1780
0
  {
1781
0
    libcerror_error_set(
1782
0
     error,
1783
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1784
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1785
0
     "%s: invalid file - missing file header.",
1786
0
     function );
1787
1788
0
    return( -1 );
1789
0
  }
1790
0
  if( flags == NULL )
1791
0
  {
1792
0
    libcerror_error_set(
1793
0
     error,
1794
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1795
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1796
0
     "%s: invalid flags.",
1797
0
     function );
1798
1799
0
    return( -1 );
1800
0
  }
1801
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1802
0
  if( libcthreads_read_write_lock_grab_for_read(
1803
0
       internal_file->read_write_lock,
1804
0
       error ) != 1 )
1805
0
  {
1806
0
    libcerror_error_set(
1807
0
     error,
1808
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1809
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1810
0
     "%s: unable to grab read/write lock for reading.",
1811
0
     function );
1812
1813
0
    return( -1 );
1814
0
  }
1815
0
#endif
1816
0
  *flags = internal_file->file_header->file_flags;
1817
1818
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1819
0
  if( libcthreads_read_write_lock_release_for_read(
1820
0
       internal_file->read_write_lock,
1821
0
       error ) != 1 )
1822
0
  {
1823
0
    libcerror_error_set(
1824
0
     error,
1825
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1826
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1827
0
     "%s: unable to release read/write lock for reading.",
1828
0
     function );
1829
1830
0
    return( -1 );
1831
0
  }
1832
0
#endif
1833
0
  return( 1 );
1834
0
}
1835
1836
/* Retrieves the number of records
1837
 * Returns 1 if successful or -1 on error
1838
 */
1839
int libevt_file_get_number_of_records(
1840
     libevt_file_t *file,
1841
     int *number_of_records,
1842
     libcerror_error_t **error )
1843
0
{
1844
0
  libevt_internal_file_t *internal_file = NULL;
1845
0
  static char *function                 = "libevt_file_get_number_of_records";
1846
0
  int result                            = 1;
1847
1848
0
  if( file == NULL )
1849
0
  {
1850
0
    libcerror_error_set(
1851
0
     error,
1852
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1853
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1854
0
     "%s: invalid file.",
1855
0
     function );
1856
1857
0
    return( -1 );
1858
0
  }
1859
0
  internal_file = (libevt_internal_file_t *) file;
1860
1861
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1862
0
  if( libcthreads_read_write_lock_grab_for_write(
1863
0
       internal_file->read_write_lock,
1864
0
       error ) != 1 )
1865
0
  {
1866
0
    libcerror_error_set(
1867
0
     error,
1868
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1869
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1870
0
     "%s: unable to grab read/write lock for writing.",
1871
0
     function );
1872
1873
0
    return( -1 );
1874
0
  }
1875
0
#endif
1876
0
  if( libfdata_list_get_number_of_elements(
1877
0
       internal_file->records_list,
1878
0
       number_of_records,
1879
0
       error ) != 1 )
1880
0
  {
1881
0
    libcerror_error_set(
1882
0
     error,
1883
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1884
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1885
0
     "%s: unable to retrieve number of elements from records list.",
1886
0
     function );
1887
1888
0
    result = -1;
1889
0
  }
1890
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1891
0
  if( libcthreads_read_write_lock_release_for_write(
1892
0
       internal_file->read_write_lock,
1893
0
       error ) != 1 )
1894
0
  {
1895
0
    libcerror_error_set(
1896
0
     error,
1897
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1898
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1899
0
     "%s: unable to release read/write lock for writing.",
1900
0
     function );
1901
1902
0
    return( -1 );
1903
0
  }
1904
0
#endif
1905
0
  return( result );
1906
0
}
1907
1908
/* Retrieves a specific record
1909
 * Returns 1 if successful or -1 on error
1910
 */
1911
int libevt_file_get_record(
1912
     libevt_file_t *file,
1913
     int record_index,
1914
     libevt_record_t **record,
1915
     libcerror_error_t **error )
1916
0
{
1917
0
  libevt_internal_file_t *internal_file = NULL;
1918
0
  libevt_record_values_t *record_values = NULL;
1919
0
  static char *function                 = "libevt_file_get_record";
1920
0
  int result                            = 1;
1921
1922
0
  if( file == NULL )
1923
0
  {
1924
0
    libcerror_error_set(
1925
0
     error,
1926
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1927
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1928
0
     "%s: invalid file.",
1929
0
     function );
1930
1931
0
    return( -1 );
1932
0
  }
1933
0
  internal_file = (libevt_internal_file_t *) file;
1934
1935
0
  if( record == NULL )
1936
0
  {
1937
0
    libcerror_error_set(
1938
0
     error,
1939
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1940
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1941
0
     "%s: invalid record.",
1942
0
     function );
1943
1944
0
    return( -1 );
1945
0
  }
1946
0
  if( *record != NULL )
1947
0
  {
1948
0
    libcerror_error_set(
1949
0
     error,
1950
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1951
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1952
0
     "%s: invalid record value already set.",
1953
0
     function );
1954
1955
0
    return( -1 );
1956
0
  }
1957
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
1958
0
  if( libcthreads_read_write_lock_grab_for_write(
1959
0
       internal_file->read_write_lock,
1960
0
       error ) != 1 )
1961
0
  {
1962
0
    libcerror_error_set(
1963
0
     error,
1964
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1965
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1966
0
     "%s: unable to grab read/write lock for writing.",
1967
0
     function );
1968
1969
0
    return( -1 );
1970
0
  }
1971
0
#endif
1972
0
  if( libfdata_list_get_element_value_by_index(
1973
0
       internal_file->records_list,
1974
0
       (intptr_t *) internal_file->file_io_handle,
1975
0
       (libfdata_cache_t *) internal_file->records_cache,
1976
0
       record_index,
1977
0
       (intptr_t **) &record_values,
1978
0
       0,
1979
0
       error ) != 1 )
1980
0
  {
1981
0
    libcerror_error_set(
1982
0
     error,
1983
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1984
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1985
0
     "%s: unable to retrieve record values: %d.",
1986
0
     function,
1987
0
     record_index );
1988
1989
0
    result = -1;
1990
0
  }
1991
0
  else if( libevt_record_initialize(
1992
0
            record,
1993
0
            internal_file->io_handle,
1994
0
            internal_file->file_io_handle,
1995
0
            record_values,
1996
0
            error ) != 1 )
1997
0
  {
1998
0
    libcerror_error_set(
1999
0
     error,
2000
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2001
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2002
0
     "%s: unable to create record.",
2003
0
     function );
2004
2005
0
    result = -1;
2006
0
  }
2007
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
2008
0
  if( libcthreads_read_write_lock_release_for_write(
2009
0
       internal_file->read_write_lock,
2010
0
       error ) != 1 )
2011
0
  {
2012
0
    libcerror_error_set(
2013
0
     error,
2014
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2015
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2016
0
     "%s: unable to release read/write lock for writing.",
2017
0
     function );
2018
2019
0
    return( -1 );
2020
0
  }
2021
0
#endif
2022
0
  return( result );
2023
0
}
2024
2025
/* Retrieves a specific record
2026
 * Returns 1 if successful or -1 on error
2027
 */
2028
int libevt_file_get_record_by_index(
2029
     libevt_file_t *file,
2030
     int record_index,
2031
     libevt_record_t **record,
2032
     libcerror_error_t **error )
2033
0
{
2034
0
  libevt_internal_file_t *internal_file = NULL;
2035
0
  libevt_record_values_t *record_values = NULL;
2036
0
  static char *function                 = "libevt_file_get_record_by_index";
2037
0
  int result                            = 1;
2038
2039
0
  if( file == NULL )
2040
0
  {
2041
0
    libcerror_error_set(
2042
0
     error,
2043
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2044
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2045
0
     "%s: invalid file.",
2046
0
     function );
2047
2048
0
    return( -1 );
2049
0
  }
2050
0
  internal_file = (libevt_internal_file_t *) file;
2051
2052
0
  if( record == NULL )
2053
0
  {
2054
0
    libcerror_error_set(
2055
0
     error,
2056
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2057
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2058
0
     "%s: invalid record.",
2059
0
     function );
2060
2061
0
    return( -1 );
2062
0
  }
2063
0
  if( *record != NULL )
2064
0
  {
2065
0
    libcerror_error_set(
2066
0
     error,
2067
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2068
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2069
0
     "%s: invalid record value already set.",
2070
0
     function );
2071
2072
0
    return( -1 );
2073
0
  }
2074
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
2075
0
  if( libcthreads_read_write_lock_grab_for_write(
2076
0
       internal_file->read_write_lock,
2077
0
       error ) != 1 )
2078
0
  {
2079
0
    libcerror_error_set(
2080
0
     error,
2081
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2082
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2083
0
     "%s: unable to grab read/write lock for writing.",
2084
0
     function );
2085
2086
0
    return( -1 );
2087
0
  }
2088
0
#endif
2089
0
  if( libfdata_list_get_element_value_by_index(
2090
0
       internal_file->records_list,
2091
0
       (intptr_t *) internal_file->file_io_handle,
2092
0
       (libfdata_cache_t *) internal_file->records_cache,
2093
0
       record_index,
2094
0
       (intptr_t **) &record_values,
2095
0
       0,
2096
0
       error ) != 1 )
2097
0
  {
2098
0
    libcerror_error_set(
2099
0
     error,
2100
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2101
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2102
0
     "%s: unable to retrieve record values: %d.",
2103
0
     function,
2104
0
     record_index );
2105
2106
0
    result = -1;
2107
0
  }
2108
0
  else if( libevt_record_initialize(
2109
0
            record,
2110
0
            internal_file->io_handle,
2111
0
            internal_file->file_io_handle,
2112
0
            record_values,
2113
0
            error ) != 1 )
2114
0
  {
2115
0
    libcerror_error_set(
2116
0
     error,
2117
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2118
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2119
0
     "%s: unable to create record.",
2120
0
     function );
2121
2122
0
    result = -1;
2123
0
  }
2124
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
2125
0
  if( libcthreads_read_write_lock_release_for_write(
2126
0
       internal_file->read_write_lock,
2127
0
       error ) != 1 )
2128
0
  {
2129
0
    libcerror_error_set(
2130
0
     error,
2131
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2132
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2133
0
     "%s: unable to release read/write lock for writing.",
2134
0
     function );
2135
2136
0
    return( -1 );
2137
0
  }
2138
0
#endif
2139
0
  return( result );
2140
0
}
2141
2142
/* Retrieves the number of recovered records
2143
 * Returns 1 if successful or -1 on error
2144
 */
2145
int libevt_file_get_number_of_recovered_records(
2146
     libevt_file_t *file,
2147
     int *number_of_records,
2148
     libcerror_error_t **error )
2149
0
{
2150
0
  libevt_internal_file_t *internal_file = NULL;
2151
0
  static char *function                 = "libevt_file_get_number_of_recovered_records";
2152
0
  int result                            = 1;
2153
2154
0
  if( file == NULL )
2155
0
  {
2156
0
    libcerror_error_set(
2157
0
     error,
2158
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2159
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2160
0
     "%s: invalid file.",
2161
0
     function );
2162
2163
0
    return( -1 );
2164
0
  }
2165
0
  internal_file = (libevt_internal_file_t *) file;
2166
2167
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
2168
0
  if( libcthreads_read_write_lock_grab_for_write(
2169
0
       internal_file->read_write_lock,
2170
0
       error ) != 1 )
2171
0
  {
2172
0
    libcerror_error_set(
2173
0
     error,
2174
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2175
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2176
0
     "%s: unable to grab read/write lock for writing.",
2177
0
     function );
2178
2179
0
    return( -1 );
2180
0
  }
2181
0
#endif
2182
0
  if( libfdata_list_get_number_of_elements(
2183
0
       internal_file->recovered_records_list,
2184
0
       number_of_records,
2185
0
       error ) != 1 )
2186
0
  {
2187
0
    libcerror_error_set(
2188
0
     error,
2189
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2190
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2191
0
     "%s: unable to retrieve number of elements from recovered records list.",
2192
0
     function );
2193
2194
0
    result = -1;
2195
0
  }
2196
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
2197
0
  if( libcthreads_read_write_lock_release_for_write(
2198
0
       internal_file->read_write_lock,
2199
0
       error ) != 1 )
2200
0
  {
2201
0
    libcerror_error_set(
2202
0
     error,
2203
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2204
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2205
0
     "%s: unable to release read/write lock for writing.",
2206
0
     function );
2207
2208
0
    return( -1 );
2209
0
  }
2210
0
#endif
2211
0
  return( result );
2212
0
}
2213
2214
/* Retrieves a specific recovered record
2215
 * Returns 1 if successful or -1 on error
2216
 */
2217
int libevt_file_get_recovered_record(
2218
     libevt_file_t *file,
2219
     int record_index,
2220
     libevt_record_t **record,
2221
     libcerror_error_t **error )
2222
0
{
2223
0
  libevt_internal_file_t *internal_file = NULL;
2224
0
  libevt_record_values_t *record_values = NULL;
2225
0
  static char *function                 = "libevt_file_get_recovered_record";
2226
0
  int result                            = 1;
2227
2228
0
  if( file == NULL )
2229
0
  {
2230
0
    libcerror_error_set(
2231
0
     error,
2232
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2233
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2234
0
     "%s: invalid file.",
2235
0
     function );
2236
2237
0
    return( -1 );
2238
0
  }
2239
0
  internal_file = (libevt_internal_file_t *) file;
2240
2241
0
  if( record == NULL )
2242
0
  {
2243
0
    libcerror_error_set(
2244
0
     error,
2245
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2246
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2247
0
     "%s: invalid record.",
2248
0
     function );
2249
2250
0
    return( -1 );
2251
0
  }
2252
0
  if( *record != NULL )
2253
0
  {
2254
0
    libcerror_error_set(
2255
0
     error,
2256
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2257
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2258
0
     "%s: invalid record value already set.",
2259
0
     function );
2260
2261
0
    return( -1 );
2262
0
  }
2263
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
2264
0
  if( libcthreads_read_write_lock_grab_for_write(
2265
0
       internal_file->read_write_lock,
2266
0
       error ) != 1 )
2267
0
  {
2268
0
    libcerror_error_set(
2269
0
     error,
2270
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2271
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2272
0
     "%s: unable to grab read/write lock for writing.",
2273
0
     function );
2274
2275
0
    return( -1 );
2276
0
  }
2277
0
#endif
2278
0
  if( libfdata_list_get_element_value_by_index(
2279
0
       internal_file->recovered_records_list,
2280
0
       (intptr_t *) internal_file->file_io_handle,
2281
0
       (libfdata_cache_t *) internal_file->records_cache,
2282
0
       record_index,
2283
0
       (intptr_t **) &record_values,
2284
0
       0,
2285
0
       error ) != 1 )
2286
0
  {
2287
0
    libcerror_error_set(
2288
0
     error,
2289
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2290
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2291
0
     "%s: unable to retrieve recovered record values: %d.",
2292
0
     function,
2293
0
     record_index );
2294
2295
0
    result = -1;
2296
0
  }
2297
0
  else if( libevt_record_initialize(
2298
0
            record,
2299
0
            internal_file->io_handle,
2300
0
            internal_file->file_io_handle,
2301
0
            record_values,
2302
0
            error ) != 1 )
2303
0
  {
2304
0
    libcerror_error_set(
2305
0
     error,
2306
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2307
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2308
0
     "%s: unable to create record.",
2309
0
     function );
2310
2311
0
    result = -1;
2312
0
  }
2313
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
2314
0
  if( libcthreads_read_write_lock_release_for_write(
2315
0
       internal_file->read_write_lock,
2316
0
       error ) != 1 )
2317
0
  {
2318
0
    libcerror_error_set(
2319
0
     error,
2320
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2321
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2322
0
     "%s: unable to release read/write lock for writing.",
2323
0
     function );
2324
2325
0
    return( -1 );
2326
0
  }
2327
0
#endif
2328
0
  return( result );
2329
0
}
2330
2331
/* Retrieves a specific recovered record
2332
 * Returns 1 if successful or -1 on error
2333
 */
2334
int libevt_file_get_recovered_record_by_index(
2335
     libevt_file_t *file,
2336
     int record_index,
2337
     libevt_record_t **record,
2338
     libcerror_error_t **error )
2339
0
{
2340
0
  libevt_internal_file_t *internal_file = NULL;
2341
0
  libevt_record_values_t *record_values = NULL;
2342
0
  static char *function                 = "libevt_file_get_recovered_record_by_index";
2343
0
  int result                            = 1;
2344
2345
0
  if( file == NULL )
2346
0
  {
2347
0
    libcerror_error_set(
2348
0
     error,
2349
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2350
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2351
0
     "%s: invalid file.",
2352
0
     function );
2353
2354
0
    return( -1 );
2355
0
  }
2356
0
  internal_file = (libevt_internal_file_t *) file;
2357
2358
0
  if( record == NULL )
2359
0
  {
2360
0
    libcerror_error_set(
2361
0
     error,
2362
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2363
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2364
0
     "%s: invalid record.",
2365
0
     function );
2366
2367
0
    return( -1 );
2368
0
  }
2369
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
2370
0
  if( libcthreads_read_write_lock_grab_for_write(
2371
0
       internal_file->read_write_lock,
2372
0
       error ) != 1 )
2373
0
  {
2374
0
    libcerror_error_set(
2375
0
     error,
2376
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2377
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2378
0
     "%s: unable to grab read/write lock for writing.",
2379
0
     function );
2380
2381
0
    return( -1 );
2382
0
  }
2383
0
#endif
2384
0
  if( libfdata_list_get_element_value_by_index(
2385
0
       internal_file->recovered_records_list,
2386
0
       (intptr_t *) internal_file->file_io_handle,
2387
0
       (libfdata_cache_t *) internal_file->records_cache,
2388
0
       record_index,
2389
0
       (intptr_t **) &record_values,
2390
0
       0,
2391
0
       error ) != 1 )
2392
0
  {
2393
0
    libcerror_error_set(
2394
0
     error,
2395
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2396
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2397
0
     "%s: unable to retrieve recovered record values: %d.",
2398
0
     function,
2399
0
     record_index );
2400
2401
0
    result = -1;
2402
0
  }
2403
0
  else if( libevt_record_initialize(
2404
0
            record,
2405
0
            internal_file->io_handle,
2406
0
            internal_file->file_io_handle,
2407
0
            record_values,
2408
0
            error ) != 1 )
2409
0
  {
2410
0
    libcerror_error_set(
2411
0
     error,
2412
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2413
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2414
0
     "%s: unable to create record.",
2415
0
     function );
2416
2417
0
    result = -1;
2418
0
  }
2419
0
#if defined( HAVE_LIBEVT_MULTI_THREAD_SUPPORT )
2420
0
  if( libcthreads_read_write_lock_release_for_write(
2421
0
       internal_file->read_write_lock,
2422
0
       error ) != 1 )
2423
0
  {
2424
0
    libcerror_error_set(
2425
0
     error,
2426
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2427
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2428
0
     "%s: unable to release read/write lock for writing.",
2429
0
     function );
2430
2431
0
    return( -1 );
2432
0
  }
2433
0
#endif
2434
0
  return( result );
2435
0
}
2436