Coverage Report

Created: 2023-06-07 06:53

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