Coverage Report

Created: 2025-06-13 07:22

/src/libfwevt/libfwevt/libfwevt_manifest.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Map 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 <byte_stream.h>
24
#include <memory.h>
25
#include <system_string.h>
26
#include <types.h>
27
28
#include "libfwevt_debug.h"
29
#include "libfwevt_libcerror.h"
30
#include "libfwevt_libcnotify.h"
31
#include "libfwevt_libfguid.h"
32
#include "libfwevt_manifest.h"
33
#include "libfwevt_provider.h"
34
#include "libfwevt_types.h"
35
36
#include "fwevt_template.h"
37
38
/* Creates a manifest
39
 * Make sure the value manifest is referencing, is set to NULL
40
 * Returns 1 if successful or -1 on error
41
 */
42
int libfwevt_manifest_initialize(
43
     libfwevt_manifest_t **manifest,
44
     libcerror_error_t **error )
45
4.07k
{
46
4.07k
  libfwevt_internal_manifest_t *internal_manifest = NULL;
47
4.07k
  static char *function                           = "libfwevt_manifest_initialize";
48
49
4.07k
  if( manifest == NULL )
50
0
  {
51
0
    libcerror_error_set(
52
0
     error,
53
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
54
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
55
0
     "%s: invalid manifest.",
56
0
     function );
57
58
0
    return( -1 );
59
0
  }
60
4.07k
  if( *manifest != NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
65
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
66
0
     "%s: invalid manifest value already set.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
4.07k
  internal_manifest = memory_allocate_structure(
72
4.07k
                       libfwevt_internal_manifest_t );
73
74
4.07k
  if( internal_manifest == NULL )
75
0
  {
76
0
    libcerror_error_set(
77
0
     error,
78
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
79
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
80
0
     "%s: unable to create manifest.",
81
0
     function );
82
83
0
    goto on_error;
84
0
  }
85
4.07k
  if( memory_set(
86
4.07k
       internal_manifest,
87
4.07k
       0,
88
4.07k
       sizeof( libfwevt_internal_manifest_t ) ) == NULL )
89
0
  {
90
0
    libcerror_error_set(
91
0
     error,
92
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
93
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
94
0
     "%s: unable to clear manifest.",
95
0
     function );
96
97
0
    memory_free(
98
0
     internal_manifest );
99
100
0
    return( -1 );
101
0
  }
102
4.07k
  if( libcdata_array_initialize(
103
4.07k
       &( internal_manifest->providers_array ),
104
4.07k
       0,
105
4.07k
       error ) != 1 )
106
0
  {
107
0
    libcerror_error_set(
108
0
     error,
109
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
110
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
111
0
     "%s: unable to create providers array.",
112
0
     function );
113
114
0
    goto on_error;
115
0
  }
116
4.07k
  *manifest = (libfwevt_manifest_t *) internal_manifest;
117
118
4.07k
  return( 1 );
119
120
0
on_error:
121
0
  if( internal_manifest != NULL )
122
0
  {
123
0
    memory_free(
124
0
     internal_manifest );
125
0
  }
126
0
  return( -1 );
127
4.07k
}
128
129
/* Frees a manifest
130
 * Returns 1 if successful or -1 on error
131
 */
132
int libfwevt_manifest_free(
133
     libfwevt_manifest_t **manifest,
134
     libcerror_error_t **error )
135
4.07k
{
136
4.07k
  libfwevt_internal_manifest_t *internal_manifest = NULL;
137
4.07k
  static char *function                           = "libfwevt_manifest_free";
138
4.07k
  int result                                      = 1;
139
140
4.07k
  if( manifest == NULL )
141
0
  {
142
0
    libcerror_error_set(
143
0
     error,
144
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
145
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
146
0
     "%s: invalid manifest.",
147
0
     function );
148
149
0
    return( -1 );
150
0
  }
151
4.07k
  if( *manifest != NULL )
152
4.07k
  {
153
4.07k
    internal_manifest = (libfwevt_internal_manifest_t *) *manifest;
154
4.07k
    *manifest         = NULL;
155
156
4.07k
    if( libcdata_array_free(
157
4.07k
         &( internal_manifest->providers_array ),
158
4.07k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_provider_free,
159
4.07k
         error ) != 1 )
160
0
    {
161
0
      libcerror_error_set(
162
0
       error,
163
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
164
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
165
0
       "%s: unable to free providers array.",
166
0
       function );
167
168
0
      result = -1;
169
0
    }
170
4.07k
    memory_free(
171
4.07k
     internal_manifest );
172
4.07k
  }
173
4.07k
  return( result );
174
4.07k
}
175
176
/* Reads the manifest
177
 * Returns 1 if successful or -1 on error
178
 */
179
int libfwevt_manifest_read(
180
     libfwevt_manifest_t *manifest,
181
     const uint8_t *data,
182
     size_t data_size,
183
     libcerror_error_t **error )
184
4.07k
{
185
4.07k
  fwevt_template_manifest_t *wevt_manifest        = NULL;
186
4.07k
  fwevt_template_provider_entry_t *provider_entry = NULL;
187
4.07k
  libfwevt_internal_manifest_t *internal_manifest = NULL;
188
4.07k
  libfwevt_provider_t *provider                   = NULL;
189
4.07k
  static char *function                           = "libfwevt_manifest_read";
190
4.07k
  size_t data_offset                              = 0;
191
4.07k
  uint32_t number_of_providers                    = 0;
192
4.07k
  uint32_t provider_data_offset                   = 0;
193
4.07k
  uint32_t provider_index                         = 0;
194
4.07k
  int entry_index                                 = 0;
195
196
#if defined( HAVE_DEBUG_OUTPUT )
197
  uint32_t value_32bit                            = 0;
198
#endif
199
200
4.07k
  if( manifest == NULL )
201
0
  {
202
0
    libcerror_error_set(
203
0
     error,
204
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
205
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
206
0
     "%s: invalid manifest.",
207
0
     function );
208
209
0
    return( -1 );
210
0
  }
211
4.07k
  internal_manifest = (libfwevt_internal_manifest_t *) manifest;
212
213
4.07k
  if( data == NULL )
214
0
  {
215
0
    libcerror_error_set(
216
0
     error,
217
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
218
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
219
0
     "%s: invalid data.",
220
0
     function );
221
222
0
    return( -1 );
223
0
  }
224
4.07k
  if( ( data_size < sizeof( fwevt_template_manifest_t ) )
225
4.07k
   || ( data_size > (size_t) SSIZE_MAX ) )
226
6
  {
227
6
    libcerror_error_set(
228
6
     error,
229
6
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
230
6
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
231
6
     "%s: invalid data size value out of bounds.",
232
6
     function );
233
234
6
    return( -1 );
235
6
  }
236
4.06k
  wevt_manifest = (fwevt_template_manifest_t *) data;
237
238
#if defined( HAVE_DEBUG_OUTPUT )
239
  if( libcnotify_verbose != 0 )
240
  {
241
    libcnotify_printf(
242
     "%s: manifest data:\n",
243
     function );
244
    libcnotify_print_data(
245
     (uint8_t *) wevt_manifest,
246
     sizeof( fwevt_template_manifest_t ),
247
     0 );
248
  }
249
#endif
250
4.06k
  byte_stream_copy_to_uint16_little_endian(
251
4.06k
   wevt_manifest->major_version,
252
4.06k
   internal_manifest->major_version );
253
254
4.06k
  byte_stream_copy_to_uint16_little_endian(
255
4.06k
   wevt_manifest->minor_version,
256
4.06k
   internal_manifest->minor_version );
257
258
4.06k
  byte_stream_copy_to_uint32_little_endian(
259
4.06k
   wevt_manifest->number_of_providers,
260
4.06k
   number_of_providers );
261
262
#if defined( HAVE_DEBUG_OUTPUT )
263
  if( libcnotify_verbose != 0 )
264
  {
265
    libcnotify_printf(
266
     "%s: signature\t\t\t\t\t: %c%c%c%c\n",
267
     function,
268
     wevt_manifest->signature[ 0 ],
269
     wevt_manifest->signature[ 1 ],
270
     wevt_manifest->signature[ 2 ],
271
     wevt_manifest->signature[ 3 ] );
272
273
    byte_stream_copy_to_uint32_little_endian(
274
     wevt_manifest->size,
275
     value_32bit );
276
    libcnotify_printf(
277
     "%s: size\t\t\t\t\t\t: %" PRIu32 "\n",
278
     function,
279
     value_32bit );
280
281
    libcnotify_printf(
282
     "%s: major version\t\t\t\t\t: %" PRIu16 "\n",
283
     function,
284
     internal_manifest->major_version );
285
286
    libcnotify_printf(
287
     "%s: minor version\t\t\t\t\t: %" PRIu16 "\n",
288
     function,
289
     internal_manifest->minor_version );
290
291
    libcnotify_printf(
292
     "%s: number of providers\t\t\t\t: %" PRIu32 "\n",
293
     function,
294
     number_of_providers );
295
296
    libcnotify_printf(
297
     "\n" );
298
  }
299
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
300
301
4.06k
  if( memory_compare(
302
4.06k
       wevt_manifest->signature,
303
4.06k
       "CRIM",
304
4.06k
       4 ) != 0 )
305
35
  {
306
35
    libcerror_error_set(
307
35
     error,
308
35
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
309
35
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
310
35
     "%s: unsupported manifest signature.",
311
35
     function );
312
313
35
    goto on_error;
314
35
  }
315
4.03k
  data_offset = sizeof( fwevt_template_manifest_t );
316
317
4.03k
  for( provider_index = 0;
318
13.2k
       provider_index < number_of_providers;
319
9.17k
       provider_index++ )
320
9.81k
  {
321
9.81k
    if( ( data_size - data_offset ) < sizeof( fwevt_template_provider_entry_t ) )
322
120
    {
323
120
      libcerror_error_set(
324
120
       error,
325
120
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
326
120
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
327
120
       "%s: invalid data value too small.",
328
120
       function );
329
330
120
      goto on_error;
331
120
    }
332
9.69k
    provider_entry = (fwevt_template_provider_entry_t *) &( data[ data_offset ] );
333
334
#if defined( HAVE_DEBUG_OUTPUT )
335
    if( libcnotify_verbose != 0 )
336
    {
337
      libcnotify_printf(
338
       "%s: provider entry: %02" PRIu32 " data:\n",
339
       function,
340
       provider_index );
341
      libcnotify_print_data(
342
       (uint8_t *) provider_entry,
343
       sizeof( fwevt_template_provider_entry_t ),
344
       0 );
345
    }
346
#endif
347
9.69k
    byte_stream_copy_to_uint32_little_endian(
348
9.69k
     provider_entry->data_offset,
349
9.69k
     provider_data_offset );
350
351
#if defined( HAVE_DEBUG_OUTPUT )
352
    if( libcnotify_verbose != 0 )
353
    {
354
      libcnotify_printf(
355
       "%s: provider entry: %02" PRIu32 ":\n",
356
       function,
357
       provider_index );
358
359
      if( libfwevt_debug_print_guid_value(
360
           function,
361
           "identifier\t\t\t\t\t",
362
           provider_entry->identifier,
363
           16,
364
           LIBFGUID_ENDIAN_LITTLE,
365
           LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
366
           error ) != 1 )
367
      {
368
        libcerror_error_set(
369
         error,
370
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
371
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
372
         "%s: unable to print GUID value.",
373
         function );
374
375
        goto on_error;
376
      }
377
      libcnotify_printf(
378
       "%s: data offset\t\t\t\t\t: 0x%08" PRIx32 "\n",
379
       function,
380
       provider_data_offset );
381
382
      libcnotify_printf(
383
       "\n" );
384
    }
385
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
386
387
9.69k
    data_offset += sizeof( fwevt_template_provider_entry_t );
388
389
9.69k
    if( libfwevt_provider_initialize(
390
9.69k
         &provider,
391
9.69k
         provider_entry->identifier,
392
9.69k
         16,
393
9.69k
         error ) != 1 )
394
0
    {
395
0
      libcerror_error_set(
396
0
       error,
397
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
398
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
399
0
       "%s: unable to create provider: %" PRIu32 ".",
400
0
       function,
401
0
       provider_index );
402
403
0
      goto on_error;
404
0
    }
405
9.69k
    if( libfwevt_provider_read_data(
406
9.69k
         provider,
407
9.69k
         data,
408
9.69k
         data_size,
409
9.69k
         (size_t) provider_data_offset,
410
9.69k
         error ) != 1 )
411
517
    {
412
517
      libcerror_error_set(
413
517
       error,
414
517
       LIBCERROR_ERROR_DOMAIN_IO,
415
517
       LIBCERROR_IO_ERROR_READ_FAILED,
416
517
       "%s: unable to read provider: %d.",
417
517
       function,
418
517
       provider_index );
419
420
517
      goto on_error;
421
517
    }
422
9.17k
    if( libcdata_array_append_entry(
423
9.17k
         internal_manifest->providers_array,
424
9.17k
         &entry_index,
425
9.17k
         (intptr_t *) provider,
426
9.17k
         error ) != 1 )
427
0
    {
428
0
      libcerror_error_set(
429
0
       error,
430
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
431
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
432
0
       "%s: unable to append provider: %" PRIu32 ".",
433
0
       function,
434
0
       provider_index );
435
436
0
      goto on_error;
437
0
    }
438
9.17k
    provider = NULL;
439
9.17k
  }
440
/* TODO refactor to read on demand ? */
441
3.39k
  for( provider_index = 0;
442
8.66k
       provider_index < number_of_providers;
443
5.26k
       provider_index++ )
444
8.06k
  {
445
8.06k
    if( libcdata_array_get_entry_by_index(
446
8.06k
         internal_manifest->providers_array,
447
8.06k
         provider_index,
448
8.06k
         (intptr_t **) &provider,
449
8.06k
         error ) != 1 )
450
0
    {
451
0
      libcerror_error_set(
452
0
       error,
453
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
454
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
455
0
       "%s: unable to retrieve provider: %d.",
456
0
       function,
457
0
       provider_index );
458
459
0
      provider = NULL;
460
461
0
      goto on_error;
462
0
    }
463
8.06k
    if( libfwevt_provider_read_channels(
464
8.06k
         provider,
465
8.06k
         data,
466
8.06k
         data_size,
467
8.06k
         error ) != 1 )
468
331
    {
469
331
      libcerror_error_set(
470
331
       error,
471
331
       LIBCERROR_ERROR_DOMAIN_IO,
472
331
       LIBCERROR_IO_ERROR_READ_FAILED,
473
331
       "%s: unable to read channels.",
474
331
       function );
475
476
331
      provider = NULL;
477
478
331
      goto on_error;
479
331
    }
480
7.73k
    if( libfwevt_provider_read_events(
481
7.73k
         provider,
482
7.73k
         data,
483
7.73k
         data_size,
484
7.73k
         error ) != 1 )
485
173
    {
486
173
      libcerror_error_set(
487
173
       error,
488
173
       LIBCERROR_ERROR_DOMAIN_IO,
489
173
       LIBCERROR_IO_ERROR_READ_FAILED,
490
173
       "%s: unable to read events.",
491
173
       function );
492
493
173
      provider = NULL;
494
495
173
      goto on_error;
496
173
    }
497
7.56k
    if( libfwevt_provider_read_keywords(
498
7.56k
         provider,
499
7.56k
         data,
500
7.56k
         data_size,
501
7.56k
         error ) != 1 )
502
291
    {
503
291
      libcerror_error_set(
504
291
       error,
505
291
       LIBCERROR_ERROR_DOMAIN_IO,
506
291
       LIBCERROR_IO_ERROR_READ_FAILED,
507
291
       "%s: unable to read keywords.",
508
291
       function );
509
510
291
      provider = NULL;
511
512
291
      goto on_error;
513
291
    }
514
7.27k
    if( libfwevt_provider_read_levels(
515
7.27k
         provider,
516
7.27k
         data,
517
7.27k
         data_size,
518
7.27k
         error ) != 1 )
519
335
    {
520
335
      libcerror_error_set(
521
335
       error,
522
335
       LIBCERROR_ERROR_DOMAIN_IO,
523
335
       LIBCERROR_IO_ERROR_READ_FAILED,
524
335
       "%s: unable to read levels.",
525
335
       function );
526
527
335
      provider = NULL;
528
529
335
      goto on_error;
530
335
    }
531
6.93k
    if( libfwevt_provider_read_maps(
532
6.93k
         provider,
533
6.93k
         data,
534
6.93k
         data_size,
535
6.93k
         error ) != 1 )
536
309
    {
537
309
      libcerror_error_set(
538
309
       error,
539
309
       LIBCERROR_ERROR_DOMAIN_IO,
540
309
       LIBCERROR_IO_ERROR_READ_FAILED,
541
309
       "%s: unable to read maps.",
542
309
       function );
543
544
309
      provider = NULL;
545
546
309
      goto on_error;
547
309
    }
548
6.62k
    if( libfwevt_provider_read_opcodes(
549
6.62k
         provider,
550
6.62k
         data,
551
6.62k
         data_size,
552
6.62k
         error ) != 1 )
553
302
    {
554
302
      libcerror_error_set(
555
302
       error,
556
302
       LIBCERROR_ERROR_DOMAIN_IO,
557
302
       LIBCERROR_IO_ERROR_READ_FAILED,
558
302
       "%s: unable to read opcodes.",
559
302
       function );
560
561
302
      provider = NULL;
562
563
302
      goto on_error;
564
302
    }
565
6.32k
    if( libfwevt_provider_read_tasks(
566
6.32k
         provider,
567
6.32k
         data,
568
6.32k
         data_size,
569
6.32k
         error ) != 1 )
570
356
    {
571
356
      libcerror_error_set(
572
356
       error,
573
356
       LIBCERROR_ERROR_DOMAIN_IO,
574
356
       LIBCERROR_IO_ERROR_READ_FAILED,
575
356
       "%s: unable to read tasks.",
576
356
       function );
577
578
356
      provider = NULL;
579
580
356
      goto on_error;
581
356
    }
582
5.96k
    if( libfwevt_provider_read_templates(
583
5.96k
         provider,
584
5.96k
         data,
585
5.96k
         data_size,
586
5.96k
         error ) != 1 )
587
700
    {
588
700
      libcerror_error_set(
589
700
       error,
590
700
       LIBCERROR_ERROR_DOMAIN_IO,
591
700
       LIBCERROR_IO_ERROR_READ_FAILED,
592
700
       "%s: unable to read templates.",
593
700
       function );
594
595
700
      provider = NULL;
596
597
700
      goto on_error;
598
700
    }
599
5.96k
  }
600
/* TODO end refactor */
601
#if defined( HAVE_DEBUG_OUTPUT )
602
  if( libcnotify_verbose != 0 )
603
  {
604
    if( number_of_providers > 0 )
605
    {
606
      libcnotify_printf(
607
       "\n" );
608
    }
609
  }
610
#endif
611
596
  return( 1 );
612
613
3.46k
on_error:
614
3.46k
  if( provider != NULL )
615
517
  {
616
517
    libfwevt_internal_provider_free(
617
517
     (libfwevt_internal_provider_t **) &provider,
618
517
     NULL );
619
517
  }
620
3.46k
  libcdata_array_empty(
621
3.46k
   internal_manifest->providers_array,
622
3.46k
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_provider_free,
623
3.46k
   NULL );
624
625
3.46k
  return( -1 );
626
3.39k
}
627
628
/* Retrieves the number of providers
629
 * Returns 1 if successful or -1 on error
630
 */
631
int libfwevt_manifest_get_number_of_providers(
632
     libfwevt_manifest_t *manifest,
633
     int *number_of_providers,
634
     libcerror_error_t **error )
635
0
{
636
0
  libfwevt_internal_manifest_t *internal_manifest = NULL;
637
0
  static char *function                           = "libfwevt_manifest_get_number_of_providers";
638
639
0
  if( manifest == NULL )
640
0
  {
641
0
    libcerror_error_set(
642
0
     error,
643
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
644
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
645
0
     "%s: invalid manifest.",
646
0
     function );
647
648
0
    return( -1 );
649
0
  }
650
0
  internal_manifest = (libfwevt_internal_manifest_t *) manifest;
651
652
0
  if( libcdata_array_get_number_of_entries(
653
0
       internal_manifest->providers_array,
654
0
       number_of_providers,
655
0
       error ) != 1 )
656
0
  {
657
0
    libcerror_error_set(
658
0
     error,
659
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
660
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
661
0
     "%s: unable to retrieve number of entries.",
662
0
     function );
663
664
0
    return( -1 );
665
0
  }
666
0
  return( 1 );
667
0
}
668
669
/* Retrieves a specific provider
670
 * Returns 1 if successful or -1 on error
671
 */
672
int libfwevt_manifest_get_provider_by_index(
673
     libfwevt_manifest_t *manifest,
674
     int provider_index,
675
     libfwevt_provider_t **provider,
676
     libcerror_error_t **error )
677
0
{
678
0
  libfwevt_internal_manifest_t *internal_manifest = NULL;
679
0
  static char *function                           = "libfwevt_manifest_get_provider_by_index";
680
681
0
  if( manifest == NULL )
682
0
  {
683
0
    libcerror_error_set(
684
0
     error,
685
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
686
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
687
0
     "%s: invalid manifest.",
688
0
     function );
689
690
0
    return( -1 );
691
0
  }
692
0
  internal_manifest = (libfwevt_internal_manifest_t *) manifest;
693
694
0
  if( libcdata_array_get_entry_by_index(
695
0
       internal_manifest->providers_array,
696
0
       provider_index,
697
0
       (intptr_t **) provider,
698
0
       error ) != 1 )
699
0
  {
700
0
    libcerror_error_set(
701
0
     error,
702
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
703
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
704
0
     "%s: unable to retrieve entry: %d.",
705
0
     function,
706
0
     provider_index );
707
708
0
    return( -1 );
709
0
  }
710
0
  return( 1 );
711
0
}
712
713
/* Retrieves a specific provider by identifier (GUID)
714
 * Returns 1 if successful, 0 if not available or -1 on error
715
 */
716
int libfwevt_manifest_get_provider_by_identifier(
717
     libfwevt_manifest_t *manifest,
718
     const uint8_t *provider_identifier,
719
     size_t provider_identifier_size,
720
     libfwevt_provider_t **provider,
721
     libcerror_error_t **error )
722
0
{
723
0
  libfwevt_internal_manifest_t *internal_manifest = NULL;
724
0
  libfwevt_provider_t *safe_provider              = NULL;
725
0
  static char *function                           = "libfwevt_manifest_get_provider_by_identifier";
726
0
  int number_of_providers                         = 0;
727
0
  int provider_index                              = 0;
728
0
  int result                                      = 0;
729
730
0
  if( manifest == NULL )
731
0
  {
732
0
    libcerror_error_set(
733
0
     error,
734
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
735
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
736
0
     "%s: invalid manifest.",
737
0
     function );
738
739
0
    return( -1 );
740
0
  }
741
0
  internal_manifest = (libfwevt_internal_manifest_t *) manifest;
742
743
0
  if( provider_identifier == NULL )
744
0
  {
745
0
    libcerror_error_set(
746
0
     error,
747
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
748
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
749
0
     "%s: invalid provider identifier.",
750
0
     function );
751
752
0
    return( -1 );
753
0
  }
754
0
  if( provider_identifier_size != 16 )
755
0
  {
756
0
    libcerror_error_set(
757
0
     error,
758
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
759
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
760
0
     "%s: invalid provider identifier size value out of bounds.",
761
0
     function );
762
763
0
    return( -1 );
764
0
  }
765
0
  if( provider == NULL )
766
0
  {
767
0
    libcerror_error_set(
768
0
     error,
769
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
770
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
771
0
     "%s: invalid provider.",
772
0
     function );
773
774
0
    return( -1 );
775
0
  }
776
0
  *provider = NULL;
777
778
0
  if( libcdata_array_get_number_of_entries(
779
0
       internal_manifest->providers_array,
780
0
       &number_of_providers,
781
0
       error ) != 1 )
782
0
  {
783
0
    libcerror_error_set(
784
0
     error,
785
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
786
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
787
0
     "%s: unable to retrieve number of entries.",
788
0
     function );
789
790
0
    return( -1 );
791
0
  }
792
0
  for( provider_index = 0;
793
0
       provider_index < number_of_providers;
794
0
       provider_index++ )
795
0
  {
796
0
    if( libcdata_array_get_entry_by_index(
797
0
         internal_manifest->providers_array,
798
0
         provider_index,
799
0
         (intptr_t **) &safe_provider,
800
0
         error ) != 1 )
801
0
    {
802
0
      libcerror_error_set(
803
0
       error,
804
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
805
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
806
0
       "%s: unable to retrieve entry: %d.",
807
0
       function,
808
0
       provider_index );
809
810
0
      return( -1 );
811
0
    }
812
0
    result = libfwevt_provider_compare_identifier(
813
0
              safe_provider,
814
0
              provider_identifier,
815
0
              16,
816
0
              error );
817
818
0
    if( result == -1 )
819
0
    {
820
0
      libcerror_error_set(
821
0
       error,
822
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
823
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
824
0
       "%s: unable to compare identifier of provider: %d.",
825
0
       function,
826
0
       provider_index );
827
828
0
      return( -1 );
829
0
    }
830
0
    else if( result != 0 )
831
0
    {
832
0
      *provider = safe_provider;
833
834
0
      return( 1 );
835
0
    }
836
0
  }
837
0
  return( 0 );
838
0
}
839