Coverage Report

Created: 2024-02-25 07:19

/src/libevtx/libfwevt/libfwevt_template.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Template functions
3
 *
4
 * Copyright (C) 2011-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <system_string.h>
26
#include <types.h>
27
28
#include "libfwevt_debug.h"
29
#include "libfwevt_definitions.h"
30
#include "libfwevt_libcdata.h"
31
#include "libfwevt_libcerror.h"
32
#include "libfwevt_libcnotify.h"
33
#include "libfwevt_libfguid.h"
34
#include "libfwevt_template.h"
35
#include "libfwevt_template_item.h"
36
#include "libfwevt_xml_document.h"
37
#include "libfwevt_xml_template_value.h"
38
39
#include "fwevt_template.h"
40
41
/* Creates a template
42
 * Make sure the value template is referencing, is set to NULL
43
 * Returns 1 if successful or -1 on error
44
 */
45
int libfwevt_template_initialize(
46
     libfwevt_template_t **wevt_template,
47
     libcerror_error_t **error )
48
0
{
49
0
  libfwevt_internal_template_t *internal_template = NULL;
50
0
  static char *function                           = "libfwevt_template_initialize";
51
52
0
  if( wevt_template == NULL )
53
0
  {
54
0
    libcerror_error_set(
55
0
     error,
56
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
57
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
58
0
     "%s: invalid template.",
59
0
     function );
60
61
0
    return( -1 );
62
0
  }
63
0
  if( *wevt_template != NULL )
64
0
  {
65
0
    libcerror_error_set(
66
0
     error,
67
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
68
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
69
0
     "%s: invalid template value already set.",
70
0
     function );
71
72
0
    return( -1 );
73
0
  }
74
0
  internal_template = memory_allocate_structure(
75
0
                       libfwevt_internal_template_t );
76
77
0
  if( internal_template == NULL )
78
0
  {
79
0
    libcerror_error_set(
80
0
     error,
81
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
82
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
83
0
     "%s: unable to create template.",
84
0
     function );
85
86
0
    goto on_error;
87
0
  }
88
0
  if( memory_set(
89
0
       internal_template,
90
0
       0,
91
0
       sizeof( libfwevt_internal_template_t ) ) == NULL )
92
0
  {
93
0
    libcerror_error_set(
94
0
     error,
95
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
96
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
97
0
     "%s: unable to clear template.",
98
0
     function );
99
100
0
    goto on_error;
101
0
  }
102
0
  if( libcdata_array_initialize(
103
0
       &( internal_template->items_array ),
104
0
       0,
105
0
       error ) != 1 )
106
0
  {
107
0
    libcerror_error_set(
108
0
     error,
109
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
110
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
111
0
     "%s: unable to create items array.",
112
0
     function );
113
114
0
    goto on_error;
115
0
  }
116
0
  if( libcdata_array_initialize(
117
0
       &( internal_template->values_array ),
118
0
       0,
119
0
       error ) != 1 )
120
0
  {
121
0
    libcerror_error_set(
122
0
     error,
123
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
124
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
125
0
     "%s: unable to create values array.",
126
0
     function );
127
128
0
    goto on_error;
129
0
  }
130
0
  internal_template->ascii_codepage = 1252;
131
132
0
  *wevt_template = (libfwevt_template_t *) internal_template;
133
134
0
  return( 1 );
135
136
0
on_error:
137
0
  if( internal_template != NULL )
138
0
  {
139
0
    if( internal_template->items_array != NULL )
140
0
    {
141
0
      libcdata_array_free(
142
0
       &( internal_template->items_array ),
143
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_template_item_free,
144
0
       NULL );
145
0
    }
146
0
    memory_free(
147
0
     internal_template );
148
0
  }
149
0
  return( -1 );
150
0
}
151
152
/* Frees a template
153
 * Returns 1 if successful or -1 on error
154
 */
155
int libfwevt_template_free(
156
     libfwevt_template_t **wevt_template,
157
     libcerror_error_t **error )
158
0
{
159
0
  libfwevt_internal_template_t *internal_template = NULL;
160
0
  static char *function                           = "libfwevt_template_free";
161
0
  int result                                      = 1;
162
163
0
  if( wevt_template == NULL )
164
0
  {
165
0
    libcerror_error_set(
166
0
     error,
167
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
168
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
169
0
     "%s: invalid template.",
170
0
     function );
171
172
0
    return( -1 );
173
0
  }
174
0
  if( *wevt_template != NULL )
175
0
  {
176
0
    internal_template = (libfwevt_internal_template_t *) *wevt_template;
177
178
0
    if( internal_template->is_managed == 0 )
179
0
    {
180
0
      if( libfwevt_internal_template_free(
181
0
           (libfwevt_internal_template_t **) wevt_template,
182
0
           error ) != 1 )
183
0
      {
184
0
        libcerror_error_set(
185
0
         error,
186
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
187
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
188
0
         "%s: unable to free template.",
189
0
         function );
190
191
0
        result = -1;
192
0
      }
193
0
    }
194
0
    *wevt_template = NULL;
195
0
  }
196
0
  return( result );
197
0
}
198
199
/* Frees a template
200
 * Returns 1 if successful or -1 on error
201
 */
202
int libfwevt_internal_template_free(
203
     libfwevt_internal_template_t **internal_template,
204
     libcerror_error_t **error )
205
0
{
206
0
  static char *function = "libfwevt_internal_template_free";
207
0
  int result            = 1;
208
209
0
  if( internal_template == NULL )
210
0
  {
211
0
    libcerror_error_set(
212
0
     error,
213
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
214
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
215
0
     "%s: invalid template.",
216
0
     function );
217
218
0
    return( -1 );
219
0
  }
220
0
  if( *internal_template != NULL )
221
0
  {
222
0
    if( ( *internal_template )->data != NULL )
223
0
    {
224
0
      memory_free(
225
0
       ( *internal_template )->data );
226
0
    }
227
0
    if( libcdata_array_free(
228
0
         &( ( *internal_template )->items_array ),
229
0
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_template_item_free,
230
0
         error ) != 1 )
231
0
    {
232
0
      libcerror_error_set(
233
0
       error,
234
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
235
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
236
0
       "%s: unable to free items array.",
237
0
       function );
238
239
0
      result = -1;
240
0
    }
241
0
    if( libcdata_array_free(
242
0
         &( ( *internal_template )->values_array ),
243
0
         (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
244
0
         error ) != 1 )
245
0
    {
246
0
      libcerror_error_set(
247
0
       error,
248
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
249
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
250
0
       "%s: unable to free values array.",
251
0
       function );
252
253
0
      result = -1;
254
0
    }
255
0
    memory_free(
256
0
     *internal_template );
257
258
0
    *internal_template = NULL;
259
0
  }
260
0
  return( result );
261
0
}
262
263
/* Reads the template
264
 * Returns 1 if successful or -1 on error
265
 */
266
int libfwevt_template_read(
267
     libfwevt_template_t *wevt_template,
268
     const uint8_t *data,
269
     size_t data_size,
270
     size_t data_offset,
271
     libcerror_error_t **error )
272
0
{
273
0
  libfwevt_internal_template_t *internal_template = NULL;
274
0
  static char *function                           = "libfwevt_template_read";
275
276
#if defined( HAVE_DEBUG_OUTPUT )
277
  libfwevt_xml_document_t *xml_document           = NULL;
278
#endif
279
280
0
  if( wevt_template == NULL )
281
0
  {
282
0
    libcerror_error_set(
283
0
     error,
284
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
285
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
286
0
     "%s: invalid template.",
287
0
     function );
288
289
0
    return( -1 );
290
0
  }
291
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
292
293
0
  if( internal_template->data != NULL )
294
0
  {
295
0
    libcerror_error_set(
296
0
     error,
297
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
298
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
299
0
     "%s: invalid template - data value already set.",
300
0
     function );
301
302
0
    return( -1 );
303
0
  }
304
0
  if( data == NULL )
305
0
  {
306
0
    libcerror_error_set(
307
0
     error,
308
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
309
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
310
0
     "%s: invalid data.",
311
0
     function );
312
313
0
    return( -1 );
314
0
  }
315
0
  if( data_size > (size_t) SSIZE_MAX )
316
0
  {
317
0
    libcerror_error_set(
318
0
     error,
319
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
320
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
321
0
     "%s: invalid data size value exceeds maximum.",
322
0
     function );
323
324
0
    return( -1 );
325
0
  }
326
0
  if( data_offset >= data_size )
327
0
  {
328
0
    libcerror_error_set(
329
0
     error,
330
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
331
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
332
0
     "%s: invalid data offset value out of bounds.",
333
0
     function );
334
335
0
    return( -1 );
336
0
  }
337
0
  if( libfwevt_template_read_header(
338
0
       internal_template,
339
0
       &( data[ data_offset ] ),
340
0
       data_size - data_offset,
341
0
       error ) != 1 )
342
0
  {
343
0
    libcerror_error_set(
344
0
     error,
345
0
     LIBCERROR_ERROR_DOMAIN_IO,
346
0
     LIBCERROR_IO_ERROR_READ_FAILED,
347
0
     "%s: unable to read template header.",
348
0
     function );
349
350
0
    goto on_error;
351
0
  }
352
0
  if( ( internal_template->size == 0 )
353
0
   || ( (size_t) internal_template->size > ( data_size - data_offset ) ) )
354
0
  {
355
0
    libcerror_error_set(
356
0
     error,
357
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
358
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
359
0
     "%s: invalid template size value out of bounds.",
360
0
     function );
361
362
0
    goto on_error;
363
0
  }
364
0
  internal_template->offset = (uint32_t) data_offset;
365
366
0
  if( libfwevt_template_read_template_items(
367
0
       internal_template,
368
0
       &( data[ data_offset ] ),
369
0
       (size_t) internal_template->size,
370
0
       error ) != 1 )
371
0
  {
372
0
    libcerror_error_set(
373
0
     error,
374
0
     LIBCERROR_ERROR_DOMAIN_IO,
375
0
     LIBCERROR_IO_ERROR_READ_FAILED,
376
0
     "%s: unable to read template template items.",
377
0
     function );
378
379
0
    goto on_error;
380
0
  }
381
0
  if( (size_t) internal_template->size > MEMORY_MAXIMUM_ALLOCATION_SIZE )
382
0
  {
383
0
    libcerror_error_set(
384
0
     error,
385
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
386
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
387
0
     "%s: invalid template size value out of bounds.",
388
0
     function );
389
390
0
    goto on_error;
391
0
  }
392
0
  internal_template->data = (uint8_t *) memory_allocate(
393
0
                                         sizeof( uint8_t ) * internal_template->size );
394
395
0
  if( internal_template->data == NULL )
396
0
  {
397
0
    libcerror_error_set(
398
0
     error,
399
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
400
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
401
0
     "%s: unable to create data.",
402
0
     function );
403
404
0
    goto on_error;
405
0
  }
406
0
  if( memory_copy(
407
0
       internal_template->data,
408
0
       &( data[ data_offset ] ),
409
0
       (size_t) internal_template->size ) == NULL )
410
0
  {
411
0
    libcerror_error_set(
412
0
     error,
413
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
414
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
415
0
     "%s: unable to copy data.",
416
0
     function );
417
418
0
    goto on_error;
419
0
  }
420
0
  internal_template->data_size = (size_t) internal_template->size;
421
422
#if defined( HAVE_DEBUG_OUTPUT )
423
  if( libcnotify_verbose != 0 )
424
  {
425
    if( libfwevt_xml_document_initialize(
426
         &xml_document,
427
         error ) != 1 )
428
    {
429
      libcerror_error_set(
430
       error,
431
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
432
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
433
       "%s: unable to create XML document.",
434
       function );
435
436
      goto on_error;
437
    }
438
    if( libfwevt_template_read_xml_document(
439
         wevt_template,
440
         xml_document,
441
         error ) != 1 )
442
    {
443
      libcerror_error_set(
444
       error,
445
       LIBCERROR_ERROR_DOMAIN_IO,
446
       LIBCERROR_IO_ERROR_READ_FAILED,
447
       "%s: unable to read binary XML document.",
448
       function );
449
450
      goto on_error;
451
    }
452
    libcnotify_printf(
453
     "%s: XML document:\n",
454
     function );
455
456
    if( libfwevt_xml_document_debug_print(
457
         xml_document,
458
         error ) != 1 )
459
    {
460
      libcerror_error_set(
461
       error,
462
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
463
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
464
       "%s: unable to print XML document.",
465
       function );
466
467
      goto on_error;
468
    }
469
    libcnotify_printf(
470
     "\n" );
471
472
    if( libfwevt_xml_document_free(
473
         &xml_document,
474
         error ) != 1 )
475
    {
476
      libcerror_error_set(
477
       error,
478
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
479
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
480
       "%s: unable to free XML document.",
481
       function );
482
483
      goto on_error;
484
    }
485
  }
486
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
487
488
0
  return( 1 );
489
490
0
on_error:
491
#if defined( HAVE_DEBUG_OUTPUT )
492
  if( xml_document != NULL )
493
  {
494
    libfwevt_xml_document_free(
495
     &xml_document,
496
     NULL );
497
  }
498
#endif
499
0
  if( internal_template->data != NULL )
500
0
  {
501
0
    memory_free(
502
0
     internal_template->data );
503
504
0
    internal_template->data = NULL;
505
0
  }
506
0
  return( -1 );
507
0
}
508
509
/* Reads the template header
510
 * Returns 1 if successful or -1 on error
511
 */
512
int libfwevt_template_read_header(
513
     libfwevt_internal_template_t *internal_template,
514
     const uint8_t *data,
515
     size_t data_size,
516
     libcerror_error_t **error )
517
0
{
518
0
  static char *function = "libfwevt_template_read_header";
519
520
#if defined( HAVE_DEBUG_OUTPUT )
521
  uint32_t value_32bit  = 0;
522
#endif
523
524
0
  if( internal_template == NULL )
525
0
  {
526
0
    libcerror_error_set(
527
0
     error,
528
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
529
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
530
0
     "%s: invalid template.",
531
0
     function );
532
533
0
    return( -1 );
534
0
  }
535
0
  if( data == NULL )
536
0
  {
537
0
    libcerror_error_set(
538
0
     error,
539
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
540
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
541
0
     "%s: invalid data.",
542
0
     function );
543
544
0
    return( -1 );
545
0
  }
546
0
  if( ( data_size < sizeof( fwevt_template_header_t ) )
547
0
   || ( data_size > (size_t) SSIZE_MAX ) )
548
0
  {
549
0
    libcerror_error_set(
550
0
     error,
551
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
552
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
553
0
     "%s: invalid data size value out of bounds.",
554
0
     function );
555
556
0
    return( -1 );
557
0
  }
558
#if defined( HAVE_DEBUG_OUTPUT )
559
  if( libcnotify_verbose != 0 )
560
  {
561
    libcnotify_printf(
562
     "%s: template header data:\n",
563
     function );
564
    libcnotify_print_data(
565
     data,
566
     sizeof( fwevt_template_header_t ),
567
     0 );
568
  }
569
#endif
570
0
  byte_stream_copy_to_uint32_little_endian(
571
0
   ( (fwevt_template_header_t *) data )->size,
572
0
   internal_template->size );
573
574
0
  byte_stream_copy_to_uint32_little_endian(
575
0
   ( (fwevt_template_header_t *) data )->number_of_descriptors,
576
0
   internal_template->number_of_descriptors );
577
578
0
  byte_stream_copy_to_uint32_little_endian(
579
0
   ( (fwevt_template_header_t *) data )->number_of_names,
580
0
   internal_template->number_of_names );
581
582
0
  byte_stream_copy_to_uint32_little_endian(
583
0
   ( (fwevt_template_header_t *) data )->template_items_offset,
584
0
   internal_template->template_items_offset );
585
586
0
  if( memory_copy(
587
0
       internal_template->identifier,
588
0
       ( (fwevt_template_header_t *) data )->identifier,
589
0
       16 ) == NULL )
590
0
  {
591
0
    libcerror_error_set(
592
0
     error,
593
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
594
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
595
0
     "%s: unable to copy identifier.",
596
0
     function );
597
598
0
    return( -1 );
599
0
  }
600
#if defined( HAVE_DEBUG_OUTPUT )
601
  if( libcnotify_verbose != 0 )
602
  {
603
    libcnotify_printf(
604
     "%s: signature\t\t\t\t: %c%c%c%c\n",
605
     function,
606
     ( (fwevt_template_header_t *) data )->signature[ 0 ],
607
     ( (fwevt_template_header_t *) data )->signature[ 1 ],
608
     ( (fwevt_template_header_t *) data )->signature[ 2 ],
609
     ( (fwevt_template_header_t *) data )->signature[ 3 ] );
610
611
    libcnotify_printf(
612
     "%s: size\t\t\t\t\t: %" PRIu32 "\n",
613
     function,
614
     internal_template->size );
615
616
    libcnotify_printf(
617
     "%s: number of descriptors\t\t\t: %" PRIu32 "\n",
618
     function,
619
     internal_template->number_of_descriptors );
620
621
    libcnotify_printf(
622
     "%s: number of names\t\t\t\t: %" PRIu32 "\n",
623
     function,
624
     internal_template->number_of_names );
625
626
    libcnotify_printf(
627
     "%s: template items offset\t\t\t: 0x%08" PRIx32 "\n",
628
     function,
629
     internal_template->template_items_offset );
630
631
    byte_stream_copy_to_uint32_little_endian(
632
     ( (fwevt_template_header_t *) data )->unknown1,
633
     value_32bit );
634
    libcnotify_printf(
635
     "%s: unknown1\t\t\t\t\t: %" PRIu32 "\n",
636
     function,
637
     value_32bit );
638
639
    if( libfwevt_debug_print_guid_value(
640
         function,
641
         "identifier\t\t\t\t",
642
         ( (fwevt_template_header_t *) data )->identifier,
643
         16,
644
         LIBFGUID_ENDIAN_LITTLE,
645
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
646
         error ) != 1 )
647
    {
648
      libcerror_error_set(
649
       error,
650
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
651
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
652
       "%s: unable to print GUID value.",
653
       function );
654
655
      return( -1 );
656
    }
657
    libcnotify_printf(
658
     "\n" );
659
  }
660
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
661
662
0
  if( memory_compare(
663
0
       ( (fwevt_template_header_t *) data )->signature,
664
0
       "TEMP",
665
0
       4 ) != 0 )
666
0
  {
667
0
    libcerror_error_set(
668
0
     error,
669
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
670
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
671
0
     "%s: unsupported template signature.",
672
0
     function );
673
674
0
    return( -1 );
675
0
  }
676
0
  return( 1 );
677
0
}
678
679
/* Reads the template items
680
 * Returns 1 if successful or -1 on error
681
 */
682
int libfwevt_template_read_template_items(
683
     libfwevt_internal_template_t *internal_template,
684
     const uint8_t *data,
685
     size_t data_size,
686
     libcerror_error_t **error )
687
0
{
688
0
  libfwevt_template_item_t *template_item       = NULL;
689
0
  libfwevt_xml_template_value_t *template_value = NULL;
690
0
  static char *function                         = "libfwevt_template_read_template_items";
691
0
  uint32_t template_items_data_offset           = 0;
692
0
  uint32_t first_template_item_name_offset      = 0;
693
0
  uint32_t template_item_name_offset            = 0;
694
0
  uint16_t template_value_data_size             = 0;
695
0
  uint8_t input_data_type                       = 0;
696
0
  int entry_index                               = 0;
697
0
  int template_value_index                      = 0;
698
699
0
  if( internal_template == NULL )
700
0
  {
701
0
    libcerror_error_set(
702
0
     error,
703
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
704
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
705
0
     "%s: invalid template.",
706
0
     function );
707
708
0
    return( -1 );
709
0
  }
710
0
  if( data == NULL )
711
0
  {
712
0
    libcerror_error_set(
713
0
     error,
714
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
715
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
716
0
     "%s: invalid data.",
717
0
     function );
718
719
0
    return( -1 );
720
0
  }
721
0
  if( ( data_size < 20 )
722
0
   || ( data_size > (size_t) SSIZE_MAX ) )
723
0
  {
724
0
    libcerror_error_set(
725
0
     error,
726
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
727
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
728
0
     "%s: invalid data size value out of bounds.",
729
0
     function );
730
731
0
    return( -1 );
732
0
  }
733
0
  if( (size_t) internal_template->size > data_size )
734
0
  {
735
0
    libcerror_error_set(
736
0
     error,
737
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
738
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
739
0
     "%s: invalid template - size value out of bounds.",
740
0
     function );
741
742
0
    goto on_error;
743
0
  }
744
0
  if( internal_template->number_of_descriptors == 0 )
745
0
  {
746
    /* The data offset should either be 0 or point to the end of the data
747
     */
748
0
    if( ( internal_template->template_items_offset != 0 )
749
0
     && ( internal_template->template_items_offset != ( internal_template->offset + internal_template->size ) ) )
750
0
    {
751
0
      libcerror_error_set(
752
0
       error,
753
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
754
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
755
0
       "%s: invalid template - template items offset value out of bounds.",
756
0
       function );
757
758
0
      goto on_error;
759
0
    }
760
0
    return( 1 );
761
0
  }
762
0
  if( internal_template->template_items_offset < internal_template->offset )
763
0
  {
764
0
    libcerror_error_set(
765
0
     error,
766
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
767
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
768
0
     "%s: invalid template - template items offset value out of bounds.",
769
0
     function );
770
771
0
    goto on_error;
772
0
  }
773
0
  template_items_data_offset = internal_template->template_items_offset - internal_template->offset;
774
775
0
  if( ( template_items_data_offset < sizeof( fwevt_template_header_t ) )
776
0
   || ( template_items_data_offset >= (size_t) internal_template->size ) )
777
0
  {
778
0
    libcerror_error_set(
779
0
     error,
780
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
781
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
782
0
     "%s: invalid template items data offset value out of bounds.",
783
0
     function );
784
785
0
    goto on_error;
786
0
  }
787
#if defined( HAVE_DEBUG_OUTPUT )
788
  if( libcnotify_verbose != 0 )
789
  {
790
    libcnotify_printf(
791
     "%s: reading template template items data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
792
     function,
793
     internal_template->template_items_offset,
794
     internal_template->template_items_offset );
795
796
    libcnotify_printf(
797
     "%s: template template items data:\n",
798
     function );
799
    libcnotify_print_data(
800
     &( data[ template_items_data_offset ] ),
801
     internal_template->size - template_items_data_offset,
802
     0 );
803
  }
804
#endif
805
0
  do
806
0
  {
807
0
    if( libfwevt_template_item_initialize(
808
0
         &template_item,
809
0
         error ) != 1 )
810
0
    {
811
0
      libcerror_error_set(
812
0
       error,
813
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
814
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
815
0
       "%s: unable to create template item.",
816
0
       function );
817
818
0
      goto on_error;
819
0
    }
820
0
    if( libfwevt_template_item_read_data(
821
0
         template_item,
822
0
         data,
823
0
         data_size,
824
0
         (size_t) template_items_data_offset,
825
0
         internal_template->offset,
826
0
         error ) != 1 )
827
0
    {
828
0
      libcerror_error_set(
829
0
       error,
830
0
       LIBCERROR_ERROR_DOMAIN_IO,
831
0
       LIBCERROR_IO_ERROR_READ_FAILED,
832
0
       "%s: unable to read template item: %d.",
833
0
       function,
834
0
       template_value_index );
835
836
0
      goto on_error;
837
0
    }
838
0
    template_items_data_offset += 20;
839
840
0
    template_item_name_offset = ( (libfwevt_internal_template_item_t *) template_item )->name_offset;
841
842
0
    if( first_template_item_name_offset == 0 )
843
0
    {
844
0
      first_template_item_name_offset = template_item_name_offset;
845
0
    }
846
0
    input_data_type = ( (libfwevt_internal_template_item_t *) template_item )->input_data_type;
847
848
0
    if( libcdata_array_append_entry(
849
0
         internal_template->items_array,
850
0
         &entry_index,
851
0
         (intptr_t *) template_item,
852
0
         error ) != 1 )
853
0
    {
854
0
      libcerror_error_set(
855
0
       error,
856
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
857
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
858
0
       "%s: unable to append template item: %d to array.",
859
0
       function,
860
0
       template_value_index );
861
862
0
      goto on_error;
863
0
    }
864
0
    template_item = NULL;
865
866
0
    if( libfwevt_xml_template_value_initialize(
867
0
         &template_value,
868
0
         error ) != 1 )
869
0
    {
870
0
      libcerror_error_set(
871
0
       error,
872
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
873
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
874
0
       "%s: unable to create template value.",
875
0
       function );
876
877
0
      goto on_error;
878
0
    }
879
0
    if( libfwevt_xml_template_value_set_flags(
880
0
         template_value,
881
0
         LIBFWEVT_XML_TEMPLATE_VALUE_FLAG_IS_DEFINITION,
882
0
         error ) != 1 )
883
0
    {
884
0
      libcerror_error_set(
885
0
       error,
886
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
887
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
888
0
       "%s: unable to set template value flags.",
889
0
       function );
890
891
0
      goto on_error;
892
0
    }
893
0
    if( libfwevt_xml_template_value_set_type(
894
0
         template_value,
895
0
         input_data_type,
896
0
         error ) != 1 )
897
0
    {
898
0
      libcerror_error_set(
899
0
       error,
900
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
901
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
902
0
       "%s: unable to set template value type.",
903
0
       function );
904
905
0
      goto on_error;
906
0
    }
907
0
    if( libfwevt_xml_template_value_set_offset(
908
0
         template_value,
909
0
         template_item_name_offset,
910
0
         error ) != 1 )
911
0
    {
912
0
      libcerror_error_set(
913
0
       error,
914
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
915
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
916
0
       "%s: unable to set template value data offset.",
917
0
       function );
918
919
0
      goto on_error;
920
0
    }
921
0
    if( libfwevt_xml_template_value_set_size(
922
0
         template_value,
923
0
         template_value_data_size,
924
0
         error ) != 1 )
925
0
    {
926
0
      libcerror_error_set(
927
0
       error,
928
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
929
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
930
0
       "%s: unable to set template value data size.",
931
0
       function );
932
933
0
      goto on_error;
934
0
    }
935
0
    if( libcdata_array_append_entry(
936
0
         internal_template->values_array,
937
0
         &entry_index,
938
0
         (intptr_t *) template_value,
939
0
         error ) != 1 )
940
0
    {
941
0
      libcerror_error_set(
942
0
       error,
943
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
944
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
945
0
       "%s: unable to append template value: %d to array.",
946
0
       function,
947
0
       template_value_index );
948
949
0
      goto on_error;
950
0
    }
951
0
    template_value = NULL;
952
953
0
    template_value_index++;
954
0
  }
955
0
  while( ( internal_template->offset + template_items_data_offset ) < first_template_item_name_offset );
956
957
0
  return( 1 );
958
959
0
on_error:
960
0
  if( template_value != NULL )
961
0
  {
962
0
    libfwevt_xml_template_value_free(
963
0
     &template_value,
964
0
     NULL );
965
0
  }
966
0
  if( template_item != NULL )
967
0
  {
968
0
    libfwevt_template_item_free(
969
0
     &template_item,
970
0
     NULL );
971
0
  }
972
0
  libcdata_array_empty(
973
0
   internal_template->values_array,
974
0
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
975
0
   NULL );
976
977
0
  libcdata_array_empty(
978
0
   internal_template->items_array,
979
0
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_internal_template_item_free,
980
0
   NULL );
981
982
0
  return( -1 );
983
0
}
984
985
/* Reads the template XML document
986
 * Returns 1 if successful or -1 on error
987
 */
988
int libfwevt_template_read_xml_document(
989
     libfwevt_template_t *wevt_template,
990
     libfwevt_xml_document_t *xml_document,
991
     libcerror_error_t **error )
992
0
{
993
0
  libfwevt_internal_template_t *internal_template = NULL;
994
0
  static char *function                           = "libfwevt_template_read_xml_document";
995
0
  size_t binary_xml_data_size                     = 0;
996
997
0
  if( wevt_template == NULL )
998
0
  {
999
0
    libcerror_error_set(
1000
0
     error,
1001
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1002
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1003
0
     "%s: invalid template.",
1004
0
     function );
1005
1006
0
    return( -1 );
1007
0
  }
1008
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1009
1010
0
  if( internal_template->data == NULL )
1011
0
  {
1012
0
    libcerror_error_set(
1013
0
     error,
1014
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1015
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1016
0
     "%s: invalid template - missing data.",
1017
0
     function );
1018
1019
0
    return( -1 );
1020
0
  }
1021
0
  if( (size_t) internal_template->size > internal_template->data_size )
1022
0
  {
1023
0
    libcerror_error_set(
1024
0
     error,
1025
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1026
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1027
0
     "%s: invalid template - size value out of bounds.",
1028
0
     function );
1029
1030
0
    return( -1 );
1031
0
  }
1032
0
  if( internal_template->template_items_offset == 0 )
1033
0
  {
1034
0
    binary_xml_data_size = (size_t) internal_template->size;
1035
0
  }
1036
0
  else
1037
0
  {
1038
0
    if( internal_template->template_items_offset < internal_template->offset )
1039
0
    {
1040
0
      libcerror_error_set(
1041
0
       error,
1042
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1043
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1044
0
       "%s: invalid template - template items offset value out of bounds.",
1045
0
       function );
1046
1047
0
      return( -1 );
1048
0
    }
1049
0
    binary_xml_data_size = internal_template->template_items_offset - internal_template->offset;
1050
0
  }
1051
0
  if( binary_xml_data_size < sizeof( fwevt_template_header_t ) )
1052
0
  {
1053
0
    libcerror_error_set(
1054
0
     error,
1055
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1056
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1057
0
     "%s: invalid binary XML data size value out of bounds.",
1058
0
     function );
1059
1060
0
    goto on_error;
1061
0
  }
1062
0
  binary_xml_data_size -= sizeof( fwevt_template_header_t );
1063
1064
0
  if( ( binary_xml_data_size == 0 )
1065
0
   || ( binary_xml_data_size > internal_template->data_size ) )
1066
0
  {
1067
0
    libcerror_error_set(
1068
0
     error,
1069
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1070
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1071
0
     "%s: invalid binary XML data size value out of bounds.",
1072
0
     function );
1073
1074
0
    goto on_error;
1075
0
  }
1076
#if defined( HAVE_DEBUG_OUTPUT )
1077
  if( libcnotify_verbose != 0 )
1078
  {
1079
    libcnotify_printf(
1080
     "%s: reading template binary XML document data at offset: %" PRIzd " (0x%08" PRIzx "):\n",
1081
     function,
1082
     internal_template->offset + sizeof( fwevt_template_header_t ),
1083
     internal_template->offset + sizeof( fwevt_template_header_t ) );
1084
1085
    libcnotify_printf(
1086
     "%s: template binary XML document data:\n",
1087
     function );
1088
    libcnotify_print_data(
1089
     &( internal_template->data[ sizeof( fwevt_template_header_t ) ] ),
1090
     binary_xml_data_size,
1091
     0 );
1092
  }
1093
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1094
1095
0
  if( libfwevt_xml_document_read_with_template_values(
1096
0
       xml_document,
1097
0
       internal_template->data,
1098
0
       internal_template->data_size,
1099
0
       sizeof( fwevt_template_header_t ),
1100
0
       internal_template->ascii_codepage,
1101
0
       LIBFWEVT_XML_DOCUMENT_READ_FLAG_HAS_DEPENDENCY_IDENTIFIERS,
1102
0
       internal_template->values_array,
1103
0
       error ) != 1 )
1104
0
  {
1105
0
    libcerror_error_set(
1106
0
     error,
1107
0
     LIBCERROR_ERROR_DOMAIN_IO,
1108
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1109
0
     "%s: unable to read binary XML document.",
1110
0
     function );
1111
1112
0
    goto on_error;
1113
0
  }
1114
0
  return( 1 );
1115
1116
0
on_error:
1117
0
  libcdata_array_empty(
1118
0
   internal_template->values_array,
1119
0
   (int (*)(intptr_t **, libcerror_error_t **)) &libfwevt_xml_template_value_free,
1120
0
   NULL );
1121
1122
0
  return( -1 );
1123
0
}
1124
1125
/* Sets the ASCII codepage
1126
 * Returns 1 if successful or -1 on error
1127
 */
1128
int libfwevt_template_set_ascii_codepage(
1129
     libfwevt_template_t *wevt_template,
1130
     int ascii_codepage,
1131
     libcerror_error_t **error )
1132
0
{
1133
0
  libfwevt_internal_template_t *internal_template = NULL;
1134
0
  static char *function                           = "libfwevt_template_set_ascii_codepage";
1135
1136
0
  if( wevt_template == NULL )
1137
0
  {
1138
0
    libcerror_error_set(
1139
0
     error,
1140
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1141
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1142
0
     "%s: invalid template.",
1143
0
     function );
1144
1145
0
    return( -1 );
1146
0
  }
1147
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1148
1149
/* TODO check supported codepages ? */
1150
1151
0
  internal_template->ascii_codepage = ascii_codepage;
1152
1153
0
  return( 1 );
1154
0
}
1155
1156
/* Retrieves the data
1157
 * Returns 1 if successful or -1 on error
1158
 */
1159
int libfwevt_template_get_data(
1160
     libfwevt_template_t *wevt_template,
1161
     const uint8_t **data,
1162
     size_t *data_size,
1163
     libcerror_error_t **error )
1164
0
{
1165
0
  libfwevt_internal_template_t *internal_template = NULL;
1166
0
  static char *function                           = "libfwevt_template_get_data";
1167
1168
0
  if( wevt_template == NULL )
1169
0
  {
1170
0
    libcerror_error_set(
1171
0
     error,
1172
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1173
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1174
0
     "%s: invalid template.",
1175
0
     function );
1176
1177
0
    return( -1 );
1178
0
  }
1179
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1180
1181
0
  if( data == NULL )
1182
0
  {
1183
0
    libcerror_error_set(
1184
0
     error,
1185
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1186
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1187
0
     "%s: invalid data.",
1188
0
     function );
1189
1190
0
    return( -1 );
1191
0
  }
1192
0
  if( data_size == NULL )
1193
0
  {
1194
0
    libcerror_error_set(
1195
0
     error,
1196
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1197
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1198
0
     "%s: invalid data size.",
1199
0
     function );
1200
1201
0
    return( -1 );
1202
0
  }
1203
0
  *data      = internal_template->data;
1204
0
  *data_size = internal_template->data_size;
1205
1206
0
  return( 1 );
1207
0
}
1208
1209
/* Sets the data
1210
 * Returns 1 if successful or -1 on error
1211
 */
1212
int libfwevt_template_set_data(
1213
     libfwevt_template_t *wevt_template,
1214
     const uint8_t *data,
1215
     size_t data_size,
1216
     libcerror_error_t **error )
1217
0
{
1218
0
  libfwevt_internal_template_t *internal_template = NULL;
1219
0
  static char *function                           = "libfwevt_template_set_data";
1220
1221
0
  if( wevt_template == NULL )
1222
0
  {
1223
0
    libcerror_error_set(
1224
0
     error,
1225
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1226
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1227
0
     "%s: invalid template.",
1228
0
     function );
1229
1230
0
    return( -1 );
1231
0
  }
1232
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1233
1234
0
  if( internal_template->data != NULL )
1235
0
  {
1236
0
    libcerror_error_set(
1237
0
     error,
1238
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1239
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1240
0
     "%s: invalid template - data value already set.",
1241
0
     function );
1242
1243
0
    return( -1 );
1244
0
  }
1245
0
  if( data == NULL )
1246
0
  {
1247
0
    libcerror_error_set(
1248
0
     error,
1249
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1250
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1251
0
     "%s: invalid data.",
1252
0
     function );
1253
1254
0
    return( -1 );
1255
0
  }
1256
0
  if( ( data_size == 0 )
1257
0
   || ( data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
1258
0
  {
1259
0
    libcerror_error_set(
1260
0
     error,
1261
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1262
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1263
0
     "%s: invalid data size value out of bounds.",
1264
0
     function );
1265
1266
0
    return( -1 );
1267
0
  }
1268
0
  if( libfwevt_template_read_header(
1269
0
       internal_template,
1270
0
       data,
1271
0
       data_size,
1272
0
       error ) != 1 )
1273
0
  {
1274
0
    libcerror_error_set(
1275
0
     error,
1276
0
     LIBCERROR_ERROR_DOMAIN_IO,
1277
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1278
0
     "%s: unable to read template header.",
1279
0
     function );
1280
1281
0
    goto on_error;
1282
0
  }
1283
0
  if( ( internal_template->size == 0 )
1284
0
   || ( (size_t) internal_template->size > data_size ) )
1285
0
  {
1286
0
    libcerror_error_set(
1287
0
     error,
1288
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1289
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1290
0
     "%s: invalid template size value out of bounds.",
1291
0
     function );
1292
1293
0
    goto on_error;
1294
0
  }
1295
0
  internal_template->offset = 0;
1296
1297
0
  if( libfwevt_template_read_template_items(
1298
0
       internal_template,
1299
0
       data,
1300
0
       data_size,
1301
0
       error ) != 1 )
1302
0
  {
1303
0
    libcerror_error_set(
1304
0
     error,
1305
0
     LIBCERROR_ERROR_DOMAIN_IO,
1306
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1307
0
     "%s: unable to read template template items.",
1308
0
     function );
1309
1310
0
    goto on_error;
1311
0
  }
1312
0
  internal_template->data = (uint8_t *) memory_allocate(
1313
0
                                         sizeof( uint8_t ) * data_size );
1314
1315
0
  if( internal_template->data == NULL )
1316
0
  {
1317
0
    libcerror_error_set(
1318
0
     error,
1319
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1320
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1321
0
     "%s: unable to create data.",
1322
0
     function );
1323
1324
0
    goto on_error;
1325
0
  }
1326
0
  if( memory_copy(
1327
0
       internal_template->data,
1328
0
       data,
1329
0
       data_size ) == NULL )
1330
0
  {
1331
0
    libcerror_error_set(
1332
0
     error,
1333
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1334
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1335
0
     "%s: unable to copy data.",
1336
0
     function );
1337
1338
0
    goto on_error;
1339
0
  }
1340
0
  internal_template->data_size = data_size;
1341
1342
0
  return( 1 );
1343
1344
0
on_error:
1345
0
  if( internal_template->data != NULL )
1346
0
  {
1347
0
    memory_free(
1348
0
     internal_template->data );
1349
1350
0
    internal_template->data = NULL;
1351
0
  }
1352
0
  internal_template->data_size = 0;
1353
1354
0
  return( -1 );
1355
0
}
1356
1357
/* Retrieves the offset
1358
 * Returns 1 if successful or -1 on error
1359
 */
1360
int libfwevt_template_get_offset(
1361
     libfwevt_template_t *wevt_template,
1362
     uint32_t *offset,
1363
     libcerror_error_t **error )
1364
0
{
1365
0
  libfwevt_internal_template_t *internal_template = NULL;
1366
0
  static char *function                           = "libfwevt_template_get_offset";
1367
1368
0
  if( wevt_template == NULL )
1369
0
  {
1370
0
    libcerror_error_set(
1371
0
     error,
1372
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1373
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1374
0
     "%s: invalid template.",
1375
0
     function );
1376
1377
0
    return( -1 );
1378
0
  }
1379
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1380
1381
0
  if( offset == NULL )
1382
0
  {
1383
0
    libcerror_error_set(
1384
0
     error,
1385
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1386
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1387
0
     "%s: invalid offset.",
1388
0
     function );
1389
1390
0
    return( -1 );
1391
0
  }
1392
0
  *offset = internal_template->offset;
1393
1394
0
  return( 1 );
1395
0
}
1396
1397
/* Sets the offset
1398
 * Returns 1 if successful or -1 on error
1399
 */
1400
int libfwevt_template_set_offset(
1401
     libfwevt_template_t *wevt_template,
1402
     uint32_t offset,
1403
     libcerror_error_t **error )
1404
0
{
1405
0
  libfwevt_internal_template_t *internal_template = NULL;
1406
0
  static char *function                           = "libfwevt_template_set_offset";
1407
1408
0
  if( wevt_template == NULL )
1409
0
  {
1410
0
    libcerror_error_set(
1411
0
     error,
1412
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1413
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1414
0
     "%s: invalid template.",
1415
0
     function );
1416
1417
0
    return( -1 );
1418
0
  }
1419
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1420
1421
0
  internal_template->offset = offset;
1422
1423
0
  return( 1 );
1424
0
}
1425
1426
/* Retrieves the size
1427
 * Returns 1 if successful or -1 on error
1428
 */
1429
int libfwevt_template_get_size(
1430
     libfwevt_template_t *wevt_template,
1431
     uint32_t *size,
1432
     libcerror_error_t **error )
1433
0
{
1434
0
  libfwevt_internal_template_t *internal_template = NULL;
1435
0
  static char *function                           = "libfwevt_template_get_size";
1436
1437
0
  if( wevt_template == NULL )
1438
0
  {
1439
0
    libcerror_error_set(
1440
0
     error,
1441
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1442
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1443
0
     "%s: invalid template.",
1444
0
     function );
1445
1446
0
    return( -1 );
1447
0
  }
1448
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1449
1450
0
  if( size == 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 size.",
1457
0
     function );
1458
1459
0
    return( -1 );
1460
0
  }
1461
0
  *size = internal_template->size;
1462
1463
0
  return( 1 );
1464
0
}
1465
1466
/* Retrieves the identifier
1467
 * The identifier is a GUID stored in little-endian and is 16 bytes of size
1468
 * Returns 1 if successful, 0 if value is not available or -1 on error
1469
 */
1470
int libfwevt_template_get_identifier(
1471
     libfwevt_template_t *wevt_template,
1472
     uint8_t *guid_data,
1473
     size_t guid_data_size,
1474
     libcerror_error_t **error )
1475
0
{
1476
0
  libfwevt_internal_template_t *internal_template = NULL;
1477
0
  static char *function                           = "libfwevt_template_get_identifier";
1478
1479
0
  if( wevt_template == NULL )
1480
0
  {
1481
0
    libcerror_error_set(
1482
0
     error,
1483
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1484
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1485
0
     "%s: invalid template.",
1486
0
     function );
1487
1488
0
    return( -1 );
1489
0
  }
1490
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1491
1492
0
  if( guid_data == NULL )
1493
0
  {
1494
0
    libcerror_error_set(
1495
0
     error,
1496
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1497
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1498
0
     "%s: invalid GUID data.",
1499
0
     function );
1500
1501
0
    return( -1 );
1502
0
  }
1503
0
  if( ( guid_data_size < 16 )
1504
0
   || ( guid_data_size > (size_t) SSIZE_MAX ) )
1505
0
  {
1506
0
    libcerror_error_set(
1507
0
     error,
1508
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1509
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1510
0
     "%s: GUID data size value out of bounds.",
1511
0
     function );
1512
1513
0
    return( -1 );
1514
0
  }
1515
0
  if( memory_copy(
1516
0
       guid_data,
1517
0
       internal_template->identifier,
1518
0
       16 ) == NULL )
1519
0
  {
1520
0
    libcerror_error_set(
1521
0
     error,
1522
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1523
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1524
0
     "%s: unable to copy identifier.",
1525
0
     function );
1526
1527
0
    return( -1 );
1528
0
  }
1529
0
  return( 1 );
1530
0
}
1531
1532
/* Retrieves the number of items
1533
 * Returns 1 if successful or -1 on error
1534
 */
1535
int libfwevt_template_get_number_of_items(
1536
     libfwevt_template_t *wevt_template,
1537
     int *number_of_items,
1538
     libcerror_error_t **error )
1539
0
{
1540
0
  libfwevt_internal_template_t *internal_template = NULL;
1541
0
  static char *function                           = "libfwevt_template_get_number_of_items";
1542
1543
0
  if( wevt_template == NULL )
1544
0
  {
1545
0
    libcerror_error_set(
1546
0
     error,
1547
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1548
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1549
0
     "%s: invalid template.",
1550
0
     function );
1551
1552
0
    return( -1 );
1553
0
  }
1554
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1555
1556
0
  if( libcdata_array_get_number_of_entries(
1557
0
       internal_template->items_array,
1558
0
       number_of_items,
1559
0
       error ) != 1 )
1560
0
  {
1561
0
    libcerror_error_set(
1562
0
     error,
1563
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1564
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1565
0
     "%s: unable to retrieve number of entries.",
1566
0
     function );
1567
1568
0
    return( -1 );
1569
0
  }
1570
0
  return( 1 );
1571
0
}
1572
1573
/* Retrieves a specific item
1574
 * Returns 1 if successful or -1 on error
1575
 */
1576
int libfwevt_template_get_item_by_index(
1577
     libfwevt_template_t *wevt_template,
1578
     int item_index,
1579
     libfwevt_template_item_t **item,
1580
     libcerror_error_t **error )
1581
0
{
1582
0
  libfwevt_internal_template_t *internal_template = NULL;
1583
0
  static char *function                           = "libfwevt_template_get_item_by_index";
1584
1585
0
  if( wevt_template == NULL )
1586
0
  {
1587
0
    libcerror_error_set(
1588
0
     error,
1589
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1590
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1591
0
     "%s: invalid template.",
1592
0
     function );
1593
1594
0
    return( -1 );
1595
0
  }
1596
0
  internal_template = (libfwevt_internal_template_t *) wevt_template;
1597
1598
0
  if( libcdata_array_get_entry_by_index(
1599
0
       internal_template->items_array,
1600
0
       item_index,
1601
0
       (intptr_t **) item,
1602
0
       error ) != 1 )
1603
0
  {
1604
0
    libcerror_error_set(
1605
0
     error,
1606
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1607
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1608
0
     "%s: unable to retrieve entry: %d.",
1609
0
     function,
1610
0
     item_index );
1611
1612
0
    return( -1 );
1613
0
  }
1614
0
  return( 1 );
1615
0
}
1616