Coverage Report

Created: 2023-06-07 06:53

/src/libfwevt/libfwevt/libfwevt_provider.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Provider functions
3
 *
4
 * Copyright (C) 2011-2023, 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 <types.h>
26
27
#include "libfwevt_channel.h"
28
#include "libfwevt_event.h"
29
#include "libfwevt_keyword.h"
30
#include "libfwevt_level.h"
31
#include "libfwevt_libcdata.h"
32
#include "libfwevt_libcerror.h"
33
#include "libfwevt_libcnotify.h"
34
#include "libfwevt_libfguid.h"
35
#include "libfwevt_libuna.h"
36
#include "libfwevt_map.h"
37
#include "libfwevt_opcode.h"
38
#include "libfwevt_provider.h"
39
#include "libfwevt_task.h"
40
#include "libfwevt_template.h"
41
#include "libfwevt_types.h"
42
43
#include "fwevt_template.h"
44
45
/* Creates a provider
46
 * Make sure the value provider is referencing, is set to NULL
47
 * Returns 1 if successful or -1 on error
48
 */
49
int libfwevt_provider_initialize(
50
     libfwevt_provider_t **provider,
51
     const uint8_t *identifier,
52
     size_t identifier_size,
53
     libcerror_error_t **error )
54
10.3k
{
55
10.3k
  libfwevt_internal_provider_t *internal_provider = NULL;
56
10.3k
  static char *function                           = "libfwevt_provider_initialize";
57
58
10.3k
  if( provider == NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
63
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
64
0
     "%s: invalid provider.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
10.3k
  if( *provider != NULL )
70
0
  {
71
0
    libcerror_error_set(
72
0
     error,
73
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
74
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
75
0
     "%s: invalid provider value already set.",
76
0
     function );
77
78
0
    return( -1 );
79
0
  }
80
10.3k
  if( identifier == NULL )
81
0
  {
82
0
    libcerror_error_set(
83
0
     error,
84
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
85
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
86
0
     "%s: invalid identifier.",
87
0
     function );
88
89
0
    return( -1 );
90
0
  }
91
10.3k
  if( identifier_size != 16 )
92
0
  {
93
0
    libcerror_error_set(
94
0
     error,
95
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
96
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
97
0
     "%s: invalid identifier size value out of bounds.",
98
0
     function );
99
100
0
    return( -1 );
101
0
  }
102
10.3k
  internal_provider = memory_allocate_structure(
103
10.3k
                       libfwevt_internal_provider_t );
104
105
10.3k
  if( internal_provider == NULL )
106
0
  {
107
0
    libcerror_error_set(
108
0
     error,
109
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
110
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
111
0
     "%s: unable to create provider.",
112
0
     function );
113
114
0
    goto on_error;
115
0
  }
116
10.3k
  if( memory_set(
117
10.3k
       internal_provider,
118
10.3k
       0,
119
10.3k
       sizeof( libfwevt_internal_provider_t ) ) == NULL )
120
0
  {
121
0
    libcerror_error_set(
122
0
     error,
123
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
124
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
125
0
     "%s: unable to clear provider.",
126
0
     function );
127
128
0
    memory_free(
129
0
     internal_provider );
130
131
0
    return( -1 );
132
0
  }
133
10.3k
  if( memory_copy(
134
10.3k
       internal_provider->identifier,
135
10.3k
       identifier,
136
10.3k
       16 ) == NULL )
137
0
  {
138
0
    libcerror_error_set(
139
0
     error,
140
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
141
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
142
0
     "%s: unable to copy identifier.",
143
0
     function );
144
145
0
    goto on_error;
146
0
  }
147
10.3k
  if( libcdata_array_initialize(
148
10.3k
       &( internal_provider->channels_array ),
149
10.3k
       0,
150
10.3k
       error ) != 1 )
151
0
  {
152
0
    libcerror_error_set(
153
0
     error,
154
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
155
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
156
0
     "%s: unable to create channels array.",
157
0
     function );
158
159
0
    goto on_error;
160
0
  }
161
10.3k
  if( libcdata_array_initialize(
162
10.3k
       &( internal_provider->events_array ),
163
10.3k
       0,
164
10.3k
       error ) != 1 )
165
0
  {
166
0
    libcerror_error_set(
167
0
     error,
168
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
169
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
170
0
     "%s: unable to create events array.",
171
0
     function );
172
173
0
    goto on_error;
174
0
  }
175
10.3k
  if( libcdata_array_initialize(
176
10.3k
       &( internal_provider->keywords_array ),
177
10.3k
       0,
178
10.3k
       error ) != 1 )
179
0
  {
180
0
    libcerror_error_set(
181
0
     error,
182
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
183
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
184
0
     "%s: unable to create keywords array.",
185
0
     function );
186
187
0
    goto on_error;
188
0
  }
189
10.3k
  if( libcdata_array_initialize(
190
10.3k
       &( internal_provider->levels_array ),
191
10.3k
       0,
192
10.3k
       error ) != 1 )
193
0
  {
194
0
    libcerror_error_set(
195
0
     error,
196
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
197
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
198
0
     "%s: unable to create levels array.",
199
0
     function );
200
201
0
    goto on_error;
202
0
  }
203
10.3k
  if( libcdata_array_initialize(
204
10.3k
       &( internal_provider->maps_array ),
205
10.3k
       0,
206
10.3k
       error ) != 1 )
207
0
  {
208
0
    libcerror_error_set(
209
0
     error,
210
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
211
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
212
0
     "%s: unable to create maps array.",
213
0
     function );
214
215
0
    goto on_error;
216
0
  }
217
10.3k
  if( libcdata_array_initialize(
218
10.3k
       &( internal_provider->opcodes_array ),
219
10.3k
       0,
220
10.3k
       error ) != 1 )
221
0
  {
222
0
    libcerror_error_set(
223
0
     error,
224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
225
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
226
0
     "%s: unable to create opcodes array.",
227
0
     function );
228
229
0
    goto on_error;
230
0
  }
231
10.3k
  if( libcdata_array_initialize(
232
10.3k
       &( internal_provider->tasks_array ),
233
10.3k
       0,
234
10.3k
       error ) != 1 )
235
0
  {
236
0
    libcerror_error_set(
237
0
     error,
238
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
239
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
240
0
     "%s: unable to create tasks array.",
241
0
     function );
242
243
0
    goto on_error;
244
0
  }
245
10.3k
  if( libcdata_array_initialize(
246
10.3k
       &( internal_provider->templates_array ),
247
10.3k
       0,
248
10.3k
       error ) != 1 )
249
0
  {
250
0
    libcerror_error_set(
251
0
     error,
252
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
253
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
254
0
     "%s: unable to create templates array.",
255
0
     function );
256
257
0
    goto on_error;
258
0
  }
259
10.3k
  *provider = (libfwevt_provider_t *) internal_provider;
260
261
10.3k
  return( 1 );
262
263
0
on_error:
264
0
  if( internal_provider != NULL )
265
0
  {
266
0
    if( internal_provider->tasks_array != NULL )
267
0
    {
268
0
      libcdata_array_free(
269
0
       &( internal_provider->tasks_array ),
270
0
       NULL,
271
0
       NULL );
272
0
    }
273
0
    if( internal_provider->opcodes_array != NULL )
274
0
    {
275
0
      libcdata_array_free(
276
0
       &( internal_provider->opcodes_array ),
277
0
       NULL,
278
0
       NULL );
279
0
    }
280
0
    if( internal_provider->maps_array != NULL )
281
0
    {
282
0
      libcdata_array_free(
283
0
       &( internal_provider->maps_array ),
284
0
       NULL,
285
0
       NULL );
286
0
    }
287
0
    if( internal_provider->levels_array != NULL )
288
0
    {
289
0
      libcdata_array_free(
290
0
       &( internal_provider->levels_array ),
291
0
       NULL,
292
0
       NULL );
293
0
    }
294
0
    if( internal_provider->keywords_array != NULL )
295
0
    {
296
0
      libcdata_array_free(
297
0
       &( internal_provider->keywords_array ),
298
0
       NULL,
299
0
       NULL );
300
0
    }
301
0
    if( internal_provider->events_array != NULL )
302
0
    {
303
0
      libcdata_array_free(
304
0
       &( internal_provider->events_array ),
305
0
       NULL,
306
0
       NULL );
307
0
    }
308
0
    if( internal_provider->channels_array != NULL )
309
0
    {
310
0
      libcdata_array_free(
311
0
       &( internal_provider->channels_array ),
312
0
       NULL,
313
0
       NULL );
314
0
    }
315
0
    memory_free(
316
0
     internal_provider );
317
0
  }
318
0
  return( -1 );
319
10.3k
}
320
321
/* Frees a provider
322
 * Returns 1 if successful or -1 on error
323
 */
324
int libfwevt_provider_free(
325
     libfwevt_provider_t **provider,
326
     libcerror_error_t **error )
327
0
{
328
0
  static char *function = "libfwevt_provider_free";
329
330
0
  if( provider == NULL )
331
0
  {
332
0
    libcerror_error_set(
333
0
     error,
334
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
335
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
336
0
     "%s: invalid provider.",
337
0
     function );
338
339
0
    return( -1 );
340
0
  }
341
0
  if( *provider != NULL )
342
0
  {
343
0
    *provider = NULL;
344
0
  }
345
0
  return( 1 );
346
0
}
347
348
/* Frees a provider
349
 * Returns 1 if successful or -1 on error
350
 */
351
int libfwevt_internal_provider_free(
352
     libfwevt_internal_provider_t **internal_provider,
353
     libcerror_error_t **error )
354
10.3k
{
355
10.3k
  static char *function = "libfwevt_internal_provider_free";
356
10.3k
  int result            = 1;
357
358
10.3k
  if( internal_provider == NULL )
359
0
  {
360
0
    libcerror_error_set(
361
0
     error,
362
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
363
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
364
0
     "%s: invalid provider.",
365
0
     function );
366
367
0
    return( -1 );
368
0
  }
369
10.3k
  if( *internal_provider != NULL )
370
10.3k
  {
371
10.3k
    if( libcdata_array_free(
372
10.3k
         &( ( *internal_provider )->channels_array ),
373
10.3k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_channel_free,
374
10.3k
         error ) != 1 )
375
0
    {
376
0
      libcerror_error_set(
377
0
       error,
378
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
379
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
380
0
       "%s: unable to free channels array.",
381
0
       function );
382
383
0
      result = -1;
384
0
    }
385
10.3k
    if( libcdata_array_free(
386
10.3k
         &( ( *internal_provider )->events_array ),
387
10.3k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_event_free,
388
10.3k
         error ) != 1 )
389
0
    {
390
0
      libcerror_error_set(
391
0
       error,
392
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
393
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
394
0
       "%s: unable to free events array.",
395
0
       function );
396
397
0
      result = -1;
398
0
    }
399
10.3k
    if( libcdata_array_free(
400
10.3k
         &( ( *internal_provider )->keywords_array ),
401
10.3k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_keyword_free,
402
10.3k
         error ) != 1 )
403
0
    {
404
0
      libcerror_error_set(
405
0
       error,
406
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
407
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
408
0
       "%s: unable to free keywords array.",
409
0
       function );
410
411
0
      result = -1;
412
0
    }
413
10.3k
    if( libcdata_array_free(
414
10.3k
         &( ( *internal_provider )->levels_array ),
415
10.3k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_level_free,
416
10.3k
         error ) != 1 )
417
0
    {
418
0
      libcerror_error_set(
419
0
       error,
420
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
421
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
422
0
       "%s: unable to free levels array.",
423
0
       function );
424
425
0
      result = -1;
426
0
    }
427
10.3k
    if( libcdata_array_free(
428
10.3k
         &( ( *internal_provider )->maps_array ),
429
10.3k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_map_free,
430
10.3k
         error ) != 1 )
431
0
    {
432
0
      libcerror_error_set(
433
0
       error,
434
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
435
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
436
0
       "%s: unable to free maps array.",
437
0
       function );
438
439
0
      result = -1;
440
0
    }
441
10.3k
    if( libcdata_array_free(
442
10.3k
         &( ( *internal_provider )->opcodes_array ),
443
10.3k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_opcode_free,
444
10.3k
         error ) != 1 )
445
0
    {
446
0
      libcerror_error_set(
447
0
       error,
448
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
449
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
450
0
       "%s: unable to free opcodes array.",
451
0
       function );
452
453
0
      result = -1;
454
0
    }
455
10.3k
    if( libcdata_array_free(
456
10.3k
         &( ( *internal_provider )->tasks_array ),
457
10.3k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_task_free,
458
10.3k
         error ) != 1 )
459
0
    {
460
0
      libcerror_error_set(
461
0
       error,
462
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
463
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
464
0
       "%s: unable to free tasks array.",
465
0
       function );
466
467
0
      result = -1;
468
0
    }
469
10.3k
    if( libcdata_array_free(
470
10.3k
         &( ( *internal_provider )->templates_array ),
471
10.3k
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_template_free,
472
10.3k
         error ) != 1 )
473
0
    {
474
0
      libcerror_error_set(
475
0
       error,
476
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
477
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
478
0
       "%s: unable to free templates array.",
479
0
       function );
480
481
0
      result = -1;
482
0
    }
483
10.3k
    memory_free(
484
10.3k
     *internal_provider );
485
486
10.3k
    *internal_provider = NULL;
487
10.3k
  }
488
10.3k
  return( result );
489
10.3k
}
490
491
/* Reads the provider
492
 * Returns 1 if successful or -1 on error
493
 */
494
int libfwevt_provider_read_data(
495
     libfwevt_provider_t *provider,
496
     const uint8_t *data,
497
     size_t data_size,
498
     size_t data_offset,
499
     libcerror_error_t **error )
500
10.3k
{
501
10.3k
  libfwevt_internal_provider_t *internal_provider = NULL;
502
10.3k
  fwevt_template_provider_t *wevt_provider        = NULL;
503
10.3k
  static char *function                           = "libfwevt_provider_read_data";
504
10.3k
  uint32_t descriptor_index                       = 0;
505
10.3k
  uint32_t descriptor_offset                      = 0;
506
10.3k
  uint32_t descriptor_type                        = 0;
507
10.3k
  uint32_t number_of_descriptors                  = 0;
508
10.3k
  uint32_t number_of_unknown2                     = 0;
509
10.3k
  uint32_t unknown2_index                         = 0;
510
511
#if defined( HAVE_DEBUG_OUTPUT )
512
  uint32_t value_32bit                            = 0;
513
#endif
514
515
10.3k
  if( provider == NULL )
516
0
  {
517
0
    libcerror_error_set(
518
0
     error,
519
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
520
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
521
0
     "%s: invalid provider.",
522
0
     function );
523
524
0
    return( -1 );
525
0
  }
526
10.3k
  internal_provider = (libfwevt_internal_provider_t *) provider;
527
528
10.3k
  if( data == NULL )
529
0
  {
530
0
    libcerror_error_set(
531
0
     error,
532
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
533
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
534
0
     "%s: invalid data.",
535
0
     function );
536
537
0
    return( -1 );
538
0
  }
539
10.3k
  if( data_size > (size_t) SSIZE_MAX )
540
0
  {
541
0
    libcerror_error_set(
542
0
     error,
543
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
544
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
545
0
     "%s: invalid data size value exceeds maximum.",
546
0
     function );
547
548
0
    return( -1 );
549
0
  }
550
10.3k
  if( data_offset >= data_size )
551
33
  {
552
33
    libcerror_error_set(
553
33
     error,
554
33
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
555
33
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
556
33
     "%s: invalid data offset value out of bounds.",
557
33
     function );
558
559
33
    return( -1 );
560
33
  }
561
10.3k
  if( ( data_size - data_offset ) < sizeof( fwevt_template_provider_t ) )
562
7
  {
563
7
    libcerror_error_set(
564
7
     error,
565
7
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
566
7
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
567
7
     "%s: invalid data size value out of bounds.",
568
7
     function );
569
570
7
    return( -1 );
571
7
  }
572
10.2k
  wevt_provider = (fwevt_template_provider_t *) &( data[ data_offset ] );
573
574
#if defined( HAVE_DEBUG_OUTPUT )
575
  if( libcnotify_verbose != 0 )
576
  {
577
    libcnotify_printf(
578
     "%s: reading event provider data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
579
     function,
580
     data_offset,
581
     data_offset );
582
583
    libcnotify_printf(
584
     "%s: event provider data:\n",
585
     function );
586
    libcnotify_print_data(
587
     (uint8_t *) wevt_provider,
588
     sizeof( fwevt_template_provider_t ),
589
     0 );
590
  }
591
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
592
593
10.2k
  byte_stream_copy_to_uint32_little_endian(
594
10.2k
   wevt_provider->number_of_descriptors,
595
10.2k
   number_of_descriptors );
596
597
10.2k
  byte_stream_copy_to_uint32_little_endian(
598
10.2k
   wevt_provider->number_of_unknown2,
599
10.2k
   number_of_unknown2 );
600
601
#if defined( HAVE_DEBUG_OUTPUT )
602
  if( libcnotify_verbose != 0 )
603
  {
604
    libcnotify_printf(
605
     "%s: signature\t\t\t\t\t: %c%c%c%c\n",
606
     function,
607
     wevt_provider->signature[ 0 ],
608
     wevt_provider->signature[ 1 ],
609
     wevt_provider->signature[ 2 ],
610
     wevt_provider->signature[ 3 ] );
611
612
    byte_stream_copy_to_uint32_little_endian(
613
     wevt_provider->size,
614
     value_32bit );
615
    libcnotify_printf(
616
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
617
     function,
618
     value_32bit );
619
620
    byte_stream_copy_to_uint32_little_endian(
621
     wevt_provider->message_identifier,
622
     value_32bit );
623
    libcnotify_printf(
624
     "%s: message identifier\t\t\t\t: 0x%08" PRIx32 "\n",
625
     function,
626
     value_32bit );
627
628
    libcnotify_printf(
629
     "%s: number of descriptors\t\t\t: %" PRIu32 "\n",
630
     function,
631
     number_of_descriptors );
632
633
    libcnotify_printf(
634
     "%s: number of unknown2\t\t\t\t: %" PRIu32 "\n",
635
     function,
636
     number_of_unknown2 );
637
638
    libcnotify_printf(
639
     "\n" );
640
  }
641
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
642
643
10.2k
  data_offset += sizeof( fwevt_template_provider_t );
644
645
10.2k
  if( memory_compare(
646
10.2k
       wevt_provider->signature,
647
10.2k
       "WEVT",
648
10.2k
       4 ) != 0 )
649
36
  {
650
36
    libcerror_error_set(
651
36
     error,
652
36
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
653
36
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
654
36
     "%s: unsupported event provider signature.",
655
36
     function );
656
657
36
    return( -1 );
658
36
  }
659
10.2k
  if( number_of_descriptors > 0 )
660
9.87k
  {
661
9.87k
    if( ( number_of_descriptors > ( (uint32_t) UINT32_MAX / 8 ) )
662
9.87k
     || ( ( number_of_descriptors * 8 ) > ( data_size - data_offset ) ) )
663
77
    {
664
77
      libcerror_error_set(
665
77
       error,
666
77
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
667
77
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
668
77
       "%s: invalid number of descriptors value out of bounds.",
669
77
       function );
670
671
77
      return( -1 );
672
77
    }
673
9.79k
    for( descriptor_index = 0;
674
48.9k
         descriptor_index < number_of_descriptors;
675
39.1k
         descriptor_index++ )
676
39.1k
    {
677
#if defined( HAVE_DEBUG_OUTPUT )
678
      if( libcnotify_verbose != 0 )
679
      {
680
        libcnotify_printf(
681
         "%s: descriptor: %02" PRIu32 " data:\n",
682
         function,
683
         descriptor_index );
684
        libcnotify_print_data(
685
         &( data[ data_offset ] ),
686
         8,
687
         0 );
688
      }
689
#endif
690
39.1k
      byte_stream_copy_to_uint32_little_endian(
691
39.1k
       &( data[ data_offset ] ),
692
39.1k
       descriptor_offset );
693
694
#if defined( HAVE_DEBUG_OUTPUT )
695
      if( libcnotify_verbose != 0 )
696
      {
697
        libcnotify_printf(
698
         "%s: descriptor: %02" PRIu32 " offset\t\t\t: 0x%08" PRIx32 "\n",
699
         function,
700
         descriptor_index,
701
         descriptor_offset );
702
703
        byte_stream_copy_to_uint32_little_endian(
704
         &( data[ data_offset + 4 ] ),
705
         value_32bit );
706
        libcnotify_printf(
707
         "%s: descriptor: %02" PRIu32 " unknown1\t\t\t: %" PRIu32 "\n",
708
         function,
709
         descriptor_index,
710
         value_32bit );
711
      }
712
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
713
714
39.1k
      data_offset += 8;
715
716
39.1k
      if( descriptor_offset >= ( data_size - 4 ) )
717
28
      {
718
28
        libcerror_error_set(
719
28
         error,
720
28
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
721
28
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
722
28
         "%s: invalid descriptor offset value out of bounds.",
723
28
         function );
724
725
28
        return( -1 );
726
28
      }
727
#if defined( HAVE_DEBUG_OUTPUT )
728
      if( libcnotify_verbose != 0 )
729
      {
730
        libcnotify_printf(
731
         "%s: descriptor: %02" PRIu32 " type\t\t\t: %c%c%c%c\n",
732
         function,
733
         descriptor_index,
734
         data[ descriptor_offset ],
735
         data[ descriptor_offset + 1 ],
736
         data[ descriptor_offset + 2 ],
737
         data[ descriptor_offset + 3 ] );
738
      }
739
#endif
740
39.1k
      byte_stream_copy_to_uint32_big_endian(
741
39.1k
       &( data[ descriptor_offset ] ),
742
39.1k
       descriptor_type );
743
744
39.1k
      switch( descriptor_type )
745
39.1k
      {
746
        /* CHAN */
747
2.14k
        case 0x4348414e:
748
2.14k
          internal_provider->channels_offset = descriptor_offset;
749
2.14k
          break;
750
751
        /* EVTN */
752
1.68k
        case 0x45564e54:
753
1.68k
          internal_provider->events_offset = descriptor_offset;
754
1.68k
          break;
755
756
        /* KEYW */
757
1.65k
        case 0x4b455957:
758
1.65k
          internal_provider->keywords_offset = descriptor_offset;
759
1.65k
          break;
760
761
        /* LEVL */
762
3.42k
        case 0x4c45564c:
763
3.42k
          internal_provider->levels_offset = descriptor_offset;
764
3.42k
          break;
765
766
        /* MAPS */
767
4.28k
        case 0x4d415053:
768
4.28k
          internal_provider->maps_offset = descriptor_offset;
769
4.28k
          break;
770
771
        /* TASK */
772
1.57k
        case 0x5441534b:
773
1.57k
          internal_provider->tasks_offset = descriptor_offset;
774
1.57k
          break;
775
776
        /* TTBL */
777
2.27k
        case 0x5454424c:
778
2.27k
          internal_provider->templates_offset = descriptor_offset;
779
2.27k
          break;
780
781
        /* OPCO */
782
4.07k
        case 0x4f50434f:
783
4.07k
          internal_provider->opcodes_offset = descriptor_offset;
784
4.07k
          break;
785
39.1k
      }
786
39.1k
    }
787
#if defined( HAVE_DEBUG_OUTPUT )
788
    if( libcnotify_verbose != 0 )
789
    {
790
      libcnotify_printf(
791
       "\n" );
792
    }
793
#endif
794
9.79k
  }
795
10.1k
  if( number_of_unknown2 > 0 )
796
6.91k
  {
797
6.91k
    if( ( number_of_unknown2 > ( (uint32_t) UINT32_MAX / 4 ) )
798
6.91k
     || ( ( number_of_unknown2 * 4 ) > ( data_size - data_offset ) ) )
799
376
    {
800
376
      libcerror_error_set(
801
376
       error,
802
376
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
803
376
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
804
376
       "%s: invalid number of unknown2 value out of bounds.",
805
376
       function );
806
807
376
      return( -1 );
808
376
    }
809
6.53k
    for( unknown2_index = 0;
810
243k
         unknown2_index < number_of_unknown2;
811
237k
         unknown2_index++ )
812
237k
    {
813
#if defined( HAVE_DEBUG_OUTPUT )
814
      if( libcnotify_verbose != 0 )
815
      {
816
        byte_stream_copy_to_uint32_little_endian(
817
         &( data[ data_offset ] ),
818
         value_32bit );
819
        libcnotify_printf(
820
         "%s: unknown2: %02" PRIu32 " value\t\t\t\t: 0x%08" PRIx32 "\n",
821
         function,
822
         unknown2_index,
823
         value_32bit );
824
      }
825
#endif
826
237k
      data_offset += 4;
827
237k
    }
828
#if defined( HAVE_DEBUG_OUTPUT )
829
    if( libcnotify_verbose != 0 )
830
    {
831
      libcnotify_printf(
832
       "\n" );
833
    }
834
#endif
835
6.53k
  }
836
9.78k
  return( 1 );
837
10.1k
}
838
839
/* Reads the provider channels
840
 * Returns 1 if successful or -1 on error
841
 */
842
int libfwevt_provider_read_channels(
843
     libfwevt_provider_t *provider,
844
     const uint8_t *data,
845
     size_t data_size,
846
     libcerror_error_t **error )
847
8.40k
{
848
8.40k
  fwevt_template_channels_t *wevt_channels        = NULL;
849
8.40k
  libfwevt_channel_t *channel                     = NULL;
850
8.40k
  libfwevt_internal_provider_t *internal_provider = NULL;
851
8.40k
  static char *function                           = "libfwevt_provider_read_channels";
852
8.40k
  size_t data_offset                              = 0;
853
8.40k
  uint32_t channel_index                          = 0;
854
8.40k
  uint32_t channels_data_size                     = 0;
855
8.40k
  uint32_t number_of_channels                     = 0;
856
8.40k
  int entry_index                                 = 0;
857
858
8.40k
  if( provider == NULL )
859
0
  {
860
0
    libcerror_error_set(
861
0
     error,
862
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
863
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
864
0
     "%s: invalid provider.",
865
0
     function );
866
867
0
    return( -1 );
868
0
  }
869
8.40k
  internal_provider = (libfwevt_internal_provider_t *) provider;
870
871
8.40k
  if( data == NULL )
872
0
  {
873
0
    libcerror_error_set(
874
0
     error,
875
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
876
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
877
0
     "%s: invalid data.",
878
0
     function );
879
880
0
    return( -1 );
881
0
  }
882
8.40k
  if( data_size > (size_t) SSIZE_MAX )
883
0
  {
884
0
    libcerror_error_set(
885
0
     error,
886
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
887
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
888
0
     "%s: invalid data size value exceeds maximum.",
889
0
     function );
890
891
0
    return( -1 );
892
0
  }
893
8.40k
  if( (size_t) internal_provider->channels_offset >= data_size )
894
0
  {
895
0
    libcerror_error_set(
896
0
     error,
897
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
898
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
899
0
     "%s: invalid data offset value out of bounds.",
900
0
     function );
901
902
0
    return( -1 );
903
0
  }
904
8.40k
  if( ( data_size - (size_t) internal_provider->channels_offset ) < sizeof( fwevt_template_channels_t ) )
905
5
  {
906
5
    libcerror_error_set(
907
5
     error,
908
5
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
909
5
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
910
5
     "%s: invalid data value too small.",
911
5
     function );
912
913
5
    return( -1 );
914
5
  }
915
8.39k
  if( internal_provider->channels_offset == 0 )
916
7.27k
  {
917
7.27k
    return( 1 );
918
7.27k
  }
919
1.12k
  data_offset   = (size_t) internal_provider->channels_offset;
920
1.12k
  wevt_channels = (fwevt_template_channels_t *) &( data[ data_offset ] );
921
922
#if defined( HAVE_DEBUG_OUTPUT )
923
  if( libcnotify_verbose != 0 )
924
  {
925
    libcnotify_printf(
926
     "%s: reading channels data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
927
     function,
928
     data_offset,
929
     data_offset );
930
931
    libcnotify_printf(
932
     "%s: channels data:\n",
933
     function );
934
    libcnotify_print_data(
935
     (uint8_t *) wevt_channels,
936
     sizeof( fwevt_template_channels_t ),
937
     0 );
938
  }
939
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
940
941
1.12k
  byte_stream_copy_to_uint32_little_endian(
942
1.12k
   wevt_channels->size,
943
1.12k
   channels_data_size );
944
945
1.12k
  byte_stream_copy_to_uint32_little_endian(
946
1.12k
   wevt_channels->number_of_channels,
947
1.12k
   number_of_channels );
948
949
#if defined( HAVE_DEBUG_OUTPUT )
950
  if( libcnotify_verbose != 0 )
951
  {
952
    libcnotify_printf(
953
     "%s: signature\t\t\t\t: %c%c%c%c\n",
954
     function,
955
     wevt_channels->signature[ 0 ],
956
     wevt_channels->signature[ 1 ],
957
     wevt_channels->signature[ 2 ],
958
     wevt_channels->signature[ 3 ] );
959
960
    libcnotify_printf(
961
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
962
     function,
963
     channels_data_size );
964
965
    libcnotify_printf(
966
     "%s: number of channels\t\t\t: %" PRIu32 "\n",
967
     function,
968
     number_of_channels );
969
970
    libcnotify_printf(
971
     "\n" );
972
  }
973
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
974
975
1.12k
  data_offset += sizeof( fwevt_template_channels_t );
976
977
1.12k
  if( memory_compare(
978
1.12k
       wevt_channels->signature,
979
1.12k
       "CHAN",
980
1.12k
       4 ) != 0 )
981
0
  {
982
0
    libcerror_error_set(
983
0
     error,
984
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
985
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
986
0
     "%s: unsupported channels signature.",
987
0
     function );
988
989
0
    goto on_error;
990
0
  }
991
1.12k
  if( number_of_channels > ( ( data_size - data_offset ) / sizeof( fwevt_template_channel_t ) ) )
992
50
  {
993
50
    libcerror_error_set(
994
50
     error,
995
50
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
996
50
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
997
50
     "%s: invalid data value too small.",
998
50
     function );
999
1000
50
    goto on_error;
1001
50
  }
1002
1.07k
  if( channels_data_size > 0 )
1003
694
  {
1004
694
    if( ( channels_data_size < sizeof( fwevt_template_channels_t ) )
1005
694
     || ( channels_data_size >= data_size ) )
1006
79
    {
1007
79
      libcerror_error_set(
1008
79
       error,
1009
79
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1010
79
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1011
79
       "%s: invalid channels data size value out of bounds.",
1012
79
       function );
1013
1014
79
      goto on_error;
1015
79
    }
1016
615
    channels_data_size -= sizeof( fwevt_template_channels_t );
1017
615
  }
1018
995
  for( channel_index = 0;
1019
31.6k
       channel_index < number_of_channels;
1020
30.6k
       channel_index++ )
1021
30.8k
  {
1022
#if defined( HAVE_DEBUG_OUTPUT )
1023
    if( libcnotify_verbose != 0 )
1024
    {
1025
      libcnotify_printf(
1026
       "%s: reading channel: %03" PRIu32 " at offset: %" PRIzd " (0x%08" PRIzx "):\n",
1027
       function,
1028
       channel_index,
1029
       data_offset,
1030
       data_offset );
1031
    }
1032
#endif
1033
30.8k
    if( libfwevt_channel_initialize(
1034
30.8k
         &channel,
1035
30.8k
         error ) != 1 )
1036
0
    {
1037
0
      libcerror_error_set(
1038
0
       error,
1039
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1040
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1041
0
       "%s: unable to create channel: %" PRIu32 ".",
1042
0
       function,
1043
0
       channel_index );
1044
1045
0
      goto on_error;
1046
0
    }
1047
30.8k
    if( libfwevt_channel_read_data(
1048
30.8k
         channel,
1049
30.8k
         data,
1050
30.8k
         data_size,
1051
30.8k
         data_offset,
1052
30.8k
         error ) != 1 )
1053
182
    {
1054
182
      libcerror_error_set(
1055
182
       error,
1056
182
       LIBCERROR_ERROR_DOMAIN_IO,
1057
182
       LIBCERROR_IO_ERROR_READ_FAILED,
1058
182
       "%s: unable to read channel: %" PRIu32 ".",
1059
182
       function,
1060
182
       channel_index );
1061
1062
182
      goto on_error;
1063
182
    }
1064
30.7k
    if( channels_data_size < sizeof( fwevt_template_channel_t ) )
1065
24
    {
1066
24
      libcerror_error_set(
1067
24
       error,
1068
24
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1069
24
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1070
24
       "%s: invalid channels data size value out of bounds.",
1071
24
       function );
1072
1073
24
      goto on_error;
1074
24
    }
1075
30.6k
    data_offset        += sizeof( fwevt_template_channel_t );
1076
30.6k
    channels_data_size -= sizeof( fwevt_template_channel_t );
1077
1078
30.6k
    if( libcdata_array_append_entry(
1079
30.6k
         internal_provider->channels_array,
1080
30.6k
         &entry_index,
1081
30.6k
         (intptr_t *) channel,
1082
30.6k
         error ) != 1 )
1083
0
    {
1084
0
      libcerror_error_set(
1085
0
       error,
1086
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1087
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1088
0
       "%s: unable to append channel: %" PRIu32 " to array.",
1089
0
       function,
1090
0
       channel_index );
1091
1092
0
      goto on_error;
1093
0
    }
1094
30.6k
    channel = NULL;
1095
30.6k
  }
1096
/* TODO count data size ?
1097
#if defined( HAVE_DEBUG_OUTPUT )
1098
  if( libcnotify_verbose != 0 )
1099
  {
1100
    if( channels_data_size > 0 )
1101
    {
1102
      libcnotify_printf(
1103
       "%s: trailing data:\n",
1104
       function );
1105
      libcnotify_print_data(
1106
       &( data[ data_offset ] ),
1107
       channels_data_size,
1108
       0 );
1109
    }
1110
  }
1111
#endif
1112
*/
1113
789
  return( 1 );
1114
1115
335
on_error:
1116
335
  if( channel != NULL )
1117
206
  {
1118
206
    libfwevt_internal_channel_free(
1119
206
     (libfwevt_internal_channel_t **) &channel,
1120
206
     NULL );
1121
206
  }
1122
335
  libcdata_array_empty(
1123
335
   internal_provider->channels_array,
1124
335
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_channel_free,
1125
335
   NULL );
1126
1127
335
  return( -1 );
1128
995
}
1129
1130
/* Reads the provider events
1131
 * Returns 1 if successful or -1 on error
1132
 */
1133
int libfwevt_provider_read_events(
1134
     libfwevt_provider_t *provider,
1135
     const uint8_t *data,
1136
     size_t data_size,
1137
     libcerror_error_t **error )
1138
8.06k
{
1139
8.06k
  fwevt_template_events_t *wevt_events            = NULL;
1140
8.06k
  libfwevt_event_t *event                         = NULL;
1141
8.06k
  libfwevt_internal_provider_t *internal_provider = NULL;
1142
8.06k
  static char *function                           = "libfwevt_provider_read_events";
1143
8.06k
  size_t data_offset                              = 0;
1144
8.06k
  uint32_t event_index                            = 0;
1145
8.06k
  uint32_t events_data_size                       = 0;
1146
8.06k
  uint32_t number_of_events                       = 0;
1147
8.06k
  int entry_index                                 = 0;
1148
1149
#if defined( HAVE_DEBUG_OUTPUT )
1150
  uint32_t value_32bit                            = 0;
1151
#endif
1152
1153
8.06k
  if( provider == NULL )
1154
0
  {
1155
0
    libcerror_error_set(
1156
0
     error,
1157
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1158
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1159
0
     "%s: invalid provider.",
1160
0
     function );
1161
1162
0
    return( -1 );
1163
0
  }
1164
8.06k
  internal_provider = (libfwevt_internal_provider_t *) provider;
1165
1166
8.06k
  if( data == NULL )
1167
0
  {
1168
0
    libcerror_error_set(
1169
0
     error,
1170
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1171
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1172
0
     "%s: invalid data.",
1173
0
     function );
1174
1175
0
    return( -1 );
1176
0
  }
1177
8.06k
  if( data_size > (size_t) SSIZE_MAX )
1178
0
  {
1179
0
    libcerror_error_set(
1180
0
     error,
1181
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1182
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1183
0
     "%s: invalid data size value exceeds maximum.",
1184
0
     function );
1185
1186
0
    return( -1 );
1187
0
  }
1188
8.06k
  if( (size_t) internal_provider->events_offset >= data_size )
1189
0
  {
1190
0
    libcerror_error_set(
1191
0
     error,
1192
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1193
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1194
0
     "%s: invalid data offset value out of bounds.",
1195
0
     function );
1196
1197
0
    return( -1 );
1198
0
  }
1199
8.06k
  if( ( data_size - (size_t) internal_provider->events_offset ) < sizeof( fwevt_template_events_t ) )
1200
5
  {
1201
5
    libcerror_error_set(
1202
5
     error,
1203
5
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1204
5
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1205
5
     "%s: invalid data value too small.",
1206
5
     function );
1207
1208
5
    return( -1 );
1209
5
  }
1210
8.05k
  if( internal_provider->events_offset == 0 )
1211
6.70k
  {
1212
6.70k
    return( 1 );
1213
6.70k
  }
1214
1.35k
  data_offset = (size_t) internal_provider->events_offset;
1215
1.35k
  wevt_events = (fwevt_template_events_t *) &( data[ data_offset ] );
1216
1217
#if defined( HAVE_DEBUG_OUTPUT )
1218
  if( libcnotify_verbose != 0 )
1219
  {
1220
    libcnotify_printf(
1221
     "%s: reading events data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
1222
     function,
1223
     data_offset,
1224
     data_offset );
1225
1226
    libcnotify_printf(
1227
     "%s: events data:\n",
1228
     function );
1229
    libcnotify_print_data(
1230
     (uint8_t *) wevt_events,
1231
     sizeof( fwevt_template_events_t ),
1232
     0 );
1233
  }
1234
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1235
1236
1.35k
  byte_stream_copy_to_uint32_little_endian(
1237
1.35k
   wevt_events->size,
1238
1.35k
   events_data_size );
1239
1240
1.35k
  byte_stream_copy_to_uint32_little_endian(
1241
1.35k
   wevt_events->number_of_events,
1242
1.35k
   number_of_events );
1243
1244
#if defined( HAVE_DEBUG_OUTPUT )
1245
  if( libcnotify_verbose != 0 )
1246
  {
1247
    libcnotify_printf(
1248
     "%s: signature\t\t\t\t: %c%c%c%c\n",
1249
     function,
1250
     wevt_events->signature[ 0 ],
1251
     wevt_events->signature[ 1 ],
1252
     wevt_events->signature[ 2 ],
1253
     wevt_events->signature[ 3 ] );
1254
1255
    libcnotify_printf(
1256
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
1257
     function,
1258
     events_data_size );
1259
1260
    libcnotify_printf(
1261
     "%s: number of events\t\t\t\t: %" PRIu32 "\n",
1262
     function,
1263
     number_of_events );
1264
1265
    byte_stream_copy_to_uint32_little_endian(
1266
     wevt_events->unknown1,
1267
     value_32bit );
1268
    libcnotify_printf(
1269
     "%s: unknown1\t\t\t\t\t: 0x%08" PRIx32 "\n",
1270
     function,
1271
     value_32bit );
1272
1273
    libcnotify_printf(
1274
     "\n" );
1275
  }
1276
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1277
1278
1.35k
  data_offset += sizeof( fwevt_template_events_t );
1279
1280
1.35k
  if( memory_compare(
1281
1.35k
       wevt_events->signature,
1282
1.35k
       "EVNT",
1283
1.35k
       4 ) != 0 )
1284
0
  {
1285
0
    libcerror_error_set(
1286
0
     error,
1287
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1288
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1289
0
     "%s: unsupported events signature.",
1290
0
     function );
1291
1292
0
    goto on_error;
1293
0
  }
1294
1.35k
  if( number_of_events > ( ( data_size - data_offset ) / sizeof( fwevt_template_event_t ) ) )
1295
23
  {
1296
23
    libcerror_error_set(
1297
23
     error,
1298
23
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1299
23
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1300
23
     "%s: invalid data value too small.",
1301
23
     function );
1302
1303
23
    goto on_error;
1304
23
  }
1305
1.33k
  if( events_data_size > 0 )
1306
1.12k
  {
1307
1.12k
    if( ( events_data_size < sizeof( fwevt_template_events_t ) )
1308
1.12k
     || ( events_data_size >= data_size ) )
1309
89
    {
1310
89
      libcerror_error_set(
1311
89
       error,
1312
89
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1313
89
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1314
89
       "%s: invalid events data size value out of bounds.",
1315
89
       function );
1316
1317
89
      goto on_error;
1318
89
    }
1319
1.03k
    events_data_size -= sizeof( fwevt_template_events_t );
1320
1.03k
  }
1321
1.24k
  for( event_index = 0;
1322
70.7k
       event_index < number_of_events;
1323
69.4k
       event_index++ )
1324
69.5k
  {
1325
#if defined( HAVE_DEBUG_OUTPUT )
1326
    if( libcnotify_verbose != 0 )
1327
    {
1328
      libcnotify_printf(
1329
       "%s: reading event: %03" PRIu32 " at offset: %" PRIzd " (0x%08" PRIzx "):\n",
1330
       function,
1331
       event_index,
1332
       data_offset,
1333
       data_offset );
1334
    }
1335
#endif
1336
69.5k
    if( libfwevt_event_initialize(
1337
69.5k
         &event,
1338
69.5k
         error ) != 1 )
1339
0
    {
1340
0
      libcerror_error_set(
1341
0
       error,
1342
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1343
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1344
0
       "%s: unable to create event: %" PRIu32 ".",
1345
0
       function,
1346
0
       event_index );
1347
1348
0
      goto on_error;
1349
0
    }
1350
69.5k
    if( libfwevt_event_read_data(
1351
69.5k
         event,
1352
69.5k
         data,
1353
69.5k
         data_size,
1354
69.5k
         data_offset,
1355
69.5k
         error ) != 1 )
1356
0
    {
1357
0
      libcerror_error_set(
1358
0
       error,
1359
0
       LIBCERROR_ERROR_DOMAIN_IO,
1360
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1361
0
       "%s: unable to read event: %" PRIu32 ".",
1362
0
       function,
1363
0
       event_index );
1364
1365
0
      goto on_error;
1366
0
    }
1367
69.5k
    if( events_data_size < sizeof( fwevt_template_event_t ) )
1368
54
    {
1369
54
      libcerror_error_set(
1370
54
       error,
1371
54
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1372
54
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1373
54
       "%s: invalid events data size value out of bounds.",
1374
54
       function );
1375
1376
54
      goto on_error;
1377
54
    }
1378
69.4k
    data_offset      += sizeof( fwevt_template_event_t );
1379
69.4k
    events_data_size -= sizeof( fwevt_template_event_t );
1380
1381
69.4k
    if( libcdata_array_append_entry(
1382
69.4k
         internal_provider->events_array,
1383
69.4k
         &entry_index,
1384
69.4k
         (intptr_t *) event,
1385
69.4k
         error ) != 1 )
1386
0
    {
1387
0
      libcerror_error_set(
1388
0
       error,
1389
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1390
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1391
0
       "%s: unable to append event: %" PRIu32 " to array.",
1392
0
       function,
1393
0
       event_index );
1394
1395
0
      goto on_error;
1396
0
    }
1397
69.4k
    event = NULL;
1398
69.4k
  }
1399
#if defined( HAVE_DEBUG_OUTPUT )
1400
  if( libcnotify_verbose != 0 )
1401
  {
1402
    if( events_data_size > 0 )
1403
    {
1404
      libcnotify_printf(
1405
       "%s: trailing data:\n",
1406
       function );
1407
      libcnotify_print_data(
1408
       &( data[ data_offset ] ),
1409
       events_data_size,
1410
       0 );
1411
    }
1412
  }
1413
#endif
1414
1.18k
  return( 1 );
1415
1416
166
on_error:
1417
166
  if( event != NULL )
1418
54
  {
1419
54
    libfwevt_internal_event_free(
1420
54
     (libfwevt_internal_event_t **) &event,
1421
54
     NULL );
1422
54
  }
1423
166
  libcdata_array_empty(
1424
166
   internal_provider->events_array,
1425
166
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_event_free,
1426
166
   NULL );
1427
1428
166
  return( -1 );
1429
1.24k
}
1430
1431
/* Reads the provider keywords
1432
 * Returns 1 if successful or -1 on error
1433
 */
1434
int libfwevt_provider_read_keywords(
1435
     libfwevt_provider_t *provider,
1436
     const uint8_t *data,
1437
     size_t data_size,
1438
     libcerror_error_t **error )
1439
7.89k
{
1440
7.89k
  fwevt_template_keywords_t *keywords             = NULL;
1441
7.89k
  libfwevt_internal_provider_t *internal_provider = NULL;
1442
7.89k
  libfwevt_keyword_t *keyword                     = NULL;
1443
7.89k
  static char *function                           = "libfwevt_provider_read_keywords";
1444
7.89k
  size_t data_offset                              = 0;
1445
7.89k
  uint32_t keyword_index                          = 0;
1446
7.89k
  uint32_t keywords_data_size                     = 0;
1447
7.89k
  uint32_t number_of_keywords                     = 0;
1448
7.89k
  int entry_index                                 = 0;
1449
1450
7.89k
  if( provider == NULL )
1451
0
  {
1452
0
    libcerror_error_set(
1453
0
     error,
1454
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1455
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1456
0
     "%s: invalid provider.",
1457
0
     function );
1458
1459
0
    return( -1 );
1460
0
  }
1461
7.89k
  internal_provider = (libfwevt_internal_provider_t *) provider;
1462
1463
7.89k
  if( data == NULL )
1464
0
  {
1465
0
    libcerror_error_set(
1466
0
     error,
1467
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1468
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1469
0
     "%s: invalid data.",
1470
0
     function );
1471
1472
0
    return( -1 );
1473
0
  }
1474
7.89k
  if( data_size > (size_t) SSIZE_MAX )
1475
0
  {
1476
0
    libcerror_error_set(
1477
0
     error,
1478
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1479
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1480
0
     "%s: invalid data size value exceeds maximum.",
1481
0
     function );
1482
1483
0
    return( -1 );
1484
0
  }
1485
7.89k
  if( (size_t) internal_provider->keywords_offset >= data_size )
1486
0
  {
1487
0
    libcerror_error_set(
1488
0
     error,
1489
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1490
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1491
0
     "%s: invalid data offset value out of bounds.",
1492
0
     function );
1493
1494
0
    return( -1 );
1495
0
  }
1496
7.89k
  if( ( data_size - (size_t) internal_provider->keywords_offset ) < sizeof( fwevt_template_keywords_t ) )
1497
7
  {
1498
7
    libcerror_error_set(
1499
7
     error,
1500
7
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1501
7
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1502
7
     "%s: invalid data value too small.",
1503
7
     function );
1504
1505
7
    return( -1 );
1506
7
  }
1507
7.88k
  if( internal_provider->keywords_offset == 0 )
1508
6.77k
  {
1509
6.77k
    return( 1 );
1510
6.77k
  }
1511
1.11k
  data_offset = (size_t) internal_provider->keywords_offset;
1512
1.11k
  keywords    = (fwevt_template_keywords_t *) &( data[ data_offset ] );
1513
1514
#if defined( HAVE_DEBUG_OUTPUT )
1515
  if( libcnotify_verbose != 0 )
1516
  {
1517
    libcnotify_printf(
1518
     "%s: reading keywords data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
1519
     function,
1520
     data_offset,
1521
     data_offset );
1522
1523
    libcnotify_printf(
1524
     "%s: keywords data:\n",
1525
     function );
1526
    libcnotify_print_data(
1527
     (uint8_t *) keywords,
1528
     sizeof( fwevt_template_keywords_t ),
1529
     0 );
1530
  }
1531
#endif
1532
1.11k
  byte_stream_copy_to_uint32_little_endian(
1533
1.11k
   keywords->size,
1534
1.11k
   keywords_data_size );
1535
1536
1.11k
  byte_stream_copy_to_uint32_little_endian(
1537
1.11k
   keywords->number_of_keywords,
1538
1.11k
   number_of_keywords );
1539
1540
#if defined( HAVE_DEBUG_OUTPUT )
1541
  if( libcnotify_verbose != 0 )
1542
  {
1543
    libcnotify_printf(
1544
     "%s: signature\t\t\t\t: %c%c%c%c\n",
1545
     function,
1546
     keywords->signature[ 0 ],
1547
     keywords->signature[ 1 ],
1548
     keywords->signature[ 2 ],
1549
     keywords->signature[ 3 ] );
1550
1551
    libcnotify_printf(
1552
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
1553
     function,
1554
     keywords_data_size );
1555
1556
    libcnotify_printf(
1557
     "%s: number of keywords\t\t\t: %" PRIu32 "\n",
1558
     function,
1559
     number_of_keywords );
1560
1561
    libcnotify_printf(
1562
     "\n" );
1563
  }
1564
#endif
1565
1.11k
  data_offset += sizeof( fwevt_template_keywords_t );
1566
1567
1.11k
  if( memory_compare(
1568
1.11k
       keywords->signature,
1569
1.11k
       "KEYW",
1570
1.11k
       4 ) != 0 )
1571
0
  {
1572
0
    libcerror_error_set(
1573
0
     error,
1574
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1575
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1576
0
     "%s: unsupported keywords signature.",
1577
0
     function );
1578
1579
0
    goto on_error;
1580
0
  }
1581
1.11k
  if( number_of_keywords > ( ( data_size - data_offset ) / sizeof( fwevt_template_keyword_t ) ) )
1582
47
  {
1583
47
    libcerror_error_set(
1584
47
     error,
1585
47
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1586
47
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1587
47
     "%s: invalid data value too small.",
1588
47
     function );
1589
1590
47
    goto on_error;
1591
47
  }
1592
1.06k
  if( keywords_data_size > 0 )
1593
803
  {
1594
803
    if( ( keywords_data_size < sizeof( fwevt_template_keywords_t ) )
1595
803
     || ( keywords_data_size >= data_size ) )
1596
79
    {
1597
79
      libcerror_error_set(
1598
79
       error,
1599
79
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1600
79
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1601
79
       "%s: invalid keywords data size value out of bounds.",
1602
79
       function );
1603
1604
79
      goto on_error;
1605
79
    }
1606
724
    keywords_data_size -= sizeof( fwevt_template_keywords_t );
1607
724
  }
1608
987
  for( keyword_index = 0;
1609
46.4k
       keyword_index < number_of_keywords;
1610
45.4k
       keyword_index++ )
1611
45.6k
  {
1612
#if defined( HAVE_DEBUG_OUTPUT )
1613
    if( libcnotify_verbose != 0 )
1614
    {
1615
      libcnotify_printf(
1616
       "%s: reading keyword: %03" PRIu32 " at offset: %" PRIzd " (0x%08" PRIzx "):\n",
1617
       function,
1618
       keyword_index,
1619
       data_offset,
1620
       data_offset );
1621
    }
1622
#endif
1623
45.6k
    if( libfwevt_keyword_initialize(
1624
45.6k
         &keyword,
1625
45.6k
         error ) != 1 )
1626
0
    {
1627
0
      libcerror_error_set(
1628
0
       error,
1629
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1630
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1631
0
       "%s: unable to create keyword: %" PRIu32 ".",
1632
0
       function,
1633
0
       keyword_index );
1634
1635
0
      goto on_error;
1636
0
    }
1637
45.6k
    if( libfwevt_keyword_read_data(
1638
45.6k
         keyword,
1639
45.6k
         data,
1640
45.6k
         data_size,
1641
45.6k
         data_offset,
1642
45.6k
         error ) != 1 )
1643
173
    {
1644
173
      libcerror_error_set(
1645
173
       error,
1646
173
       LIBCERROR_ERROR_DOMAIN_IO,
1647
173
       LIBCERROR_IO_ERROR_READ_FAILED,
1648
173
       "%s: unable to read keyword: %" PRIu32 ".",
1649
173
       function,
1650
173
       keyword_index );
1651
1652
173
      goto on_error;
1653
173
    }
1654
45.5k
    if( keywords_data_size < sizeof( fwevt_template_keyword_t ) )
1655
28
    {
1656
28
      libcerror_error_set(
1657
28
       error,
1658
28
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1659
28
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1660
28
       "%s: invalid keywords data size value out of bounds.",
1661
28
       function );
1662
1663
28
      goto on_error;
1664
28
    }
1665
45.4k
    data_offset        += sizeof( fwevt_template_keyword_t );
1666
45.4k
    keywords_data_size -= sizeof( fwevt_template_keyword_t );
1667
1668
45.4k
    if( libcdata_array_append_entry(
1669
45.4k
         internal_provider->keywords_array,
1670
45.4k
         &entry_index,
1671
45.4k
         (intptr_t *) keyword,
1672
45.4k
         error ) != 1 )
1673
0
    {
1674
0
      libcerror_error_set(
1675
0
       error,
1676
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1677
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1678
0
       "%s: unable to append keyword: %" PRIu32 " to array.",
1679
0
       function,
1680
0
       keyword_index );
1681
1682
0
      goto on_error;
1683
0
    }
1684
45.4k
    keyword = NULL;
1685
45.4k
  }
1686
/* TODO count data size ?
1687
#if defined( HAVE_DEBUG_OUTPUT )
1688
  if( libcnotify_verbose != 0 )
1689
  {
1690
    if( keywords_data_size > 0 )
1691
    {
1692
      libcnotify_printf(
1693
       "%s: trailing data:\n",
1694
       function );
1695
      libcnotify_print_data(
1696
       &( data[ data_offset ] ),
1697
       keywords_data_size,
1698
       0 );
1699
    }
1700
  }
1701
#endif
1702
*/
1703
786
  return( 1 );
1704
1705
327
on_error:
1706
327
  if( keyword != NULL )
1707
201
  {
1708
201
    libfwevt_internal_keyword_free(
1709
201
     (libfwevt_internal_keyword_t **) &keyword,
1710
201
     NULL );
1711
201
  }
1712
327
  libcdata_array_empty(
1713
327
   internal_provider->keywords_array,
1714
327
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_keyword_free,
1715
327
   NULL );
1716
1717
327
  return( -1 );
1718
987
}
1719
1720
/* Reads the provider levels
1721
 * Returns 1 if successful or -1 on error
1722
 */
1723
int libfwevt_provider_read_levels(
1724
     libfwevt_provider_t *provider,
1725
     const uint8_t *data,
1726
     size_t data_size,
1727
     libcerror_error_t **error )
1728
7.55k
{
1729
7.55k
  fwevt_template_levels_t *levels                 = NULL;
1730
7.55k
  libfwevt_internal_provider_t *internal_provider = NULL;
1731
7.55k
  libfwevt_level_t *level                         = NULL;
1732
7.55k
  static char *function                           = "libfwevt_provider_read_levels";
1733
7.55k
  size_t data_offset                              = 0;
1734
7.55k
  uint32_t level_index                            = 0;
1735
7.55k
  uint32_t levels_data_size                       = 0;
1736
7.55k
  uint32_t number_of_levels                       = 0;
1737
7.55k
  int entry_index                                 = 0;
1738
1739
7.55k
  if( provider == NULL )
1740
0
  {
1741
0
    libcerror_error_set(
1742
0
     error,
1743
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1744
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1745
0
     "%s: invalid provider.",
1746
0
     function );
1747
1748
0
    return( -1 );
1749
0
  }
1750
7.55k
  internal_provider = (libfwevt_internal_provider_t *) provider;
1751
1752
7.55k
  if( data == NULL )
1753
0
  {
1754
0
    libcerror_error_set(
1755
0
     error,
1756
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1757
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1758
0
     "%s: invalid data.",
1759
0
     function );
1760
1761
0
    return( -1 );
1762
0
  }
1763
7.55k
  if( data_size > (size_t) SSIZE_MAX )
1764
0
  {
1765
0
    libcerror_error_set(
1766
0
     error,
1767
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1768
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1769
0
     "%s: invalid data size value exceeds maximum.",
1770
0
     function );
1771
1772
0
    return( -1 );
1773
0
  }
1774
7.55k
  if( (size_t) internal_provider->levels_offset >= data_size )
1775
0
  {
1776
0
    libcerror_error_set(
1777
0
     error,
1778
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1779
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1780
0
     "%s: invalid data offset value out of bounds.",
1781
0
     function );
1782
1783
0
    return( -1 );
1784
0
  }
1785
7.55k
  if( ( data_size - (size_t) internal_provider->levels_offset ) < sizeof( fwevt_template_levels_t ) )
1786
5
  {
1787
5
    libcerror_error_set(
1788
5
     error,
1789
5
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1790
5
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1791
5
     "%s: invalid data value too small.",
1792
5
     function );
1793
1794
5
    return( -1 );
1795
5
  }
1796
7.55k
  if( internal_provider->levels_offset == 0 )
1797
6.22k
  {
1798
6.22k
    return( 1 );
1799
6.22k
  }
1800
1.32k
  data_offset = (size_t) internal_provider->levels_offset;
1801
1.32k
  levels      = (fwevt_template_levels_t *) &( data[ data_offset ] );
1802
1803
#if defined( HAVE_DEBUG_OUTPUT )
1804
  if( libcnotify_verbose != 0 )
1805
  {
1806
    libcnotify_printf(
1807
     "%s: reading levels data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
1808
     function,
1809
     data_offset,
1810
     data_offset );
1811
1812
    libcnotify_printf(
1813
     "%s: levels data:\n",
1814
     function );
1815
    libcnotify_print_data(
1816
     (uint8_t *) levels,
1817
     sizeof( fwevt_template_levels_t ),
1818
     0 );
1819
  }
1820
#endif
1821
1.32k
  byte_stream_copy_to_uint32_little_endian(
1822
1.32k
   levels->size,
1823
1.32k
   levels_data_size );
1824
1825
1.32k
  byte_stream_copy_to_uint32_little_endian(
1826
1.32k
   levels->number_of_levels,
1827
1.32k
   number_of_levels );
1828
1829
#if defined( HAVE_DEBUG_OUTPUT )
1830
  if( libcnotify_verbose != 0 )
1831
  {
1832
    libcnotify_printf(
1833
     "%s: signature\t\t\t\t: %c%c%c%c\n",
1834
     function,
1835
     levels->signature[ 0 ],
1836
     levels->signature[ 1 ],
1837
     levels->signature[ 2 ],
1838
     levels->signature[ 3 ] );
1839
1840
    libcnotify_printf(
1841
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
1842
     function,
1843
     levels_data_size );
1844
1845
    libcnotify_printf(
1846
     "%s: number of levels\t\t\t\t: %" PRIu32 "\n",
1847
     function,
1848
     number_of_levels );
1849
1850
    libcnotify_printf(
1851
     "\n" );
1852
  }
1853
#endif
1854
1.32k
  data_offset += sizeof( fwevt_template_levels_t );
1855
1856
1.32k
  if( memory_compare(
1857
1.32k
       levels->signature,
1858
1.32k
       "LEVL",
1859
1.32k
       4 ) != 0 )
1860
0
  {
1861
0
    libcerror_error_set(
1862
0
     error,
1863
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1864
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1865
0
     "%s: unsupported levels signature.",
1866
0
     function );
1867
1868
0
    goto on_error;
1869
0
  }
1870
1.32k
  if( number_of_levels > ( ( data_size - data_offset ) / sizeof( fwevt_template_level_t ) ) )
1871
32
  {
1872
32
    libcerror_error_set(
1873
32
     error,
1874
32
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1875
32
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1876
32
     "%s: invalid data value too small.",
1877
32
     function );
1878
1879
32
    goto on_error;
1880
32
  }
1881
1.29k
  if( levels_data_size > 0 )
1882
1.08k
  {
1883
1.08k
    if( ( levels_data_size < sizeof( fwevt_template_levels_t ) )
1884
1.08k
     || ( levels_data_size >= data_size ) )
1885
91
    {
1886
91
      libcerror_error_set(
1887
91
       error,
1888
91
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1889
91
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1890
91
       "%s: invalid levels data size value out of bounds.",
1891
91
       function );
1892
1893
91
      goto on_error;
1894
91
    }
1895
991
    levels_data_size -= sizeof( fwevt_template_levels_t );
1896
991
  }
1897
1.19k
  for( level_index = 0;
1898
45.0k
       level_index < number_of_levels;
1899
43.8k
       level_index++ )
1900
44.1k
  {
1901
#if defined( HAVE_DEBUG_OUTPUT )
1902
    if( libcnotify_verbose != 0 )
1903
    {
1904
      libcnotify_printf(
1905
       "%s: reading level: %03" PRIu32 " at offset: %" PRIzd " (0x%08" PRIzx "):\n",
1906
       function,
1907
       level_index,
1908
       data_offset,
1909
       data_offset );
1910
    }
1911
#endif
1912
44.1k
    if( libfwevt_level_initialize(
1913
44.1k
         &level,
1914
44.1k
         error ) != 1 )
1915
0
    {
1916
0
      libcerror_error_set(
1917
0
       error,
1918
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1919
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1920
0
       "%s: unable to create level: %" PRIu32 ".",
1921
0
       function,
1922
0
       level_index );
1923
1924
0
      goto on_error;
1925
0
    }
1926
44.1k
    if( libfwevt_level_read_data(
1927
44.1k
         level,
1928
44.1k
         data,
1929
44.1k
         data_size,
1930
44.1k
         data_offset,
1931
44.1k
         error ) != 1 )
1932
209
    {
1933
209
      libcerror_error_set(
1934
209
       error,
1935
209
       LIBCERROR_ERROR_DOMAIN_IO,
1936
209
       LIBCERROR_IO_ERROR_READ_FAILED,
1937
209
       "%s: unable to read level: %" PRIu32 ".",
1938
209
       function,
1939
209
       level_index );
1940
1941
209
      goto on_error;
1942
209
    }
1943
43.9k
    if( levels_data_size < sizeof( fwevt_template_level_t ) )
1944
11
    {
1945
11
      libcerror_error_set(
1946
11
       error,
1947
11
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1948
11
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1949
11
       "%s: invalid levels data size value out of bounds.",
1950
11
       function );
1951
1952
11
      goto on_error;
1953
11
    }
1954
43.8k
    data_offset      += sizeof( fwevt_template_level_t );
1955
43.8k
    levels_data_size -= sizeof( fwevt_template_level_t );
1956
1957
43.8k
    if( libcdata_array_append_entry(
1958
43.8k
         internal_provider->levels_array,
1959
43.8k
         &entry_index,
1960
43.8k
         (intptr_t *) level,
1961
43.8k
         error ) != 1 )
1962
0
    {
1963
0
      libcerror_error_set(
1964
0
       error,
1965
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1966
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1967
0
       "%s: unable to append level: %" PRIu32 " to array.",
1968
0
       function,
1969
0
       level_index );
1970
1971
0
      goto on_error;
1972
0
    }
1973
43.8k
    level = NULL;
1974
43.8k
  }
1975
/* TODO count data size ?
1976
#if defined( HAVE_DEBUG_OUTPUT )
1977
  if( libcnotify_verbose != 0 )
1978
  {
1979
    if( levels_data_size > 0 )
1980
    {
1981
      libcnotify_printf(
1982
       "%s: trailing data:\n",
1983
       function );
1984
      libcnotify_print_data(
1985
       &( data[ data_offset ] ),
1986
       levels_data_size,
1987
       0 );
1988
    }
1989
  }
1990
#endif
1991
*/
1992
979
  return( 1 );
1993
1994
343
on_error:
1995
343
  if( level != NULL )
1996
220
  {
1997
220
    libfwevt_internal_level_free(
1998
220
     (libfwevt_internal_level_t **) &level,
1999
220
     NULL );
2000
220
  }
2001
343
  libcdata_array_empty(
2002
343
   internal_provider->levels_array,
2003
343
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_level_free,
2004
343
   NULL );
2005
2006
343
  return( -1 );
2007
1.19k
}
2008
2009
/* Reads the provider maps
2010
 * Returns 1 if successful or -1 on error
2011
 */
2012
int libfwevt_provider_read_maps(
2013
     libfwevt_provider_t *provider,
2014
     const uint8_t *data,
2015
     size_t data_size,
2016
     libcerror_error_t **error )
2017
7.20k
{
2018
7.20k
  fwevt_template_maps_t *maps                     = NULL;
2019
7.20k
  libfwevt_internal_provider_t *internal_provider = NULL;
2020
7.20k
  libfwevt_map_t *map                             = NULL;
2021
7.20k
  const uint8_t *map_offsets_data                 = NULL;
2022
7.20k
  static char *function                           = "libfwevt_provider_read_maps";
2023
7.20k
  size_t data_offset                              = 0;
2024
7.20k
  size_t maps_header_size                         = 0;
2025
7.20k
  uint32_t map_index                              = 0;
2026
7.20k
  uint32_t map_offset                             = 0;
2027
7.20k
  uint32_t maps_data_size                         = 0;
2028
7.20k
  uint32_t number_of_maps                         = 0;
2029
7.20k
  int entry_index                                 = 0;
2030
2031
7.20k
  if( provider == NULL )
2032
0
  {
2033
0
    libcerror_error_set(
2034
0
     error,
2035
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2036
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2037
0
     "%s: invalid provider.",
2038
0
     function );
2039
2040
0
    return( -1 );
2041
0
  }
2042
7.20k
  internal_provider = (libfwevt_internal_provider_t *) provider;
2043
2044
7.20k
  if( data == NULL )
2045
0
  {
2046
0
    libcerror_error_set(
2047
0
     error,
2048
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2049
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2050
0
     "%s: invalid data.",
2051
0
     function );
2052
2053
0
    return( -1 );
2054
0
  }
2055
7.20k
  if( data_size > (size_t) SSIZE_MAX )
2056
0
  {
2057
0
    libcerror_error_set(
2058
0
     error,
2059
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2060
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2061
0
     "%s: invalid data size value exceeds maximum.",
2062
0
     function );
2063
2064
0
    return( -1 );
2065
0
  }
2066
7.20k
  if( (size_t) internal_provider->maps_offset >= data_size )
2067
0
  {
2068
0
    libcerror_error_set(
2069
0
     error,
2070
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2071
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2072
0
     "%s: invalid data offset value out of bounds.",
2073
0
     function );
2074
2075
0
    return( -1 );
2076
0
  }
2077
7.20k
  if( ( data_size - (size_t) internal_provider->maps_offset ) < sizeof( fwevt_template_maps_t ) )
2078
3
  {
2079
3
    libcerror_error_set(
2080
3
     error,
2081
3
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2082
3
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2083
3
     "%s: invalid data value too small.",
2084
3
     function );
2085
2086
3
    return( -1 );
2087
3
  }
2088
7.20k
  if( internal_provider->maps_offset == 0 )
2089
5.70k
  {
2090
5.70k
    return( 1 );
2091
5.70k
  }
2092
1.50k
  data_offset = (size_t) internal_provider->maps_offset;
2093
1.50k
  maps        = (fwevt_template_maps_t *) &( data[ data_offset ] );
2094
2095
#if defined( HAVE_DEBUG_OUTPUT )
2096
  if( libcnotify_verbose != 0 )
2097
  {
2098
    libcnotify_printf(
2099
     "%s: reading maps data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
2100
     function,
2101
     data_offset,
2102
     data_offset );
2103
2104
    libcnotify_printf(
2105
     "%s: maps data:\n",
2106
     function );
2107
    libcnotify_print_data(
2108
     (uint8_t *) maps,
2109
     sizeof( fwevt_template_maps_t ),
2110
     0 );
2111
  }
2112
#endif
2113
1.50k
  byte_stream_copy_to_uint32_little_endian(
2114
1.50k
   maps->size,
2115
1.50k
   maps_data_size );
2116
2117
1.50k
  byte_stream_copy_to_uint32_little_endian(
2118
1.50k
   maps->number_of_maps,
2119
1.50k
   number_of_maps );
2120
2121
#if defined( HAVE_DEBUG_OUTPUT )
2122
  if( libcnotify_verbose != 0 )
2123
  {
2124
    libcnotify_printf(
2125
     "%s: signature\t\t\t\t\t: %c%c%c%c\n",
2126
     function,
2127
     maps->signature[ 0 ],
2128
     maps->signature[ 1 ],
2129
     maps->signature[ 2 ],
2130
     maps->signature[ 3 ] );
2131
2132
    libcnotify_printf(
2133
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
2134
     function,
2135
     maps_data_size );
2136
2137
    libcnotify_printf(
2138
     "%s: number of maps\t\t\t\t: %" PRIu32 "\n",
2139
     function,
2140
     number_of_maps );
2141
2142
    libcnotify_printf(
2143
     "\n" );
2144
  }
2145
#endif
2146
1.50k
  data_offset += sizeof( fwevt_template_maps_t );
2147
2148
1.50k
  if( memory_compare(
2149
1.50k
       maps->signature,
2150
1.50k
       "MAPS",
2151
1.50k
       4 ) != 0 )
2152
0
  {
2153
0
    libcerror_error_set(
2154
0
     error,
2155
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2156
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2157
0
     "%s: unsupported maps signature.",
2158
0
     function );
2159
2160
0
    goto on_error;
2161
0
  }
2162
1.50k
  if( number_of_maps > 1 )
2163
697
  {
2164
697
    map_offsets_data = &( data[ data_offset ] );
2165
2166
697
    if( ( number_of_maps - 1 ) > ( ( data_size - data_offset ) / sizeof( uint32_t ) ) )
2167
68
    {
2168
68
      libcerror_error_set(
2169
68
       error,
2170
68
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2171
68
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2172
68
       "%s: invalid data value too small.",
2173
68
       function );
2174
2175
68
      goto on_error;
2176
68
    }
2177
#if defined( HAVE_DEBUG_OUTPUT )
2178
    if( libcnotify_verbose != 0 )
2179
    {
2180
      libcnotify_printf(
2181
       "%s: map descriptor offsets data:\n",
2182
       function );
2183
      libcnotify_print_data(
2184
       &( data[ data_offset ] ),
2185
       ( number_of_maps - 1 ) * sizeof( uint32_t ),
2186
       0 );
2187
2188
      for( map_index = 0;
2189
           map_index < number_of_maps - 1;
2190
           map_index++ )
2191
      {
2192
        byte_stream_copy_to_uint32_little_endian(
2193
         &( data[ data_offset ] ),
2194
         map_offset );
2195
2196
        data_offset += 4;
2197
2198
        libcnotify_printf(
2199
         "%s: map: %03" PRIu32 " descriptor offset\t\t\t: 0x%08" PRIx32 "\n",
2200
         function,
2201
         map_index,
2202
         map_offset );
2203
      }
2204
      libcnotify_printf(
2205
       "\n" );
2206
    }
2207
#else
2208
629
    data_offset += ( number_of_maps - 1 ) * sizeof( uint32_t );
2209
629
#endif
2210
629
  }
2211
1.43k
  if( number_of_maps > 0 )
2212
1.05k
  {
2213
1.05k
    if( number_of_maps > ( ( data_size - data_offset ) / sizeof( fwevt_template_map_t ) ) )
2214
17
    {
2215
17
      libcerror_error_set(
2216
17
       error,
2217
17
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2218
17
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2219
17
       "%s: invalid data value too small.",
2220
17
       function );
2221
2222
17
      goto on_error;
2223
17
    }
2224
1.04k
    if( maps_data_size > 0 )
2225
1.04k
    {
2226
1.04k
      maps_header_size = sizeof( fwevt_template_maps_t )
2227
1.04k
           + ( number_of_maps * sizeof( uint32_t ) );
2228
2229
1.04k
      if( ( maps_data_size < maps_header_size )
2230
1.04k
       || ( maps_data_size >= data_size ) )
2231
95
      {
2232
95
        libcerror_error_set(
2233
95
         error,
2234
95
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2235
95
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2236
95
         "%s: invalid maps data size value out of bounds.",
2237
95
         function );
2238
2239
95
        goto on_error;
2240
95
      }
2241
945
      maps_data_size -= (uint32_t) maps_header_size;
2242
945
    }
2243
947
    for( map_index = 0;
2244
320k
         map_index < number_of_maps;
2245
319k
         map_index++ )
2246
319k
    {
2247
319k
      if( map_index == 0 )
2248
947
      {
2249
947
        map_offset = (uint32_t) data_offset;
2250
947
      }
2251
318k
      else
2252
318k
      {
2253
318k
        if( map_offsets_data == NULL )
2254
0
        {
2255
0
          libcerror_error_set(
2256
0
           error,
2257
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2258
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2259
0
           "%s: invalid map offsets data value.",
2260
0
           function );
2261
2262
0
          goto on_error;
2263
0
        }
2264
318k
        byte_stream_copy_to_uint32_little_endian(
2265
318k
         map_offsets_data,
2266
318k
         map_offset );
2267
2268
318k
        map_offsets_data += 4;
2269
318k
      }
2270
#if defined( HAVE_DEBUG_OUTPUT )
2271
      if( libcnotify_verbose != 0 )
2272
      {
2273
        libcnotify_printf(
2274
         "%s: reading map: %03" PRIu32 " at offset: %" PRIu32 " (0x%08" PRIx32 "):\n",
2275
         function,
2276
         map_index,
2277
         map_offset,
2278
         map_offset );
2279
      }
2280
#endif
2281
319k
      if( libfwevt_map_initialize(
2282
319k
           &map,
2283
319k
           error ) != 1 )
2284
0
      {
2285
0
        libcerror_error_set(
2286
0
         error,
2287
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2288
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2289
0
         "%s: unable to create map: %" PRIu32 ".",
2290
0
         function,
2291
0
         map_index );
2292
2293
0
        goto on_error;
2294
0
      }
2295
319k
      if( libfwevt_map_read_data(
2296
319k
           map,
2297
319k
           data,
2298
319k
           data_size,
2299
319k
           (size_t) map_offset,
2300
319k
           error ) != 1 )
2301
124
      {
2302
124
        libcerror_error_set(
2303
124
         error,
2304
124
         LIBCERROR_ERROR_DOMAIN_IO,
2305
124
         LIBCERROR_IO_ERROR_READ_FAILED,
2306
124
         "%s: unable to read map: %" PRIu32 ".",
2307
124
         function,
2308
124
         map_index );
2309
2310
124
        goto on_error;
2311
124
      }
2312
319k
      if( maps_data_size < sizeof( fwevt_template_map_t ) )
2313
12
      {
2314
12
        libcerror_error_set(
2315
12
         error,
2316
12
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2317
12
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2318
12
         "%s: invalid maps data size value out of bounds.",
2319
12
         function );
2320
2321
12
        goto on_error;
2322
12
      }
2323
319k
      maps_data_size -= sizeof( fwevt_template_map_t );
2324
2325
319k
      if( libcdata_array_append_entry(
2326
319k
           internal_provider->maps_array,
2327
319k
           &entry_index,
2328
319k
           (intptr_t *) map,
2329
319k
           error ) != 1 )
2330
0
      {
2331
0
        libcerror_error_set(
2332
0
         error,
2333
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2334
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2335
0
         "%s: unable to append map: %" PRIu32 " to array.",
2336
0
         function,
2337
0
         map_index );
2338
2339
0
        goto on_error;
2340
0
      }
2341
319k
      map = NULL;
2342
319k
    }
2343
947
  }
2344
/* TODO count data size ?
2345
#if defined( HAVE_DEBUG_OUTPUT )
2346
  if( libcnotify_verbose != 0 )
2347
  {
2348
    if( maps_data_size > 0 )
2349
    {
2350
      libcnotify_printf(
2351
       "%s: trailing data:\n",
2352
       function );
2353
      libcnotify_print_data(
2354
       &( data[ data_offset ] ),
2355
       maps_data_size,
2356
       0 );
2357
    }
2358
  }
2359
#endif
2360
*/
2361
1.18k
  return( 1 );
2362
2363
316
on_error:
2364
316
  if( map != NULL )
2365
136
  {
2366
136
    libfwevt_internal_map_free(
2367
136
     (libfwevt_internal_map_t **) &map,
2368
136
     NULL );
2369
136
  }
2370
316
  libcdata_array_empty(
2371
316
   internal_provider->maps_array,
2372
316
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_map_free,
2373
316
   NULL );
2374
2375
316
  return( -1 );
2376
1.43k
}
2377
2378
/* Reads the provider opcodes
2379
 * Returns 1 if successful or -1 on error
2380
 */
2381
int libfwevt_provider_read_opcodes(
2382
     libfwevt_provider_t *provider,
2383
     const uint8_t *data,
2384
     size_t data_size,
2385
     libcerror_error_t **error )
2386
6.88k
{
2387
6.88k
  fwevt_template_opcodes_t *opcodes               = NULL;
2388
6.88k
  libfwevt_internal_provider_t *internal_provider = NULL;
2389
6.88k
  libfwevt_opcode_t *opcode                       = NULL;
2390
6.88k
  static char *function                           = "libfwevt_provider_read_opcodes";
2391
6.88k
  size_t data_offset                              = 0;
2392
6.88k
  uint32_t number_of_opcodes                      = 0;
2393
6.88k
  uint32_t opcode_index                           = 0;
2394
6.88k
  uint32_t opcodes_data_size                      = 0;
2395
6.88k
  int entry_index                                 = 0;
2396
2397
6.88k
  if( provider == NULL )
2398
0
  {
2399
0
    libcerror_error_set(
2400
0
     error,
2401
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2402
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2403
0
     "%s: invalid provider.",
2404
0
     function );
2405
2406
0
    return( -1 );
2407
0
  }
2408
6.88k
  internal_provider = (libfwevt_internal_provider_t *) provider;
2409
2410
6.88k
  if( data == NULL )
2411
0
  {
2412
0
    libcerror_error_set(
2413
0
     error,
2414
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2415
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2416
0
     "%s: invalid data.",
2417
0
     function );
2418
2419
0
    return( -1 );
2420
0
  }
2421
6.88k
  if( data_size > (size_t) SSIZE_MAX )
2422
0
  {
2423
0
    libcerror_error_set(
2424
0
     error,
2425
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2426
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2427
0
     "%s: invalid data size value exceeds maximum.",
2428
0
     function );
2429
2430
0
    return( -1 );
2431
0
  }
2432
6.88k
  if( (size_t) internal_provider->opcodes_offset >= data_size )
2433
0
  {
2434
0
    libcerror_error_set(
2435
0
     error,
2436
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2437
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2438
0
     "%s: invalid data offset value out of bounds.",
2439
0
     function );
2440
2441
0
    return( -1 );
2442
0
  }
2443
6.88k
  if( ( data_size - (size_t) internal_provider->opcodes_offset ) < sizeof( fwevt_template_opcodes_t ) )
2444
5
  {
2445
5
    libcerror_error_set(
2446
5
     error,
2447
5
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2448
5
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2449
5
     "%s: invalid data value too small.",
2450
5
     function );
2451
2452
5
    return( -1 );
2453
5
  }
2454
6.88k
  if( internal_provider->opcodes_offset == 0 )
2455
5.42k
  {
2456
5.42k
    return( 1 );
2457
5.42k
  }
2458
1.46k
  data_offset = (size_t) internal_provider->opcodes_offset;
2459
1.46k
  opcodes     = (fwevt_template_opcodes_t *) &( data[ data_offset ] );
2460
2461
#if defined( HAVE_DEBUG_OUTPUT )
2462
  if( libcnotify_verbose != 0 )
2463
  {
2464
    libcnotify_printf(
2465
     "%s: reading opcodes data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
2466
     function,
2467
     data_offset,
2468
     data_offset );
2469
2470
    libcnotify_printf(
2471
     "%s: opcodes data:\n",
2472
     function );
2473
    libcnotify_print_data(
2474
     (uint8_t *) opcodes,
2475
     sizeof( fwevt_template_opcodes_t ),
2476
     0 );
2477
  }
2478
#endif
2479
1.46k
  byte_stream_copy_to_uint32_little_endian(
2480
1.46k
   opcodes->size,
2481
1.46k
   opcodes_data_size );
2482
2483
1.46k
  byte_stream_copy_to_uint32_little_endian(
2484
1.46k
   opcodes->number_of_opcodes,
2485
1.46k
   number_of_opcodes );
2486
2487
#if defined( HAVE_DEBUG_OUTPUT )
2488
  if( libcnotify_verbose != 0 )
2489
  {
2490
    libcnotify_printf(
2491
     "%s: signature\t\t\t\t: %c%c%c%c\n",
2492
     function,
2493
     opcodes->signature[ 0 ],
2494
     opcodes->signature[ 1 ],
2495
     opcodes->signature[ 2 ],
2496
     opcodes->signature[ 3 ] );
2497
2498
    libcnotify_printf(
2499
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
2500
     function,
2501
     opcodes_data_size );
2502
2503
    libcnotify_printf(
2504
     "%s: number of opcodes\t\t\t: %" PRIu32 "\n",
2505
     function,
2506
     number_of_opcodes );
2507
2508
    libcnotify_printf(
2509
     "\n" );
2510
  }
2511
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2512
2513
1.46k
  data_offset += sizeof( fwevt_template_opcodes_t );
2514
2515
1.46k
  if( memory_compare(
2516
1.46k
       opcodes->signature,
2517
1.46k
       "OPCO",
2518
1.46k
       4 ) != 0 )
2519
0
  {
2520
0
    libcerror_error_set(
2521
0
     error,
2522
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2523
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2524
0
     "%s: unsupported opcodes signature.",
2525
0
     function );
2526
2527
0
    goto on_error;
2528
0
  }
2529
1.46k
  if( number_of_opcodes > ( ( data_size - data_offset ) / sizeof( fwevt_template_opcode_t ) ) )
2530
44
  {
2531
44
    libcerror_error_set(
2532
44
     error,
2533
44
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2534
44
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2535
44
     "%s: invalid data value too small.",
2536
44
     function );
2537
2538
44
    goto on_error;
2539
44
  }
2540
1.41k
  if( opcodes_data_size > 0 )
2541
1.21k
  {
2542
1.21k
    if( ( opcodes_data_size < sizeof( fwevt_template_opcodes_t ) )
2543
1.21k
     || ( opcodes_data_size >= data_size ) )
2544
102
    {
2545
102
      libcerror_error_set(
2546
102
       error,
2547
102
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2548
102
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2549
102
       "%s: invalid opcodes data size value out of bounds.",
2550
102
       function );
2551
2552
102
      goto on_error;
2553
102
    }
2554
1.11k
    opcodes_data_size -= sizeof( fwevt_template_opcodes_t );
2555
1.11k
  }
2556
1.31k
  for( opcode_index = 0;
2557
41.8k
       opcode_index < number_of_opcodes;
2558
40.5k
       opcode_index++ )
2559
40.7k
  {
2560
#if defined( HAVE_DEBUG_OUTPUT )
2561
    if( libcnotify_verbose != 0 )
2562
    {
2563
      libcnotify_printf(
2564
       "%s: reading opcode: %03" PRIu32 " at offset: %" PRIzd " (0x%08" PRIzx "):\n",
2565
       function,
2566
       opcode_index,
2567
       data_offset,
2568
       data_offset );
2569
    }
2570
#endif
2571
40.7k
    if( libfwevt_opcode_initialize(
2572
40.7k
         &opcode,
2573
40.7k
         error ) != 1 )
2574
0
    {
2575
0
      libcerror_error_set(
2576
0
       error,
2577
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2578
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2579
0
       "%s: unable to create opcode: %" PRIu32 ".",
2580
0
       function,
2581
0
       opcode_index );
2582
2583
0
      goto on_error;
2584
0
    }
2585
40.7k
    if( libfwevt_opcode_read_data(
2586
40.7k
         opcode,
2587
40.7k
         data,
2588
40.7k
         data_size,
2589
40.7k
         data_offset,
2590
40.7k
         error ) != 1 )
2591
198
    {
2592
198
      libcerror_error_set(
2593
198
       error,
2594
198
       LIBCERROR_ERROR_DOMAIN_IO,
2595
198
       LIBCERROR_IO_ERROR_READ_FAILED,
2596
198
       "%s: unable to read opcode: %" PRIu32 ".",
2597
198
       function,
2598
198
       opcode_index );
2599
2600
198
      goto on_error;
2601
198
    }
2602
40.5k
    if( opcodes_data_size < sizeof( fwevt_template_opcode_t ) )
2603
18
    {
2604
18
      libcerror_error_set(
2605
18
       error,
2606
18
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2607
18
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2608
18
       "%s: invalid opcodes data size value out of bounds.",
2609
18
       function );
2610
2611
18
      goto on_error;
2612
18
    }
2613
40.5k
    data_offset       += sizeof( fwevt_template_opcode_t );
2614
40.5k
    opcodes_data_size -= sizeof( fwevt_template_opcode_t );
2615
2616
40.5k
    if( libcdata_array_append_entry(
2617
40.5k
         internal_provider->opcodes_array,
2618
40.5k
         &entry_index,
2619
40.5k
         (intptr_t *) opcode,
2620
40.5k
         error ) != 1 )
2621
0
    {
2622
0
      libcerror_error_set(
2623
0
       error,
2624
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2625
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2626
0
       "%s: unable to append opcode: %" PRIu32 " to array.",
2627
0
       function,
2628
0
       opcode_index );
2629
2630
0
      goto on_error;
2631
0
    }
2632
40.5k
    opcode = NULL;
2633
40.5k
  }
2634
/* TODO count data size ?
2635
#if defined( HAVE_DEBUG_OUTPUT )
2636
  if( libcnotify_verbose != 0 )
2637
  {
2638
    if( opcodes_data_size > 0 )
2639
    {
2640
      libcnotify_printf(
2641
       "%s: trailing data:\n",
2642
       function );
2643
      libcnotify_print_data(
2644
       &( data[ data_offset ] ),
2645
       opcodes_data_size,
2646
       0 );
2647
    }
2648
  }
2649
#endif
2650
*/
2651
1.10k
  return( 1 );
2652
2653
362
on_error:
2654
362
  if( opcode != NULL )
2655
216
  {
2656
216
    libfwevt_internal_opcode_free(
2657
216
     (libfwevt_internal_opcode_t **) &opcode,
2658
216
     NULL );
2659
216
  }
2660
362
  libcdata_array_empty(
2661
362
   internal_provider->opcodes_array,
2662
362
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_opcode_free,
2663
362
   NULL );
2664
2665
362
  return( -1 );
2666
1.31k
}
2667
2668
/* Reads the provider tasks
2669
 * Returns 1 if successful or -1 on error
2670
 */
2671
int libfwevt_provider_read_tasks(
2672
     libfwevt_provider_t *provider,
2673
     const uint8_t *data,
2674
     size_t data_size,
2675
     libcerror_error_t **error )
2676
6.52k
{
2677
6.52k
  fwevt_template_tasks_t *tasks                   = NULL;
2678
6.52k
  libfwevt_internal_provider_t *internal_provider = NULL;
2679
6.52k
  libfwevt_task_t *task                           = NULL;
2680
6.52k
  static char *function                           = "libfwevt_provider_read_tasks";
2681
6.52k
  size_t data_offset                              = 0;
2682
6.52k
  uint32_t number_of_tasks                        = 0;
2683
6.52k
  uint32_t task_index                             = 0;
2684
6.52k
  uint32_t tasks_data_size                        = 0;
2685
6.52k
  int entry_index                                 = 0;
2686
2687
6.52k
  if( provider == NULL )
2688
0
  {
2689
0
    libcerror_error_set(
2690
0
     error,
2691
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2692
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2693
0
     "%s: invalid provider.",
2694
0
     function );
2695
2696
0
    return( -1 );
2697
0
  }
2698
6.52k
  internal_provider = (libfwevt_internal_provider_t *) provider;
2699
2700
6.52k
  if( data == NULL )
2701
0
  {
2702
0
    libcerror_error_set(
2703
0
     error,
2704
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2705
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2706
0
     "%s: invalid data.",
2707
0
     function );
2708
2709
0
    return( -1 );
2710
0
  }
2711
6.52k
  if( data_size > (size_t) SSIZE_MAX )
2712
0
  {
2713
0
    libcerror_error_set(
2714
0
     error,
2715
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2716
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2717
0
     "%s: invalid data size value exceeds maximum.",
2718
0
     function );
2719
2720
0
    return( -1 );
2721
0
  }
2722
6.52k
  if( (size_t) internal_provider->tasks_offset >= data_size )
2723
0
  {
2724
0
    libcerror_error_set(
2725
0
     error,
2726
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2727
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2728
0
     "%s: invalid data offset value out of bounds.",
2729
0
     function );
2730
2731
0
    return( -1 );
2732
0
  }
2733
6.52k
  if( ( data_size - (size_t) internal_provider->tasks_offset ) < sizeof( fwevt_template_tasks_t ) )
2734
4
  {
2735
4
    libcerror_error_set(
2736
4
     error,
2737
4
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2738
4
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2739
4
     "%s: invalid data value too small.",
2740
4
     function );
2741
2742
4
    return( -1 );
2743
4
  }
2744
6.51k
  if( internal_provider->tasks_offset == 0 )
2745
5.47k
  {
2746
5.47k
    return( 1 );
2747
5.47k
  }
2748
1.04k
  data_offset = (size_t) internal_provider->tasks_offset;
2749
1.04k
  tasks       = (fwevt_template_tasks_t *) &( data[ data_offset ] );
2750
2751
#if defined( HAVE_DEBUG_OUTPUT )
2752
  if( libcnotify_verbose != 0 )
2753
  {
2754
    libcnotify_printf(
2755
     "%s: reading tasks data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
2756
     function,
2757
     data_offset,
2758
     data_offset );
2759
2760
    libcnotify_printf(
2761
     "%s: tasks data:\n",
2762
     function );
2763
    libcnotify_print_data(
2764
     (uint8_t *) tasks,
2765
     sizeof( fwevt_template_tasks_t ),
2766
     0 );
2767
  }
2768
#endif
2769
1.04k
  byte_stream_copy_to_uint32_little_endian(
2770
1.04k
   tasks->size,
2771
1.04k
   tasks_data_size );
2772
2773
1.04k
  byte_stream_copy_to_uint32_little_endian(
2774
1.04k
   tasks->number_of_tasks,
2775
1.04k
   number_of_tasks );
2776
2777
#if defined( HAVE_DEBUG_OUTPUT )
2778
  if( libcnotify_verbose != 0 )
2779
  {
2780
    libcnotify_printf(
2781
     "%s: signature\t\t\t\t\t: %c%c%c%c\n",
2782
     function,
2783
     tasks->signature[ 0 ],
2784
     tasks->signature[ 1 ],
2785
     tasks->signature[ 2 ],
2786
     tasks->signature[ 3 ] );
2787
2788
    libcnotify_printf(
2789
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
2790
     function,
2791
     tasks_data_size );
2792
2793
    libcnotify_printf(
2794
     "%s: number of tasks\t\t\t\t: %" PRIu32 "\n",
2795
     function,
2796
     number_of_tasks );
2797
2798
    libcnotify_printf(
2799
     "\n" );
2800
  }
2801
#endif
2802
1.04k
  data_offset += sizeof( fwevt_template_tasks_t );
2803
2804
1.04k
  if( memory_compare(
2805
1.04k
       tasks->signature,
2806
1.04k
       "TASK",
2807
1.04k
       4 ) != 0 )
2808
0
  {
2809
0
    libcerror_error_set(
2810
0
     error,
2811
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2812
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2813
0
     "%s: unsupported tasks signature.",
2814
0
     function );
2815
2816
0
    goto on_error;
2817
0
  }
2818
1.04k
  if( number_of_tasks > ( ( data_size - data_offset ) / sizeof( fwevt_template_task_t ) ) )
2819
54
  {
2820
54
    libcerror_error_set(
2821
54
     error,
2822
54
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2823
54
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2824
54
     "%s: invalid data value too small.",
2825
54
     function );
2826
2827
54
    goto on_error;
2828
54
  }
2829
994
  if( tasks_data_size > 0 )
2830
789
  {
2831
789
    if( ( tasks_data_size < sizeof( fwevt_template_task_t ) )
2832
789
     || ( tasks_data_size >= data_size ) )
2833
86
    {
2834
86
      libcerror_error_set(
2835
86
       error,
2836
86
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2837
86
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2838
86
       "%s: invalid tasks data size value out of bounds.",
2839
86
       function );
2840
2841
86
      goto on_error;
2842
86
    }
2843
703
    tasks_data_size -= sizeof( fwevt_template_task_t );
2844
703
  }
2845
908
  for( task_index = 0;
2846
58.6k
       task_index < number_of_tasks;
2847
57.7k
       task_index++ )
2848
57.9k
  {
2849
#if defined( HAVE_DEBUG_OUTPUT )
2850
    if( libcnotify_verbose != 0 )
2851
    {
2852
      libcnotify_printf(
2853
       "%s: reading task: %03" PRIu32 " at offset: %" PRIzd " (0x%08" PRIzx "):\n",
2854
       function,
2855
       task_index,
2856
       data_offset,
2857
       data_offset );
2858
    }
2859
#endif
2860
57.9k
    if( libfwevt_task_initialize(
2861
57.9k
         &task,
2862
57.9k
         error ) != 1 )
2863
0
    {
2864
0
      libcerror_error_set(
2865
0
       error,
2866
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2867
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2868
0
       "%s: unable to create task: %" PRIu32 ".",
2869
0
       function,
2870
0
       task_index );
2871
2872
0
      goto on_error;
2873
0
    }
2874
57.9k
    if( libfwevt_task_read_data(
2875
57.9k
         task,
2876
57.9k
         data,
2877
57.9k
         data_size,
2878
57.9k
         data_offset,
2879
57.9k
         error ) != 1 )
2880
167
    {
2881
167
      libcerror_error_set(
2882
167
       error,
2883
167
       LIBCERROR_ERROR_DOMAIN_IO,
2884
167
       LIBCERROR_IO_ERROR_READ_FAILED,
2885
167
       "%s: unable to read task: %" PRIu32 ".",
2886
167
       function,
2887
167
       task_index );
2888
2889
167
      goto on_error;
2890
167
    }
2891
57.7k
    if( tasks_data_size < sizeof( fwevt_template_task_t ) )
2892
19
    {
2893
19
      libcerror_error_set(
2894
19
       error,
2895
19
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2896
19
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2897
19
       "%s: invalid tasks data size value out of bounds.",
2898
19
       function );
2899
2900
19
      goto on_error;
2901
19
    }
2902
57.7k
    data_offset     += sizeof( fwevt_template_task_t );
2903
57.7k
    tasks_data_size -= sizeof( fwevt_template_task_t );
2904
2905
57.7k
    if( libcdata_array_append_entry(
2906
57.7k
         internal_provider->tasks_array,
2907
57.7k
         &entry_index,
2908
57.7k
         (intptr_t *) task,
2909
57.7k
         error ) != 1 )
2910
0
    {
2911
0
      libcerror_error_set(
2912
0
       error,
2913
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2914
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2915
0
       "%s: unable to append task: %" PRIu32 " to array.",
2916
0
       function,
2917
0
       task_index );
2918
2919
0
      goto on_error;
2920
0
    }
2921
57.7k
    task = NULL;
2922
57.7k
  }
2923
/* TODO count data size ?
2924
#if defined( HAVE_DEBUG_OUTPUT )
2925
  if( libcnotify_verbose != 0 )
2926
  {
2927
    if( tasks_data_size > 0 )
2928
    {
2929
      libcnotify_printf(
2930
       "%s: trailing data:\n",
2931
       function );
2932
      libcnotify_print_data(
2933
       &( data[ data_offset ] ),
2934
       tasks_data_size,
2935
       0 );
2936
    }
2937
  }
2938
#endif
2939
*/
2940
722
  return( 1 );
2941
2942
326
on_error:
2943
326
  if( task != NULL )
2944
186
  {
2945
186
    libfwevt_internal_task_free(
2946
186
     (libfwevt_internal_task_t **) &task,
2947
186
     NULL );
2948
186
  }
2949
326
  libcdata_array_empty(
2950
326
   internal_provider->tasks_array,
2951
326
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_task_free,
2952
326
   NULL );
2953
2954
326
  return( -1 );
2955
908
}
2956
2957
/* Reads the provider template table
2958
 * Returns 1 if successful or -1 on error
2959
 */
2960
int libfwevt_provider_read_templates(
2961
     libfwevt_provider_t *provider,
2962
     const uint8_t *data,
2963
     size_t data_size,
2964
     libcerror_error_t **error )
2965
6.19k
{
2966
6.19k
  libfwevt_internal_provider_t *internal_provider = NULL;
2967
6.19k
  libfwevt_template_t *wevt_template              = NULL;
2968
6.19k
  fwevt_template_table_t *template_table          = NULL;
2969
6.19k
  static char *function                           = "libfwevt_provider_read_templates";
2970
6.19k
  size_t data_offset                              = 0;
2971
6.19k
  uint32_t number_of_templates                    = 0;
2972
6.19k
  uint32_t template_index                         = 0;
2973
6.19k
  uint32_t template_size                          = 0;
2974
6.19k
  uint32_t template_table_size                    = 0;
2975
6.19k
  int entry_index                                 = 0;
2976
2977
6.19k
  if( provider == NULL )
2978
0
  {
2979
0
    libcerror_error_set(
2980
0
     error,
2981
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2982
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2983
0
     "%s: invalid provider.",
2984
0
     function );
2985
2986
0
    return( -1 );
2987
0
  }
2988
6.19k
  internal_provider = (libfwevt_internal_provider_t *) provider;
2989
2990
6.19k
  if( data == NULL )
2991
0
  {
2992
0
    libcerror_error_set(
2993
0
     error,
2994
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2995
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2996
0
     "%s: invalid data.",
2997
0
     function );
2998
2999
0
    return( -1 );
3000
0
  }
3001
6.19k
  if( data_size > (size_t) SSIZE_MAX )
3002
0
  {
3003
0
    libcerror_error_set(
3004
0
     error,
3005
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3006
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3007
0
     "%s: invalid data size value exceeds maximum.",
3008
0
     function );
3009
3010
0
    return( -1 );
3011
0
  }
3012
6.19k
  if( (size_t) internal_provider->templates_offset >= data_size )
3013
0
  {
3014
0
    libcerror_error_set(
3015
0
     error,
3016
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3017
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3018
0
     "%s: invalid data offset value out of bounds.",
3019
0
     function );
3020
3021
0
    return( -1 );
3022
0
  }
3023
6.19k
  if( ( data_size - (size_t) internal_provider->templates_offset ) < sizeof( fwevt_template_table_t ) )
3024
5
  {
3025
5
    libcerror_error_set(
3026
5
     error,
3027
5
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3028
5
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3029
5
     "%s: invalid data size value too small.",
3030
5
     function );
3031
3032
5
    return( -1 );
3033
5
  }
3034
6.18k
  if( internal_provider->templates_offset == 0 )
3035
5.17k
  {
3036
5.17k
    return( 1 );
3037
5.17k
  }
3038
1.00k
  data_offset    = (size_t) internal_provider->templates_offset;
3039
1.00k
  template_table = (fwevt_template_table_t *) &( data[ data_offset ] );
3040
3041
#if defined( HAVE_DEBUG_OUTPUT )
3042
  if( libcnotify_verbose != 0 )
3043
  {
3044
    libcnotify_printf(
3045
     "%s: reading template table data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
3046
     function,
3047
     data_offset,
3048
     data_offset );
3049
3050
    libcnotify_printf(
3051
     "%s: template table data:\n",
3052
     function );
3053
    libcnotify_print_data(
3054
     (uint8_t *) template_table,
3055
     sizeof( fwevt_template_table_t ),
3056
     0 );
3057
  }
3058
#endif
3059
1.00k
  byte_stream_copy_to_uint32_little_endian(
3060
1.00k
   template_table->size,
3061
1.00k
   template_table_size );
3062
3063
1.00k
  byte_stream_copy_to_uint32_little_endian(
3064
1.00k
   template_table->number_of_templates,
3065
1.00k
   number_of_templates );
3066
3067
#if defined( HAVE_DEBUG_OUTPUT )
3068
  if( libcnotify_verbose != 0 )
3069
  {
3070
    libcnotify_printf(
3071
     "%s: signature\t\t\t\t: %c%c%c%c\n",
3072
     function,
3073
     template_table->signature[ 0 ],
3074
     template_table->signature[ 1 ],
3075
     template_table->signature[ 2 ],
3076
     template_table->signature[ 3 ] );
3077
3078
    libcnotify_printf(
3079
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
3080
     function,
3081
     template_table_size );
3082
3083
    libcnotify_printf(
3084
     "%s: number of templates\t\t\t: %" PRIu32 "\n",
3085
     function,
3086
     number_of_templates );
3087
3088
    libcnotify_printf(
3089
     "\n" );
3090
  }
3091
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3092
3093
1.00k
  data_offset += sizeof( fwevt_template_table_t );
3094
3095
1.00k
  if( memory_compare(
3096
1.00k
       template_table->signature,
3097
1.00k
       "TTBL",
3098
1.00k
       4 ) != 0 )
3099
0
  {
3100
0
    libcerror_error_set(
3101
0
     error,
3102
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3103
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3104
0
     "%s: unsupported template table signature.",
3105
0
     function );
3106
3107
0
    goto on_error;
3108
0
  }
3109
1.00k
  if( number_of_templates > ( ( data_size - data_offset ) / sizeof( fwevt_template_header_t ) ) )
3110
46
  {
3111
46
    libcerror_error_set(
3112
46
     error,
3113
46
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3114
46
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3115
46
     "%s: invalid data value too small.",
3116
46
     function );
3117
3118
46
    goto on_error;
3119
46
  }
3120
962
  if( template_table_size > 0 )
3121
745
  {
3122
745
    if( ( template_table_size < sizeof( fwevt_template_table_t ) )
3123
745
     || ( template_table_size >= data_size ) )
3124
101
    {
3125
101
      libcerror_error_set(
3126
101
       error,
3127
101
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3128
101
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3129
101
       "%s: invalid template table data size value out of bounds.",
3130
101
       function );
3131
3132
101
      goto on_error;
3133
101
    }
3134
644
    template_table_size -= sizeof( fwevt_template_table_t );
3135
644
  }
3136
861
  for( template_index = 0;
3137
1.68k
       template_index < number_of_templates;
3138
861
       template_index++ )
3139
962
  {
3140
#if defined( HAVE_DEBUG_OUTPUT )
3141
    if( libcnotify_verbose != 0 )
3142
    {
3143
      libcnotify_printf(
3144
       "%s: reading template: %03" PRIu32 " at offset: %" PRIzd " (0x%08" PRIzx "):\n",
3145
       function,
3146
       template_index,
3147
       data_offset,
3148
       data_offset );
3149
    }
3150
#endif
3151
962
    if( libfwevt_template_initialize(
3152
962
         &wevt_template,
3153
962
         error ) != 1 )
3154
0
    {
3155
0
      libcerror_error_set(
3156
0
       error,
3157
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3158
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3159
0
       "%s: unable to create template: %" PRIu32 ".",
3160
0
       function,
3161
0
       template_index );
3162
3163
0
      goto on_error;
3164
0
    }
3165
962
    ( (libfwevt_internal_template_t *) wevt_template )->is_managed = 1;
3166
3167
/* TODO handle ASCII codepage */
3168
962
    if( libfwevt_template_read(
3169
962
         wevt_template,
3170
962
         data,
3171
962
         data_size,
3172
962
         data_offset,
3173
962
         error ) != 1 )
3174
116
    {
3175
116
      libcerror_error_set(
3176
116
       error,
3177
116
       LIBCERROR_ERROR_DOMAIN_IO,
3178
116
       LIBCERROR_IO_ERROR_READ_FAILED,
3179
116
       "%s: unable to read template: %" PRIu32 ".",
3180
116
       function,
3181
116
       template_index );
3182
3183
116
      goto on_error;
3184
116
    }
3185
846
    if( libfwevt_template_get_size(
3186
846
         wevt_template,
3187
846
         &template_size,
3188
846
         error ) != 1 )
3189
0
    {
3190
0
      libcerror_error_set(
3191
0
       error,
3192
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3193
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3194
0
       "%s: unable to retrieve template size.",
3195
0
       function );
3196
3197
0
      goto on_error;
3198
0
    }
3199
846
    if( template_table_size < template_size )
3200
23
    {
3201
23
      libcerror_error_set(
3202
23
       error,
3203
23
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3204
23
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3205
23
       "%s: invalid templates data size value out of bounds.",
3206
23
       function );
3207
3208
23
      goto on_error;
3209
23
    }
3210
823
    data_offset         += template_size;
3211
823
    template_table_size -= template_size;
3212
3213
823
    if( libcdata_array_append_entry(
3214
823
         internal_provider->templates_array,
3215
823
         &entry_index,
3216
823
         (intptr_t *) wevt_template,
3217
823
         error ) != 1 )
3218
0
    {
3219
0
      libcerror_error_set(
3220
0
       error,
3221
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3222
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3223
0
       "%s: unable to set templates: %" PRIu32 " to array.",
3224
0
       function,
3225
0
       template_index );
3226
3227
0
      goto on_error;
3228
0
    }
3229
823
    wevt_template = NULL;
3230
823
  }
3231
/* TODO count data size ?
3232
#if defined( HAVE_DEBUG_OUTPUT )
3233
  if( libcnotify_verbose != 0 )
3234
  {
3235
    if( template_table_size > 0 )
3236
    {
3237
      libcnotify_printf(
3238
       "%s: trailing data:\n",
3239
       function );
3240
      libcnotify_print_data(
3241
       &( data[ data_offset ] ),
3242
       template_table_size,
3243
       0 );
3244
    }
3245
  }
3246
#endif
3247
*/
3248
722
  return( 1 );
3249
3250
286
on_error:
3251
286
  if( wevt_template != NULL )
3252
139
  {
3253
139
    libfwevt_internal_template_free(
3254
139
     (libfwevt_internal_template_t **) &wevt_template,
3255
139
     NULL );
3256
139
  }
3257
286
  libcdata_array_empty(
3258
286
   internal_provider->templates_array,
3259
286
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_template_free,
3260
286
   NULL );
3261
3262
286
  return( -1 );
3263
861
}
3264
3265
/* Retrieves the identifier
3266
 * The identifier is a GUID stored in little-endian and is 16 bytes of size
3267
 * Returns 1 if successful, 0 if value is not available or -1 on error
3268
 */
3269
int libfwevt_provider_get_identifier(
3270
     libfwevt_provider_t *provider,
3271
     uint8_t *guid_data,
3272
     size_t guid_data_size,
3273
     libcerror_error_t **error )
3274
0
{
3275
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3276
0
  static char *function                           = "libfwevt_provider_get_identifier";
3277
3278
0
  if( provider == NULL )
3279
0
  {
3280
0
    libcerror_error_set(
3281
0
     error,
3282
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3283
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3284
0
     "%s: invalid provider.",
3285
0
     function );
3286
3287
0
    return( -1 );
3288
0
  }
3289
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3290
3291
0
  if( guid_data == NULL )
3292
0
  {
3293
0
    libcerror_error_set(
3294
0
     error,
3295
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3296
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3297
0
     "%s: invalid GUID data.",
3298
0
     function );
3299
3300
0
    return( -1 );
3301
0
  }
3302
0
  if( ( guid_data_size < 16 )
3303
0
   || ( guid_data_size > (size_t) SSIZE_MAX ) )
3304
0
  {
3305
0
    libcerror_error_set(
3306
0
     error,
3307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3308
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3309
0
     "%s: GUID data size value out of bounds.",
3310
0
     function );
3311
3312
0
    return( -1 );
3313
0
  }
3314
0
  if( memory_copy(
3315
0
       guid_data,
3316
0
       internal_provider->identifier,
3317
0
       16 ) == NULL )
3318
0
  {
3319
0
    libcerror_error_set(
3320
0
     error,
3321
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
3322
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3323
0
     "%s: unable to copy identifier.",
3324
0
     function );
3325
3326
0
    return( -1 );
3327
0
  }
3328
0
  return( 1 );
3329
0
}
3330
3331
/* Compares the provider with the identifier
3332
 * Returns 1 if identifier matches, 0 if not or -1 on error
3333
 */
3334
int libfwevt_provider_compare_identifier(
3335
     libfwevt_provider_t *provider,
3336
     const uint8_t *identifier,
3337
     size_t identifier_size,
3338
     libcerror_error_t **error )
3339
0
{
3340
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3341
0
  static char *function                           = "libfwevt_provider_compare_identifier";
3342
3343
0
  if( provider == NULL )
3344
0
  {
3345
0
    libcerror_error_set(
3346
0
     error,
3347
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3348
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3349
0
     "%s: invalid provider.",
3350
0
     function );
3351
3352
0
    return( -1 );
3353
0
  }
3354
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3355
3356
0
  if( identifier == NULL )
3357
0
  {
3358
0
    libcerror_error_set(
3359
0
     error,
3360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3361
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3362
0
     "%s: invalid identifier.",
3363
0
     function );
3364
3365
0
    return( -1 );
3366
0
  }
3367
0
  if( identifier_size != 16 )
3368
0
  {
3369
0
    libcerror_error_set(
3370
0
     error,
3371
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3372
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3373
0
     "%s: invalid identifier size value out of bounds.",
3374
0
     function );
3375
3376
0
    return( -1 );
3377
0
  }
3378
0
  if( memory_compare(
3379
0
       internal_provider->identifier,
3380
0
       identifier,
3381
0
       16 ) == 0 )
3382
0
  {
3383
0
    return( 1 );
3384
0
  }
3385
0
  return( 0 );
3386
0
}
3387
3388
/* Retrieves the number of channels
3389
 * Returns 1 if successful or -1 on error
3390
 */
3391
int libfwevt_provider_get_number_of_channels(
3392
     libfwevt_provider_t *provider,
3393
     int *number_of_channels,
3394
     libcerror_error_t **error )
3395
0
{
3396
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3397
0
  static char *function                           = "libfwevt_provider_get_number_of_channels";
3398
3399
0
  if( provider == NULL )
3400
0
  {
3401
0
    libcerror_error_set(
3402
0
     error,
3403
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3404
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3405
0
     "%s: invalid provider.",
3406
0
     function );
3407
3408
0
    return( -1 );
3409
0
  }
3410
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3411
3412
0
  if( libcdata_array_get_number_of_entries(
3413
0
       internal_provider->channels_array,
3414
0
       number_of_channels,
3415
0
       error ) != 1 )
3416
0
  {
3417
0
    libcerror_error_set(
3418
0
     error,
3419
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3420
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3421
0
     "%s: unable to retrieve number of entries.",
3422
0
     function );
3423
3424
0
    return( -1 );
3425
0
  }
3426
0
  return( 1 );
3427
0
}
3428
3429
/* Retrieves a specific channel
3430
 * Returns 1 if successful or -1 on error
3431
 */
3432
int libfwevt_provider_get_channel_by_index(
3433
     libfwevt_provider_t *provider,
3434
     int channel_index,
3435
     libfwevt_channel_t **channel,
3436
     libcerror_error_t **error )
3437
0
{
3438
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3439
0
  static char *function                           = "libfwevt_provider_get_channel_by_index";
3440
3441
0
  if( provider == NULL )
3442
0
  {
3443
0
    libcerror_error_set(
3444
0
     error,
3445
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3446
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3447
0
     "%s: invalid provider.",
3448
0
     function );
3449
3450
0
    return( -1 );
3451
0
  }
3452
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3453
3454
0
  if( libcdata_array_get_entry_by_index(
3455
0
       internal_provider->channels_array,
3456
0
       channel_index,
3457
0
       (intptr_t **) channel,
3458
0
       error ) != 1 )
3459
0
  {
3460
0
    libcerror_error_set(
3461
0
     error,
3462
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3463
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3464
0
     "%s: unable to retrieve entry: %d.",
3465
0
     function,
3466
0
     channel_index );
3467
3468
0
    return( -1 );
3469
0
  }
3470
0
  return( 1 );
3471
0
}
3472
3473
/* Retrieves the number of events
3474
 * Returns 1 if successful or -1 on error
3475
 */
3476
int libfwevt_provider_get_number_of_events(
3477
     libfwevt_provider_t *provider,
3478
     int *number_of_events,
3479
     libcerror_error_t **error )
3480
0
{
3481
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3482
0
  static char *function                           = "libfwevt_provider_get_number_of_events";
3483
3484
0
  if( provider == NULL )
3485
0
  {
3486
0
    libcerror_error_set(
3487
0
     error,
3488
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3489
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3490
0
     "%s: invalid provider.",
3491
0
     function );
3492
3493
0
    return( -1 );
3494
0
  }
3495
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3496
3497
0
  if( libcdata_array_get_number_of_entries(
3498
0
       internal_provider->events_array,
3499
0
       number_of_events,
3500
0
       error ) != 1 )
3501
0
  {
3502
0
    libcerror_error_set(
3503
0
     error,
3504
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3505
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3506
0
     "%s: unable to retrieve number of entries.",
3507
0
     function );
3508
3509
0
    return( -1 );
3510
0
  }
3511
0
  return( 1 );
3512
0
}
3513
3514
/* Retrieves a specific event
3515
 * Returns 1 if successful or -1 on error
3516
 */
3517
int libfwevt_provider_get_event_by_index(
3518
     libfwevt_provider_t *provider,
3519
     int event_index,
3520
     libfwevt_event_t **event,
3521
     libcerror_error_t **error )
3522
0
{
3523
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3524
0
  static char *function                           = "libfwevt_provider_get_event_by_index";
3525
3526
0
  if( provider == NULL )
3527
0
  {
3528
0
    libcerror_error_set(
3529
0
     error,
3530
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3531
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3532
0
     "%s: invalid provider.",
3533
0
     function );
3534
3535
0
    return( -1 );
3536
0
  }
3537
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3538
3539
0
  if( libcdata_array_get_entry_by_index(
3540
0
       internal_provider->events_array,
3541
0
       event_index,
3542
0
       (intptr_t **) event,
3543
0
       error ) != 1 )
3544
0
  {
3545
0
    libcerror_error_set(
3546
0
     error,
3547
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3548
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3549
0
     "%s: unable to retrieve entry: %d.",
3550
0
     function,
3551
0
     event_index );
3552
3553
0
    return( -1 );
3554
0
  }
3555
0
  return( 1 );
3556
0
}
3557
3558
/* Retrieves a specific event by identifier
3559
 * Returns 1 if successful, 0 if not available or -1 on error
3560
 */
3561
int libfwevt_provider_get_event_by_identifier(
3562
     libfwevt_provider_t *provider,
3563
     uint32_t event_identifier,
3564
     libfwevt_event_t **event,
3565
     libcerror_error_t **error )
3566
0
{
3567
0
  libfwevt_event_t *safe_event                    = NULL;
3568
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3569
0
  static char *function                           = "libfwevt_provider_get_event_by_identifier";
3570
0
  uint32_t identifier                             = 0;
3571
0
  int event_index                                 = 0;
3572
0
  int number_of_events                            = 0;
3573
3574
0
  if( provider == NULL )
3575
0
  {
3576
0
    libcerror_error_set(
3577
0
     error,
3578
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3579
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3580
0
     "%s: invalid provider.",
3581
0
     function );
3582
3583
0
    return( -1 );
3584
0
  }
3585
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3586
3587
0
  if( event == NULL )
3588
0
  {
3589
0
    libcerror_error_set(
3590
0
     error,
3591
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3592
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3593
0
     "%s: invalid event.",
3594
0
     function );
3595
3596
0
    return( -1 );
3597
0
  }
3598
0
  *event = NULL;
3599
3600
0
  if( libcdata_array_get_number_of_entries(
3601
0
       internal_provider->events_array,
3602
0
       &number_of_events,
3603
0
       error ) != 1 )
3604
0
  {
3605
0
    libcerror_error_set(
3606
0
     error,
3607
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3608
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3609
0
     "%s: unable to retrieve number of entries.",
3610
0
     function );
3611
3612
0
    return( -1 );
3613
0
  }
3614
0
  for( event_index = 0;
3615
0
       event_index < number_of_events;
3616
0
       event_index++ )
3617
0
  {
3618
0
    if( libcdata_array_get_entry_by_index(
3619
0
         internal_provider->events_array,
3620
0
         event_index,
3621
0
         (intptr_t **) &safe_event,
3622
0
         error ) != 1 )
3623
0
    {
3624
0
      libcerror_error_set(
3625
0
       error,
3626
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3627
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3628
0
       "%s: unable to retrieve entry: %d.",
3629
0
       function,
3630
0
       event_index );
3631
3632
0
      return( -1 );
3633
0
    }
3634
/* TODO refactor to compare function */
3635
0
    if( libfwevt_event_get_identifier(
3636
0
         safe_event,
3637
0
         &identifier,
3638
0
         error ) != 1 )
3639
0
    {
3640
0
      libcerror_error_set(
3641
0
       error,
3642
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3643
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3644
0
       "%s: unable to retrieve event identifier: %d.",
3645
0
       function,
3646
0
       event_index );
3647
3648
0
      return( -1 );
3649
0
    }
3650
0
    if( event_identifier == identifier )
3651
0
    {
3652
0
      *event = safe_event;
3653
3654
0
      return( 1 );
3655
0
    }
3656
0
  }
3657
0
  return( 0 );
3658
0
}
3659
3660
/* Retrieves the number of keywords
3661
 * Returns 1 if successful or -1 on error
3662
 */
3663
int libfwevt_provider_get_number_of_keywords(
3664
     libfwevt_provider_t *provider,
3665
     int *number_of_keywords,
3666
     libcerror_error_t **error )
3667
0
{
3668
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3669
0
  static char *function                           = "libfwevt_provider_get_number_of_keywords";
3670
3671
0
  if( provider == NULL )
3672
0
  {
3673
0
    libcerror_error_set(
3674
0
     error,
3675
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3676
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3677
0
     "%s: invalid provider.",
3678
0
     function );
3679
3680
0
    return( -1 );
3681
0
  }
3682
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3683
3684
0
  if( libcdata_array_get_number_of_entries(
3685
0
       internal_provider->keywords_array,
3686
0
       number_of_keywords,
3687
0
       error ) != 1 )
3688
0
  {
3689
0
    libcerror_error_set(
3690
0
     error,
3691
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3692
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3693
0
     "%s: unable to retrieve number of entries.",
3694
0
     function );
3695
3696
0
    return( -1 );
3697
0
  }
3698
0
  return( 1 );
3699
0
}
3700
3701
/* Retrieves a specific keyword
3702
 * Returns 1 if successful or -1 on error
3703
 */
3704
int libfwevt_provider_get_keyword_by_index(
3705
     libfwevt_provider_t *provider,
3706
     int keyword_index,
3707
     libfwevt_keyword_t **keyword,
3708
     libcerror_error_t **error )
3709
0
{
3710
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3711
0
  static char *function                           = "libfwevt_provider_get_keyword_by_index";
3712
3713
0
  if( provider == NULL )
3714
0
  {
3715
0
    libcerror_error_set(
3716
0
     error,
3717
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3718
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3719
0
     "%s: invalid provider.",
3720
0
     function );
3721
3722
0
    return( -1 );
3723
0
  }
3724
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3725
3726
0
  if( libcdata_array_get_entry_by_index(
3727
0
       internal_provider->keywords_array,
3728
0
       keyword_index,
3729
0
       (intptr_t **) keyword,
3730
0
       error ) != 1 )
3731
0
  {
3732
0
    libcerror_error_set(
3733
0
     error,
3734
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3735
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3736
0
     "%s: unable to retrieve entry: %d.",
3737
0
     function,
3738
0
     keyword_index );
3739
3740
0
    return( -1 );
3741
0
  }
3742
0
  return( 1 );
3743
0
}
3744
3745
/* Retrieves the number of levels
3746
 * Returns 1 if successful or -1 on error
3747
 */
3748
int libfwevt_provider_get_number_of_levels(
3749
     libfwevt_provider_t *provider,
3750
     int *number_of_levels,
3751
     libcerror_error_t **error )
3752
0
{
3753
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3754
0
  static char *function                           = "libfwevt_provider_get_number_of_levels";
3755
3756
0
  if( provider == NULL )
3757
0
  {
3758
0
    libcerror_error_set(
3759
0
     error,
3760
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3761
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3762
0
     "%s: invalid provider.",
3763
0
     function );
3764
3765
0
    return( -1 );
3766
0
  }
3767
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3768
3769
0
  if( libcdata_array_get_number_of_entries(
3770
0
       internal_provider->levels_array,
3771
0
       number_of_levels,
3772
0
       error ) != 1 )
3773
0
  {
3774
0
    libcerror_error_set(
3775
0
     error,
3776
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3777
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3778
0
     "%s: unable to retrieve number of entries.",
3779
0
     function );
3780
3781
0
    return( -1 );
3782
0
  }
3783
0
  return( 1 );
3784
0
}
3785
3786
/* Retrieves a specific level
3787
 * Returns 1 if successful or -1 on error
3788
 */
3789
int libfwevt_provider_get_level_by_index(
3790
     libfwevt_provider_t *provider,
3791
     int level_index,
3792
     libfwevt_level_t **level,
3793
     libcerror_error_t **error )
3794
0
{
3795
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3796
0
  static char *function                           = "libfwevt_provider_get_level_by_index";
3797
3798
0
  if( provider == NULL )
3799
0
  {
3800
0
    libcerror_error_set(
3801
0
     error,
3802
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3803
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3804
0
     "%s: invalid provider.",
3805
0
     function );
3806
3807
0
    return( -1 );
3808
0
  }
3809
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3810
3811
0
  if( libcdata_array_get_entry_by_index(
3812
0
       internal_provider->levels_array,
3813
0
       level_index,
3814
0
       (intptr_t **) level,
3815
0
       error ) != 1 )
3816
0
  {
3817
0
    libcerror_error_set(
3818
0
     error,
3819
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3820
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3821
0
     "%s: unable to retrieve entry: %d.",
3822
0
     function,
3823
0
     level_index );
3824
3825
0
    return( -1 );
3826
0
  }
3827
0
  return( 1 );
3828
0
}
3829
3830
/* Retrieves the number of maps
3831
 * Returns 1 if successful or -1 on error
3832
 */
3833
int libfwevt_provider_get_number_of_maps(
3834
     libfwevt_provider_t *provider,
3835
     int *number_of_maps,
3836
     libcerror_error_t **error )
3837
0
{
3838
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3839
0
  static char *function                           = "libfwevt_provider_get_number_of_maps";
3840
3841
0
  if( provider == NULL )
3842
0
  {
3843
0
    libcerror_error_set(
3844
0
     error,
3845
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3846
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3847
0
     "%s: invalid provider.",
3848
0
     function );
3849
3850
0
    return( -1 );
3851
0
  }
3852
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3853
3854
0
  if( libcdata_array_get_number_of_entries(
3855
0
       internal_provider->maps_array,
3856
0
       number_of_maps,
3857
0
       error ) != 1 )
3858
0
  {
3859
0
    libcerror_error_set(
3860
0
     error,
3861
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3862
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3863
0
     "%s: unable to retrieve number of entries.",
3864
0
     function );
3865
3866
0
    return( -1 );
3867
0
  }
3868
0
  return( 1 );
3869
0
}
3870
3871
/* Retrieves a specific map
3872
 * Returns 1 if successful or -1 on error
3873
 */
3874
int libfwevt_provider_get_map_by_index(
3875
     libfwevt_provider_t *provider,
3876
     int map_index,
3877
     libfwevt_map_t **map,
3878
     libcerror_error_t **error )
3879
0
{
3880
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3881
0
  static char *function                           = "libfwevt_provider_get_map_by_index";
3882
3883
0
  if( provider == NULL )
3884
0
  {
3885
0
    libcerror_error_set(
3886
0
     error,
3887
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3888
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3889
0
     "%s: invalid provider.",
3890
0
     function );
3891
3892
0
    return( -1 );
3893
0
  }
3894
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3895
3896
0
  if( libcdata_array_get_entry_by_index(
3897
0
       internal_provider->maps_array,
3898
0
       map_index,
3899
0
       (intptr_t **) map,
3900
0
       error ) != 1 )
3901
0
  {
3902
0
    libcerror_error_set(
3903
0
     error,
3904
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3905
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3906
0
     "%s: unable to retrieve entry: %d.",
3907
0
     function,
3908
0
     map_index );
3909
3910
0
    return( -1 );
3911
0
  }
3912
0
  return( 1 );
3913
0
}
3914
3915
/* Retrieves the number of opcodes
3916
 * Returns 1 if successful or -1 on error
3917
 */
3918
int libfwevt_provider_get_number_of_opcodes(
3919
     libfwevt_provider_t *provider,
3920
     int *number_of_opcodes,
3921
     libcerror_error_t **error )
3922
0
{
3923
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3924
0
  static char *function                           = "libfwevt_provider_get_number_of_opcodes";
3925
3926
0
  if( provider == NULL )
3927
0
  {
3928
0
    libcerror_error_set(
3929
0
     error,
3930
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3931
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3932
0
     "%s: invalid provider.",
3933
0
     function );
3934
3935
0
    return( -1 );
3936
0
  }
3937
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3938
3939
0
  if( libcdata_array_get_number_of_entries(
3940
0
       internal_provider->opcodes_array,
3941
0
       number_of_opcodes,
3942
0
       error ) != 1 )
3943
0
  {
3944
0
    libcerror_error_set(
3945
0
     error,
3946
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3947
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3948
0
     "%s: unable to retrieve number of entries.",
3949
0
     function );
3950
3951
0
    return( -1 );
3952
0
  }
3953
0
  return( 1 );
3954
0
}
3955
3956
/* Retrieves a specific opcode
3957
 * Returns 1 if successful or -1 on error
3958
 */
3959
int libfwevt_provider_get_opcode_by_index(
3960
     libfwevt_provider_t *provider,
3961
     int opcode_index,
3962
     libfwevt_opcode_t **opcode,
3963
     libcerror_error_t **error )
3964
0
{
3965
0
  libfwevt_internal_provider_t *internal_provider = NULL;
3966
0
  static char *function                           = "libfwevt_provider_get_opcode_by_index";
3967
3968
0
  if( provider == NULL )
3969
0
  {
3970
0
    libcerror_error_set(
3971
0
     error,
3972
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3973
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3974
0
     "%s: invalid provider.",
3975
0
     function );
3976
3977
0
    return( -1 );
3978
0
  }
3979
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
3980
3981
0
  if( libcdata_array_get_entry_by_index(
3982
0
       internal_provider->opcodes_array,
3983
0
       opcode_index,
3984
0
       (intptr_t **) opcode,
3985
0
       error ) != 1 )
3986
0
  {
3987
0
    libcerror_error_set(
3988
0
     error,
3989
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3990
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3991
0
     "%s: unable to retrieve entry: %d.",
3992
0
     function,
3993
0
     opcode_index );
3994
3995
0
    return( -1 );
3996
0
  }
3997
0
  return( 1 );
3998
0
}
3999
4000
/* Retrieves the number of tasks
4001
 * Returns 1 if successful or -1 on error
4002
 */
4003
int libfwevt_provider_get_number_of_tasks(
4004
     libfwevt_provider_t *provider,
4005
     int *number_of_tasks,
4006
     libcerror_error_t **error )
4007
0
{
4008
0
  libfwevt_internal_provider_t *internal_provider = NULL;
4009
0
  static char *function                           = "libfwevt_provider_get_number_of_tasks";
4010
4011
0
  if( provider == NULL )
4012
0
  {
4013
0
    libcerror_error_set(
4014
0
     error,
4015
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4016
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4017
0
     "%s: invalid provider.",
4018
0
     function );
4019
4020
0
    return( -1 );
4021
0
  }
4022
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
4023
4024
0
  if( libcdata_array_get_number_of_entries(
4025
0
       internal_provider->tasks_array,
4026
0
       number_of_tasks,
4027
0
       error ) != 1 )
4028
0
  {
4029
0
    libcerror_error_set(
4030
0
     error,
4031
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4032
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4033
0
     "%s: unable to retrieve number of entries.",
4034
0
     function );
4035
4036
0
    return( -1 );
4037
0
  }
4038
0
  return( 1 );
4039
0
}
4040
4041
/* Retrieves a specific task
4042
 * Returns 1 if successful or -1 on error
4043
 */
4044
int libfwevt_provider_get_task_by_index(
4045
     libfwevt_provider_t *provider,
4046
     int task_index,
4047
     libfwevt_task_t **task,
4048
     libcerror_error_t **error )
4049
0
{
4050
0
  libfwevt_internal_provider_t *internal_provider = NULL;
4051
0
  static char *function                           = "libfwevt_provider_get_task_by_index";
4052
4053
0
  if( provider == NULL )
4054
0
  {
4055
0
    libcerror_error_set(
4056
0
     error,
4057
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4058
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4059
0
     "%s: invalid provider.",
4060
0
     function );
4061
4062
0
    return( -1 );
4063
0
  }
4064
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
4065
4066
0
  if( libcdata_array_get_entry_by_index(
4067
0
       internal_provider->tasks_array,
4068
0
       task_index,
4069
0
       (intptr_t **) task,
4070
0
       error ) != 1 )
4071
0
  {
4072
0
    libcerror_error_set(
4073
0
     error,
4074
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4075
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4076
0
     "%s: unable to retrieve entry: %d.",
4077
0
     function,
4078
0
     task_index );
4079
4080
0
    return( -1 );
4081
0
  }
4082
0
  return( 1 );
4083
0
}
4084
4085
/* Retrieves the number of templates
4086
 * Returns 1 if successful or -1 on error
4087
 */
4088
int libfwevt_provider_get_number_of_templates(
4089
     libfwevt_provider_t *provider,
4090
     int *number_of_templates,
4091
     libcerror_error_t **error )
4092
0
{
4093
0
  libfwevt_internal_provider_t *internal_provider = NULL;
4094
0
  static char *function                           = "libfwevt_provider_get_number_of_templates";
4095
4096
0
  if( provider == NULL )
4097
0
  {
4098
0
    libcerror_error_set(
4099
0
     error,
4100
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4101
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4102
0
     "%s: invalid provider.",
4103
0
     function );
4104
4105
0
    return( -1 );
4106
0
  }
4107
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
4108
4109
0
  if( libcdata_array_get_number_of_entries(
4110
0
       internal_provider->templates_array,
4111
0
       number_of_templates,
4112
0
       error ) != 1 )
4113
0
  {
4114
0
    libcerror_error_set(
4115
0
     error,
4116
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4117
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4118
0
     "%s: unable to retrieve number of entries.",
4119
0
     function );
4120
4121
0
    return( -1 );
4122
0
  }
4123
0
  return( 1 );
4124
0
}
4125
4126
/* Retrieves a specific template
4127
 * Returns 1 if successful or -1 on error
4128
 */
4129
int libfwevt_provider_get_template_by_index(
4130
     libfwevt_provider_t *provider,
4131
     int template_index,
4132
     libfwevt_template_t **wevt_template,
4133
     libcerror_error_t **error )
4134
0
{
4135
0
  libfwevt_internal_provider_t *internal_provider = NULL;
4136
0
  static char *function                           = "libfwevt_provider_get_template_by_index";
4137
4138
0
  if( provider == NULL )
4139
0
  {
4140
0
    libcerror_error_set(
4141
0
     error,
4142
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4143
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4144
0
     "%s: invalid provider.",
4145
0
     function );
4146
4147
0
    return( -1 );
4148
0
  }
4149
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
4150
4151
0
  if( libcdata_array_get_entry_by_index(
4152
0
       internal_provider->templates_array,
4153
0
       template_index,
4154
0
       (intptr_t **) wevt_template,
4155
0
       error ) != 1 )
4156
0
  {
4157
0
    libcerror_error_set(
4158
0
     error,
4159
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4160
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4161
0
     "%s: unable to retrieve entry: %d.",
4162
0
     function,
4163
0
     template_index );
4164
4165
0
    return( -1 );
4166
0
  }
4167
0
  return( 1 );
4168
0
}
4169
4170
/* Retrieves a specific template by offset
4171
 * Returns 1 if successful, 0 if not available or -1 on error
4172
 */
4173
int libfwevt_provider_get_template_by_offset(
4174
     libfwevt_provider_t *provider,
4175
     uint32_t offset,
4176
     libfwevt_template_t **wevt_template,
4177
     libcerror_error_t **error )
4178
0
{
4179
0
  libfwevt_internal_provider_t *internal_provider = NULL;
4180
0
  libfwevt_template_t *safe_wevt_template         = NULL;
4181
0
  static char *function                           = "libfwevt_provider_get_template_by_offset";
4182
0
  uint32_t template_offset                        = 0;
4183
0
  int number_of_templates                         = 0;
4184
0
  int template_index                              = 0;
4185
4186
0
  if( provider == NULL )
4187
0
  {
4188
0
    libcerror_error_set(
4189
0
     error,
4190
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4191
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4192
0
     "%s: invalid provider.",
4193
0
     function );
4194
4195
0
    return( -1 );
4196
0
  }
4197
0
  internal_provider = (libfwevt_internal_provider_t *) provider;
4198
4199
0
  if( wevt_template == NULL )
4200
0
  {
4201
0
    libcerror_error_set(
4202
0
     error,
4203
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4204
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4205
0
     "%s: invalid template.",
4206
0
     function );
4207
4208
0
    return( -1 );
4209
0
  }
4210
0
  *wevt_template = NULL;
4211
4212
0
  if( libcdata_array_get_number_of_entries(
4213
0
       internal_provider->templates_array,
4214
0
       &number_of_templates,
4215
0
       error ) != 1 )
4216
0
  {
4217
0
    libcerror_error_set(
4218
0
     error,
4219
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4220
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4221
0
     "%s: unable to retrieve number of entries.",
4222
0
     function );
4223
4224
0
    return( -1 );
4225
0
  }
4226
0
  for( template_index = 0;
4227
0
       template_index < number_of_templates;
4228
0
       template_index++ )
4229
0
  {
4230
0
    if( libcdata_array_get_entry_by_index(
4231
0
         internal_provider->templates_array,
4232
0
         template_index,
4233
0
         (intptr_t **) &safe_wevt_template,
4234
0
         error ) != 1 )
4235
0
    {
4236
0
      libcerror_error_set(
4237
0
       error,
4238
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4239
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4240
0
       "%s: unable to retrieve entry: %d.",
4241
0
       function,
4242
0
       template_index );
4243
4244
0
      return( -1 );
4245
0
    }
4246
0
    if( libfwevt_template_get_offset(
4247
0
         safe_wevt_template,
4248
0
         &template_offset,
4249
0
         error ) != 1 )
4250
0
    {
4251
0
      libcerror_error_set(
4252
0
       error,
4253
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4254
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4255
0
       "%s: unable to retrieve template offset: %d.",
4256
0
       function,
4257
0
       template_index );
4258
4259
0
      return( -1 );
4260
0
    }
4261
0
    if( offset == template_offset )
4262
0
    {
4263
0
      *wevt_template = safe_wevt_template;
4264
4265
0
      return( 1 );
4266
0
    }
4267
0
  }
4268
0
  return( 0 );
4269
0
}
4270