Coverage Report

Created: 2026-04-10 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfwsi/libfwsi/libfwsi_network_location_values.c
Line
Count
Source
1
/*
2
 * Network location (shell item) values functions
3
 *
4
 * Copyright (C) 2010-2025, 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_libcerror.h"
30
#include "libfwsi_libcnotify.h"
31
#include "libfwsi_libuna.h"
32
#include "libfwsi_network_location_values.h"
33
34
/* Creates network location values
35
 * Make sure the value network_location_values is referencing, is set to NULL
36
 * Returns 1 if successful or -1 on error
37
 */
38
int libfwsi_network_location_values_initialize(
39
     libfwsi_network_location_values_t **network_location_values,
40
     libcerror_error_t **error )
41
0
{
42
0
  static char *function = "libfwsi_network_location_values_initialize";
43
44
0
  if( network_location_values == NULL )
45
0
  {
46
0
    libcerror_error_set(
47
0
     error,
48
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50
0
     "%s: invalid network location values.",
51
0
     function );
52
53
0
    return( -1 );
54
0
  }
55
0
  if( *network_location_values != NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
60
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
61
0
     "%s: invalid network location values value already set.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
0
  *network_location_values = memory_allocate_structure(
67
0
                              libfwsi_network_location_values_t );
68
69
0
  if( *network_location_values == NULL )
70
0
  {
71
0
    libcerror_error_set(
72
0
     error,
73
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
74
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
75
0
     "%s: unable to create network location values.",
76
0
     function );
77
78
0
    goto on_error;
79
0
  }
80
0
  if( memory_set(
81
0
       *network_location_values,
82
0
       0,
83
0
       sizeof( libfwsi_network_location_values_t ) ) == NULL )
84
0
  {
85
0
    libcerror_error_set(
86
0
     error,
87
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
88
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
89
0
     "%s: unable to clear network location values.",
90
0
     function );
91
92
0
    goto on_error;
93
0
  }
94
0
  return( 1 );
95
96
0
on_error:
97
0
  if( *network_location_values != NULL )
98
0
  {
99
0
    memory_free(
100
0
     *network_location_values );
101
102
0
    *network_location_values = NULL;
103
0
  }
104
0
  return( -1 );
105
0
}
106
107
/* Frees network location values
108
 * Returns 1 if successful or -1 on error
109
 */
110
int libfwsi_network_location_values_free(
111
     libfwsi_network_location_values_t **network_location_values,
112
     libcerror_error_t **error )
113
0
{
114
0
  static char *function = "libfwsi_network_location_values_free";
115
116
0
  if( network_location_values == NULL )
117
0
  {
118
0
    libcerror_error_set(
119
0
     error,
120
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
121
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
122
0
     "%s: invalid network location values.",
123
0
     function );
124
125
0
    return( -1 );
126
0
  }
127
0
  if( *network_location_values != NULL )
128
0
  {
129
0
    if( ( *network_location_values )->location != NULL )
130
0
    {
131
0
      memory_free(
132
0
       ( *network_location_values )->location );
133
0
    }
134
0
    if( ( *network_location_values )->description != NULL )
135
0
    {
136
0
      memory_free(
137
0
       ( *network_location_values )->description );
138
0
    }
139
0
    if( ( *network_location_values )->comments != NULL )
140
0
    {
141
0
      memory_free(
142
0
       ( *network_location_values )->comments );
143
0
    }
144
0
    memory_free(
145
0
     *network_location_values );
146
147
0
    *network_location_values = NULL;
148
0
  }
149
0
  return( 1 );
150
0
}
151
152
/* Reads the network location values
153
 * Returns 1 if successful, 0 if not supported or -1 on error
154
 */
155
int libfwsi_network_location_values_read_data(
156
     libfwsi_network_location_values_t *network_location_values,
157
     const uint8_t *data,
158
     size_t data_size,
159
     int ascii_codepage,
160
     libcerror_error_t **error )
161
0
{
162
0
  static char *function = "libfwsi_network_location_values_read_data";
163
0
  size_t data_offset    = 0;
164
0
  size_t string_size    = 0;
165
0
  uint8_t flags         = 0;
166
167
#if defined( HAVE_DEBUG_OUTPUT )
168
  uint16_t value_16bit  = 0;
169
#endif
170
171
0
  if( network_location_values == NULL )
172
0
  {
173
0
    libcerror_error_set(
174
0
     error,
175
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
176
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
177
0
     "%s: invalid network location values.",
178
0
     function );
179
180
0
    return( -1 );
181
0
  }
182
0
  if( network_location_values->location != NULL )
183
0
  {
184
0
    libcerror_error_set(
185
0
     error,
186
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
187
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
188
0
     "%s: invalid network location values - location value already set.",
189
0
     function );
190
191
0
    return( -1 );
192
0
  }
193
0
  if( network_location_values->description != NULL )
194
0
  {
195
0
    libcerror_error_set(
196
0
     error,
197
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
198
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
199
0
     "%s: invalid network location values - description value already set.",
200
0
     function );
201
202
0
    return( -1 );
203
0
  }
204
0
  if( network_location_values->comments != NULL )
205
0
  {
206
0
    libcerror_error_set(
207
0
     error,
208
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
209
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
210
0
     "%s: invalid network location values - comments value already set.",
211
0
     function );
212
213
0
    return( -1 );
214
0
  }
215
0
  if( data == NULL )
216
0
  {
217
0
    libcerror_error_set(
218
0
     error,
219
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
220
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
221
0
     "%s: invalid data.",
222
0
     function );
223
224
0
    return( -1 );
225
0
  }
226
0
  if( data_size > (size_t) SSIZE_MAX )
227
0
  {
228
0
    libcerror_error_set(
229
0
     error,
230
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
231
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
232
0
     "%s: data size exceeds maximum.",
233
0
     function );
234
235
0
    return( -1 );
236
0
  }
237
  /* Do not try to parse unsupported data sizes
238
   */
239
0
  if( data_size < 6 )
240
0
  {
241
0
    return( 0 );
242
0
  }
243
  /* Do not try to parse unsupported data
244
   */
245
0
  if( ( data[ 2 ] != 0x41 )
246
0
   && ( data[ 2 ] != 0x42 )
247
0
   && ( data[ 2 ] != 0x46 )
248
0
   && ( data[ 2 ] != 0x47 )
249
0
   && ( data[ 2 ] != 0x4c )
250
0
   && ( data[ 2 ] != 0xc3 ) )
251
0
  {
252
0
    return( 0 );
253
0
  }
254
0
  network_location_values->ascii_codepage = ascii_codepage;
255
256
0
  flags = data[ 4 ];
257
258
#if defined( HAVE_DEBUG_OUTPUT )
259
  if( libcnotify_verbose != 0 )
260
  {
261
    libcnotify_printf(
262
     "%s: unknown0\t\t\t: 0x%02" PRIx8 "\n",
263
     function,
264
     data[ 3 ] );
265
266
    libcnotify_printf(
267
     "%s: flags\t\t\t: 0x%02" PRIx8 "\n",
268
     function,
269
     flags );
270
  }
271
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
272
273
0
  data_offset = 5;
274
275
  /* Determine the network location
276
   */
277
0
  for( string_size = data_offset;
278
0
       string_size < data_size;
279
0
       string_size++ )
280
0
  {
281
0
    if( data[ string_size ] == 0 )
282
0
    {
283
0
      string_size++;
284
285
0
      break;
286
0
    }
287
0
  }
288
0
  string_size -= data_offset;
289
290
0
  if( ( string_size == 0 )
291
0
   || ( string_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
292
0
  {
293
0
    libcerror_error_set(
294
0
     error,
295
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
296
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
297
0
     "%s: invalid location string size value out of bounds.",
298
0
     function );
299
300
0
    goto on_error;
301
0
  }
302
0
  network_location_values->location = (uint8_t *) memory_allocate(
303
0
                                                   sizeof( uint8_t ) * string_size );
304
305
0
  if( network_location_values->location == NULL )
306
0
  {
307
0
    libcerror_error_set(
308
0
     error,
309
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
310
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
311
0
     "%s: unable to create location.",
312
0
     function );
313
314
0
    goto on_error;
315
0
  }
316
0
  if( memory_copy(
317
0
       network_location_values->location,
318
0
       &( data[ data_offset ] ),
319
0
       string_size ) == NULL )
320
0
  {
321
0
    libcerror_error_set(
322
0
     error,
323
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
324
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
325
0
     "%s: unable to copy location.",
326
0
     function );
327
328
0
    goto on_error;
329
0
  }
330
0
  network_location_values->location_size = string_size;
331
332
#if defined( HAVE_DEBUG_OUTPUT )
333
  if( libcnotify_verbose != 0 )
334
  {
335
    if( libfwsi_debug_print_string_value(
336
         function,
337
         "network location\t\t",
338
         network_location_values->location,
339
         network_location_values->location_size,
340
         ascii_codepage,
341
         error ) != 1 )
342
    {
343
      libcerror_error_set(
344
       error,
345
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
346
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
347
       "%s: unable to print string value.",
348
       function );
349
350
      goto on_error;
351
    }
352
  }
353
#endif
354
0
  data_offset += string_size;
355
356
0
  if( ( ( flags & 0x80 ) != 0 )
357
0
   && ( data_offset < data_size ) )
358
0
  {
359
    /* Determine the network description
360
     */
361
0
    for( string_size = data_offset;
362
0
         string_size < data_size;
363
0
         string_size++ )
364
0
    {
365
0
      if( data[ string_size ] == 0 )
366
0
      {
367
0
        string_size++;
368
369
0
        break;
370
0
      }
371
0
    }
372
0
    string_size -= data_offset;
373
374
0
    if( ( string_size == 0 )
375
0
     || ( string_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
376
0
    {
377
0
      libcerror_error_set(
378
0
       error,
379
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
380
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
381
0
       "%s: invalid description string size value out of bounds.",
382
0
       function );
383
384
0
      goto on_error;
385
0
    }
386
0
    network_location_values->description = (uint8_t *) memory_allocate(
387
0
                                                        sizeof( uint8_t ) * string_size );
388
389
0
    if( network_location_values->description == NULL )
390
0
    {
391
0
      libcerror_error_set(
392
0
       error,
393
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
394
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
395
0
       "%s: unable to create description.",
396
0
       function );
397
398
0
      goto on_error;
399
0
    }
400
0
    if( memory_copy(
401
0
         network_location_values->description,
402
0
         &( data[ data_offset ] ),
403
0
         string_size ) == NULL )
404
0
    {
405
0
      libcerror_error_set(
406
0
       error,
407
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
408
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
409
0
       "%s: unable to copy description.",
410
0
       function );
411
412
0
      goto on_error;
413
0
    }
414
0
    network_location_values->description_size = string_size;
415
416
#if defined( HAVE_DEBUG_OUTPUT )
417
    if( libcnotify_verbose != 0 )
418
    {
419
      if( libfwsi_debug_print_string_value(
420
           function,
421
           "network description\t\t",
422
           network_location_values->description,
423
           network_location_values->description_size,
424
           ascii_codepage,
425
           error ) != 1 )
426
      {
427
        libcerror_error_set(
428
         error,
429
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
430
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
431
         "%s: unable to print string value.",
432
         function );
433
434
        goto on_error;
435
      }
436
    }
437
#endif
438
0
    data_offset += string_size;
439
0
  }
440
0
  if( ( ( flags & 0x40 ) != 0 )
441
0
   && ( data_size > 0 ) )
442
0
  {
443
    /* Determine the network comments
444
     */
445
0
    for( string_size = data_offset;
446
0
         string_size < data_size;
447
0
         string_size++ )
448
0
    {
449
0
      if( data[ string_size ] == 0 )
450
0
      {
451
0
        string_size++;
452
453
0
        break;
454
0
      }
455
0
    }
456
0
    string_size -= data_offset;
457
458
0
    if( ( string_size == 0 )
459
0
     || ( string_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
460
0
    {
461
0
      libcerror_error_set(
462
0
       error,
463
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
464
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
465
0
       "%s: invalid comments string size value out of bounds.",
466
0
       function );
467
468
0
      goto on_error;
469
0
    }
470
0
    network_location_values->comments = (uint8_t *) memory_allocate(
471
0
                                                     sizeof( uint8_t ) * string_size );
472
473
0
    if( network_location_values->comments == NULL )
474
0
    {
475
0
      libcerror_error_set(
476
0
       error,
477
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
478
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
479
0
       "%s: unable to create comments.",
480
0
       function );
481
482
0
      goto on_error;
483
0
    }
484
0
    if( memory_copy(
485
0
         network_location_values->comments,
486
0
         &( data[ data_offset ] ),
487
0
         string_size ) == NULL )
488
0
    {
489
0
      libcerror_error_set(
490
0
       error,
491
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
492
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
493
0
       "%s: unable to copy comments.",
494
0
       function );
495
496
0
      goto on_error;
497
0
    }
498
0
    network_location_values->comments_size = string_size;
499
500
#if defined( HAVE_DEBUG_OUTPUT )
501
    if( libcnotify_verbose != 0 )
502
    {
503
      if( libfwsi_debug_print_string_value(
504
           function,
505
           "network comments\t\t",
506
           network_location_values->comments,
507
           network_location_values->comments_size,
508
           ascii_codepage,
509
           error ) != 1 )
510
      {
511
        libcerror_error_set(
512
         error,
513
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
514
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
515
         "%s: unable to print string value.",
516
         function );
517
518
        goto on_error;
519
      }
520
    }
521
#endif
522
0
    data_offset += string_size;
523
0
  }
524
0
  if( data_offset <= ( data_size - 2 ) )
525
0
  {
526
#if defined( HAVE_DEBUG_OUTPUT )
527
    if( libcnotify_verbose != 0 )
528
    {
529
      byte_stream_copy_to_uint16_little_endian(
530
       &( data[ data_offset ] ),
531
       value_16bit );
532
533
      libcnotify_printf(
534
       "%s: unknown1\t\t\t: 0x%04" PRIx16 "\n",
535
       function,
536
       value_16bit );
537
    }
538
#endif
539
0
    data_offset += 2;
540
0
  }
541
#if defined( HAVE_DEBUG_OUTPUT )
542
  if( libcnotify_verbose != 0 )
543
  {
544
    libcnotify_printf(
545
     "\n" );
546
  }
547
#endif
548
0
  return( 1 );
549
550
0
on_error:
551
0
  if( network_location_values->comments != NULL )
552
0
  {
553
0
    memory_free(
554
0
     network_location_values->comments );
555
556
0
    network_location_values->comments = NULL;
557
0
  }
558
0
  network_location_values->comments_size = 0;
559
560
0
  if( network_location_values->description != NULL )
561
0
  {
562
0
    memory_free(
563
0
     network_location_values->description );
564
565
0
    network_location_values->description = NULL;
566
0
  }
567
0
  network_location_values->description_size = 0;
568
569
0
  if( network_location_values->location != NULL )
570
0
  {
571
0
    memory_free(
572
0
     network_location_values->location );
573
574
0
    network_location_values->location = NULL;
575
0
  }
576
0
  network_location_values->location_size = 0;
577
578
0
  return( -1 );
579
0
}
580