Coverage Report

Created: 2025-10-14 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/liblnk/liblnk/liblnk_strings_data_block.c
Line
Count
Source
1
/*
2
 * Strings data block functions
3
 *
4
 * Copyright (C) 2009-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 <memory.h>
24
#include <types.h>
25
26
#include "liblnk_data_block.h"
27
#include "liblnk_data_string.h"
28
#include "liblnk_debug.h"
29
#include "liblnk_definitions.h"
30
#include "liblnk_libcerror.h"
31
#include "liblnk_libcnotify.h"
32
#include "liblnk_libuna.h"
33
34
#include "lnk_data_blocks.h"
35
36
/* Reads a strings data block
37
 * Returns 1 if successful or -1 on error
38
 */
39
int liblnk_strings_data_block_read(
40
     liblnk_data_block_t *data_block,
41
     libcerror_error_t **error )
42
2.01k
{
43
2.01k
  liblnk_data_string_t *data_string                 = NULL;
44
2.01k
  liblnk_internal_data_block_t *internal_data_block = NULL;
45
2.01k
  const uint8_t *string_data                        = NULL;
46
2.01k
  const uint8_t *unicode_string_data                = NULL;
47
2.01k
  static char *function                             = "liblnk_data_block_strings_read";
48
2.01k
  size_t string_size                                = 0;
49
2.01k
  size_t unicode_string_size                        = 0;
50
51
#if defined( HAVE_DEBUG_OUTPUT )
52
  uint32_t encoding_flags                           = 0;
53
#endif
54
55
2.01k
  if( data_block == NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
60
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
61
0
     "%s: invalid data block.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
2.01k
  internal_data_block = (liblnk_internal_data_block_t *) data_block;
67
68
2.01k
  if( internal_data_block->data == NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
73
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
74
0
     "%s: invalid data block - missing data.",
75
0
     function );
76
77
0
    return( -1 );
78
0
  }
79
2.01k
  if( internal_data_block->data_size < sizeof( lnk_data_block_strings_t ) )
80
30
  {
81
30
    libcerror_error_set(
82
30
     error,
83
30
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
84
30
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
85
30
     "%s: invalid data block - data size out of bounds.",
86
30
     function );
87
88
30
    return( -1 );
89
30
  }
90
1.98k
  if( internal_data_block->value != NULL )
91
0
  {
92
0
    libcerror_error_set(
93
0
     error,
94
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
95
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
96
0
     "%s: invalid data block - value already set.",
97
0
     function );
98
99
0
    return( -1 );
100
0
  }
101
1.98k
  if( liblnk_data_string_initialize(
102
1.98k
       &data_string,
103
1.98k
       error ) != 1 )
104
0
  {
105
0
    libcerror_error_set(
106
0
     error,
107
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
108
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
109
0
     "%s: unable to create environment variables location.",
110
0
     function );
111
112
0
    goto on_error;
113
0
  }
114
1.98k
  string_data = ( (lnk_data_block_strings_t *) internal_data_block->data )->string;
115
116
1.98k
  for( string_size = 0;
117
329k
       string_size < 260;
118
327k
       string_size++ )
119
329k
  {
120
329k
    if( string_data[ string_size ] == 0 )
121
1.07k
    {
122
1.07k
      break;
123
1.07k
    }
124
329k
  }
125
1.98k
  if( ( string_size == 260 )
126
1.07k
   || ( string_data[ string_size ] != 0 ) )
127
906
  {
128
#if defined( HAVE_VERBOSE_OUTPUT )
129
    if( libcnotify_verbose != 0 )
130
    {
131
      libcnotify_printf(
132
       "%s: unsupported data block strings\n" );
133
    }
134
#endif
135
906
    string_size = 0;
136
906
  }
137
1.07k
  else
138
1.07k
  {
139
1.07k
    string_size += 1;
140
1.07k
  }
141
#if defined( HAVE_DEBUG_OUTPUT )
142
  if( libcnotify_verbose != 0 )
143
  {
144
    libcnotify_printf(
145
     "%s: string data:\n",
146
     function );
147
    libcnotify_print_data(
148
     string_data,
149
     260,
150
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
151
152
    if( liblnk_debug_print_string_value(
153
         function,
154
         "string\t\t\t\t\t",
155
         string_data,
156
         260,
157
         internal_data_block->ascii_codepage,
158
         error ) != 1 )
159
    {
160
      libcerror_error_set(
161
       error,
162
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
163
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
164
       "%s: unable to print string value.",
165
       function );
166
167
      goto on_error;
168
    }
169
  }
170
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
171
172
1.98k
  unicode_string_data = ( (lnk_data_block_strings_t *) internal_data_block->data )->unicode_string;
173
174
1.98k
  for( unicode_string_size = 0;
175
369k
       unicode_string_size < 520;
176
367k
       unicode_string_size += 2 )
177
368k
  {
178
368k
    if( ( unicode_string_data[ unicode_string_size ] == 0 )
179
41.7k
     && ( unicode_string_data[ unicode_string_size + 1 ] == 0 ) )
180
997
    {
181
997
      break;
182
997
    }
183
368k
  }
184
1.98k
  if( ( unicode_string_size == 520 )
185
997
   || ( unicode_string_data[ unicode_string_size ] != 0 )
186
997
   || ( unicode_string_data[ unicode_string_size + 1 ] != 0 ) )
187
985
  {
188
#if defined( HAVE_VERBOSE_OUTPUT )
189
    if( libcnotify_verbose != 0 )
190
    {
191
      libcnotify_printf(
192
       "%s: unsupported Unicode string\n" );
193
    }
194
#endif
195
985
    unicode_string_size = 0;
196
985
  }
197
997
  else
198
997
  {
199
997
    unicode_string_size += 2;
200
997
  }
201
#if defined( HAVE_DEBUG_OUTPUT )
202
  if( libcnotify_verbose != 0 )
203
  {
204
    if( ( internal_data_block->signature == LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION )
205
     || ( internal_data_block->signature == LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION ) )
206
    {
207
      encoding_flags = LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE;
208
    }
209
    libcnotify_printf(
210
     "%s: Unicode string data:\n",
211
     function );
212
    libcnotify_print_data(
213
     unicode_string_data,
214
     520,
215
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
216
217
    if( liblnk_debug_print_utf16_string_value(
218
         function,
219
         "Unicode string\t\t\t\t",
220
         unicode_string_data,
221
         520,
222
         LIBUNA_ENDIAN_LITTLE | encoding_flags,
223
         error ) != 1 )
224
    {
225
      libcerror_error_set(
226
       error,
227
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
228
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
229
       "%s: unable to print UTF-16 string value.",
230
       function );
231
232
      goto on_error;
233
    }
234
    libcnotify_printf(
235
     "\n" );
236
  }
237
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
238
239
1.98k
  if( unicode_string_size > 0 )
240
997
  {
241
997
    data_string->data_size = unicode_string_size;
242
243
997
    data_string->data = (uint8_t *) memory_allocate(
244
997
                                     sizeof( uint8_t ) * data_string->data_size );
245
246
997
    if( data_string->data == NULL )
247
0
    {
248
0
      libcerror_error_set(
249
0
       error,
250
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
251
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
252
0
       "%s: unable to create data string data.",
253
0
       function );
254
255
0
      goto on_error;
256
0
    }
257
997
    if( memory_copy(
258
997
         data_string->data,
259
997
         unicode_string_data,
260
997
         data_string->data_size ) == NULL )
261
0
    {
262
0
      libcerror_error_set(
263
0
       error,
264
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
265
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
266
0
       "%s: unable to copy Unicode string data.",
267
0
       function );
268
269
0
      goto on_error;
270
0
    }
271
997
    data_string->is_unicode = 1;
272
997
  }
273
985
  else if( string_size > 0 )
274
433
  {
275
433
    data_string->data_size = string_size;
276
277
433
    data_string->data = (uint8_t *) memory_allocate(
278
433
                                     sizeof( uint8_t ) * data_string->data_size );
279
280
433
    if( data_string->data == NULL )
281
0
    {
282
0
      libcerror_error_set(
283
0
       error,
284
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
285
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
286
0
       "%s: unable to create data string data.",
287
0
       function );
288
289
0
      goto on_error;
290
0
    }
291
433
    if( memory_copy(
292
433
         data_string->data,
293
433
         unicode_string_data,
294
433
         data_string->data_size ) == NULL )
295
0
    {
296
0
      libcerror_error_set(
297
0
       error,
298
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
299
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
300
0
       "%s: unable to copy string data.",
301
0
       function );
302
303
0
      goto on_error;
304
0
    }
305
433
    data_string->is_unicode = 0;
306
433
  }
307
#if defined( HAVE_DEBUG_OUTPUT )
308
  if( libcnotify_verbose != 0 )
309
  {
310
    if( internal_data_block->data_size > sizeof( lnk_data_block_strings_t ) )
311
    {
312
      libcnotify_printf(
313
       "%s: trailing data:\n",
314
       function );
315
      libcnotify_print_data(
316
       &( internal_data_block->data[ sizeof( lnk_data_block_strings_t ) ] ),
317
       internal_data_block->data_size - sizeof( lnk_data_block_strings_t ),
318
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
319
    }
320
  }
321
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
322
323
1.98k
  internal_data_block->value      = (intptr_t *) data_string;
324
1.98k
  internal_data_block->free_value = (int(*)(intptr_t **, libcerror_error_t **)) &liblnk_data_string_free;
325
326
1.98k
  return( 1 );
327
328
0
on_error:
329
0
  if( data_string != NULL )
330
0
  {
331
0
    liblnk_data_string_free(
332
0
     &data_string,
333
0
     NULL );
334
0
  }
335
0
  return( -1 );
336
1.98k
}
337
338
/* Retrieves the size of the UTF-8 string
339
 * The size includes the end of string character
340
 * Returns 1 if successful or -1 on error
341
 */
342
int liblnk_strings_data_block_get_utf8_string_size(
343
     liblnk_data_block_t *data_block,
344
     size_t *utf8_string_size,
345
     libcerror_error_t **error )
346
0
{
347
0
  liblnk_internal_data_block_t *internal_data_block = NULL;
348
0
  static char *function                             = "liblnk_strings_data_block_get_utf8_string_size";
349
350
0
  if( data_block == NULL )
351
0
  {
352
0
    libcerror_error_set(
353
0
     error,
354
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
355
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
356
0
     "%s: invalid data block.",
357
0
     function );
358
359
0
    return( -1 );
360
0
  }
361
0
  internal_data_block = (liblnk_internal_data_block_t *) data_block;
362
363
0
  if( internal_data_block->value == NULL )
364
0
  {
365
0
    libcerror_error_set(
366
0
     error,
367
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
368
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
369
0
     "%s: invalid data block - missing value.",
370
0
     function );
371
372
0
    return( -1 );
373
0
  }
374
0
  if( internal_data_block->data_size < 4 )
375
0
  {
376
0
    libcerror_error_set(
377
0
     error,
378
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
379
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
380
0
     "%s: invalid data block - data size value out of bounds.",
381
0
     function );
382
383
0
    return( -1 );
384
0
  }
385
0
  if( ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION )
386
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_DARWIN_PROPERTIES )
387
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION ) )
388
0
  {
389
0
    libcerror_error_set(
390
0
     error,
391
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
392
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
393
0
     "%s: invalid data block - unsupported signature.",
394
0
     function );
395
396
0
    return( -1 );
397
0
  }
398
0
  if( liblnk_data_string_get_utf8_string_size(
399
0
       (liblnk_data_string_t *) internal_data_block->value,
400
0
       internal_data_block->ascii_codepage,
401
0
       utf8_string_size,
402
0
       error ) != 1 )
403
0
  {
404
0
    libcerror_error_set(
405
0
     error,
406
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
407
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
408
0
     "%s: unable to retrieve UTF-8 string size.",
409
0
     function );
410
411
0
    return( -1 );
412
0
  }
413
0
  return( 1 );
414
0
}
415
416
/* Retrieves the UTF-8 string
417
 * The size should include the end of string character
418
 * Returns 1 if successful or -1 on error
419
 */
420
int liblnk_strings_data_block_get_utf8_string(
421
     liblnk_data_block_t *data_block,
422
     uint8_t *utf8_string,
423
     size_t utf8_string_size,
424
     libcerror_error_t **error )
425
0
{
426
0
  liblnk_internal_data_block_t *internal_data_block = NULL;
427
0
  static char *function                             = "liblnk_strings_data_block_get_utf8_string";
428
429
0
  if( data_block == NULL )
430
0
  {
431
0
    libcerror_error_set(
432
0
     error,
433
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
434
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
435
0
     "%s: invalid data block.",
436
0
     function );
437
438
0
    return( -1 );
439
0
  }
440
0
  internal_data_block = (liblnk_internal_data_block_t *) data_block;
441
442
0
  if( internal_data_block->value == NULL )
443
0
  {
444
0
    libcerror_error_set(
445
0
     error,
446
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
447
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
448
0
     "%s: invalid data block - missing value.",
449
0
     function );
450
451
0
    return( -1 );
452
0
  }
453
0
  if( internal_data_block->data_size < 4 )
454
0
  {
455
0
    libcerror_error_set(
456
0
     error,
457
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
458
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
459
0
     "%s: invalid data block - data size value out of bounds.",
460
0
     function );
461
462
0
    return( -1 );
463
0
  }
464
0
  if( ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION )
465
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_DARWIN_PROPERTIES )
466
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION ) )
467
0
  {
468
0
    libcerror_error_set(
469
0
     error,
470
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
471
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
472
0
     "%s: invalid data block - unsupported signature.",
473
0
     function );
474
475
0
    return( -1 );
476
0
  }
477
0
  if( liblnk_data_string_get_utf8_string(
478
0
       (liblnk_data_string_t *) internal_data_block->value,
479
0
       internal_data_block->ascii_codepage,
480
0
       utf8_string,
481
0
       utf8_string_size,
482
0
       error ) != 1 )
483
0
  {
484
0
    libcerror_error_set(
485
0
     error,
486
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
487
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
488
0
     "%s: unable to retrieve UTF-8 string.",
489
0
     function );
490
491
0
    return( -1 );
492
0
  }
493
0
  return( 1 );
494
0
}
495
496
/* Retrieves the size of the UTF-16 string
497
 * The size includes the end of string character
498
 * Returns 1 if successful or -1 on error
499
 */
500
int liblnk_strings_data_block_get_utf16_string_size(
501
     liblnk_data_block_t *data_block,
502
     size_t *utf16_string_size,
503
     libcerror_error_t **error )
504
0
{
505
0
  liblnk_internal_data_block_t *internal_data_block = NULL;
506
0
  static char *function                             = "liblnk_strings_data_block_get_utf16_string_size";
507
508
0
  if( data_block == NULL )
509
0
  {
510
0
    libcerror_error_set(
511
0
     error,
512
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
513
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
514
0
     "%s: invalid data block.",
515
0
     function );
516
517
0
    return( -1 );
518
0
  }
519
0
  internal_data_block = (liblnk_internal_data_block_t *) data_block;
520
521
0
  if( internal_data_block->value == NULL )
522
0
  {
523
0
    libcerror_error_set(
524
0
     error,
525
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
526
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
527
0
     "%s: invalid data block - missing value.",
528
0
     function );
529
530
0
    return( -1 );
531
0
  }
532
0
  if( internal_data_block->data_size < 4 )
533
0
  {
534
0
    libcerror_error_set(
535
0
     error,
536
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
537
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
538
0
     "%s: invalid data block - data size value out of bounds.",
539
0
     function );
540
541
0
    return( -1 );
542
0
  }
543
0
  if( ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION )
544
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_DARWIN_PROPERTIES )
545
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION ) )
546
0
  {
547
0
    libcerror_error_set(
548
0
     error,
549
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
550
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
551
0
     "%s: invalid data block - unsupported signature.",
552
0
     function );
553
554
0
    return( -1 );
555
0
  }
556
0
  if( liblnk_data_string_get_utf16_string_size(
557
0
       (liblnk_data_string_t *) internal_data_block->value,
558
0
       internal_data_block->ascii_codepage,
559
0
       utf16_string_size,
560
0
       error ) != 1 )
561
0
  {
562
0
    libcerror_error_set(
563
0
     error,
564
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
565
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
566
0
     "%s: unable to retrieve UTF-16 string size.",
567
0
     function );
568
569
0
    return( -1 );
570
0
  }
571
0
  return( 1 );
572
0
}
573
574
/* Retrieves the UTF-16 string
575
 * The size should include the end of string character
576
 * Returns 1 if successful or -1 on error
577
 */
578
int liblnk_strings_data_block_get_utf16_string(
579
     liblnk_data_block_t *data_block,
580
     uint16_t *utf16_string,
581
     size_t utf16_string_size,
582
     libcerror_error_t **error )
583
0
{
584
0
  liblnk_internal_data_block_t *internal_data_block = NULL;
585
0
  static char *function                             = "liblnk_strings_data_block_get_utf16_string";
586
587
0
  if( data_block == NULL )
588
0
  {
589
0
    libcerror_error_set(
590
0
     error,
591
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
592
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
593
0
     "%s: invalid data block.",
594
0
     function );
595
596
0
    return( -1 );
597
0
  }
598
0
  internal_data_block = (liblnk_internal_data_block_t *) data_block;
599
600
0
  if( internal_data_block->value == NULL )
601
0
  {
602
0
    libcerror_error_set(
603
0
     error,
604
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
605
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
606
0
     "%s: invalid data block - missing value.",
607
0
     function );
608
609
0
    return( -1 );
610
0
  }
611
0
  if( internal_data_block->data_size < 4 )
612
0
  {
613
0
    libcerror_error_set(
614
0
     error,
615
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
616
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
617
0
     "%s: invalid data block - data size value out of bounds.",
618
0
     function );
619
620
0
    return( -1 );
621
0
  }
622
0
  if( ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION )
623
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_DARWIN_PROPERTIES )
624
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION ) )
625
0
  {
626
0
    libcerror_error_set(
627
0
     error,
628
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
629
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
630
0
     "%s: invalid data block - unsupported signature.",
631
0
     function );
632
633
0
    return( -1 );
634
0
  }
635
0
  if( liblnk_data_string_get_utf16_string(
636
0
       (liblnk_data_string_t *) internal_data_block->value,
637
0
       internal_data_block->ascii_codepage,
638
0
       utf16_string,
639
0
       utf16_string_size,
640
0
       error ) != 1 )
641
0
  {
642
0
    libcerror_error_set(
643
0
     error,
644
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
645
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
646
0
     "%s: unable to retrieve UTF-16 string.",
647
0
     function );
648
649
0
    return( -1 );
650
0
  }
651
0
  return( 1 );
652
0
}
653
654
/* Retrieves the size of the UTF-8 path string
655
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
656
 * The size includes the end of string character
657
 * Returns 1 if successful or -1 on error
658
 */
659
int liblnk_strings_data_block_get_utf8_path_string_size(
660
     liblnk_data_block_t *data_block,
661
     size_t *utf8_string_size,
662
     libcerror_error_t **error )
663
0
{
664
0
  liblnk_internal_data_block_t *internal_data_block = NULL;
665
0
  static char *function                             = "liblnk_strings_data_block_get_utf8_path_string_size";
666
667
0
  if( data_block == NULL )
668
0
  {
669
0
    libcerror_error_set(
670
0
     error,
671
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
672
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
673
0
     "%s: invalid data block.",
674
0
     function );
675
676
0
    return( -1 );
677
0
  }
678
0
  internal_data_block = (liblnk_internal_data_block_t *) data_block;
679
680
0
  if( internal_data_block->value == NULL )
681
0
  {
682
0
    libcerror_error_set(
683
0
     error,
684
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
685
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
686
0
     "%s: invalid data block - missing value.",
687
0
     function );
688
689
0
    return( -1 );
690
0
  }
691
0
  if( internal_data_block->data_size < 4 )
692
0
  {
693
0
    libcerror_error_set(
694
0
     error,
695
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
696
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
697
0
     "%s: invalid data block - data size value out of bounds.",
698
0
     function );
699
700
0
    return( -1 );
701
0
  }
702
0
  if( ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION )
703
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION ) )
704
0
  {
705
0
    libcerror_error_set(
706
0
     error,
707
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
708
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
709
0
     "%s: invalid data block - unsupported signature.",
710
0
     function );
711
712
0
    return( -1 );
713
0
  }
714
0
  if( liblnk_data_string_get_utf8_path_string_size(
715
0
       (liblnk_data_string_t *) internal_data_block->value,
716
0
       internal_data_block->ascii_codepage,
717
0
       utf8_string_size,
718
0
       error ) != 1 )
719
0
  {
720
0
    libcerror_error_set(
721
0
     error,
722
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
723
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
724
0
     "%s: unable to retrieve UTF-8 string size.",
725
0
     function );
726
727
0
    return( -1 );
728
0
  }
729
0
  return( 1 );
730
0
}
731
732
/* Retrieves the UTF-8 path string
733
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
734
 * The size should include the end of string character
735
 * Returns 1 if successful or -1 on error
736
 */
737
int liblnk_strings_data_block_get_utf8_path_string(
738
     liblnk_data_block_t *data_block,
739
     uint8_t *utf8_string,
740
     size_t utf8_string_size,
741
     libcerror_error_t **error )
742
0
{
743
0
  liblnk_internal_data_block_t *internal_data_block = NULL;
744
0
  static char *function                             = "liblnk_strings_data_block_get_utf8_path_string";
745
746
0
  if( data_block == NULL )
747
0
  {
748
0
    libcerror_error_set(
749
0
     error,
750
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
751
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
752
0
     "%s: invalid data block.",
753
0
     function );
754
755
0
    return( -1 );
756
0
  }
757
0
  internal_data_block = (liblnk_internal_data_block_t *) data_block;
758
759
0
  if( internal_data_block->value == NULL )
760
0
  {
761
0
    libcerror_error_set(
762
0
     error,
763
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
764
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
765
0
     "%s: invalid data block - missing value.",
766
0
     function );
767
768
0
    return( -1 );
769
0
  }
770
0
  if( internal_data_block->data_size < 4 )
771
0
  {
772
0
    libcerror_error_set(
773
0
     error,
774
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
775
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
776
0
     "%s: invalid data block - data size value out of bounds.",
777
0
     function );
778
779
0
    return( -1 );
780
0
  }
781
0
  if( ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION )
782
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION ) )
783
0
  {
784
0
    libcerror_error_set(
785
0
     error,
786
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
787
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
788
0
     "%s: invalid data block - unsupported signature.",
789
0
     function );
790
791
0
    return( -1 );
792
0
  }
793
0
  if( liblnk_data_string_get_utf8_path_string(
794
0
       (liblnk_data_string_t *) internal_data_block->value,
795
0
       internal_data_block->ascii_codepage,
796
0
       utf8_string,
797
0
       utf8_string_size,
798
0
       error ) != 1 )
799
0
  {
800
0
    libcerror_error_set(
801
0
     error,
802
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
803
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
804
0
     "%s: unable to retrieve UTF-8 string.",
805
0
     function );
806
807
0
    return( -1 );
808
0
  }
809
0
  return( 1 );
810
0
}
811
812
/* Retrieves the size of the UTF-16 path string
813
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
814
 * The size includes the end of string character
815
 * Returns 1 if successful or -1 on error
816
 */
817
int liblnk_strings_data_block_get_utf16_path_string_size(
818
     liblnk_data_block_t *data_block,
819
     size_t *utf16_string_size,
820
     libcerror_error_t **error )
821
0
{
822
0
  liblnk_internal_data_block_t *internal_data_block = NULL;
823
0
  static char *function                             = "liblnk_strings_data_block_get_utf16_path_string_size";
824
825
0
  if( data_block == NULL )
826
0
  {
827
0
    libcerror_error_set(
828
0
     error,
829
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
830
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
831
0
     "%s: invalid data block.",
832
0
     function );
833
834
0
    return( -1 );
835
0
  }
836
0
  internal_data_block = (liblnk_internal_data_block_t *) data_block;
837
838
0
  if( internal_data_block->value == NULL )
839
0
  {
840
0
    libcerror_error_set(
841
0
     error,
842
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
843
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
844
0
     "%s: invalid data block - missing value.",
845
0
     function );
846
847
0
    return( -1 );
848
0
  }
849
0
  if( internal_data_block->data_size < 4 )
850
0
  {
851
0
    libcerror_error_set(
852
0
     error,
853
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
854
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
855
0
     "%s: invalid data block - data size value out of bounds.",
856
0
     function );
857
858
0
    return( -1 );
859
0
  }
860
0
  if( ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION )
861
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION ) )
862
0
  {
863
0
    libcerror_error_set(
864
0
     error,
865
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
866
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
867
0
     "%s: invalid data block - unsupported signature.",
868
0
     function );
869
870
0
    return( -1 );
871
0
  }
872
0
  if( liblnk_data_string_get_utf16_path_string_size(
873
0
       (liblnk_data_string_t *) internal_data_block->value,
874
0
       internal_data_block->ascii_codepage,
875
0
       utf16_string_size,
876
0
       error ) != 1 )
877
0
  {
878
0
    libcerror_error_set(
879
0
     error,
880
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
881
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
882
0
     "%s: unable to retrieve UTF-16 string size.",
883
0
     function );
884
885
0
    return( -1 );
886
0
  }
887
0
  return( 1 );
888
0
}
889
890
/* Retrieves the UTF-16 path string
891
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
892
 * The size should include the end of string character
893
 * Returns 1 if successful or -1 on error
894
 */
895
int liblnk_strings_data_block_get_utf16_path_string(
896
     liblnk_data_block_t *data_block,
897
     uint16_t *utf16_string,
898
     size_t utf16_string_size,
899
     libcerror_error_t **error )
900
0
{
901
0
  liblnk_internal_data_block_t *internal_data_block = NULL;
902
0
  static char *function                             = "liblnk_strings_data_block_get_utf16_path_string";
903
904
0
  if( data_block == NULL )
905
0
  {
906
0
    libcerror_error_set(
907
0
     error,
908
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
909
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
910
0
     "%s: invalid data block.",
911
0
     function );
912
913
0
    return( -1 );
914
0
  }
915
0
  internal_data_block = (liblnk_internal_data_block_t *) data_block;
916
917
0
  if( internal_data_block->value == NULL )
918
0
  {
919
0
    libcerror_error_set(
920
0
     error,
921
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
922
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
923
0
     "%s: invalid data block - missing value.",
924
0
     function );
925
926
0
    return( -1 );
927
0
  }
928
0
  if( internal_data_block->data_size < 4 )
929
0
  {
930
0
    libcerror_error_set(
931
0
     error,
932
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
933
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
934
0
     "%s: invalid data block - data size value out of bounds.",
935
0
     function );
936
937
0
    return( -1 );
938
0
  }
939
0
  if( ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION )
940
0
   && ( internal_data_block->signature != LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION ) )
941
0
  {
942
0
    libcerror_error_set(
943
0
     error,
944
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
945
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
946
0
     "%s: invalid data block - unsupported signature.",
947
0
     function );
948
949
0
    return( -1 );
950
0
  }
951
0
  if( liblnk_data_string_get_utf16_path_string(
952
0
       (liblnk_data_string_t *) internal_data_block->value,
953
0
       internal_data_block->ascii_codepage,
954
0
       utf16_string,
955
0
       utf16_string_size,
956
0
       error ) != 1 )
957
0
  {
958
0
    libcerror_error_set(
959
0
     error,
960
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
961
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
962
0
     "%s: unable to retrieve UTF-16 string.",
963
0
     function );
964
965
0
    return( -1 );
966
0
  }
967
0
  return( 1 );
968
0
}
969