Coverage Report

Created: 2026-01-13 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/liblnk/liblnk/liblnk_location_information.c
Line
Count
Source
1
/*
2
 * Location information functions
3
 *
4
 * Copyright (C) 2009-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 "liblnk_debug.h"
28
#include "liblnk_definitions.h"
29
#include "liblnk_libbfio.h"
30
#include "liblnk_libcerror.h"
31
#include "liblnk_libcnotify.h"
32
#include "liblnk_libfwsi.h"
33
#include "liblnk_libuna.h"
34
#include "liblnk_location_information.h"
35
36
#include "lnk_location_information.h"
37
#include "lnk_network_share_information.h"
38
#include "lnk_volume_information.h"
39
40
/* Creates location information
41
 * Make sure the value location_information is referencing, is set to NULL
42
 * Returns 1 if successful or -1 on error
43
 */
44
int liblnk_location_information_initialize(
45
     liblnk_location_information_t **location_information,
46
     libcerror_error_t **error )
47
1.47k
{
48
1.47k
  static char *function = "liblnk_location_information_initialize";
49
50
1.47k
  if( location_information == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid location information.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
1.47k
  if( *location_information != NULL )
62
0
  {
63
0
    libcerror_error_set(
64
0
     error,
65
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
66
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
67
0
     "%s: invalid location information value already set.",
68
0
     function );
69
70
0
    return( -1 );
71
0
  }
72
1.47k
  *location_information = memory_allocate_structure(
73
1.47k
         liblnk_location_information_t );
74
75
1.47k
  if( *location_information == NULL )
76
0
  {
77
0
    libcerror_error_set(
78
0
     error,
79
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
80
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
81
0
     "%s: unable to create location information.",
82
0
     function );
83
84
0
    goto on_error;
85
0
  }
86
1.47k
  if( memory_set(
87
1.47k
       *location_information,
88
1.47k
       0,
89
1.47k
       sizeof( liblnk_location_information_t ) ) == NULL )
90
0
  {
91
0
    libcerror_error_set(
92
0
     error,
93
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
94
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
95
0
     "%s: unable to clear location information.",
96
0
     function );
97
98
0
    goto on_error;
99
0
  }
100
1.47k
  return( 1 );
101
102
0
on_error:
103
0
  if( *location_information != NULL )
104
0
  {
105
0
    memory_free(
106
0
     *location_information );
107
108
0
    *location_information = NULL;
109
0
  }
110
0
  return( -1 );
111
1.47k
}
112
113
/* Frees location information
114
 * Returns 1 if successful or -1 on error
115
 */
116
int liblnk_location_information_free(
117
     liblnk_location_information_t **location_information,
118
     libcerror_error_t **error )
119
1.47k
{
120
1.47k
  static char *function = "liblnk_location_information_free";
121
122
1.47k
  if( location_information == NULL )
123
0
  {
124
0
    libcerror_error_set(
125
0
     error,
126
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
127
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
128
0
     "%s: invalid location information.",
129
0
     function );
130
131
0
    return( -1 );
132
0
  }
133
1.47k
  if( *location_information != NULL )
134
1.47k
  {
135
1.47k
    if( ( *location_information )->volume_label != NULL )
136
28
    {
137
28
      memory_free(
138
28
       ( *location_information )->volume_label );
139
28
    }
140
1.47k
    if( ( *location_information )->local_path != NULL )
141
87
    {
142
87
      memory_free(
143
87
       ( *location_information )->local_path );
144
87
    }
145
1.47k
    if( ( *location_information )->network_share_name != NULL )
146
32
    {
147
32
      memory_free(
148
32
       ( *location_information )->network_share_name );
149
32
    }
150
1.47k
    if( ( *location_information )->device_name != NULL )
151
37
    {
152
37
      memory_free(
153
37
       ( *location_information )->device_name );
154
37
    }
155
1.47k
    if( ( *location_information )->common_path != NULL )
156
175
    {
157
175
      memory_free(
158
175
       ( *location_information )->common_path );
159
175
    }
160
1.47k
    memory_free(
161
1.47k
     *location_information );
162
163
1.47k
    *location_information = NULL;
164
1.47k
  }
165
1.47k
  return( 1 );
166
1.47k
}
167
168
/* Reads a location information
169
 * Returns the number of bytes read if successful or -1 on error
170
 */
171
int liblnk_location_information_read_data(
172
     liblnk_location_information_t *location_information,
173
     liblnk_io_handle_t *io_handle,
174
     const uint8_t *data,
175
     size_t data_size,
176
     libcerror_error_t **error )
177
1.39k
{
178
1.39k
  const uint8_t *location_information_value_data = NULL;
179
1.39k
  const uint8_t *string_data                     = NULL;
180
1.39k
  const uint8_t *unicode_string_data             = NULL;
181
1.39k
  static char *function                          = "liblnk_location_information_read_data";
182
1.39k
  ssize_t read_count                             = 0;
183
1.39k
  uint32_t common_path_offset                    = 0;
184
1.39k
  uint32_t device_name_offset                    = 0;
185
1.39k
  uint32_t local_path_offset                     = 0;
186
1.39k
  uint32_t location_information_header_size      = 0;
187
1.39k
  uint32_t location_information_value_size       = 0;
188
1.39k
  uint32_t network_share_information_offset      = 0;
189
1.39k
  uint32_t network_share_name_offset             = 0;
190
1.39k
  uint32_t unicode_common_path_offset            = 0;
191
1.39k
  uint32_t unicode_device_name_offset            = 0;
192
1.39k
  uint32_t unicode_local_path_offset             = 0;
193
1.39k
  uint32_t unicode_network_share_name_offset     = 0;
194
1.39k
  uint32_t unicode_value_size                    = 0;
195
1.39k
  uint32_t unicode_volume_label_offset           = 0;
196
1.39k
  uint32_t value_size                            = 0;
197
1.39k
  uint32_t volume_information_offset             = 0;
198
1.39k
  uint32_t volume_label_data_size                = 0;
199
1.39k
  uint32_t volume_label_offset                   = 0;
200
201
#if defined( HAVE_DEBUG_OUTPUT )
202
  uint32_t value_32bit                           = 0;
203
#endif
204
205
1.39k
  if( location_information == NULL )
206
0
  {
207
0
    libcerror_error_set(
208
0
     error,
209
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
210
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
211
0
     "%s: invalid location information.",
212
0
     function );
213
214
0
    return( -1 );
215
0
  }
216
1.39k
  if( io_handle == NULL )
217
0
  {
218
0
    libcerror_error_set(
219
0
     error,
220
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
221
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
222
0
     "%s: invalid IO handle.",
223
0
     function );
224
225
0
    return( -1 );
226
0
  }
227
1.39k
  if( data == NULL )
228
0
  {
229
0
    libcerror_error_set(
230
0
     error,
231
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
232
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
233
0
     "%s: invalid data.",
234
0
     function );
235
236
0
    return( -1 );
237
0
  }
238
1.39k
  if( data_size < sizeof( lnk_location_information_t ) )
239
8
  {
240
8
    libcerror_error_set(
241
8
     error,
242
8
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
243
8
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
244
8
     "%s: invalid data size value too small.",
245
8
     function );
246
247
8
    return( -1 );
248
8
  }
249
1.38k
  if( data_size > (size_t) SSIZE_MAX )
250
0
  {
251
0
    libcerror_error_set(
252
0
     error,
253
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
254
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
255
0
     "%s: invalid data size value exceeds maximum.",
256
0
     function );
257
258
0
    return( -1 );
259
0
  }
260
#if defined( HAVE_DEBUG_OUTPUT )
261
  if( libcnotify_verbose != 0 )
262
  {
263
    libcnotify_printf(
264
     "%s: location information data:\n",
265
     function );
266
    libcnotify_print_data(
267
     data,
268
     data_size,
269
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
270
  }
271
#endif
272
1.38k
  byte_stream_copy_to_uint32_little_endian(
273
1.38k
   ( (lnk_location_information_t *) data )->header_size,
274
1.38k
   location_information_header_size );
275
276
1.38k
  if( location_information_header_size == 0 )
277
2
  {
278
2
    io_handle->flags |= LIBLNK_IO_HANDLE_FLAG_IS_CORRUPTED;
279
280
2
    return( read_count + 4 );
281
2
  }
282
1.38k
  byte_stream_copy_to_uint32_little_endian(
283
1.38k
   ( (lnk_location_information_t *) data )->location_flags,
284
1.38k
   location_information->flags );
285
286
1.38k
  byte_stream_copy_to_uint32_little_endian(
287
1.38k
   ( (lnk_location_information_t *) data )->volume_information_offset,
288
1.38k
   volume_information_offset );
289
290
1.38k
  byte_stream_copy_to_uint32_little_endian(
291
1.38k
   ( (lnk_location_information_t *) data )->local_path_offset,
292
1.38k
   local_path_offset );
293
294
1.38k
  byte_stream_copy_to_uint32_little_endian(
295
1.38k
   ( (lnk_location_information_t *) data )->network_share_information_offset,
296
1.38k
   network_share_information_offset );
297
298
1.38k
  byte_stream_copy_to_uint32_little_endian(
299
1.38k
   ( (lnk_location_information_t *) data )->common_path_offset,
300
1.38k
   common_path_offset );
301
302
#if defined( HAVE_DEBUG_OUTPUT )
303
  if( libcnotify_verbose != 0 )
304
  {
305
    libcnotify_printf(
306
     "%s: location information header size\t\t\t\t: %" PRIu32 "\n",
307
     function,
308
     location_information_header_size );
309
310
    libcnotify_printf(
311
     "%s: location information flags\t\t\t\t: 0x%08" PRIx32 "\n",
312
     function,
313
     location_information->flags );
314
315
    libcnotify_printf(
316
     "%s: location information volume information offset\t\t: 0x%08" PRIx32 "\n",
317
     function,
318
     volume_information_offset );
319
320
    libcnotify_printf(
321
     "%s: location information local path offset\t\t\t: 0x%08" PRIx32 "\n",
322
     function,
323
     local_path_offset );
324
325
    libcnotify_printf(
326
     "%s: location information network share information offset\t: 0x%08" PRIx32 "\n",
327
     function,
328
     network_share_information_offset );
329
330
    libcnotify_printf(
331
     "%s: location information common path offset\t\t\t: 0x%08" PRIx32 "\n",
332
     function,
333
     common_path_offset );
334
  }
335
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
336
337
1.38k
  if( ( location_information_header_size != 28 )
338
575
   && ( location_information_header_size != 32 )
339
354
   && ( location_information_header_size != 36 ) )
340
58
  {
341
58
    libcerror_error_set(
342
58
     error,
343
58
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
344
58
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
345
58
     "%s: unsupported location information header size: %" PRIu32 ".",
346
58
     function,
347
58
     location_information_header_size );
348
349
58
    goto on_error;
350
58
  }
351
1.32k
  if( location_information_header_size > 28 )
352
517
  {
353
517
    byte_stream_copy_to_uint32_little_endian(
354
517
     ( (lnk_location_information_t *) data )->unicode_local_path_offset,
355
517
     unicode_local_path_offset );
356
357
#if defined( HAVE_DEBUG_OUTPUT )
358
    if( libcnotify_verbose != 0 )
359
    {
360
      libcnotify_printf(
361
       "%s: location information unicode local path offset\t\t: %" PRIu32 "\n",
362
       function,
363
       unicode_local_path_offset );
364
    }
365
#endif
366
517
  }
367
1.32k
  if( location_information_header_size > 32 )
368
296
  {
369
296
    byte_stream_copy_to_uint32_little_endian(
370
296
     ( (lnk_location_information_t *) data )->unicode_common_path_offset,
371
296
     unicode_common_path_offset );
372
373
#if defined( HAVE_DEBUG_OUTPUT )
374
    if( libcnotify_verbose != 0 )
375
    {
376
      libcnotify_printf(
377
       "%s: location information unicode common path offset\t\t: %" PRIu32 "\n",
378
       function,
379
       unicode_common_path_offset );
380
    }
381
#endif
382
296
  }
383
#if defined( HAVE_DEBUG_OUTPUT )
384
  if( libcnotify_verbose != 0 )
385
  {
386
    libcnotify_printf(
387
     "\n" );
388
  }
389
#endif
390
  /* Volume information path
391
   */
392
1.32k
  if( ( ( location_information->flags & 0x00000001UL ) != 0 )
393
737
   && ( volume_information_offset > 0 ) )
394
405
  {
395
405
    if( volume_information_offset < location_information_header_size )
396
1
    {
397
1
      libcerror_error_set(
398
1
       error,
399
1
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
400
1
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
401
1
       "%s: volume information offset smaller than location information header size.",
402
1
       function );
403
404
1
      goto on_error;
405
1
    }
406
404
    volume_information_offset -= 4;
407
408
404
    if( data_size < 4 )
409
0
    {
410
0
      libcerror_error_set(
411
0
       error,
412
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
413
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
414
0
       "%s: location information size value out of bounds.",
415
0
       function );
416
417
0
      goto on_error;
418
0
    }
419
404
    if( volume_information_offset > ( data_size - 4 ) )
420
51
    {
421
51
      libcerror_error_set(
422
51
       error,
423
51
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
424
51
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
425
51
       "%s: volume information offset exceeds location information size.",
426
51
       function );
427
428
51
      goto on_error;
429
51
    }
430
353
    location_information_value_data = &( data[ volume_information_offset ] );
431
432
353
    byte_stream_copy_to_uint32_little_endian(
433
353
     ( (lnk_volume_information_t *) location_information_value_data )->size,
434
353
     location_information_value_size );
435
436
353
    if( location_information_value_size > ( data_size - volume_information_offset ) )
437
31
    {
438
31
      libcerror_error_set(
439
31
       error,
440
31
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
441
31
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
442
31
       "%s: volume information data size value out of bounds.",
443
31
       function );
444
445
31
      goto on_error;
446
31
    }
447
#if defined( HAVE_DEBUG_OUTPUT )
448
    if( libcnotify_verbose != 0 )
449
    {
450
      libcnotify_printf(
451
       "%s: volume information data:\n",
452
       function );
453
      libcnotify_print_data(
454
       location_information_value_data,
455
       location_information_value_size,
456
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
457
    }
458
#endif
459
322
    if( location_information_value_size < 16 )
460
23
    {
461
23
      libcerror_error_set(
462
23
       error,
463
23
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
464
23
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
465
23
       "%s: location information value size value out of bounds.",
466
23
       function );
467
468
23
      goto on_error;
469
23
    }
470
299
    byte_stream_copy_to_uint32_little_endian(
471
299
     ( (lnk_volume_information_t *) location_information_value_data )->drive_type,
472
299
     location_information->drive_type );
473
474
299
    byte_stream_copy_to_uint32_little_endian(
475
299
     ( (lnk_volume_information_t *) location_information_value_data )->drive_serial_number,
476
299
     location_information->drive_serial_number );
477
478
299
    byte_stream_copy_to_uint32_little_endian(
479
299
     ( (lnk_volume_information_t *) location_information_value_data )->volume_label_offset,
480
299
     volume_label_offset );
481
482
#if defined( HAVE_DEBUG_OUTPUT )
483
    if( libcnotify_verbose != 0 )
484
    {
485
      libcnotify_printf(
486
       "%s: volume information size\t\t\t\t\t: %" PRIu32 "\n",
487
       function,
488
       location_information_value_size );
489
490
      libcnotify_printf(
491
       "%s: volume information drive type\t\t\t\t: 0x%08" PRIx32 " (%s)\n",
492
       function,
493
       location_information->drive_type,
494
       liblnk_debug_print_drive_type(
495
        location_information->drive_type ) );
496
497
      libcnotify_printf(
498
       "%s: volume information drive serial number\t\t\t: 0x%08" PRIx32 "\n",
499
       function,
500
       location_information->drive_serial_number );
501
502
      libcnotify_printf(
503
       "%s: volume information volume label offset\t\t\t: %" PRIu32 "\n",
504
       function,
505
       volume_label_offset );
506
    }
507
#endif
508
299
    if( volume_label_offset > 16 )
509
245
    {
510
245
      if( location_information_value_size < 20 )
511
34
      {
512
34
        libcerror_error_set(
513
34
         error,
514
34
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
515
34
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
516
34
         "%s: location information value size value out of bounds.",
517
34
         function );
518
519
34
        goto on_error;
520
34
      }
521
211
      byte_stream_copy_to_uint32_little_endian(
522
211
       ( (lnk_volume_information_t *) location_information_value_data )->unicode_volume_label_offset,
523
211
       unicode_volume_label_offset );
524
525
#if defined( HAVE_DEBUG_OUTPUT )
526
      if( libcnotify_verbose != 0 )
527
      {
528
        libcnotify_printf(
529
         "%s: unicode volume information volume label offset\t\t: %" PRIu32 "\n",
530
         function,
531
         unicode_volume_label_offset );
532
      }
533
#endif
534
211
    }
535
265
    if( volume_label_offset > 0 )
536
256
    {
537
256
      if( volume_label_offset > location_information_value_size )
538
71
      {
539
71
        libcerror_error_set(
540
71
         error,
541
71
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
542
71
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
543
71
         "%s: volume label offset exceeds volume information data.",
544
71
         function );
545
546
71
        goto on_error;
547
71
      }
548
185
      volume_label_data_size = location_information_value_size - volume_label_offset;
549
550
185
      string_data = &( location_information_value_data[ volume_label_offset ] );
551
552
185
      for( value_size = 0;
553
2.06k
           value_size < volume_label_data_size;
554
1.88k
           value_size++ )
555
1.99k
      {
556
1.99k
        if( string_data[ value_size ] == 0 )
557
109
        {
558
109
          value_size++;
559
109
          break;
560
109
        }
561
1.99k
      }
562
#if defined( HAVE_DEBUG_OUTPUT )
563
      if( libcnotify_verbose != 0 )
564
      {
565
        libcnotify_printf(
566
         "%s: volume information volume label size\t\t\t: %" PRIu32 "\n",
567
         function,
568
         value_size );
569
570
        libcnotify_printf(
571
         "%s: volume information volume label data:\n",
572
         function );
573
        libcnotify_print_data(
574
         string_data,
575
         value_size,
576
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
577
      }
578
#endif
579
185
    }
580
194
    if( unicode_volume_label_offset > 0 )
581
131
    {
582
131
      if( unicode_volume_label_offset > location_information_value_size )
583
76
      {
584
76
        libcerror_error_set(
585
76
         error,
586
76
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
587
76
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
588
76
         "%s: unicode volume label offset exceeds volume information data.",
589
76
         function );
590
591
76
        goto on_error;
592
76
      }
593
55
      volume_label_data_size = location_information_value_size - unicode_volume_label_offset;
594
595
55
      unicode_string_data = &( location_information_value_data[ unicode_volume_label_offset ] );
596
597
55
      for( unicode_value_size = 0;
598
2.02k
           ( unicode_value_size + 1 ) < volume_label_data_size;
599
1.97k
           unicode_value_size += 2 )
600
2.01k
      {
601
2.01k
        if( ( unicode_string_data[ unicode_value_size ] == 0 )
602
551
         && ( unicode_string_data[ unicode_value_size + 1 ] == 0 ) )
603
39
        {
604
39
          unicode_value_size += 2;
605
39
          break;
606
39
        }
607
2.01k
      }
608
#if defined( HAVE_DEBUG_OUTPUT )
609
      if( libcnotify_verbose != 0 )
610
      {
611
        libcnotify_printf(
612
         "%s: unicode volume information volume label size\t\t: %" PRIu32 "\n",
613
         function,
614
         unicode_value_size );
615
616
        libcnotify_printf(
617
         "%s: unicode volume information volume label data:\n",
618
         function );
619
        libcnotify_print_data(
620
         unicode_string_data,
621
         unicode_value_size,
622
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
623
      }
624
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
625
626
55
      location_information->volume_label = (uint8_t *) memory_allocate(
627
55
                                                        sizeof( uint8_t ) * unicode_value_size );
628
629
55
      if( location_information->volume_label == NULL )
630
0
      {
631
0
        libcerror_error_set(
632
0
         error,
633
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
634
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
635
0
         "%s: unable to create volume label.",
636
0
         function );
637
638
0
        goto on_error;
639
0
      }
640
55
      if( memory_copy(
641
55
           location_information->volume_label,
642
55
           unicode_string_data,
643
55
           unicode_value_size ) == NULL )
644
0
      {
645
0
        libcerror_error_set(
646
0
         error,
647
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
648
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
649
0
         "%s: unable to copy volume label.",
650
0
         function );
651
652
0
        goto on_error;
653
0
      }
654
55
      location_information->volume_label_size = unicode_value_size;
655
55
      location_information->string_flags     |= LIBLNK_LOCATION_INFORMATION_STRING_FLAG_VOLUME_LABEL_IS_UNICODE;
656
55
    }
657
63
    else if( volume_label_offset > 0 )
658
54
    {
659
54
      location_information->volume_label = (uint8_t *) memory_allocate(
660
54
                                                        sizeof( uint8_t ) * value_size );
661
662
54
      if( location_information->volume_label == NULL )
663
0
      {
664
0
        libcerror_error_set(
665
0
         error,
666
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
667
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
668
0
         "%s: unable to create volume label.",
669
0
         function );
670
671
0
        goto on_error;
672
0
      }
673
54
      if( memory_copy(
674
54
           location_information->volume_label,
675
54
           string_data,
676
54
           value_size ) == NULL )
677
0
      {
678
0
        libcerror_error_set(
679
0
         error,
680
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
681
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
682
0
         "%s: unable to copy volume label.",
683
0
         function );
684
685
0
        goto on_error;
686
0
      }
687
54
      location_information->volume_label_size = value_size;
688
54
    }
689
#if defined( HAVE_DEBUG_OUTPUT )
690
    if( libcnotify_verbose != 0 )
691
    {
692
      if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_VOLUME_LABEL_IS_UNICODE ) != 0 )
693
      {
694
        if( liblnk_debug_print_utf16_string_value(
695
             function,
696
             "volume information volume label\t\t\t\t",
697
             location_information->volume_label,
698
             location_information->volume_label_size,
699
             LIBUNA_ENDIAN_LITTLE,
700
             error ) != 1 )
701
        {
702
          libcerror_error_set(
703
           error,
704
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
705
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
706
           "%s: unable to print UTF-16 string value.",
707
           function );
708
709
          goto on_error;
710
        }
711
      }
712
      else
713
      {
714
        if( liblnk_debug_print_string_value(
715
             function,
716
             "volume information volume label\t\t\t\t",
717
             location_information->volume_label,
718
             location_information->volume_label_size,
719
             io_handle->ascii_codepage,
720
             error ) != 1 )
721
        {
722
          libcerror_error_set(
723
           error,
724
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
725
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
726
           "%s: unable to print string value.",
727
           function );
728
729
          goto on_error;
730
        }
731
      }
732
    }
733
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
734
194
  }
735
  /* Local path
736
   */
737
1.03k
  if( ( location_information->flags & 0x00000001UL ) != 0 )
738
450
  {
739
450
    if( local_path_offset > 0 )
740
359
    {
741
359
      if( local_path_offset < location_information_header_size )
742
4
      {
743
4
        libcerror_error_set(
744
4
         error,
745
4
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
746
4
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
747
4
         "%s: local path information offset smaller than location information header size",
748
4
         function );
749
750
4
        goto on_error;
751
4
      }
752
355
      local_path_offset -= 4;
753
754
355
      if( local_path_offset > data_size )
755
92
      {
756
92
        libcerror_error_set(
757
92
         error,
758
92
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
759
92
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
760
92
         "%s: local path offset exceeds location information data.",
761
92
         function );
762
763
92
        goto on_error;
764
92
      }
765
263
      string_data = &( data[ local_path_offset ] );
766
767
263
      for( value_size = 0;
768
3.57k
           value_size < ( data_size - local_path_offset );
769
3.31k
           value_size++ )
770
3.47k
      {
771
3.47k
        if( string_data[ value_size ] == 0 )
772
164
        {
773
164
          value_size++;
774
164
          break;
775
164
        }
776
3.47k
      }
777
#if defined( HAVE_DEBUG_OUTPUT )
778
      if( libcnotify_verbose != 0 )
779
      {
780
        libcnotify_printf(
781
         "%s: local path data size\t\t\t\t\t: %" PRIu32 "\n",
782
         function,
783
         value_size );
784
785
        libcnotify_printf(
786
         "%s: local path data:\n",
787
         function );
788
        libcnotify_print_data(
789
         string_data,
790
         value_size,
791
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
792
      }
793
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
794
263
    }
795
354
    if( unicode_local_path_offset > 0 )
796
172
    {
797
172
      if( unicode_local_path_offset < location_information_header_size )
798
3
      {
799
3
        libcerror_error_set(
800
3
         error,
801
3
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
802
3
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
803
3
         "%s: unicode local path information offset smaller than location information header size",
804
3
         function );
805
806
3
        goto on_error;
807
3
      }
808
169
      unicode_local_path_offset -= 4;
809
810
169
      if( unicode_local_path_offset > data_size )
811
50
      {
812
50
        libcerror_error_set(
813
50
         error,
814
50
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
815
50
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
816
50
         "%s: unicode local path offset exceeds location information data.",
817
50
         function );
818
819
50
        goto on_error;
820
50
      }
821
119
      unicode_string_data = &( data[ unicode_local_path_offset ] );
822
823
119
      for( unicode_value_size = 0;
824
4.91k
           ( unicode_value_size + 1 ) < ( data_size - unicode_local_path_offset );
825
4.79k
           unicode_value_size += 2 )
826
4.85k
      {
827
4.85k
        if( ( unicode_string_data[ unicode_value_size ] == 0 )
828
548
         && ( unicode_string_data[ unicode_value_size + 1 ] == 0 ) )
829
64
        {
830
64
          unicode_value_size += 2;
831
64
          break;
832
64
        }
833
4.85k
      }
834
#if defined( HAVE_DEBUG_OUTPUT )
835
      if( libcnotify_verbose != 0 )
836
      {
837
        libcnotify_printf(
838
         "%s: unicode local path data size\t\t\t\t: %" PRIu32 "\n",
839
         function,
840
         value_size );
841
842
        libcnotify_printf(
843
         "%s: unicode local path data:\n",
844
         function );
845
        libcnotify_print_data(
846
         unicode_string_data,
847
         unicode_value_size,
848
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
849
      }
850
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
851
852
119
      location_information->local_path = (uint8_t *) memory_allocate(
853
119
                                                      sizeof( uint8_t ) * unicode_value_size );
854
855
119
      if( location_information->local_path == NULL )
856
0
      {
857
0
        libcerror_error_set(
858
0
         error,
859
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
860
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
861
0
         "%s: unable to create local path.",
862
0
         function );
863
864
0
        goto on_error;
865
0
      }
866
119
      if( memory_copy(
867
119
           location_information->local_path,
868
119
           unicode_string_data,
869
119
           unicode_value_size ) == NULL )
870
0
      {
871
0
        libcerror_error_set(
872
0
         error,
873
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
874
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
875
0
         "%s: unable to copy local path.",
876
0
         function );
877
878
0
        goto on_error;
879
0
      }
880
119
      location_information->local_path_size = unicode_value_size;
881
119
      location_information->string_flags   |= LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE;
882
119
    }
883
182
    else if( local_path_offset > 0 )
884
132
    {
885
132
      location_information->local_path = (uint8_t *) memory_allocate(
886
132
                                                      sizeof( uint8_t ) * value_size );
887
888
132
      if( location_information->local_path == NULL )
889
0
      {
890
0
        libcerror_error_set(
891
0
         error,
892
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
893
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
894
0
         "%s: unable to create local path.",
895
0
         function );
896
897
0
        goto on_error;
898
0
      }
899
132
      if( memory_copy(
900
132
           location_information->local_path,
901
132
           string_data,
902
132
           value_size ) == NULL )
903
0
      {
904
0
        libcerror_error_set(
905
0
         error,
906
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
907
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
908
0
         "%s: unable to copy local path.",
909
0
         function );
910
911
0
        goto on_error;
912
0
      }
913
132
      location_information->local_path_size = value_size;
914
132
    }
915
#if defined( HAVE_DEBUG_OUTPUT )
916
    if( libcnotify_verbose != 0 )
917
    {
918
      if( ( local_path_offset > 0 )
919
       || ( unicode_local_path_offset > 0 ) )
920
      {
921
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE ) != 0 )
922
        {
923
          if( liblnk_debug_print_utf16_string_value(
924
               function,
925
               "local path\t\t\t\t\t\t",
926
               location_information->local_path,
927
               location_information->local_path_size,
928
               LIBUNA_ENDIAN_LITTLE,
929
               error ) != 1 )
930
          {
931
            libcerror_error_set(
932
             error,
933
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
934
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
935
             "%s: unable to print UTF-16 string value.",
936
             function );
937
938
            goto on_error;
939
          }
940
        }
941
        else
942
        {
943
          if( liblnk_debug_print_string_value(
944
               function,
945
               "local path\t\t\t\t\t\t",
946
               location_information->local_path,
947
               location_information->local_path_size,
948
               io_handle->ascii_codepage,
949
               error ) != 1 )
950
          {
951
            libcerror_error_set(
952
             error,
953
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
954
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
955
             "%s: unable to print string value.",
956
             function );
957
958
            goto on_error;
959
          }
960
        }
961
      }
962
    }
963
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
964
354
  }
965
  /* Network share information
966
   */
967
887
  if( ( ( location_information->flags & 0x00000002UL ) != 0 )
968
627
   && ( network_share_information_offset > 0 ) )
969
589
  {
970
589
    if( network_share_information_offset < location_information_header_size )
971
2
    {
972
2
      libcerror_error_set(
973
2
       error,
974
2
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
975
2
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
976
2
       "%s: network share information offset smaller than location information header size.",
977
2
       function );
978
979
2
      goto on_error;
980
2
    }
981
587
    network_share_information_offset -= 4;
982
983
587
    if( data_size < 4 )
984
0
    {
985
0
      libcerror_error_set(
986
0
       error,
987
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
988
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
989
0
       "%s: location information size value out of bounds.",
990
0
       function );
991
992
0
      goto on_error;
993
0
    }
994
587
    if( network_share_information_offset > ( data_size - 4 ) )
995
90
    {
996
90
      libcerror_error_set(
997
90
       error,
998
90
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
999
90
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1000
90
       "%s: network share information offset exceeds location information size.",
1001
90
       function );
1002
1003
90
      goto on_error;
1004
90
    }
1005
497
    location_information_value_data = &( data[ network_share_information_offset ] );
1006
1007
497
    byte_stream_copy_to_uint32_little_endian(
1008
497
     ( (lnk_network_share_information_t *) location_information_value_data )->size,
1009
497
     location_information_value_size );
1010
1011
497
    if( location_information_value_size > ( data_size - network_share_information_offset ) )
1012
41
    {
1013
41
      libcerror_error_set(
1014
41
       error,
1015
41
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1016
41
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1017
41
       "%s: network share information data size value out of bounds.",
1018
41
       function );
1019
1020
41
      goto on_error;
1021
41
    }
1022
#if defined( HAVE_DEBUG_OUTPUT )
1023
    if( libcnotify_verbose != 0 )
1024
    {
1025
      libcnotify_printf(
1026
       "%s: network share information data:\n",
1027
       function );
1028
      libcnotify_print_data(
1029
       location_information_value_data,
1030
       location_information_value_size,
1031
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1032
    }
1033
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1034
1035
456
    if( location_information_value_size < 20 )
1036
31
    {
1037
31
      libcerror_error_set(
1038
31
       error,
1039
31
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1040
31
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1041
31
       "%s: location information value size value out of bounds.",
1042
31
       function );
1043
1044
31
      goto on_error;
1045
31
    }
1046
425
    byte_stream_copy_to_uint32_little_endian(
1047
425
     ( (lnk_network_share_information_t *) location_information_value_data )->network_share_name_offset,
1048
425
     network_share_name_offset );
1049
1050
425
    byte_stream_copy_to_uint32_little_endian(
1051
425
     ( (lnk_network_share_information_t *) location_information_value_data )->device_name_offset,
1052
425
     device_name_offset );
1053
1054
425
    byte_stream_copy_to_uint32_little_endian(
1055
425
     ( (lnk_network_share_information_t *) location_information_value_data )->network_provider_type,
1056
425
     location_information->network_provider_type );
1057
1058
#if defined( HAVE_DEBUG_OUTPUT )
1059
    if( libcnotify_verbose != 0 )
1060
    {
1061
      libcnotify_printf(
1062
       "%s: network share information size\t\t\t\t: %" PRIu32 "\n",
1063
       function,
1064
       location_information_value_size );
1065
1066
      byte_stream_copy_to_uint32_little_endian(
1067
       ( (lnk_network_share_information_t *) location_information_value_data )->network_share_type,
1068
       value_32bit );
1069
      libcnotify_printf(
1070
       "%s: network share information network share type\t\t: 0x%08" PRIx32 "\n",
1071
       function,
1072
       value_32bit );
1073
1074
      libcnotify_printf(
1075
       "%s: network share information network share name offset\t: %" PRIu32 "\n",
1076
       function,
1077
       network_share_name_offset );
1078
1079
      libcnotify_printf(
1080
       "%s: network share information device name offset\t\t: %" PRIu32 "\n",
1081
       function,
1082
       device_name_offset );
1083
1084
      libcnotify_printf(
1085
       "%s: network share information network provider type\t\t: 0x%08" PRIx32 " (%s)\n",
1086
       function,
1087
       location_information->network_provider_type,
1088
       liblnk_debug_print_network_provider_type(
1089
        location_information->network_provider_type ) );
1090
    }
1091
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1092
1093
425
    if( network_share_name_offset > 20 )
1094
325
    {
1095
325
      if( location_information_value_size < 28 )
1096
33
      {
1097
33
        libcerror_error_set(
1098
33
         error,
1099
33
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1100
33
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1101
33
         "%s: location information value size value out of bounds.",
1102
33
         function );
1103
1104
33
        goto on_error;
1105
33
      }
1106
292
      byte_stream_copy_to_uint32_little_endian(
1107
292
       ( (lnk_network_share_information_t *) location_information_value_data )->unicode_network_share_name_offset,
1108
292
       unicode_network_share_name_offset );
1109
1110
292
      byte_stream_copy_to_uint32_little_endian(
1111
292
       ( (lnk_network_share_information_t *) location_information_value_data )->unicode_device_name_offset,
1112
292
       unicode_device_name_offset );
1113
1114
#if defined( HAVE_DEBUG_OUTPUT )
1115
      if( libcnotify_verbose != 0 )
1116
      {
1117
        libcnotify_printf(
1118
         "%s: network share information unicode network share name offset\t: %" PRIu32 "\n",
1119
         function,
1120
         unicode_network_share_name_offset );
1121
1122
        libcnotify_printf(
1123
         "%s: network share information unicode device name offset\t: %" PRIu32 "\n",
1124
         function,
1125
         unicode_device_name_offset );
1126
      }
1127
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1128
292
    }
1129
392
    if( network_share_name_offset > 0 )
1130
351
    {
1131
351
      if( network_share_name_offset > location_information_value_size )
1132
74
      {
1133
74
        libcerror_error_set(
1134
74
         error,
1135
74
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1136
74
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1137
74
         "%s: network share name offset exceeds network share information data.",
1138
74
         function );
1139
1140
74
        goto on_error;
1141
74
      }
1142
277
      string_data = &( location_information_value_data[ network_share_name_offset ] );
1143
1144
277
      for( value_size = 0;
1145
1.75k
           value_size < ( location_information_value_size - network_share_name_offset );
1146
1.47k
           value_size++ )
1147
1.65k
      {
1148
1.65k
        if( string_data[ value_size ] == 0 )
1149
182
        {
1150
182
          value_size++;
1151
182
          break;
1152
182
        }
1153
1.65k
      }
1154
#if defined( HAVE_DEBUG_OUTPUT )
1155
      if( libcnotify_verbose != 0 )
1156
      {
1157
        libcnotify_printf(
1158
         "%s: network share information network share name size\t: %" PRIu32 "\n",
1159
         function,
1160
         value_size );
1161
1162
        libcnotify_printf(
1163
         "%s: network share information network share name data:\n",
1164
         function );
1165
        libcnotify_print_data(
1166
         string_data,
1167
         value_size,
1168
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1169
      }
1170
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1171
277
    }
1172
318
    if( unicode_network_share_name_offset > 0 )
1173
173
    {
1174
173
      if( unicode_network_share_name_offset > location_information_value_size )
1175
65
      {
1176
65
        libcerror_error_set(
1177
65
         error,
1178
65
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1179
65
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1180
65
         "%s: unicode network share name offset exceeds volume information data.",
1181
65
         function );
1182
1183
65
        goto on_error;
1184
65
      }
1185
108
      unicode_string_data = &( location_information_value_data[ unicode_network_share_name_offset ] );
1186
1187
108
      for( unicode_value_size = 0;
1188
2.52k
           ( unicode_value_size + 1 ) < ( location_information_value_size - unicode_network_share_name_offset );
1189
2.41k
           unicode_value_size += 2 )
1190
2.49k
      {
1191
2.49k
        if( ( unicode_string_data[ unicode_value_size ] == 0 )
1192
820
         && ( unicode_string_data[ unicode_value_size + 1 ] == 0 ) )
1193
78
        {
1194
78
          unicode_value_size += 2;
1195
78
          break;
1196
78
        }
1197
2.49k
      }
1198
#if defined( HAVE_DEBUG_OUTPUT )
1199
      if( libcnotify_verbose != 0 )
1200
      {
1201
        libcnotify_printf(
1202
         "%s: unicode volume information network share name size\t\t: %" PRIu32 "\n",
1203
         function,
1204
         unicode_value_size );
1205
1206
        libcnotify_printf(
1207
         "%s: unicode volume information network share name data:\n",
1208
         function );
1209
        libcnotify_print_data(
1210
         unicode_string_data,
1211
         unicode_value_size,
1212
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1213
      }
1214
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1215
1216
108
      location_information->network_share_name = (uint8_t *) memory_allocate(
1217
108
                                                              sizeof( uint8_t ) * unicode_value_size );
1218
1219
108
      if( location_information->network_share_name == NULL )
1220
0
      {
1221
0
        libcerror_error_set(
1222
0
         error,
1223
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1224
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1225
0
         "%s: unable to create network share name.",
1226
0
         function );
1227
1228
0
        goto on_error;
1229
0
      }
1230
108
      if( memory_copy(
1231
108
           location_information->network_share_name,
1232
108
           unicode_string_data,
1233
108
           unicode_value_size ) == NULL )
1234
0
      {
1235
0
        libcerror_error_set(
1236
0
         error,
1237
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1238
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1239
0
         "%s: unable to copy network share name.",
1240
0
         function );
1241
1242
0
        goto on_error;
1243
0
      }
1244
108
      location_information->network_share_name_size = unicode_value_size;
1245
108
      location_information->string_flags           |= LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE;
1246
108
    }
1247
145
    else if( network_share_name_offset > 0 )
1248
104
    {
1249
104
      location_information->network_share_name = (uint8_t *) memory_allocate(
1250
104
                    sizeof( uint8_t ) * value_size );
1251
1252
104
      if( location_information->network_share_name == NULL )
1253
0
      {
1254
0
        libcerror_error_set(
1255
0
         error,
1256
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1257
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1258
0
         "%s: unable to create network share name.",
1259
0
         function );
1260
1261
0
        goto on_error;
1262
0
      }
1263
104
      if( memory_copy(
1264
104
           location_information->network_share_name,
1265
104
           string_data,
1266
104
           value_size ) == NULL )
1267
0
      {
1268
0
        libcerror_error_set(
1269
0
         error,
1270
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1271
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1272
0
         "%s: unable to copy network share name.",
1273
0
         function );
1274
1275
0
        goto on_error;
1276
0
      }
1277
104
      location_information->network_share_name_size = value_size;
1278
104
    }
1279
#if defined( HAVE_DEBUG_OUTPUT )
1280
    if( libcnotify_verbose != 0 )
1281
    {
1282
      if( location_information->network_share_name != NULL )
1283
      {
1284
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE ) != 0 )
1285
        {
1286
          if( liblnk_debug_print_utf16_string_value(
1287
               function,
1288
               "volume information network share name\t\t\t",
1289
               location_information->network_share_name,
1290
               location_information->network_share_name_size,
1291
               LIBUNA_ENDIAN_LITTLE,
1292
               error ) != 1 )
1293
          {
1294
            libcerror_error_set(
1295
             error,
1296
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1297
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1298
             "%s: unable to print UTF-16 string value.",
1299
             function );
1300
1301
            goto on_error;
1302
          }
1303
        }
1304
        else
1305
        {
1306
          if( liblnk_debug_print_string_value(
1307
               function,
1308
               "volume information network share name\t\t\t",
1309
               location_information->network_share_name,
1310
               location_information->network_share_name_size,
1311
               io_handle->ascii_codepage,
1312
               error ) != 1 )
1313
          {
1314
            libcerror_error_set(
1315
             error,
1316
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1317
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1318
             "%s: unable to print string value.",
1319
             function );
1320
1321
            goto on_error;
1322
          }
1323
        }
1324
      }
1325
    }
1326
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1327
1328
253
    if( device_name_offset > 0 )
1329
223
    {
1330
223
      if( device_name_offset > location_information_value_size )
1331
77
      {
1332
77
        libcerror_error_set(
1333
77
         error,
1334
77
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1335
77
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1336
77
         "%s: device name offset exceeds network share information data.",
1337
77
         function );
1338
1339
77
        goto on_error;
1340
77
      }
1341
146
      string_data = &( location_information_value_data[ device_name_offset ] );
1342
1343
146
      for( value_size = 0;
1344
1.70k
           value_size < ( location_information_value_size - device_name_offset );
1345
1.55k
           value_size++ )
1346
1.66k
      {
1347
1.66k
        if( string_data[ value_size ] == 0 )
1348
104
        {
1349
104
          value_size++;
1350
104
          break;
1351
104
        }
1352
1.66k
      }
1353
#if defined( HAVE_DEBUG_OUTPUT )
1354
      if( libcnotify_verbose != 0 )
1355
      {
1356
        libcnotify_printf(
1357
         "%s: network share information device name size\t\t: %" PRIu32 "\n",
1358
         function,
1359
         value_size );
1360
1361
        libcnotify_printf(
1362
         "%s: network share information device name data:\n",
1363
         function );
1364
        libcnotify_print_data(
1365
         string_data,
1366
         value_size,
1367
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1368
      }
1369
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1370
146
    }
1371
176
    if( unicode_device_name_offset > 0 )
1372
134
    {
1373
134
      if( unicode_device_name_offset > location_information_value_size )
1374
77
      {
1375
77
        libcerror_error_set(
1376
77
         error,
1377
77
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1378
77
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1379
77
         "%s: unicode device name offset exceeds volume information data.",
1380
77
         function );
1381
1382
77
        goto on_error;
1383
77
      }
1384
57
      unicode_string_data = &( location_information_value_data[ unicode_device_name_offset ] );
1385
1386
57
      for( unicode_value_size = 0;
1387
686
           ( unicode_value_size + 1 ) < ( location_information_value_size - unicode_device_name_offset );
1388
629
           unicode_value_size += 2 )
1389
669
      {
1390
669
        if( ( unicode_string_data[ unicode_value_size ] == 0 )
1391
293
         && ( unicode_string_data[ unicode_value_size + 1 ] == 0 ) )
1392
40
        {
1393
40
          unicode_value_size += 2;
1394
40
          break;
1395
40
        }
1396
669
      }
1397
#if defined( HAVE_DEBUG_OUTPUT )
1398
      if( libcnotify_verbose != 0 )
1399
      {
1400
        libcnotify_printf(
1401
         "%s: unicode volume information device name size\t\t: %" PRIu32 "\n",
1402
         function,
1403
         unicode_value_size );
1404
1405
        libcnotify_printf(
1406
         "%s: unicode volume information device name data:\n",
1407
         function );
1408
        libcnotify_print_data(
1409
         unicode_string_data,
1410
         unicode_value_size,
1411
         LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1412
      }
1413
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1414
1415
57
      location_information->device_name = (uint8_t *) memory_allocate(
1416
57
                                                       sizeof( uint8_t ) * unicode_value_size );
1417
1418
57
      if( location_information->device_name == NULL )
1419
0
      {
1420
0
        libcerror_error_set(
1421
0
         error,
1422
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1423
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1424
0
         "%s: unable to create device name.",
1425
0
         function );
1426
1427
0
        goto on_error;
1428
0
      }
1429
57
      if( memory_copy(
1430
57
           location_information->device_name,
1431
57
           unicode_string_data,
1432
57
           unicode_value_size ) == NULL )
1433
0
      {
1434
0
        libcerror_error_set(
1435
0
         error,
1436
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1437
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1438
0
         "%s: unable to copy device name.",
1439
0
         function );
1440
1441
0
        goto on_error;
1442
0
      }
1443
57
      location_information->device_name_size = unicode_value_size;
1444
57
      location_information->string_flags    |= LIBLNK_LOCATION_INFORMATION_STRING_FLAG_DEVICE_NAME_IS_UNICODE;
1445
57
    }
1446
42
    else if( device_name_offset > 0 )
1447
38
    {
1448
38
      location_information->device_name = (uint8_t *) memory_allocate(
1449
38
                                                       sizeof( uint8_t ) * value_size );
1450
1451
38
      if( location_information->device_name == NULL )
1452
0
      {
1453
0
        libcerror_error_set(
1454
0
         error,
1455
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1456
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1457
0
         "%s: unable to create device name.",
1458
0
         function );
1459
1460
0
        goto on_error;
1461
0
      }
1462
38
      if( memory_copy(
1463
38
           location_information->device_name,
1464
38
           string_data,
1465
38
           value_size ) == NULL )
1466
0
      {
1467
0
        libcerror_error_set(
1468
0
         error,
1469
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1470
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1471
0
         "%s: unable to copy device name.",
1472
0
         function );
1473
1474
0
        goto on_error;
1475
0
      }
1476
38
      location_information->device_name_size = value_size;
1477
38
    }
1478
#if defined( HAVE_DEBUG_OUTPUT )
1479
    if( libcnotify_verbose != 0 )
1480
    {
1481
      if( location_information->device_name != NULL )
1482
      {
1483
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_DEVICE_NAME_IS_UNICODE ) != 0 )
1484
        {
1485
          if( liblnk_debug_print_utf16_string_value(
1486
               function,
1487
               "volume information device name\t\t\t",
1488
               location_information->device_name,
1489
               location_information->device_name_size,
1490
               LIBUNA_ENDIAN_LITTLE,
1491
               error ) != 1 )
1492
          {
1493
            libcerror_error_set(
1494
             error,
1495
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1496
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1497
             "%s: unable to print UTF-16 string value.",
1498
             function );
1499
1500
            goto on_error;
1501
          }
1502
        }
1503
        else
1504
        {
1505
          if( liblnk_debug_print_string_value(
1506
               function,
1507
               "volume information device name\t\t\t",
1508
               location_information->device_name,
1509
               location_information->device_name_size,
1510
               io_handle->ascii_codepage,
1511
               error ) != 1 )
1512
          {
1513
            libcerror_error_set(
1514
             error,
1515
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
1516
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1517
             "%s: unable to print string value.",
1518
             function );
1519
1520
            goto on_error;
1521
          }
1522
        }
1523
      }
1524
    }
1525
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1526
176
  }
1527
  /* Common path
1528
   */
1529
397
  if( common_path_offset > 0 )
1530
286
  {
1531
286
    if( common_path_offset < location_information_header_size )
1532
2
    {
1533
2
      libcerror_error_set(
1534
2
       error,
1535
2
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1536
2
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1537
2
       "%s: common path offset smaller than location information header size.",
1538
2
       function );
1539
1540
2
      goto on_error;
1541
2
    }
1542
284
    common_path_offset -= 4;
1543
1544
284
    if( common_path_offset > data_size )
1545
138
    {
1546
138
      libcerror_error_set(
1547
138
       error,
1548
138
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1549
138
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1550
138
       "%s: common path offset exceeds location information data.",
1551
138
       function );
1552
1553
138
      goto on_error;
1554
138
    }
1555
146
    string_data = &( data[ common_path_offset ] );
1556
1557
146
    for( value_size = 0;
1558
2.46k
         value_size < ( data_size - common_path_offset );
1559
2.31k
         value_size++ )
1560
2.42k
    {
1561
2.42k
      if( string_data[ value_size ] == 0 )
1562
107
      {
1563
107
        value_size++;
1564
107
        break;
1565
107
      }
1566
2.42k
    }
1567
#if defined( HAVE_DEBUG_OUTPUT )
1568
    if( libcnotify_verbose != 0 )
1569
    {
1570
      libcnotify_printf(
1571
       "%s: common path data size\t\t\t\t\t: %" PRIu32 "\n",
1572
       function,
1573
       value_size );
1574
1575
      libcnotify_printf(
1576
       "%s: common path data:\n",
1577
       function );
1578
      libcnotify_print_data(
1579
       string_data,
1580
       value_size,
1581
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1582
    }
1583
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1584
146
  }
1585
257
  if( unicode_common_path_offset > 0 )
1586
159
  {
1587
159
    if( unicode_common_path_offset < location_information_header_size )
1588
1
    {
1589
1
      libcerror_error_set(
1590
1
       error,
1591
1
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1592
1
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1593
1
       "%s: unicode common path information offset smaller than location information header size",
1594
1
       function );
1595
1596
1
      goto on_error;
1597
1
    }
1598
158
    unicode_common_path_offset -= 4;
1599
1600
158
    if( unicode_common_path_offset > data_size )
1601
68
    {
1602
68
      libcerror_error_set(
1603
68
       error,
1604
68
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1605
68
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1606
68
       "%s: unicode common path offset exceeds location information data.",
1607
68
       function );
1608
1609
68
      goto on_error;
1610
68
    }
1611
90
    unicode_string_data = &( data[ unicode_common_path_offset ] );
1612
1613
90
    for( unicode_value_size = 0;
1614
2.55k
         ( unicode_value_size + 1 ) < ( data_size - unicode_common_path_offset );
1615
2.46k
         unicode_value_size += 2 )
1616
2.51k
    {
1617
2.51k
      if( ( unicode_string_data[ unicode_value_size ] == 0 )
1618
618
       && ( unicode_string_data[ unicode_value_size + 1 ] == 0 ) )
1619
51
      {
1620
51
        unicode_value_size += 2;
1621
51
        break;
1622
51
      }
1623
2.51k
    }
1624
#if defined( HAVE_DEBUG_OUTPUT )
1625
    if( libcnotify_verbose != 0 )
1626
    {
1627
      libcnotify_printf(
1628
       "%s: unicode common path data size\t\t\t\t: %" PRIu32 "\n",
1629
       function,
1630
       value_size );
1631
1632
      libcnotify_printf(
1633
       "%s: unicode common path data:\n",
1634
       function );
1635
      libcnotify_print_data(
1636
       unicode_string_data,
1637
       unicode_value_size,
1638
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1639
    }
1640
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1641
1642
90
    location_information->common_path = (uint8_t *) memory_allocate(
1643
90
                                                     sizeof( uint8_t ) * unicode_value_size );
1644
1645
90
    if( location_information->common_path == NULL )
1646
0
    {
1647
0
      libcerror_error_set(
1648
0
       error,
1649
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1650
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1651
0
       "%s: unable to create common path.",
1652
0
       function );
1653
1654
0
      goto on_error;
1655
0
    }
1656
90
    if( memory_copy(
1657
90
         location_information->common_path,
1658
90
         unicode_string_data,
1659
90
         unicode_value_size ) == NULL )
1660
0
    {
1661
0
      libcerror_error_set(
1662
0
       error,
1663
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1664
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1665
0
       "%s: unable to copy common path.",
1666
0
       function );
1667
1668
0
      goto on_error;
1669
0
    }
1670
90
    location_information->common_path_size = unicode_value_size;
1671
90
    location_information->string_flags    |= LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE;
1672
90
  }
1673
98
  else if( common_path_offset > 0 )
1674
85
  {
1675
85
    location_information->common_path = (uint8_t *) memory_allocate(
1676
85
                                                     sizeof( uint8_t ) * value_size );
1677
1678
85
    if( location_information->common_path == NULL )
1679
0
    {
1680
0
      libcerror_error_set(
1681
0
       error,
1682
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1683
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1684
0
       "%s: unable to create common path.",
1685
0
       function );
1686
1687
0
      goto on_error;
1688
0
    }
1689
85
    if( memory_copy(
1690
85
         location_information->common_path,
1691
85
         string_data,
1692
85
         value_size ) == NULL )
1693
0
    {
1694
0
      libcerror_error_set(
1695
0
       error,
1696
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1697
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1698
0
       "%s: unable to copy common path.",
1699
0
       function );
1700
1701
0
      goto on_error;
1702
0
    }
1703
85
    location_information->common_path_size = value_size;
1704
85
  }
1705
#if defined( HAVE_DEBUG_OUTPUT )
1706
  if( libcnotify_verbose != 0 )
1707
  {
1708
    if( ( common_path_offset > 0 )
1709
     || ( unicode_common_path_offset > 0 ) )
1710
    {
1711
      if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
1712
      {
1713
        if( liblnk_debug_print_utf16_string_value(
1714
             function,
1715
             "common path\t\t\t\t\t\t",
1716
             location_information->common_path,
1717
             location_information->common_path_size,
1718
             LIBUNA_ENDIAN_LITTLE,
1719
             error ) != 1 )
1720
        {
1721
          libcerror_error_set(
1722
           error,
1723
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1724
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1725
           "%s: unable to print UTF-16 string value.",
1726
           function );
1727
1728
          goto on_error;
1729
        }
1730
      }
1731
      else
1732
      {
1733
        if( liblnk_debug_print_string_value(
1734
             function,
1735
             "common path\t\t\t\t\t\t",
1736
             location_information->device_name,
1737
             location_information->device_name_size,
1738
             io_handle->ascii_codepage,
1739
             error ) != 1 )
1740
        {
1741
          libcerror_error_set(
1742
           error,
1743
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1744
           LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1745
           "%s: unable to print string value.",
1746
           function );
1747
1748
          goto on_error;
1749
        }
1750
      }
1751
    }
1752
  }
1753
#endif /* defined( HAVE_VERBOSE_OUTPUT ) */
1754
1755
188
  return( 1 );
1756
1757
1.19k
on_error:
1758
1.19k
  if( location_information->common_path != NULL )
1759
0
  {
1760
0
    memory_free(
1761
0
     location_information->common_path );
1762
1763
0
    location_information->common_path = NULL;
1764
0
  }
1765
1.19k
  if( location_information->device_name != NULL )
1766
58
  {
1767
58
    memory_free(
1768
58
     location_information->device_name );
1769
1770
58
    location_information->device_name = NULL;
1771
58
  }
1772
1.19k
  if( location_information->network_share_name != NULL )
1773
180
  {
1774
180
    memory_free(
1775
180
     location_information->network_share_name );
1776
1777
180
    location_information->network_share_name = NULL;
1778
180
  }
1779
1.19k
  if( location_information->local_path != NULL )
1780
164
  {
1781
164
    memory_free(
1782
164
     location_information->local_path );
1783
1784
164
    location_information->local_path = NULL;
1785
164
  }
1786
1.19k
  if( location_information->volume_label != NULL )
1787
81
  {
1788
81
    memory_free(
1789
81
     location_information->volume_label );
1790
1791
81
    location_information->volume_label = NULL;
1792
81
  }
1793
1.19k
  return( -1 );
1794
257
}
1795
1796
/* Reads a location information
1797
 * Returns the number of bytes read if successful or -1 on error
1798
 */
1799
ssize_t liblnk_location_information_read(
1800
         liblnk_location_information_t *location_information,
1801
         liblnk_io_handle_t *io_handle,
1802
         libbfio_handle_t *file_io_handle,
1803
         off64_t location_information_offset,
1804
         libcerror_error_t **error )
1805
1.47k
{
1806
1.47k
  uint8_t location_information_size_data[ 4 ];
1807
1808
1.47k
  uint8_t *location_information_data = NULL;
1809
1.47k
  static char *function              = "liblnk_location_information_read";
1810
1.47k
  size_t location_information_size   = 0;
1811
1.47k
  ssize_t read_count                 = 0;
1812
1813
1.47k
  if( location_information == NULL )
1814
0
  {
1815
0
    libcerror_error_set(
1816
0
     error,
1817
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1818
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1819
0
     "%s: invalid location information.",
1820
0
     function );
1821
1822
0
    return( -1 );
1823
0
  }
1824
#if defined( HAVE_DEBUG_OUTPUT )
1825
  if( libcnotify_verbose != 0 )
1826
  {
1827
    libcnotify_printf(
1828
     "%s: reading location information at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
1829
     function,
1830
     location_information_offset,
1831
     location_information_offset );
1832
  }
1833
#endif
1834
1.47k
  read_count = libbfio_handle_read_buffer_at_offset(
1835
1.47k
                file_io_handle,
1836
1.47k
                location_information_size_data,
1837
1.47k
                4,
1838
1.47k
                location_information_offset,
1839
1.47k
                error );
1840
1841
1.47k
  if( read_count != (ssize_t) 4 )
1842
14
  {
1843
14
    libcerror_error_set(
1844
14
     error,
1845
14
     LIBCERROR_ERROR_DOMAIN_IO,
1846
14
     LIBCERROR_IO_ERROR_READ_FAILED,
1847
14
     "%s: unable to read location information size data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1848
14
     function,
1849
14
     location_information_offset,
1850
14
     location_information_offset );
1851
1852
14
    goto on_error;
1853
14
  }
1854
1.46k
  byte_stream_copy_to_uint32_little_endian(
1855
1.46k
   location_information_size_data,
1856
1.46k
   location_information_size );
1857
  
1858
#if defined( HAVE_DEBUG_OUTPUT )
1859
  if( libcnotify_verbose != 0 )
1860
  {
1861
    libcnotify_printf(
1862
     "%s: location information size\t\t\t\t\t: %" PRIzd "\n",
1863
     function,
1864
     location_information_size );
1865
  }
1866
#endif
1867
1.46k
  if( location_information_size <= 4 )
1868
15
  {
1869
#if defined( HAVE_VERBOSE_OUTPUT )
1870
    if( libcnotify_verbose != 0 )
1871
    {
1872
      libcnotify_printf(
1873
       "%s: empty location information.\n",
1874
       function );
1875
    }
1876
#endif
1877
15
    return( read_count );
1878
15
  }
1879
1.45k
  if( location_information_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
1880
8
  {
1881
8
    libcerror_error_set(
1882
8
     error,
1883
8
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1884
8
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1885
8
     "%s: location information size value exceeds maximum.",
1886
8
     function );
1887
1888
8
    goto on_error;
1889
8
  }
1890
1.44k
  location_information_size -= 4;
1891
1892
1.44k
  location_information_data = (uint8_t *) memory_allocate(
1893
1.44k
                                           sizeof( uint8_t ) * location_information_size );
1894
1895
1.44k
  if( location_information_data == NULL )
1896
0
  {
1897
0
    libcerror_error_set(
1898
0
     error,
1899
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1900
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1901
0
     "%s: unable to create location information data.",
1902
0
     function );
1903
1904
0
    goto on_error;
1905
0
  }
1906
1.44k
  read_count = libbfio_handle_read_buffer(
1907
1.44k
                file_io_handle,
1908
1.44k
                location_information_data,
1909
1.44k
                location_information_size,
1910
1.44k
                error );
1911
1912
1.44k
  if( read_count != (ssize_t) location_information_size )
1913
51
  {
1914
51
    libcerror_error_set(
1915
51
     error,
1916
51
     LIBCERROR_ERROR_DOMAIN_IO,
1917
51
     LIBCERROR_IO_ERROR_READ_FAILED,
1918
51
     "%s: unable to read location information data.",
1919
51
     function );
1920
1921
51
    goto on_error;
1922
51
  }
1923
1.39k
  if( liblnk_location_information_read_data(
1924
1.39k
       location_information,
1925
1.39k
       io_handle,
1926
1.39k
       location_information_data,
1927
1.39k
       location_information_size,
1928
1.39k
       error ) != 1 )
1929
1.20k
  {
1930
1.20k
    libcerror_error_set(
1931
1.20k
     error,
1932
1.20k
     LIBCERROR_ERROR_DOMAIN_IO,
1933
1.20k
     LIBCERROR_IO_ERROR_READ_FAILED,
1934
1.20k
     "%s: unable to read location information.",
1935
1.20k
     function );
1936
1937
1.20k
    goto on_error;
1938
1.20k
  }
1939
188
  memory_free(
1940
188
   location_information_data );
1941
1942
188
  location_information_data = NULL;
1943
1944
#if defined( HAVE_DEBUG_OUTPUT )
1945
  if( libcnotify_verbose != 0 )
1946
  {
1947
    libcnotify_printf(
1948
     "\n" );
1949
  }
1950
#endif
1951
188
  return( read_count + 4 );
1952
1953
1.27k
on_error:
1954
1.27k
  if( location_information_data != NULL )
1955
1.25k
  {
1956
1.25k
    memory_free(
1957
1.25k
     location_information_data );
1958
1.25k
  }
1959
1.27k
  return( -1 );
1960
1.39k
}
1961
1962
/* Retrieves the size of the UTF-8 encoded volume label
1963
 * The size includes the end of string character
1964
 * The volume label is only set if the link refers to a file on a local volume
1965
 * Returns 1 if successful, 0 if value is not available or -1 on error
1966
 */
1967
int liblnk_location_information_get_utf8_volume_label_size(
1968
     liblnk_location_information_t *location_information,
1969
     int ascii_codepage,
1970
     size_t *utf8_string_size,
1971
     libcerror_error_t **error )
1972
0
{
1973
0
  static char *function = "liblnk_location_information_get_utf8_volume_label_size";
1974
0
  int result            = 0;
1975
1976
0
  if( location_information == NULL )
1977
0
  {
1978
0
    libcerror_error_set(
1979
0
     error,
1980
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1981
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1982
0
     "%s: invalid location information.",
1983
0
     function );
1984
1985
0
    return( -1 );
1986
0
  }
1987
0
  if( utf8_string_size == NULL )
1988
0
  {
1989
0
    libcerror_error_set(
1990
0
     error,
1991
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1992
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1993
0
     "%s: invalid UTF-8 string size.",
1994
0
     function );
1995
1996
0
    return( -1 );
1997
0
  }
1998
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_VOLUME_INFORMATION ) == 0 )
1999
0
  {
2000
0
    return( 0 );
2001
0
  }
2002
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_VOLUME_LABEL_IS_UNICODE ) != 0 )
2003
0
  {
2004
0
    result = libuna_utf8_string_size_from_utf16_stream(
2005
0
        location_information->volume_label,
2006
0
        location_information->volume_label_size,
2007
0
        LIBUNA_ENDIAN_LITTLE,
2008
0
        utf8_string_size,
2009
0
        error );
2010
0
  }
2011
0
  else
2012
0
  {
2013
0
    result = libuna_utf8_string_size_from_byte_stream(
2014
0
        location_information->volume_label,
2015
0
        location_information->volume_label_size,
2016
0
        ascii_codepage,
2017
0
        utf8_string_size,
2018
0
        error );
2019
0
  }
2020
0
  if( result != 1 )
2021
0
  {
2022
0
    libcerror_error_set(
2023
0
     error,
2024
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2025
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2026
0
     "%s: unable to retrieve UTF-8 volume label string size.",
2027
0
     function );
2028
2029
0
    return( -1 );
2030
0
  }
2031
0
  return( 1 );
2032
0
}
2033
2034
/* Retrieves the UTF-8 encoded volume label
2035
 * The size should include the end of string character
2036
 * The volume label is only set if the link refers to a file on a local volume
2037
 * Returns 1 if successful, 0 if value is not available or -1 on error
2038
 */
2039
int liblnk_location_information_get_utf8_volume_label(
2040
     liblnk_location_information_t *location_information,
2041
     int ascii_codepage,
2042
     uint8_t *utf8_string,
2043
     size_t utf8_string_size,
2044
     libcerror_error_t **error )
2045
0
{
2046
0
  static char *function = "liblnk_location_information_get_utf8_volume_label";
2047
0
  size_t string_index   = 0;
2048
0
  int result            = 0;
2049
2050
0
  if( location_information == NULL )
2051
0
  {
2052
0
    libcerror_error_set(
2053
0
     error,
2054
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2055
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2056
0
     "%s: invalid location information.",
2057
0
     function );
2058
2059
0
    return( -1 );
2060
0
  }
2061
0
  if( utf8_string == NULL )
2062
0
  {
2063
0
    libcerror_error_set(
2064
0
     error,
2065
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2066
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2067
0
     "%s: invalid UTF-8 string.",
2068
0
     function );
2069
2070
0
    return( -1 );
2071
0
  }
2072
0
  if( ( utf8_string_size == 0 )
2073
0
   || ( utf8_string_size > (size_t) SSIZE_MAX ) )
2074
0
  {
2075
0
    libcerror_error_set(
2076
0
     error,
2077
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2078
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2079
0
     "%s: invalid UTF-8 string size value out of bounds.",
2080
0
     function );
2081
2082
0
    return( -1 );
2083
0
  }
2084
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_VOLUME_INFORMATION ) == 0 )
2085
0
  {
2086
0
    return( 0 );
2087
0
  }
2088
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_VOLUME_LABEL_IS_UNICODE ) != 0 )
2089
0
  {
2090
0
    result = libuna_utf8_string_with_index_copy_from_utf16_stream(
2091
0
        utf8_string,
2092
0
        utf8_string_size,
2093
0
        &string_index,
2094
0
        location_information->volume_label,
2095
0
        location_information->volume_label_size,
2096
0
        LIBUNA_ENDIAN_LITTLE,
2097
0
        error );
2098
0
  }
2099
0
  else
2100
0
  {
2101
0
    result = libuna_utf8_string_with_index_copy_from_byte_stream(
2102
0
        utf8_string,
2103
0
        utf8_string_size,
2104
0
        &string_index,
2105
0
        location_information->volume_label,
2106
0
        location_information->volume_label_size,
2107
0
        ascii_codepage,
2108
0
        error );
2109
0
  }
2110
0
  if( result != 1 )
2111
0
  {
2112
0
    libcerror_error_set(
2113
0
     error,
2114
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2115
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2116
0
     "%s: unable to set UTF-8 volume label string.",
2117
0
     function );
2118
2119
0
    return( -1 );
2120
0
  }
2121
0
  return( 1 );
2122
0
}
2123
2124
/* Retrieves the size of the UTF-16 encoded volume label
2125
 * The size includes the end of string character
2126
 * The volume label is only set if the link refers to a file on a local volume
2127
 * Returns 1 if successful, 0 if value is not available or -1 on error
2128
 */
2129
int liblnk_location_information_get_utf16_volume_label_size(
2130
     liblnk_location_information_t *location_information,
2131
     int ascii_codepage,
2132
     size_t *utf16_string_size,
2133
     libcerror_error_t **error )
2134
0
{
2135
0
  static char *function = "liblnk_location_information_get_utf16_volume_label_size";
2136
0
  int result            = 0;
2137
2138
0
  if( location_information == NULL )
2139
0
  {
2140
0
    libcerror_error_set(
2141
0
     error,
2142
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2143
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2144
0
     "%s: invalid location information.",
2145
0
     function );
2146
2147
0
    return( -1 );
2148
0
  }
2149
0
  if( utf16_string_size == NULL )
2150
0
  {
2151
0
    libcerror_error_set(
2152
0
     error,
2153
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2154
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2155
0
     "%s: invalid UTF-16 string size.",
2156
0
     function );
2157
2158
0
    return( -1 );
2159
0
  }
2160
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_VOLUME_INFORMATION ) == 0 )
2161
0
  {
2162
0
    return( 0 );
2163
0
  }
2164
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_VOLUME_LABEL_IS_UNICODE ) != 0 )
2165
0
  {
2166
0
    result = libuna_utf16_string_size_from_utf16_stream(
2167
0
        location_information->volume_label,
2168
0
        location_information->volume_label_size,
2169
0
        LIBUNA_ENDIAN_LITTLE,
2170
0
        utf16_string_size,
2171
0
        error );
2172
0
  }
2173
0
  else
2174
0
  {
2175
0
    result = libuna_utf16_string_size_from_byte_stream(
2176
0
        location_information->volume_label,
2177
0
        location_information->volume_label_size,
2178
0
        ascii_codepage,
2179
0
        utf16_string_size,
2180
0
        error );
2181
0
  }
2182
0
  if( result != 1 )
2183
0
  {
2184
0
    libcerror_error_set(
2185
0
     error,
2186
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2187
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2188
0
     "%s: unable to retrieve UTF-16 volume label string size.",
2189
0
     function );
2190
2191
0
    return( -1 );
2192
0
  }
2193
0
  return( 1 );
2194
0
}
2195
2196
/* Retrieves the UTF-16 encoded volume label
2197
 * The size should include the end of string character
2198
 * The volume label is only set if the link refers to a file on a local volume
2199
 * Returns 1 if successful, 0 if value is not available or -1 on error
2200
 */
2201
int liblnk_location_information_get_utf16_volume_label(
2202
     liblnk_location_information_t *location_information,
2203
     int ascii_codepage,
2204
     uint16_t *utf16_string,
2205
     size_t utf16_string_size,
2206
     libcerror_error_t **error )
2207
0
{
2208
0
  static char *function = "liblnk_location_information_get_utf16_volume_label";
2209
0
  size_t string_index   = 0;
2210
0
  int result            = 0;
2211
2212
0
  if( location_information == NULL )
2213
0
  {
2214
0
    libcerror_error_set(
2215
0
     error,
2216
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2217
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2218
0
     "%s: invalid location information.",
2219
0
     function );
2220
2221
0
    return( -1 );
2222
0
  }
2223
0
  if( utf16_string == NULL )
2224
0
  {
2225
0
    libcerror_error_set(
2226
0
     error,
2227
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2228
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2229
0
     "%s: invalid UTF-16 string.",
2230
0
     function );
2231
2232
0
    return( -1 );
2233
0
  }
2234
0
  if( ( utf16_string_size == 0 )
2235
0
   || ( utf16_string_size > (size_t) SSIZE_MAX ) )
2236
0
  {
2237
0
    libcerror_error_set(
2238
0
     error,
2239
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2240
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2241
0
     "%s: invalid UTF-16 string size value out of bounds.",
2242
0
     function );
2243
2244
0
    return( -1 );
2245
0
  }
2246
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_VOLUME_INFORMATION ) == 0 )
2247
0
  {
2248
0
    return( 0 );
2249
0
  }
2250
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_VOLUME_LABEL_IS_UNICODE ) != 0 )
2251
0
  {
2252
0
    result = libuna_utf16_string_with_index_copy_from_utf16_stream(
2253
0
        utf16_string,
2254
0
        utf16_string_size,
2255
0
        &string_index,
2256
0
        location_information->volume_label,
2257
0
        location_information->volume_label_size,
2258
0
        LIBUNA_ENDIAN_LITTLE,
2259
0
        error );
2260
0
  }
2261
0
  else
2262
0
  {
2263
0
    result = libuna_utf16_string_with_index_copy_from_byte_stream(
2264
0
        utf16_string,
2265
0
        utf16_string_size,
2266
0
        &string_index,
2267
0
        location_information->volume_label,
2268
0
        location_information->volume_label_size,
2269
0
        ascii_codepage,
2270
0
        error );
2271
0
  }
2272
0
  if( result != 1 )
2273
0
  {
2274
0
    libcerror_error_set(
2275
0
     error,
2276
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2277
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2278
0
     "%s: unable to set UTF-16 volume label string.",
2279
0
     function );
2280
2281
0
    return( -1 );
2282
0
  }
2283
0
  return( 1 );
2284
0
}
2285
2286
/* Retrieves the size of the UTF-8 encoded local path
2287
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2288
 * The size includes the end of string character
2289
 * The local path is only set if the link refers to a file on a local volume
2290
 * Returns 1 if successful, 0 if value is not available or -1 on error
2291
 */
2292
int liblnk_location_information_get_utf8_local_path_size(
2293
     liblnk_location_information_t *location_information,
2294
     int ascii_codepage,
2295
     size_t *utf8_string_size,
2296
     libcerror_error_t **error )
2297
0
{
2298
0
  static char *function        = "liblnk_location_information_get_utf8_local_path_size";
2299
0
  size_t utf8_common_path_size = 0;
2300
0
  size_t utf8_local_path_size  = 0;
2301
0
  int result                   = 0;
2302
2303
0
  if( location_information == NULL )
2304
0
  {
2305
0
    libcerror_error_set(
2306
0
     error,
2307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2309
0
     "%s: invalid location information.",
2310
0
     function );
2311
2312
0
    return( -1 );
2313
0
  }
2314
0
  if( utf8_string_size == NULL )
2315
0
  {
2316
0
    libcerror_error_set(
2317
0
     error,
2318
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2319
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2320
0
     "%s: invalid UTF-8 string size.",
2321
0
     function );
2322
2323
0
    return( -1 );
2324
0
  }
2325
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_VOLUME_INFORMATION ) == 0 )
2326
0
  {
2327
0
    return( 0 );
2328
0
  }
2329
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE ) != 0 )
2330
0
  {
2331
0
    result = libuna_utf8_string_size_from_utf16_stream(
2332
0
        location_information->local_path,
2333
0
        location_information->local_path_size,
2334
0
        LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2335
0
        &utf8_local_path_size,
2336
0
        error );
2337
0
  }
2338
0
  else
2339
0
  {
2340
0
    result = libuna_utf8_string_size_from_byte_stream(
2341
0
        location_information->local_path,
2342
0
        location_information->local_path_size,
2343
0
        ascii_codepage,
2344
0
        &utf8_local_path_size,
2345
0
        error );
2346
0
  }
2347
0
  if( result != 1 )
2348
0
  {
2349
0
    libcerror_error_set(
2350
0
     error,
2351
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2352
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2353
0
     "%s: unable to retrieve UTF-8 local path string size.",
2354
0
     function );
2355
2356
0
    return( -1 );
2357
0
  }
2358
0
  result = 0;
2359
2360
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE ) != 0 )
2361
0
  {
2362
0
    if( location_information->local_path_size >= 4 )
2363
0
    {
2364
0
      if( ( ( location_information->local_path )[ location_information->local_path_size - 4 ] != (uint8_t) '\\' )
2365
0
       || ( ( location_information->local_path )[ location_information->local_path_size - 3 ] != 0 ) )
2366
0
      {
2367
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2368
0
        {
2369
0
          if( location_information->common_path_size > 2 )
2370
0
          {
2371
0
            result = 1;
2372
0
          }
2373
0
        }
2374
0
        else
2375
0
        {
2376
0
          if( location_information->common_path_size > 1 )
2377
0
          {
2378
0
            result = 1;
2379
0
          }
2380
0
        }
2381
0
      }
2382
0
    }
2383
0
  }
2384
0
  else
2385
0
  {
2386
0
    if( location_information->local_path_size >= 2 )
2387
0
    {
2388
0
      if( ( location_information->local_path )[ location_information->local_path_size - 2 ] != (uint8_t) '\\' )
2389
0
      {
2390
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2391
0
        {
2392
0
          if( location_information->common_path_size > 2 )
2393
0
          {
2394
0
            result = 1;
2395
0
          }
2396
0
        }
2397
0
        else
2398
0
        {
2399
0
          if( location_information->common_path_size > 1 )
2400
0
          {
2401
0
            result = 1;
2402
0
          }
2403
0
        }
2404
0
      }
2405
0
    }
2406
0
  }
2407
0
  if( result != 0 )
2408
0
  {
2409
0
    utf8_local_path_size += 1;
2410
0
  }
2411
0
  if( location_information->common_path != NULL )
2412
0
  {
2413
0
    if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2414
0
    {
2415
0
      result = libuna_utf8_string_size_from_utf16_stream(
2416
0
          location_information->common_path,
2417
0
          location_information->common_path_size,
2418
0
          LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2419
0
          &utf8_common_path_size,
2420
0
          error );
2421
0
    }
2422
0
    else
2423
0
    {
2424
0
      result = libuna_utf8_string_size_from_byte_stream(
2425
0
          location_information->common_path,
2426
0
          location_information->common_path_size,
2427
0
          ascii_codepage,
2428
0
          &utf8_common_path_size,
2429
0
          error );
2430
0
    }
2431
0
    if( result != 1 )
2432
0
    {
2433
0
      libcerror_error_set(
2434
0
       error,
2435
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2436
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2437
0
       "%s: unable to retrieve UTF-8 common path string size.",
2438
0
       function );
2439
2440
0
      return( -1 );
2441
0
    }
2442
0
    utf8_local_path_size -= 1;
2443
0
  }
2444
0
  *utf8_string_size = utf8_local_path_size + utf8_common_path_size;
2445
2446
0
  return( 1 );
2447
0
}
2448
2449
/* Retrieves the UTF-8 encoded local path
2450
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2451
 * The size should include the end of string character
2452
 * The local path is only set if the link refers to a file on a local volume
2453
 * Returns 1 if successful, 0 if value is not available or -1 on error
2454
 */
2455
int liblnk_location_information_get_utf8_local_path(
2456
     liblnk_location_information_t *location_information,
2457
     int ascii_codepage,
2458
     uint8_t *utf8_string,
2459
     size_t utf8_string_size,
2460
     libcerror_error_t **error )
2461
0
{
2462
0
  static char *function = "liblnk_location_information_get_utf8_local_path";
2463
0
  size_t string_index   = 0;
2464
0
  int result            = 0;
2465
2466
0
  if( location_information == NULL )
2467
0
  {
2468
0
    libcerror_error_set(
2469
0
     error,
2470
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2471
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2472
0
     "%s: invalid location information.",
2473
0
     function );
2474
2475
0
    return( -1 );
2476
0
  }
2477
0
  if( utf8_string == NULL )
2478
0
  {
2479
0
    libcerror_error_set(
2480
0
     error,
2481
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2482
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2483
0
     "%s: invalid UTF-8 string.",
2484
0
     function );
2485
2486
0
    return( -1 );
2487
0
  }
2488
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
2489
0
  {
2490
0
    libcerror_error_set(
2491
0
     error,
2492
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2493
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2494
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
2495
0
     function );
2496
2497
0
    return( -1 );
2498
0
  }
2499
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_VOLUME_INFORMATION ) == 0 )
2500
0
  {
2501
0
    return( 0 );
2502
0
  }
2503
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE ) != 0 )
2504
0
  {
2505
0
    result = libuna_utf8_string_with_index_copy_from_utf16_stream(
2506
0
        utf8_string,
2507
0
        utf8_string_size,
2508
0
        &string_index,
2509
0
        location_information->local_path,
2510
0
        location_information->local_path_size,
2511
0
        LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2512
0
        error );
2513
0
  }
2514
0
  else
2515
0
  {
2516
0
    result = libuna_utf8_string_with_index_copy_from_byte_stream(
2517
0
        utf8_string,
2518
0
        utf8_string_size,
2519
0
        &string_index,
2520
0
        location_information->local_path,
2521
0
        location_information->local_path_size,
2522
0
        ascii_codepage,
2523
0
        error );
2524
0
  }
2525
0
  if( result != 1 )
2526
0
  {
2527
0
    libcerror_error_set(
2528
0
     error,
2529
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2530
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2531
0
     "%s: unable to set UTF-8 local path string.",
2532
0
     function );
2533
2534
0
    return( -1 );
2535
0
  }
2536
0
  string_index--;
2537
2538
0
  result = 0;
2539
2540
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE ) != 0 )
2541
0
  {
2542
0
    if( location_information->local_path_size >= 4 )
2543
0
    {
2544
0
      if( ( ( location_information->local_path )[ location_information->local_path_size - 4 ] != (uint8_t) '\\' )
2545
0
       || ( ( location_information->local_path )[ location_information->local_path_size - 3 ] != 0 ) )
2546
0
      {
2547
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2548
0
        {
2549
0
          if( location_information->common_path_size > 2 )
2550
0
          {
2551
0
            result = 1;
2552
0
          }
2553
0
        }
2554
0
        else
2555
0
        {
2556
0
          if( location_information->common_path_size > 1 )
2557
0
          {
2558
0
            result = 1;
2559
0
          }
2560
0
        }
2561
0
      }
2562
0
    }
2563
0
  }
2564
0
  else
2565
0
  {
2566
0
    if( location_information->local_path_size >= 2 )
2567
0
    {
2568
0
      if( ( location_information->local_path )[ location_information->local_path_size - 2 ] != (uint8_t) '\\' )
2569
0
      {
2570
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2571
0
        {
2572
0
          if( location_information->common_path_size > 2 )
2573
0
          {
2574
0
            result = 1;
2575
0
          }
2576
0
        }
2577
0
        else
2578
0
        {
2579
0
          if( location_information->common_path_size > 1 )
2580
0
          {
2581
0
            result = 1;
2582
0
          }
2583
0
        }
2584
0
      }
2585
0
    }
2586
0
  }
2587
0
  if( result != 0 )
2588
0
  {
2589
0
    if( ( string_index + 1 ) > utf8_string_size )
2590
0
    {
2591
0
      libcerror_error_set(
2592
0
       error,
2593
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2594
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2595
0
       "%s: UTF-8 string value too small.",
2596
0
       function );
2597
2598
0
      return( -1 );
2599
0
    }
2600
0
    utf8_string[ string_index++ ] = (uint8_t) '\\';
2601
0
  }
2602
0
  if( location_information->common_path != NULL )
2603
0
  {
2604
0
    if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2605
0
    {
2606
0
      result = libuna_utf8_string_with_index_copy_from_utf16_stream(
2607
0
          utf8_string,
2608
0
          utf8_string_size,
2609
0
          &string_index,
2610
0
          location_information->common_path,
2611
0
          location_information->common_path_size,
2612
0
          LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2613
0
          error );
2614
0
    }
2615
0
    else
2616
0
    {
2617
0
      result = libuna_utf8_string_with_index_copy_from_byte_stream(
2618
0
          utf8_string,
2619
0
          utf8_string_size,
2620
0
          &string_index,
2621
0
          location_information->common_path,
2622
0
          location_information->common_path_size,
2623
0
          ascii_codepage,
2624
0
          error );
2625
0
    }
2626
0
    if( result != 1 )
2627
0
    {
2628
0
      libcerror_error_set(
2629
0
       error,
2630
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2631
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2632
0
       "%s: unable to set UTF-8 common path string.",
2633
0
       function );
2634
2635
0
      return( -1 );
2636
0
    }
2637
0
  }
2638
0
  return( 1 );
2639
0
}
2640
2641
/* Retrieves the size of the UTF-16 encoded local path
2642
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2643
 * The size includes the end of string character
2644
 * The local path is only set if the link refers to a file on a local volume
2645
 * Returns 1 if successful, 0 if value is not available or -1 on error
2646
 */
2647
int liblnk_location_information_get_utf16_local_path_size(
2648
     liblnk_location_information_t *location_information,
2649
     int ascii_codepage,
2650
     size_t *utf16_string_size,
2651
     libcerror_error_t **error )
2652
0
{
2653
0
  static char *function         = "liblnk_location_information_get_utf16_local_path_size";
2654
0
  size_t utf16_common_path_size = 0;
2655
0
  size_t utf16_local_path_size  = 0;
2656
0
  int result                    = 0;
2657
2658
0
  if( location_information == NULL )
2659
0
  {
2660
0
    libcerror_error_set(
2661
0
     error,
2662
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2663
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2664
0
     "%s: invalid location information.",
2665
0
     function );
2666
2667
0
    return( -1 );
2668
0
  }
2669
0
  if( utf16_string_size == NULL )
2670
0
  {
2671
0
    libcerror_error_set(
2672
0
     error,
2673
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2674
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2675
0
     "%s: invalid UTF-16 string size.",
2676
0
     function );
2677
2678
0
    return( -1 );
2679
0
  }
2680
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_VOLUME_INFORMATION ) == 0 )
2681
0
  {
2682
0
    return( 0 );
2683
0
  }
2684
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE ) != 0 )
2685
0
  {
2686
0
    result = libuna_utf16_string_size_from_utf16_stream(
2687
0
        location_information->local_path,
2688
0
        location_information->local_path_size,
2689
0
        LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2690
0
        &utf16_local_path_size,
2691
0
        error );
2692
0
  }
2693
0
  else
2694
0
  {
2695
0
    result = libuna_utf16_string_size_from_byte_stream(
2696
0
        location_information->local_path,
2697
0
        location_information->local_path_size,
2698
0
        ascii_codepage,
2699
0
        &utf16_local_path_size,
2700
0
        error );
2701
0
  }
2702
0
  if( result != 1 )
2703
0
  {
2704
0
    libcerror_error_set(
2705
0
     error,
2706
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2707
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2708
0
     "%s: unable to retrieve UTF-16 local path string size.",
2709
0
     function );
2710
2711
0
    return( -1 );
2712
0
  }
2713
0
  result = 0;
2714
2715
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE ) != 0 )
2716
0
  {
2717
0
    if( location_information->local_path_size >= 4 )
2718
0
    {
2719
0
      if( ( ( location_information->local_path )[ location_information->local_path_size - 4 ] != (uint8_t) '\\' )
2720
0
       || ( ( location_information->local_path )[ location_information->local_path_size - 3 ] != 0 ) )
2721
0
      {
2722
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2723
0
        {
2724
0
          if( location_information->common_path_size > 2 )
2725
0
          {
2726
0
            result = 1;
2727
0
          }
2728
0
        }
2729
0
        else
2730
0
        {
2731
0
          if( location_information->common_path_size > 1 )
2732
0
          {
2733
0
            result = 1;
2734
0
          }
2735
0
        }
2736
0
      }
2737
0
    }
2738
0
  }
2739
0
  else
2740
0
  {
2741
0
    if( location_information->local_path_size >= 2 )
2742
0
    {
2743
0
      if( ( location_information->local_path )[ location_information->local_path_size - 2 ] != (uint8_t) '\\' )
2744
0
      {
2745
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2746
0
        {
2747
0
          if( location_information->common_path_size > 2 )
2748
0
          {
2749
0
            result = 1;
2750
0
          }
2751
0
        }
2752
0
        else
2753
0
        {
2754
0
          if( location_information->common_path_size > 1 )
2755
0
          {
2756
0
            result = 1;
2757
0
          }
2758
0
        }
2759
0
      }
2760
0
    }
2761
0
  }
2762
0
  if( result != 0 )
2763
0
  {
2764
0
    utf16_local_path_size += 1;
2765
0
  }
2766
0
  if( location_information->common_path != NULL )
2767
0
  {
2768
0
    if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2769
0
    {
2770
0
      result = libuna_utf16_string_size_from_utf16_stream(
2771
0
          location_information->common_path,
2772
0
          location_information->common_path_size,
2773
0
          LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2774
0
          &utf16_common_path_size,
2775
0
          error );
2776
0
    }
2777
0
    else
2778
0
    {
2779
0
      result = libuna_utf16_string_size_from_byte_stream(
2780
0
          location_information->common_path,
2781
0
          location_information->common_path_size,
2782
0
          ascii_codepage,
2783
0
          &utf16_common_path_size,
2784
0
          error );
2785
0
    }
2786
0
    if( result != 1 )
2787
0
    {
2788
0
      libcerror_error_set(
2789
0
       error,
2790
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2791
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2792
0
       "%s: unable to retrieve UTF-16 common path string size.",
2793
0
       function );
2794
2795
0
      return( -1 );
2796
0
    }
2797
0
    utf16_local_path_size -= 1;
2798
0
  }
2799
0
  *utf16_string_size = utf16_local_path_size + utf16_common_path_size;
2800
2801
0
  return( 1 );
2802
0
}
2803
2804
/* Retrieves the UTF-16 encoded local path
2805
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2806
 * The size should include the end of string character
2807
 * The local path is only set if the link refers to a file on a local volume
2808
 * Returns 1 if successful, 0 if value is not available or -1 on error
2809
 */
2810
int liblnk_location_information_get_utf16_local_path(
2811
     liblnk_location_information_t *location_information,
2812
     int ascii_codepage,
2813
     uint16_t *utf16_string,
2814
     size_t utf16_string_size,
2815
     libcerror_error_t **error )
2816
0
{
2817
0
  static char *function = "liblnk_location_information_get_utf16_local_path";
2818
0
  size_t string_index   = 0;
2819
0
  int result            = 0;
2820
2821
0
  if( location_information == NULL )
2822
0
  {
2823
0
    libcerror_error_set(
2824
0
     error,
2825
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2826
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2827
0
     "%s: invalid location information.",
2828
0
     function );
2829
2830
0
    return( -1 );
2831
0
  }
2832
0
  if( utf16_string == NULL )
2833
0
  {
2834
0
    libcerror_error_set(
2835
0
     error,
2836
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2837
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2838
0
     "%s: invalid UTF-16 string.",
2839
0
     function );
2840
2841
0
    return( -1 );
2842
0
  }
2843
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
2844
0
  {
2845
0
    libcerror_error_set(
2846
0
     error,
2847
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2848
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2849
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
2850
0
     function );
2851
2852
0
    return( -1 );
2853
0
  }
2854
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_VOLUME_INFORMATION ) == 0 )
2855
0
  {
2856
0
    return( 0 );
2857
0
  }
2858
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE ) != 0 )
2859
0
  {
2860
0
    result = libuna_utf16_string_with_index_copy_from_utf16_stream(
2861
0
        utf16_string,
2862
0
        utf16_string_size,
2863
0
        &string_index,
2864
0
        location_information->local_path,
2865
0
        location_information->local_path_size,
2866
0
        LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2867
0
        error );
2868
0
  }
2869
0
  else
2870
0
  {
2871
0
    result = libuna_utf16_string_with_index_copy_from_byte_stream(
2872
0
        utf16_string,
2873
0
        utf16_string_size,
2874
0
        &string_index,
2875
0
        location_information->local_path,
2876
0
        location_information->local_path_size,
2877
0
        ascii_codepage,
2878
0
        error );
2879
0
  }
2880
0
  if( result != 1 )
2881
0
  {
2882
0
    libcerror_error_set(
2883
0
     error,
2884
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2885
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2886
0
     "%s: unable to set UTF-16 local path string.",
2887
0
     function );
2888
2889
0
    return( -1 );
2890
0
  }
2891
0
  string_index--;
2892
2893
0
  result = 0;
2894
2895
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_LOCAL_PATH_IS_UNICODE ) != 0 )
2896
0
  {
2897
0
    if( location_information->local_path_size >= 4 )
2898
0
    {
2899
0
      if( ( ( location_information->local_path )[ location_information->local_path_size - 4 ] != (uint8_t) '\\' )
2900
0
       || ( ( location_information->local_path )[ location_information->local_path_size - 3 ] != 0 ) )
2901
0
      {
2902
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2903
0
        {
2904
0
          if( location_information->common_path_size > 2 )
2905
0
          {
2906
0
            result = 1;
2907
0
          }
2908
0
        }
2909
0
        else
2910
0
        {
2911
0
          if( location_information->common_path_size > 1 )
2912
0
          {
2913
0
            result = 1;
2914
0
          }
2915
0
        }
2916
0
      }
2917
0
    }
2918
0
  }
2919
0
  else
2920
0
  {
2921
0
    if( location_information->local_path_size >= 2 )
2922
0
    {
2923
0
      if( ( location_information->local_path )[ location_information->local_path_size - 2 ] != (uint16_t) '\\' )
2924
0
      {
2925
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2926
0
        {
2927
0
          if( location_information->common_path_size > 2 )
2928
0
          {
2929
0
            result = 1;
2930
0
          }
2931
0
        }
2932
0
        else
2933
0
        {
2934
0
          if( location_information->common_path_size > 1 )
2935
0
          {
2936
0
            result = 1;
2937
0
          }
2938
0
        }
2939
0
      }
2940
0
    }
2941
0
  }
2942
0
  if( result != 0 )
2943
0
  {
2944
0
    if( ( string_index + 1 ) > utf16_string_size )
2945
0
    {
2946
0
      libcerror_error_set(
2947
0
       error,
2948
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2949
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2950
0
       "%s: UTF-16 string value too small.",
2951
0
       function );
2952
2953
0
      return( -1 );
2954
0
    }
2955
0
    utf16_string[ string_index++ ] = (uint16_t) '\\';
2956
0
  }
2957
0
  if( location_information->common_path != NULL )
2958
0
  {
2959
0
    if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
2960
0
    {
2961
0
      result = libuna_utf16_string_with_index_copy_from_utf16_stream(
2962
0
          utf16_string,
2963
0
          utf16_string_size,
2964
0
          &string_index,
2965
0
          location_information->common_path,
2966
0
          location_information->common_path_size,
2967
0
          LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
2968
0
          error );
2969
0
    }
2970
0
    else
2971
0
    {
2972
0
      result = libuna_utf16_string_with_index_copy_from_byte_stream(
2973
0
          utf16_string,
2974
0
          utf16_string_size,
2975
0
          &string_index,
2976
0
          location_information->common_path,
2977
0
          location_information->common_path_size,
2978
0
          ascii_codepage,
2979
0
          error );
2980
0
    }
2981
0
    if( result != 1 )
2982
0
    {
2983
0
      libcerror_error_set(
2984
0
       error,
2985
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2986
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2987
0
       "%s: unable to set UTF-16 common path string.",
2988
0
       function );
2989
2990
0
      return( -1 );
2991
0
    }
2992
0
  }
2993
0
  return( 1 );
2994
0
}
2995
2996
/* Retrieves the size of the UTF-8 encoded network path
2997
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2998
 * The size includes the end of string character
2999
 * The network path is only set if the link refers to a file on a network share
3000
 * Returns 1 if successful, 0 if value is not available or -1 on error
3001
 */
3002
int liblnk_location_information_get_utf8_network_path_size(
3003
     liblnk_location_information_t *location_information,
3004
     int ascii_codepage,
3005
     size_t *utf8_string_size,
3006
     libcerror_error_t **error )
3007
0
{
3008
0
  static char *function               = "liblnk_location_information_get_utf8_network_path_size";
3009
0
  size_t utf8_common_path_size        = 0;
3010
0
  size_t utf8_network_share_name_size = 0;
3011
0
  int result                          = 0;
3012
3013
0
  if( location_information == NULL )
3014
0
  {
3015
0
    libcerror_error_set(
3016
0
     error,
3017
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3018
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3019
0
     "%s: invalid location information.",
3020
0
     function );
3021
3022
0
    return( -1 );
3023
0
  }
3024
0
  if( utf8_string_size == NULL )
3025
0
  {
3026
0
    libcerror_error_set(
3027
0
     error,
3028
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3029
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3030
0
     "%s: invalid UTF-8 string size.",
3031
0
     function );
3032
3033
0
    return( -1 );
3034
0
  }
3035
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_NETWORK_SHARE_INFORMATION ) == 0 )
3036
0
  {
3037
0
    return( 0 );
3038
0
  }
3039
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE ) != 0 )
3040
0
  {
3041
0
    result = libuna_utf8_string_size_from_utf16_stream(
3042
0
        location_information->network_share_name,
3043
0
        location_information->network_share_name_size,
3044
0
        LIBUNA_ENDIAN_LITTLE,
3045
0
        &utf8_network_share_name_size,
3046
0
        error );
3047
0
  }
3048
0
  else
3049
0
  {
3050
0
    result = libuna_utf8_string_size_from_byte_stream(
3051
0
        location_information->network_share_name,
3052
0
        location_information->network_share_name_size,
3053
0
        ascii_codepage,
3054
0
        &utf8_network_share_name_size,
3055
0
        error );
3056
0
  }
3057
0
  if( result != 1 )
3058
0
  {
3059
0
    libcerror_error_set(
3060
0
     error,
3061
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3062
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3063
0
     "%s: unable to retrieve UTF-8 network share name string size.",
3064
0
     function );
3065
3066
0
    return( -1 );
3067
0
  }
3068
0
  result = 0;
3069
3070
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE ) != 0 )
3071
0
  {
3072
0
    if( location_information->network_share_name_size >= 4 )
3073
0
    {
3074
0
      if( ( ( location_information->network_share_name )[ location_information->network_share_name_size - 4 ] != (uint8_t) '\\' )
3075
0
       || ( ( location_information->network_share_name )[ location_information->network_share_name_size - 3 ] != 0 ) )
3076
0
      {
3077
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3078
0
        {
3079
0
          if( location_information->common_path_size > 2 )
3080
0
          {
3081
0
            result = 1;
3082
0
          }
3083
0
        }
3084
0
        else
3085
0
        {
3086
0
          if( location_information->common_path_size > 1 )
3087
0
          {
3088
0
            result = 1;
3089
0
          }
3090
0
        }
3091
0
      }
3092
0
    }
3093
0
  }
3094
0
  else
3095
0
  {
3096
0
    if( location_information->network_share_name_size >= 2 )
3097
0
    {
3098
0
      if( ( location_information->network_share_name )[ location_information->network_share_name_size - 2 ] != (uint8_t) '\\' )
3099
0
      {
3100
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3101
0
        {
3102
0
          if( location_information->common_path_size > 2 )
3103
0
          {
3104
0
            result = 1;
3105
0
          }
3106
0
        }
3107
0
        else
3108
0
        {
3109
0
          if( location_information->common_path_size > 1 )
3110
0
          {
3111
0
            result = 1;
3112
0
          }
3113
0
        }
3114
0
      }
3115
0
    }
3116
0
  }
3117
0
  if( result != 0 )
3118
0
  {
3119
0
    utf8_network_share_name_size += 1;
3120
0
  }
3121
0
  if( location_information->common_path != NULL )
3122
0
  {
3123
0
    if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3124
0
    {
3125
0
      result = libuna_utf8_string_size_from_utf16_stream(
3126
0
          location_information->common_path,
3127
0
          location_information->common_path_size,
3128
0
          LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
3129
0
          &utf8_common_path_size,
3130
0
          error );
3131
0
    }
3132
0
    else
3133
0
    {
3134
0
      result = libuna_utf8_string_size_from_byte_stream(
3135
0
          location_information->common_path,
3136
0
          location_information->common_path_size,
3137
0
          ascii_codepage,
3138
0
          &utf8_common_path_size,
3139
0
          error );
3140
0
    }
3141
0
    if( result != 1 )
3142
0
    {
3143
0
      libcerror_error_set(
3144
0
       error,
3145
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3146
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3147
0
       "%s: unable to retrieve UTF-8 common path string size.",
3148
0
       function );
3149
3150
0
      return( -1 );
3151
0
    }
3152
0
    utf8_network_share_name_size -= 1;
3153
0
  }
3154
0
  *utf8_string_size = utf8_network_share_name_size + utf8_common_path_size;
3155
3156
0
  return( 1 );
3157
0
}
3158
3159
/* Retrieves the UTF-8 encoded network path
3160
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
3161
 * The size should include the end of string character
3162
 * The network path is only set if the link refers to a file on a network share
3163
 * Returns 1 if successful, 0 if value is not available or -1 on error
3164
 */
3165
int liblnk_location_information_get_utf8_network_path(
3166
     liblnk_location_information_t *location_information,
3167
     int ascii_codepage,
3168
     uint8_t *utf8_string,
3169
     size_t utf8_string_size,
3170
     libcerror_error_t **error )
3171
0
{
3172
0
  static char *function = "liblnk_location_information_get_utf8_network_path";
3173
0
  size_t string_index   = 0;
3174
0
  int result            = 0;
3175
3176
0
  if( location_information == NULL )
3177
0
  {
3178
0
    libcerror_error_set(
3179
0
     error,
3180
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3181
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3182
0
     "%s: invalid location information.",
3183
0
     function );
3184
3185
0
    return( -1 );
3186
0
  }
3187
0
  if( utf8_string == NULL )
3188
0
  {
3189
0
    libcerror_error_set(
3190
0
     error,
3191
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3192
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3193
0
     "%s: invalid UTF-8 string.",
3194
0
     function );
3195
3196
0
    return( -1 );
3197
0
  }
3198
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
3199
0
  {
3200
0
    libcerror_error_set(
3201
0
     error,
3202
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3203
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3204
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
3205
0
     function );
3206
3207
0
    return( -1 );
3208
0
  }
3209
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_NETWORK_SHARE_INFORMATION ) == 0 )
3210
0
  {
3211
0
    return( 0 );
3212
0
  }
3213
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE ) != 0 )
3214
0
  {
3215
0
    result = libuna_utf8_string_with_index_copy_from_utf16_stream(
3216
0
        utf8_string,
3217
0
        utf8_string_size,
3218
0
        &string_index,
3219
0
        location_information->network_share_name,
3220
0
        location_information->network_share_name_size,
3221
0
        LIBUNA_ENDIAN_LITTLE,
3222
0
        error );
3223
0
  }
3224
0
  else
3225
0
  {
3226
0
    result = libuna_utf8_string_with_index_copy_from_byte_stream(
3227
0
        utf8_string,
3228
0
        utf8_string_size,
3229
0
        &string_index,
3230
0
        location_information->network_share_name,
3231
0
        location_information->network_share_name_size,
3232
0
        ascii_codepage,
3233
0
        error );
3234
0
  }
3235
0
  if( result != 1 )
3236
0
  {
3237
0
    libcerror_error_set(
3238
0
     error,
3239
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3240
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3241
0
     "%s: unable to set UTF-8 network share name string.",
3242
0
     function );
3243
3244
0
    return( -1 );
3245
0
  }
3246
0
  string_index--;
3247
3248
0
  result = 0;
3249
3250
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE ) != 0 )
3251
0
  {
3252
0
    if( location_information->network_share_name_size >= 4 )
3253
0
    {
3254
0
      if( ( ( location_information->network_share_name )[ location_information->network_share_name_size - 4 ] != (uint8_t) '\\' )
3255
0
       || ( ( location_information->network_share_name )[ location_information->network_share_name_size - 3 ] != 0 ) )
3256
0
      {
3257
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3258
0
        {
3259
0
          if( location_information->common_path_size > 2 )
3260
0
          {
3261
0
            result = 1;
3262
0
          }
3263
0
        }
3264
0
        else
3265
0
        {
3266
0
          if( location_information->common_path_size > 1 )
3267
0
          {
3268
0
            result = 1;
3269
0
          }
3270
0
        }
3271
0
      }
3272
0
    }
3273
0
  }
3274
0
  else
3275
0
  {
3276
0
    if( location_information->network_share_name_size >= 2 )
3277
0
    {
3278
0
      if( ( location_information->network_share_name )[ location_information->network_share_name_size - 2 ] != (uint8_t) '\\' )
3279
0
      {
3280
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3281
0
        {
3282
0
          if( location_information->common_path_size > 2 )
3283
0
          {
3284
0
            result = 1;
3285
0
          }
3286
0
        }
3287
0
        else
3288
0
        {
3289
0
          if( location_information->common_path_size > 1 )
3290
0
          {
3291
0
            result = 1;
3292
0
          }
3293
0
        }
3294
0
      }
3295
0
    }
3296
0
  }
3297
0
  if( result != 0 )
3298
0
  {
3299
0
    if( ( string_index + 1 ) > utf8_string_size )
3300
0
    {
3301
0
      libcerror_error_set(
3302
0
       error,
3303
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3304
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3305
0
       "%s: UTF-8 string value too small.",
3306
0
       function );
3307
3308
0
      return( -1 );
3309
0
    }
3310
0
    utf8_string[ string_index++ ] = (uint8_t) '\\';
3311
0
  }
3312
0
  if( location_information->common_path != NULL )
3313
0
  {
3314
0
    if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3315
0
    {
3316
0
      result = libuna_utf8_string_with_index_copy_from_utf16_stream(
3317
0
          utf8_string,
3318
0
          utf8_string_size,
3319
0
                &string_index,
3320
0
          location_information->common_path,
3321
0
          location_information->common_path_size,
3322
0
          LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
3323
0
          error );
3324
0
    }
3325
0
    else
3326
0
    {
3327
0
      result = libuna_utf8_string_with_index_copy_from_byte_stream(
3328
0
          utf8_string,
3329
0
          utf8_string_size,
3330
0
                &string_index,
3331
0
          location_information->common_path,
3332
0
          location_information->common_path_size,
3333
0
          ascii_codepage,
3334
0
          error );
3335
0
    }
3336
0
    if( result != 1 )
3337
0
    {
3338
0
      libcerror_error_set(
3339
0
       error,
3340
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3341
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3342
0
       "%s: unable to set UTF-8 common path string.",
3343
0
       function );
3344
3345
0
      return( -1 );
3346
0
    }
3347
0
  }
3348
0
  return( 1 );
3349
0
}
3350
3351
/* Retrieves the size of the UTF-16 encoded network path
3352
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
3353
 * The size includes the end of string character
3354
 * The network path is only set if the link refers to a file on a network share
3355
 * Returns 1 if successful, 0 if value is not available or -1 on error
3356
 */
3357
int liblnk_location_information_get_utf16_network_path_size(
3358
     liblnk_location_information_t *location_information,
3359
     int ascii_codepage,
3360
     size_t *utf16_string_size,
3361
     libcerror_error_t **error )
3362
0
{
3363
0
  static char *function                = "liblnk_location_information_get_utf16_network_path_size";
3364
0
  size_t utf16_common_path_size        = 0;
3365
0
  size_t utf16_network_share_name_size = 0;
3366
0
  int result                           = 0;
3367
3368
0
  if( location_information == NULL )
3369
0
  {
3370
0
    libcerror_error_set(
3371
0
     error,
3372
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3373
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3374
0
     "%s: invalid location information.",
3375
0
     function );
3376
3377
0
    return( -1 );
3378
0
  }
3379
0
  if( utf16_string_size == NULL )
3380
0
  {
3381
0
    libcerror_error_set(
3382
0
     error,
3383
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3384
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3385
0
     "%s: invalid UTF-16 string size.",
3386
0
     function );
3387
3388
0
    return( -1 );
3389
0
  }
3390
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_NETWORK_SHARE_INFORMATION ) == 0 )
3391
0
  {
3392
0
    return( 0 );
3393
0
  }
3394
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE ) != 0 )
3395
0
  {
3396
0
    result = libuna_utf16_string_size_from_utf16_stream(
3397
0
        location_information->network_share_name,
3398
0
        location_information->network_share_name_size,
3399
0
        LIBUNA_ENDIAN_LITTLE,
3400
0
        &utf16_network_share_name_size,
3401
0
        error );
3402
0
  }
3403
0
  else
3404
0
  {
3405
0
    result = libuna_utf16_string_size_from_byte_stream(
3406
0
        location_information->network_share_name,
3407
0
        location_information->network_share_name_size,
3408
0
        ascii_codepage,
3409
0
        &utf16_network_share_name_size,
3410
0
        error );
3411
0
  }
3412
0
  if( result != 1 )
3413
0
  {
3414
0
    libcerror_error_set(
3415
0
     error,
3416
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3417
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3418
0
     "%s: unable to retrieve UTF-16 network share name string size.",
3419
0
     function );
3420
3421
0
    return( -1 );
3422
0
  }
3423
0
  result = 0;
3424
3425
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE ) != 0 )
3426
0
  {
3427
0
    if( location_information->network_share_name_size >= 4 )
3428
0
    {
3429
0
      if( ( ( location_information->network_share_name )[ location_information->network_share_name_size - 4 ] != (uint8_t) '\\' )
3430
0
       || ( ( location_information->network_share_name )[ location_information->network_share_name_size - 3 ] != 0 ) )
3431
0
      {
3432
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3433
0
        {
3434
0
          if( location_information->common_path_size > 2 )
3435
0
          {
3436
0
            result = 1;
3437
0
          }
3438
0
        }
3439
0
        else
3440
0
        {
3441
0
          if( location_information->common_path_size > 1 )
3442
0
          {
3443
0
            result = 1;
3444
0
          }
3445
0
        }
3446
0
      }
3447
0
    }
3448
0
  }
3449
0
  else
3450
0
  {
3451
0
    if( location_information->network_share_name_size >= 2 )
3452
0
    {
3453
0
      if( ( location_information->network_share_name )[ location_information->network_share_name_size - 2 ] != (uint8_t) '\\' )
3454
0
      {
3455
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3456
0
        {
3457
0
          if( location_information->common_path_size > 2 )
3458
0
          {
3459
0
            result = 1;
3460
0
          }
3461
0
        }
3462
0
        else
3463
0
        {
3464
0
          if( location_information->common_path_size > 1 )
3465
0
          {
3466
0
            result = 1;
3467
0
          }
3468
0
        }
3469
0
      }
3470
0
    }
3471
0
  }
3472
0
  if( result != 0 )
3473
0
  {
3474
0
    utf16_network_share_name_size += 1;
3475
0
  }
3476
0
  if( location_information->common_path != NULL )
3477
0
  {
3478
0
    if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3479
0
    {
3480
0
      result = libuna_utf16_string_size_from_utf16_stream(
3481
0
          location_information->common_path,
3482
0
          location_information->common_path_size,
3483
0
          LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
3484
0
          &utf16_common_path_size,
3485
0
          error );
3486
0
    }
3487
0
    else
3488
0
    {
3489
0
      result = libuna_utf16_string_size_from_byte_stream(
3490
0
          location_information->common_path,
3491
0
          location_information->common_path_size,
3492
0
          ascii_codepage,
3493
0
          &utf16_common_path_size,
3494
0
          error );
3495
0
    }
3496
0
    if( result != 1 )
3497
0
    {
3498
0
      libcerror_error_set(
3499
0
       error,
3500
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3501
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3502
0
       "%s: unable to retrieve UTF-16 common path string size.",
3503
0
       function );
3504
3505
0
      return( -1 );
3506
0
    }
3507
0
    utf16_network_share_name_size -= 1;
3508
0
  }
3509
0
  *utf16_string_size = utf16_network_share_name_size + utf16_common_path_size;
3510
3511
0
  return( 1 );
3512
0
}
3513
3514
/* Retrieves the UTF-16 encoded network path
3515
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
3516
 * The size should include the end of string character
3517
 * The network path is only set if the link refers to a file on a network share
3518
 * Returns 1 if successful, 0 if value is not available or -1 on error
3519
 */
3520
int liblnk_location_information_get_utf16_network_path(
3521
     liblnk_location_information_t *location_information,
3522
     int ascii_codepage,
3523
     uint16_t *utf16_string,
3524
     size_t utf16_string_size,
3525
     libcerror_error_t **error )
3526
0
{
3527
0
  static char *function = "liblnk_location_information_get_utf16_network_path";
3528
0
  size_t string_index   = 0;
3529
0
  int result            = 0;
3530
3531
0
  if( location_information == NULL )
3532
0
  {
3533
0
    libcerror_error_set(
3534
0
     error,
3535
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3536
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3537
0
     "%s: invalid location information.",
3538
0
     function );
3539
3540
0
    return( -1 );
3541
0
  }
3542
0
  if( utf16_string == NULL )
3543
0
  {
3544
0
    libcerror_error_set(
3545
0
     error,
3546
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3547
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3548
0
     "%s: invalid UTF-16 string.",
3549
0
     function );
3550
3551
0
    return( -1 );
3552
0
  }
3553
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
3554
0
  {
3555
0
    libcerror_error_set(
3556
0
     error,
3557
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3558
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3559
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
3560
0
     function );
3561
3562
0
    return( -1 );
3563
0
  }
3564
0
  if( ( location_information->flags & LIBLNK_LOCATION_FLAG_HAS_NETWORK_SHARE_INFORMATION ) == 0 )
3565
0
  {
3566
0
    return( 0 );
3567
0
  }
3568
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE ) != 0 )
3569
0
  {
3570
0
    result = libuna_utf16_string_with_index_copy_from_utf16_stream(
3571
0
        utf16_string,
3572
0
        utf16_string_size,
3573
0
        &string_index,
3574
0
        location_information->network_share_name,
3575
0
        location_information->network_share_name_size,
3576
0
        LIBUNA_ENDIAN_LITTLE,
3577
0
        error );
3578
0
  }
3579
0
  else
3580
0
  {
3581
0
    result = libuna_utf16_string_with_index_copy_from_byte_stream(
3582
0
        utf16_string,
3583
0
        utf16_string_size,
3584
0
        &string_index,
3585
0
        location_information->network_share_name,
3586
0
        location_information->network_share_name_size,
3587
0
        ascii_codepage,
3588
0
        error );
3589
0
  }
3590
0
  if( result != 1 )
3591
0
  {
3592
0
    libcerror_error_set(
3593
0
     error,
3594
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3595
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3596
0
     "%s: unable to set UTF-16 network share name string.",
3597
0
     function );
3598
3599
0
    return( -1 );
3600
0
  }
3601
0
  string_index--;
3602
3603
0
  result = 0;
3604
3605
0
  if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_NETWORK_SHARE_NAME_IS_UNICODE ) != 0 )
3606
0
  {
3607
0
    if( location_information->network_share_name_size >= 4 )
3608
0
    {
3609
0
      if( ( ( location_information->network_share_name )[ location_information->network_share_name_size - 4 ] != (uint8_t) '\\' )
3610
0
       || ( ( location_information->network_share_name )[ location_information->network_share_name_size - 3 ] != 0 ) )
3611
0
      {
3612
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3613
0
        {
3614
0
          if( location_information->common_path_size > 2 )
3615
0
          {
3616
0
            result = 1;
3617
0
          }
3618
0
        }
3619
0
        else
3620
0
        {
3621
0
          if( location_information->common_path_size > 1 )
3622
0
          {
3623
0
            result = 1;
3624
0
          }
3625
0
        }
3626
0
      }
3627
0
    }
3628
0
  }
3629
0
  else
3630
0
  {
3631
0
    if( location_information->network_share_name_size >= 2 )
3632
0
    {
3633
0
      if( ( location_information->network_share_name )[ location_information->network_share_name_size - 2 ] != (uint8_t) '\\' )
3634
0
      {
3635
0
        if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3636
0
        {
3637
0
          if( location_information->common_path_size > 2 )
3638
0
          {
3639
0
            result = 1;
3640
0
          }
3641
0
        }
3642
0
        else
3643
0
        {
3644
0
          if( location_information->common_path_size > 1 )
3645
0
          {
3646
0
            result = 1;
3647
0
          }
3648
0
        }
3649
0
      }
3650
0
    }
3651
0
  }
3652
0
  if( result != 0 )
3653
0
  {
3654
0
    if( ( string_index + 1 ) > utf16_string_size )
3655
0
    {
3656
0
      libcerror_error_set(
3657
0
       error,
3658
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3659
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
3660
0
       "%s: UTF-16 string value too small.",
3661
0
       function );
3662
3663
0
      return( -1 );
3664
0
    }
3665
0
    utf16_string[ string_index++ ] = (uint16_t) '\\';
3666
0
  }
3667
0
  if( location_information->common_path != NULL )
3668
0
  {
3669
0
    if( ( location_information->string_flags & LIBLNK_LOCATION_INFORMATION_STRING_FLAG_COMMON_PATH_IS_UNICODE ) != 0 )
3670
0
    {
3671
0
      result = libuna_utf16_string_with_index_copy_from_utf16_stream(
3672
0
          utf16_string,
3673
0
          utf16_string_size,
3674
0
          &string_index,
3675
0
          location_information->common_path,
3676
0
          location_information->common_path_size,
3677
0
          LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
3678
0
          error );
3679
0
    }
3680
0
    else
3681
0
    {
3682
0
      result = libuna_utf16_string_with_index_copy_from_byte_stream(
3683
0
          utf16_string,
3684
0
          utf16_string_size,
3685
0
          &string_index,
3686
0
          location_information->common_path,
3687
0
          location_information->common_path_size,
3688
0
          ascii_codepage,
3689
0
          error );
3690
0
    }
3691
0
    if( result != 1 )
3692
0
    {
3693
0
      libcerror_error_set(
3694
0
       error,
3695
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3696
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3697
0
       "%s: unable to set UTF-16 common path string.",
3698
0
       function );
3699
3700
0
      return( -1 );
3701
0
    }
3702
0
  }
3703
0
  return( 1 );
3704
0
}
3705