Coverage Report

Created: 2026-05-24 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfwsi/libfwsi/libfwsi_extension_block_0xbeef0014_values.c
Line
Count
Source
1
/*
2
 * Extension block 0xbeef0014 values functions
3
 *
4
 * Copyright (C) 2010-2026, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libfwsi_debug.h"
28
#include "libfwsi_definitions.h"
29
#include "libfwsi_extension_block_0xbeef0014_values.h"
30
#include "libfwsi_libcerror.h"
31
#include "libfwsi_libcnotify.h"
32
#include "libfwsi_libfguid.h"
33
34
const uint8_t curi_class_identifier[ 16 ] = {
35
  0x13, 0xce, 0x2f, 0xdf, 0xec, 0x25, 0xbb, 0x45, 0x9d, 0x4c, 0xce, 0xcd, 0x47, 0xc2, 0x43, 0x0c };
36
37
/* Creates extension block 0xbeef0014 values
38
 * Make sure the value extension_block_0xbeef0014_values is referencing, is set to NULL
39
 * Returns 1 if successful or -1 on error
40
 */
41
int libfwsi_extension_block_0xbeef0014_values_initialize(
42
     libfwsi_extension_block_0xbeef0014_values_t **extension_block_0xbeef0014_values,
43
     libcerror_error_t **error )
44
0
{
45
0
  static char *function = "libfwsi_extension_block_0xbeef0014_values_initialize";
46
47
0
  if( extension_block_0xbeef0014_values == NULL )
48
0
  {
49
0
    libcerror_error_set(
50
0
     error,
51
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53
0
     "%s: invalid extension block 0xbeef0014 values.",
54
0
     function );
55
56
0
    return( -1 );
57
0
  }
58
0
  if( *extension_block_0xbeef0014_values != NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
63
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64
0
     "%s: invalid extension block 0xbeef0014 values value already set.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
0
  *extension_block_0xbeef0014_values = memory_allocate_structure(
70
0
                                        libfwsi_extension_block_0xbeef0014_values_t );
71
72
0
  if( *extension_block_0xbeef0014_values == NULL )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
77
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
78
0
     "%s: unable to create extension block 0xbeef0014 values.",
79
0
     function );
80
81
0
    goto on_error;
82
0
  }
83
0
  if( memory_set(
84
0
       *extension_block_0xbeef0014_values,
85
0
       0,
86
0
       sizeof( libfwsi_extension_block_0xbeef0014_values_t ) ) == NULL )
87
0
  {
88
0
    libcerror_error_set(
89
0
     error,
90
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
91
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
92
0
     "%s: unable to clear extension block 0xbeef0014 values.",
93
0
     function );
94
95
0
    goto on_error;
96
0
  }
97
0
  return( 1 );
98
99
0
on_error:
100
0
  if( *extension_block_0xbeef0014_values != NULL )
101
0
  {
102
0
    memory_free(
103
0
     *extension_block_0xbeef0014_values );
104
105
0
    *extension_block_0xbeef0014_values = NULL;
106
0
  }
107
0
  return( -1 );
108
0
}
109
110
/* Frees extension block 0xbeef0014 values
111
 * Returns 1 if successful or -1 on error
112
 */
113
int libfwsi_extension_block_0xbeef0014_values_free(
114
     libfwsi_extension_block_0xbeef0014_values_t **extension_block_0xbeef0014_values,
115
     libcerror_error_t **error )
116
0
{
117
0
  static char *function = "libfwsi_extension_block_0xbeef0014_values_free";
118
119
0
  if( extension_block_0xbeef0014_values == NULL )
120
0
  {
121
0
    libcerror_error_set(
122
0
     error,
123
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
124
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
125
0
     "%s: invalid extension block 0xbeef0014 values.",
126
0
     function );
127
128
0
    return( -1 );
129
0
  }
130
0
  if( *extension_block_0xbeef0014_values != NULL )
131
0
  {
132
0
    memory_free(
133
0
     *extension_block_0xbeef0014_values );
134
135
0
    *extension_block_0xbeef0014_values = NULL;
136
0
  }
137
0
  return( 1 );
138
0
}
139
140
/* Reads the extension block 0xbeef0014 values
141
 * Returns 1 if successful, 0 if not supported or -1 on error
142
 */
143
int libfwsi_extension_block_0xbeef0014_values_read_data(
144
     libfwsi_extension_block_0xbeef0014_values_t *extension_block_0xbeef0014_values,
145
     const uint8_t *data,
146
     size_t data_size,
147
     libcerror_error_t **error )
148
0
{
149
0
  static char *function         = "libfwsi_extension_block_0xbeef0014_values_read_data";
150
0
  size_t data_offset            = 0;
151
0
  uint32_t number_of_properties = 0;
152
0
  uint32_t property_index       = 0;
153
0
  uint32_t property_size        = 0;
154
0
  uint32_t property_type        = 0;
155
0
  uint32_t signature            = 0;
156
0
  int result                    = 0;
157
158
#if defined( HAVE_DEBUG_OUTPUT )
159
  uint32_t value_32bit          = 0;
160
#endif
161
162
0
  if( extension_block_0xbeef0014_values == NULL )
163
0
  {
164
0
    libcerror_error_set(
165
0
     error,
166
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
167
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
168
0
     "%s: invalid extension block 0xbeef0014 values.",
169
0
     function );
170
171
0
    return( -1 );
172
0
  }
173
0
  if( data == NULL )
174
0
  {
175
0
    libcerror_error_set(
176
0
     error,
177
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
178
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
179
0
     "%s: invalid data.",
180
0
     function );
181
182
0
    return( -1 );
183
0
  }
184
0
  if( data_size > (size_t) SSIZE_MAX )
185
0
  {
186
0
    libcerror_error_set(
187
0
     error,
188
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
189
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
190
0
     "%s: data size exceeds maximum.",
191
0
     function );
192
193
0
    return( -1 );
194
0
  }
195
  /* Do not try to parse unsupported data sizes
196
   */
197
0
  if( data_size < 26 )
198
0
  {
199
0
    return( 0 );
200
0
  }
201
  /* Do not try to parse unsupported extension block signatures
202
   */
203
0
  byte_stream_copy_to_uint32_little_endian(
204
0
   &( data[ 4 ] ),
205
0
   signature );
206
207
0
  if( signature != 0xbeef0014 )
208
0
  {
209
0
    return( 0 );
210
0
  }
211
#if defined( HAVE_DEBUG_OUTPUT )
212
  if( libcnotify_verbose != 0 )
213
  {
214
    if( libfwsi_debug_print_guid_value(
215
         function,
216
         "class identifier\t\t",
217
         &( data[ 8 ] ),
218
         16,
219
         LIBFGUID_ENDIAN_LITTLE,
220
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
221
         error ) != 1 )
222
    {
223
      libcerror_error_set(
224
       error,
225
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
226
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
227
       "%s: unable to print GUID value.",
228
       function );
229
230
      return( -1 );
231
    }
232
  }
233
#endif
234
0
  result = memory_compare(
235
0
            &( data[ 8 ] ),
236
0
            curi_class_identifier,
237
0
            16 );
238
239
0
  data_offset = 24;
240
241
0
  if( result == 0 )
242
0
  {
243
0
    if( data_size < 58 )
244
0
    {
245
0
      return( 0 );
246
0
    }
247
#if defined( HAVE_DEBUG_OUTPUT )
248
    if( libcnotify_verbose != 0 )
249
    {
250
      byte_stream_copy_to_uint32_little_endian(
251
       &( data[ data_offset ] ),
252
       value_32bit );
253
254
      libcnotify_printf(
255
       "%s: data size\t\t\t: %" PRIu32 "\n",
256
       function,
257
       value_32bit );
258
    }
259
#endif
260
0
    data_offset += 4;
261
262
#if defined( HAVE_DEBUG_OUTPUT )
263
    if( libcnotify_verbose != 0 )
264
    {
265
      libcnotify_printf(
266
       "%s: unknown1:\n",
267
       function );
268
      libcnotify_print_data(
269
       &( data[ data_offset ] ),
270
       8,
271
       0 );
272
    }
273
#endif
274
0
    data_offset += 8;
275
276
#if defined( HAVE_DEBUG_OUTPUT )
277
    if( libcnotify_verbose != 0 )
278
    {
279
      byte_stream_copy_to_uint32_little_endian(
280
       &( data[ data_offset ] ),
281
       value_32bit );
282
283
      libcnotify_printf(
284
       "%s: unknown2\t\t\t: 0x%08" PRIx32 "\n",
285
       function,
286
       value_32bit );
287
    }
288
#endif
289
0
    data_offset += 4;
290
291
#if defined( HAVE_DEBUG_OUTPUT )
292
    if( libcnotify_verbose != 0 )
293
    {
294
      libcnotify_printf(
295
       "%s: unknown3:\n",
296
       function );
297
      libcnotify_print_data(
298
       &( data[ data_offset ] ),
299
       12,
300
       0 );
301
    }
302
#endif
303
0
    data_offset += 12;
304
305
    /* Property table
306
     */
307
0
    byte_stream_copy_to_uint32_little_endian(
308
0
     &( data[ data_offset ] ),
309
0
     number_of_properties );
310
311
#if defined( HAVE_DEBUG_OUTPUT )
312
    if( libcnotify_verbose != 0 )
313
    {
314
      libcnotify_printf(
315
       "%s: number of properties\t: %" PRIu32 "\n",
316
       function,
317
       number_of_properties );
318
    }
319
#endif
320
0
    data_offset += 4;
321
322
0
    for( property_index = 0;
323
0
         property_index < number_of_properties;
324
0
         property_index++ )
325
0
    {
326
0
      if( data_offset > ( data_size - 8 ) )
327
0
      {
328
0
        return( 0 );
329
0
      }
330
0
      byte_stream_copy_to_uint32_little_endian(
331
0
       &( data[ data_offset ] ),
332
0
       property_type );
333
334
#if defined( HAVE_DEBUG_OUTPUT )
335
      if( libcnotify_verbose != 0 )
336
      {
337
        libcnotify_printf(
338
         "%s: property: %" PRIu32 " type\t\t: %" PRIu32 "\n",
339
         function,
340
         property_index,
341
         property_type );
342
      }
343
#endif
344
0
      data_offset += 4;
345
346
0
      byte_stream_copy_to_uint32_little_endian(
347
0
       &( data[ data_offset ] ),
348
0
       property_size );
349
350
#if defined( HAVE_DEBUG_OUTPUT )
351
      if( libcnotify_verbose != 0 )
352
      {
353
        libcnotify_printf(
354
         "%s: property: %" PRIu32 " size\t\t: %" PRIu32 "\n",
355
         function,
356
         property_index,
357
         property_size );
358
      }
359
#endif
360
0
      data_offset += 4;
361
362
0
      if( ( property_size > data_size )
363
0
       || ( data_offset > ( data_size - property_size ) ) )
364
0
      {
365
0
        return( 0 );
366
0
      }
367
#if defined( HAVE_DEBUG_OUTPUT )
368
      if( libcnotify_verbose != 0 )
369
      {
370
        libcnotify_printf(
371
         "%s: property: %" PRIu32 " data:\n",
372
         function,
373
         property_index );
374
        libcnotify_print_data(
375
         &( data[ data_offset ] ),
376
         property_size,
377
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
378
      }
379
#endif
380
0
      data_offset += property_size;
381
0
    }
382
0
  }
383
#if defined( HAVE_DEBUG_OUTPUT )
384
  if( libcnotify_verbose != 0 )
385
  {
386
    libcnotify_printf(
387
     "\n" );
388
  }
389
#endif
390
0
  return( 1 );
391
0
}
392