Coverage Report

Created: 2025-06-13 07:22

/src/liblnk/liblnk/liblnk_file.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File functions
3
 *
4
 * Copyright (C) 2009-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <narrow_string.h>
25
#include <types.h>
26
#include <wide_string.h>
27
28
#include "liblnk_codepage.h"
29
#include "liblnk_data_block.h"
30
#include "liblnk_data_string.h"
31
#include "liblnk_debug.h"
32
#include "liblnk_definitions.h"
33
#include "liblnk_distributed_link_tracking_data_block.h"
34
#include "liblnk_file.h"
35
#include "liblnk_file_header.h"
36
#include "liblnk_io_handle.h"
37
#include "liblnk_known_folder_location.h"
38
#include "liblnk_libbfio.h"
39
#include "liblnk_libcdata.h"
40
#include "liblnk_libcerror.h"
41
#include "liblnk_libcnotify.h"
42
#include "liblnk_libfwps.h"
43
#include "liblnk_libuna.h"
44
#include "liblnk_link_target_identifier.h"
45
#include "liblnk_location_information.h"
46
#include "liblnk_special_folder_location.h"
47
#include "liblnk_strings_data_block.h"
48
#include "liblnk_types.h"
49
50
/* Creates a file
51
 * Make sure the value file is referencing, is set to NULL
52
 * Returns 1 if successful or -1 on error
53
 */
54
int liblnk_file_initialize(
55
     liblnk_file_t **file,
56
     libcerror_error_t **error )
57
2.40k
{
58
2.40k
  liblnk_internal_file_t *internal_file = NULL;
59
2.40k
  static char *function                 = "liblnk_file_initialize";
60
61
2.40k
  if( file == NULL )
62
0
  {
63
0
    libcerror_error_set(
64
0
     error,
65
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
66
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
67
0
     "%s: invalid file.",
68
0
     function );
69
70
0
    return( -1 );
71
0
  }
72
2.40k
  if( *file != NULL )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
77
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
78
0
     "%s: invalid file value already set.",
79
0
     function );
80
81
0
    return( -1 );
82
0
  }
83
2.40k
  internal_file = memory_allocate_structure(
84
2.40k
                   liblnk_internal_file_t );
85
86
2.40k
  if( internal_file == NULL )
87
0
  {
88
0
    libcerror_error_set(
89
0
     error,
90
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
91
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
92
0
     "%s: unable to create file.",
93
0
     function );
94
95
0
    goto on_error;
96
0
  }
97
2.40k
  if( memory_set(
98
2.40k
       internal_file,
99
2.40k
       0,
100
2.40k
       sizeof( liblnk_internal_file_t ) ) == NULL )
101
0
  {
102
0
    libcerror_error_set(
103
0
     error,
104
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
105
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
106
0
     "%s: unable to clear file.",
107
0
     function );
108
109
0
    memory_free(
110
0
     internal_file );
111
112
0
    return( -1 );
113
0
  }
114
2.40k
  if( liblnk_io_handle_initialize(
115
2.40k
       &( internal_file->io_handle ),
116
2.40k
       error ) != 1 )
117
0
  {
118
0
    libcerror_error_set(
119
0
     error,
120
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
121
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
122
0
     "%s: unable to create IO handle.",
123
0
     function );
124
125
0
    goto on_error;
126
0
  }
127
2.40k
  if( libcdata_array_initialize(
128
2.40k
       &( internal_file->data_blocks_array ),
129
2.40k
       0,
130
2.40k
       error ) != 1 )
131
0
  {
132
0
    libcerror_error_set(
133
0
     error,
134
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
135
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
136
0
     "%s: unable to create data blocks array.",
137
0
     function );
138
139
0
    goto on_error;
140
0
  }
141
2.40k
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
142
2.40k
  if( libcthreads_read_write_lock_initialize(
143
2.40k
       &( internal_file->read_write_lock ),
144
2.40k
       error ) != 1 )
145
0
  {
146
0
    libcerror_error_set(
147
0
     error,
148
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
149
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
150
0
     "%s: unable to initialize read/write lock.",
151
0
     function );
152
153
0
    goto on_error;
154
0
  }
155
2.40k
#endif
156
2.40k
  *file = (liblnk_file_t *) internal_file;
157
158
2.40k
  return( 1 );
159
160
0
on_error:
161
0
  if( internal_file != NULL )
162
0
  {
163
0
    if( internal_file->io_handle != NULL )
164
0
    {
165
0
      liblnk_io_handle_free(
166
0
       &( internal_file->io_handle ),
167
0
       NULL );
168
0
    }
169
0
    memory_free(
170
0
     internal_file );
171
0
  }
172
0
  return( -1 );
173
2.40k
}
174
175
/* Frees a file
176
 * Returns 1 if successful or -1 on error
177
 */
178
int liblnk_file_free(
179
     liblnk_file_t **file,
180
     libcerror_error_t **error )
181
2.40k
{
182
2.40k
  liblnk_internal_file_t *internal_file = NULL;
183
2.40k
  static char *function                 = "liblnk_file_free";
184
2.40k
  int result                            = 1;
185
186
2.40k
  if( file == NULL )
187
0
  {
188
0
    libcerror_error_set(
189
0
     error,
190
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
191
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
192
0
     "%s: invalid file.",
193
0
     function );
194
195
0
    return( -1 );
196
0
  }
197
2.40k
  if( *file != NULL )
198
2.40k
  {
199
2.40k
    internal_file = (liblnk_internal_file_t *) *file;
200
201
2.40k
    if( internal_file->file_io_handle != NULL )
202
0
    {
203
0
      if( liblnk_file_close(
204
0
           *file,
205
0
           error ) != 0 )
206
0
      {
207
0
        libcerror_error_set(
208
0
         error,
209
0
         LIBCERROR_ERROR_DOMAIN_IO,
210
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
211
0
         "%s: unable to close file.",
212
0
         function );
213
214
0
        result = -1;
215
0
      }
216
0
    }
217
2.40k
    *file = NULL;
218
219
2.40k
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
220
2.40k
    if( libcthreads_read_write_lock_free(
221
2.40k
         &( internal_file->read_write_lock ),
222
2.40k
         error ) != 1 )
223
0
    {
224
0
      libcerror_error_set(
225
0
       error,
226
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
227
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
228
0
       "%s: unable to free read/write lock.",
229
0
       function );
230
231
0
      result = -1;
232
0
    }
233
2.40k
#endif
234
2.40k
    if( libcdata_array_free(
235
2.40k
         &( internal_file->data_blocks_array ),
236
2.40k
         (int(*)(intptr_t **, libcerror_error_t **)) &liblnk_internal_data_block_free,
237
2.40k
         error ) != 1 )
238
0
    {
239
0
      libcerror_error_set(
240
0
       error,
241
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
242
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
243
0
       "%s: unable to free data blocks array.",
244
0
       function );
245
246
0
      result = -1;
247
0
    }
248
2.40k
    if( liblnk_io_handle_free(
249
2.40k
         &( internal_file->io_handle ),
250
2.40k
         error ) != 1 )
251
0
    {
252
0
      libcerror_error_set(
253
0
       error,
254
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
255
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
256
0
       "%s: unable to free IO handle.",
257
0
       function );
258
259
0
      result = -1;
260
0
    }
261
2.40k
    memory_free(
262
2.40k
     internal_file );
263
2.40k
  }
264
2.40k
  return( result );
265
2.40k
}
266
267
/* Signals the file to abort its current activity
268
 * Returns 1 if successful or -1 on error
269
 */
270
int liblnk_file_signal_abort(
271
     liblnk_file_t *file,
272
     libcerror_error_t **error )
273
0
{
274
0
  liblnk_internal_file_t *internal_file = NULL;
275
0
  static char *function                 = "liblnk_file_signal_abort";
276
277
0
  if( file == NULL )
278
0
  {
279
0
    libcerror_error_set(
280
0
     error,
281
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
282
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
283
0
     "%s: invalid file.",
284
0
     function );
285
286
0
    return( -1 );
287
0
  }
288
0
  internal_file = (liblnk_internal_file_t *) file;
289
290
0
  if( internal_file->io_handle == NULL )
291
0
  {
292
0
    libcerror_error_set(
293
0
     error,
294
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
295
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
296
0
     "%s: invalid file - missing IO handle.",
297
0
     function );
298
299
0
    return( -1 );
300
0
  }
301
0
  internal_file->io_handle->abort = 1;
302
303
0
  return( 1 );
304
0
}
305
306
/* Opens a file
307
 * Returns 1 if successful or -1 on error
308
 */
309
int liblnk_file_open(
310
     liblnk_file_t *file,
311
     const char *filename,
312
     int access_flags,
313
     libcerror_error_t **error )
314
0
{
315
0
  libbfio_handle_t *file_io_handle      = NULL;
316
0
  liblnk_internal_file_t *internal_file = NULL;
317
0
  static char *function                 = "liblnk_file_open";
318
0
  size_t filename_length                = 0;
319
320
0
  if( file == NULL )
321
0
  {
322
0
    libcerror_error_set(
323
0
     error,
324
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
325
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
326
0
     "%s: invalid file.",
327
0
     function );
328
329
0
    return( -1 );
330
0
  }
331
0
  internal_file = (liblnk_internal_file_t *) file;
332
333
0
  if( filename == NULL )
334
0
  {
335
0
    libcerror_error_set(
336
0
     error,
337
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
338
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
339
0
     "%s: invalid filename.",
340
0
     function );
341
342
0
    return( -1 );
343
0
  }
344
0
  if( ( ( access_flags & LIBLNK_ACCESS_FLAG_READ ) == 0 )
345
0
   && ( ( access_flags & LIBLNK_ACCESS_FLAG_WRITE ) == 0 ) )
346
0
  {
347
0
    libcerror_error_set(
348
0
     error,
349
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
350
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
351
0
     "%s: unsupported accesss flags.",
352
0
     function );
353
354
0
    return( -1 );
355
0
  }
356
0
  if( ( access_flags & LIBLNK_ACCESS_FLAG_WRITE ) != 0 )
357
0
  {
358
0
    libcerror_error_set(
359
0
     error,
360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
362
0
     "%s: write access currently not supported.",
363
0
     function );
364
365
0
    return( -1 );
366
0
  }
367
0
  if( libbfio_file_initialize(
368
0
       &file_io_handle,
369
0
       error ) != 1 )
370
0
  {
371
0
    libcerror_error_set(
372
0
     error,
373
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
374
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
375
0
     "%s: unable to create file IO handle.",
376
0
     function );
377
378
0
    goto on_error;
379
0
  }
380
#if defined( HAVE_DEBUG_OUTPUT )
381
  if( libbfio_handle_set_track_offsets_read(
382
       file_io_handle,
383
       1,
384
       error ) != 1 )
385
  {
386
                libcerror_error_set(
387
                 error,
388
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
389
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
390
                 "%s: unable to set track offsets read in file IO handle.",
391
                 function );
392
393
    goto on_error;
394
  }
395
#endif
396
0
  filename_length = narrow_string_length(
397
0
                     filename );
398
399
0
  if( libbfio_file_set_name(
400
0
       file_io_handle,
401
0
       filename,
402
0
       filename_length + 1,
403
0
       error ) != 1 )
404
0
  {
405
0
                libcerror_error_set(
406
0
                 error,
407
0
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
408
0
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
409
0
                 "%s: unable to set filename in file IO handle.",
410
0
                 function );
411
412
0
                goto on_error;
413
0
  }
414
0
  if( liblnk_file_open_file_io_handle(
415
0
       file,
416
0
       file_io_handle,
417
0
       access_flags,
418
0
       error ) != 1 )
419
0
  {
420
0
    libcerror_error_set(
421
0
     error,
422
0
     LIBCERROR_ERROR_DOMAIN_IO,
423
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
424
0
     "%s: unable to open file: %s.",
425
0
     function,
426
0
     filename );
427
428
0
                goto on_error;
429
0
  }
430
0
  internal_file->file_io_handle_created_in_library = 1;
431
432
0
  return( 1 );
433
434
0
on_error:
435
0
  if( file_io_handle != NULL )
436
0
  {
437
0
    libbfio_handle_free(
438
0
     &file_io_handle,
439
0
     NULL );
440
0
  }
441
0
  return( -1 );
442
0
}
443
444
#if defined( HAVE_WIDE_CHARACTER_TYPE )
445
446
/* Opens a file
447
 * Returns 1 if successful or -1 on error
448
 */
449
int liblnk_file_open_wide(
450
     liblnk_file_t *file,
451
     const wchar_t *filename,
452
     int access_flags,
453
     libcerror_error_t **error )
454
{
455
  libbfio_handle_t *file_io_handle      = NULL;
456
  liblnk_internal_file_t *internal_file = NULL;
457
  static char *function                 = "liblnk_file_open_wide";
458
  size_t filename_length                = 0;
459
460
  if( file == NULL )
461
  {
462
    libcerror_error_set(
463
     error,
464
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
465
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
466
     "%s: invalid file.",
467
     function );
468
469
    return( -1 );
470
  }
471
  internal_file = (liblnk_internal_file_t *) file;
472
473
  if( filename == NULL )
474
  {
475
    libcerror_error_set(
476
     error,
477
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
478
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
479
     "%s: invalid filename.",
480
     function );
481
482
    return( -1 );
483
  }
484
  if( ( ( access_flags & LIBLNK_ACCESS_FLAG_READ ) == 0 )
485
   && ( ( access_flags & LIBLNK_ACCESS_FLAG_WRITE ) == 0 ) )
486
  {
487
    libcerror_error_set(
488
     error,
489
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
490
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
491
     "%s: unsupported access flags.",
492
     function );
493
494
    return( -1 );
495
  }
496
  if( ( access_flags & LIBLNK_ACCESS_FLAG_WRITE ) != 0 )
497
  {
498
    libcerror_error_set(
499
     error,
500
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
501
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
502
     "%s: write access currently not supported.",
503
     function );
504
505
    return( -1 );
506
  }
507
  if( libbfio_file_initialize(
508
       &file_io_handle,
509
       error ) != 1 )
510
  {
511
    libcerror_error_set(
512
     error,
513
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
514
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
515
     "%s: unable to create file IO handle.",
516
     function );
517
518
    goto on_error;
519
  }
520
#if defined( HAVE_DEBUG_OUTPUT )
521
  if( libbfio_handle_set_track_offsets_read(
522
       file_io_handle,
523
       1,
524
       error ) != 1 )
525
  {
526
                libcerror_error_set(
527
                 error,
528
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
529
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
530
                 "%s: unable to set track offsets read in file IO handle.",
531
                 function );
532
533
    goto on_error;
534
  }
535
#endif
536
  filename_length = wide_string_length(
537
                     filename );
538
539
  if( libbfio_file_set_name_wide(
540
       file_io_handle,
541
       filename,
542
       filename_length + 1,
543
       error ) != 1 )
544
  {
545
                libcerror_error_set(
546
                 error,
547
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
548
                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
549
                 "%s: unable to set filename in file IO handle.",
550
                 function );
551
552
    goto on_error;
553
  }
554
  if( liblnk_file_open_file_io_handle(
555
       file,
556
       file_io_handle,
557
       access_flags,
558
       error ) != 1 )
559
  {
560
    libcerror_error_set(
561
     error,
562
     LIBCERROR_ERROR_DOMAIN_IO,
563
     LIBCERROR_IO_ERROR_OPEN_FAILED,
564
     "%s: unable to open file: %ls.",
565
     function,
566
     filename );
567
568
    goto on_error;
569
  }
570
  internal_file->file_io_handle_created_in_library = 1;
571
572
  return( 1 );
573
574
on_error:
575
  if( file_io_handle != NULL )
576
  {
577
    libbfio_handle_free(
578
     &file_io_handle,
579
     NULL );
580
  }
581
  return( -1 );
582
}
583
584
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
585
586
/* Opens a file using a Basic File IO (bfio) handle
587
 * Returns 1 if successful or -1 on error
588
 */
589
int liblnk_file_open_file_io_handle(
590
     liblnk_file_t *file,
591
     libbfio_handle_t *file_io_handle,
592
     int access_flags,
593
     libcerror_error_t **error )
594
2.40k
{
595
2.40k
  liblnk_internal_file_t *internal_file    = NULL;
596
2.40k
  static char *function                    = "liblnk_file_open_file_io_handle";
597
2.40k
  uint8_t file_io_handle_opened_in_library = 0;
598
2.40k
  int bfio_access_flags                    = 0;
599
2.40k
  int file_io_handle_is_open               = 0;
600
601
2.40k
  if( file == NULL )
602
0
  {
603
0
    libcerror_error_set(
604
0
     error,
605
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
606
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
607
0
     "%s: invalid file.",
608
0
     function );
609
610
0
    return( -1 );
611
0
  }
612
2.40k
  internal_file = (liblnk_internal_file_t *) file;
613
614
2.40k
  if( internal_file->file_io_handle != NULL )
615
0
  {
616
0
    libcerror_error_set(
617
0
     error,
618
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
619
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
620
0
     "%s: invalid file - file IO handle already set.",
621
0
     function );
622
623
0
    return( -1 );
624
0
  }
625
2.40k
  if( file_io_handle == NULL )
626
0
  {
627
0
    libcerror_error_set(
628
0
     error,
629
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
630
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
631
0
     "%s: invalid file IO handle.",
632
0
     function );
633
634
0
    return( -1 );
635
0
  }
636
2.40k
  if( ( ( access_flags & LIBLNK_ACCESS_FLAG_READ ) == 0 )
637
2.40k
   && ( ( access_flags & LIBLNK_ACCESS_FLAG_WRITE ) == 0 ) )
638
0
  {
639
0
    libcerror_error_set(
640
0
     error,
641
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
642
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
643
0
     "%s: unsupported access flags.",
644
0
     function );
645
646
0
    return( -1 );
647
0
  }
648
2.40k
  if( ( access_flags & LIBLNK_ACCESS_FLAG_WRITE ) != 0 )
649
0
  {
650
0
    libcerror_error_set(
651
0
     error,
652
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
653
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
654
0
     "%s: write access currently not supported.",
655
0
     function );
656
657
0
    return( -1 );
658
0
  }
659
2.40k
  if( ( access_flags & LIBLNK_ACCESS_FLAG_READ ) != 0 )
660
2.40k
  {
661
2.40k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
662
2.40k
  }
663
2.40k
  file_io_handle_is_open = libbfio_handle_is_open(
664
2.40k
                            file_io_handle,
665
2.40k
                            error );
666
667
2.40k
  if( file_io_handle_is_open == -1 )
668
0
  {
669
0
    libcerror_error_set(
670
0
     error,
671
0
     LIBCERROR_ERROR_DOMAIN_IO,
672
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
673
0
     "%s: unable to open file.",
674
0
     function );
675
676
0
    goto on_error;
677
0
  }
678
2.40k
  else if( file_io_handle_is_open == 0 )
679
2.40k
  {
680
2.40k
    if( libbfio_handle_open(
681
2.40k
         file_io_handle,
682
2.40k
         bfio_access_flags,
683
2.40k
         error ) != 1 )
684
0
    {
685
0
      libcerror_error_set(
686
0
       error,
687
0
       LIBCERROR_ERROR_DOMAIN_IO,
688
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
689
0
       "%s: unable to open file IO handle.",
690
0
       function );
691
692
0
      goto on_error;
693
0
    }
694
2.40k
    file_io_handle_opened_in_library = 1;
695
2.40k
  }
696
2.40k
  if( liblnk_internal_file_open_read(
697
2.40k
       internal_file,
698
2.40k
       file_io_handle,
699
2.40k
       error ) != 1 )
700
1.90k
  {
701
1.90k
    libcerror_error_set(
702
1.90k
     error,
703
1.90k
     LIBCERROR_ERROR_DOMAIN_IO,
704
1.90k
     LIBCERROR_IO_ERROR_READ_FAILED,
705
1.90k
     "%s: unable to read from file IO handle.",
706
1.90k
     function );
707
708
1.90k
    goto on_error;
709
1.90k
  }
710
501
  internal_file->file_io_handle                   = file_io_handle;
711
501
  internal_file->file_io_handle_opened_in_library = file_io_handle_opened_in_library;
712
713
501
  return( 1 );
714
715
1.90k
on_error:
716
1.90k
  if( ( file_io_handle_is_open == 0 )
717
1.90k
   && ( file_io_handle_opened_in_library != 0 ) )
718
1.90k
  {
719
1.90k
    libbfio_handle_close(
720
1.90k
     file_io_handle,
721
1.90k
     error );
722
1.90k
  }
723
1.90k
  return( -1 );
724
2.40k
}
725
726
/* Closes a file
727
 * Returns 0 if successful or -1 on error
728
 */
729
int liblnk_file_close(
730
     liblnk_file_t *file,
731
     libcerror_error_t **error )
732
501
{
733
501
  liblnk_internal_file_t *internal_file = NULL;
734
501
  static char *function                 = "liblnk_file_close";
735
501
  int result                            = 0;
736
737
501
  if( file == NULL )
738
0
  {
739
0
    libcerror_error_set(
740
0
     error,
741
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
742
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
743
0
     "%s: invalid file.",
744
0
     function );
745
746
0
    return( -1 );
747
0
  }
748
501
  internal_file = (liblnk_internal_file_t *) file;
749
750
501
  if( internal_file->file_io_handle == NULL )
751
0
  {
752
0
    libcerror_error_set(
753
0
     error,
754
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
755
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
756
0
     "%s: invalid file - missing file IO handle.",
757
0
     function );
758
759
0
    return( -1 );
760
0
  }
761
#if defined( HAVE_DEBUG_OUTPUT )
762
  if( libcnotify_verbose != 0 )
763
  {
764
    if( internal_file->file_io_handle_created_in_library != 0 )
765
    {
766
      if( liblnk_debug_print_read_offsets(
767
           internal_file->file_io_handle,
768
           error ) != 1 )
769
      {
770
        libcerror_error_set(
771
         error,
772
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
773
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
774
         "%s: unable to print the read offsets.",
775
         function );
776
777
        result = -1;
778
      }
779
    }
780
  }
781
#endif
782
501
  if( internal_file->file_io_handle_opened_in_library != 0 )
783
501
  {
784
501
    if( libbfio_handle_close(
785
501
         internal_file->file_io_handle,
786
501
         error ) != 0 )
787
0
    {
788
0
      libcerror_error_set(
789
0
       error,
790
0
       LIBCERROR_ERROR_DOMAIN_IO,
791
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
792
0
       "%s: unable to close file IO handle.",
793
0
       function );
794
795
0
      result = -1;
796
0
    }
797
501
    internal_file->file_io_handle_opened_in_library = 0;
798
501
  }
799
501
  if( internal_file->file_io_handle_created_in_library != 0 )
800
0
  {
801
0
    if( libbfio_handle_free(
802
0
         &( internal_file->file_io_handle ),
803
0
         error ) != 1 )
804
0
    {
805
0
      libcerror_error_set(
806
0
       error,
807
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
808
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
809
0
       "%s: unable to free file IO handle.",
810
0
       function );
811
812
0
      result = -1;
813
0
    }
814
0
    internal_file->file_io_handle_created_in_library = 0;
815
0
  }
816
501
  internal_file->file_io_handle = NULL;
817
818
501
  if( liblnk_io_handle_clear(
819
501
       internal_file->io_handle,
820
501
       error ) != 1 )
821
0
  {
822
0
    libcerror_error_set(
823
0
     error,
824
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
825
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
826
0
     "%s: unable to clear IO handle.",
827
0
     function );
828
829
0
    result = -1;
830
0
  }
831
501
  if( internal_file->file_information != NULL )
832
501
  {
833
501
    if( liblnk_file_header_free(
834
501
         &( internal_file->file_information ),
835
501
         error ) != 1 )
836
0
    {
837
0
      libcerror_error_set(
838
0
       error,
839
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
840
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
841
0
       "%s: unable to free file information.",
842
0
       function );
843
844
0
      result = -1;
845
0
    }
846
501
  }
847
501
  if( internal_file->link_target_identifier != NULL )
848
32
  {
849
32
    if( liblnk_link_target_identifier_free(
850
32
         &( internal_file->link_target_identifier ),
851
32
         error ) != 1 )
852
0
    {
853
0
      libcerror_error_set(
854
0
       error,
855
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
856
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
857
0
       "%s: unable to free link target identifier.",
858
0
       function );
859
860
0
      result = -1;
861
0
    }
862
32
  }
863
501
  if( internal_file->location_information != NULL )
864
24
  {
865
24
    if( liblnk_location_information_free(
866
24
         &( internal_file->location_information ),
867
24
         error ) != 1 )
868
0
    {
869
0
      libcerror_error_set(
870
0
       error,
871
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
872
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
873
0
       "%s: unable to free location information.",
874
0
       function );
875
876
0
      result = -1;
877
0
    }
878
24
  }
879
501
  if( internal_file->description != NULL )
880
38
  {
881
38
    if( liblnk_data_string_free(
882
38
         &( internal_file->description ),
883
38
         error ) != 1 )
884
0
    {
885
0
      libcerror_error_set(
886
0
       error,
887
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
888
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
889
0
       "%s: unable to free description.",
890
0
       function );
891
892
0
      result = -1;
893
0
    }
894
38
  }
895
501
  if( internal_file->relative_path != NULL )
896
35
  {
897
35
    if( liblnk_data_string_free(
898
35
         &( internal_file->relative_path ),
899
35
         error ) != 1 )
900
0
    {
901
0
      libcerror_error_set(
902
0
       error,
903
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
904
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
905
0
       "%s: unable to free relative path.",
906
0
       function );
907
908
0
      result = -1;
909
0
    }
910
35
  }
911
501
  if( internal_file->working_directory != NULL )
912
37
  {
913
37
    if( liblnk_data_string_free(
914
37
         &( internal_file->working_directory ),
915
37
         error ) != 1 )
916
0
    {
917
0
      libcerror_error_set(
918
0
       error,
919
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
920
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
921
0
       "%s: unable to free working directory.",
922
0
       function );
923
924
0
      result = -1;
925
0
    }
926
37
  }
927
501
  if( internal_file->command_line_arguments != NULL )
928
36
  {
929
36
    if( liblnk_data_string_free(
930
36
         &( internal_file->command_line_arguments ),
931
36
         error ) != 1 )
932
0
    {
933
0
      libcerror_error_set(
934
0
       error,
935
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
936
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
937
0
       "%s: unable to free command line arguments.",
938
0
       function );
939
940
0
      result = -1;
941
0
    }
942
36
  }
943
501
  if( internal_file->icon_location != NULL )
944
36
  {
945
36
    if( liblnk_data_string_free(
946
36
         &( internal_file->icon_location ),
947
36
         error ) != 1 )
948
0
    {
949
0
      libcerror_error_set(
950
0
       error,
951
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
952
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
953
0
       "%s: unable to free icon location.",
954
0
       function );
955
956
0
      result = -1;
957
0
    }
958
36
  }
959
501
  if( internal_file->special_folder_location != NULL )
960
41
  {
961
41
    if( liblnk_special_folder_location_free(
962
41
         &( internal_file->special_folder_location ),
963
41
         error ) != 1 )
964
0
    {
965
0
      libcerror_error_set(
966
0
       error,
967
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
968
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
969
0
       "%s: unable to free special folder location.",
970
0
       function );
971
972
0
      result = -1;
973
0
    }
974
41
  }
975
501
  if( internal_file->known_folder_location != NULL )
976
15
  {
977
15
    if( liblnk_known_folder_location_free(
978
15
         &( internal_file->known_folder_location ),
979
15
         error ) != 1 )
980
0
    {
981
0
      libcerror_error_set(
982
0
       error,
983
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
984
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
985
0
       "%s: unable to free known folder location.",
986
0
       function );
987
988
0
      result = -1;
989
0
    }
990
15
  }
991
501
  if( libcdata_array_empty(
992
501
       internal_file->data_blocks_array,
993
501
       (int(*)(intptr_t **, libcerror_error_t **)) &liblnk_internal_data_block_free,
994
501
       error ) != 1 )
995
0
  {
996
0
    libcerror_error_set(
997
0
     error,
998
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
999
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1000
0
     "%s: unable to empty data blocks array.",
1001
0
     function );
1002
1003
0
    result = -1;
1004
0
  }
1005
501
  internal_file->environment_variables_location_data_block = NULL;
1006
501
  internal_file->distributed_link_tracking_data_block      = NULL;
1007
1008
501
  return( result );
1009
501
}
1010
1011
/* Opens a file for reading
1012
 * Returns 1 if successful or -1 on error
1013
 */
1014
int liblnk_internal_file_open_read(
1015
     liblnk_internal_file_t *internal_file,
1016
     libbfio_handle_t *file_io_handle,
1017
     libcerror_error_t **error )
1018
2.40k
{
1019
2.40k
  static char *function     = "liblnk_internal_file_open_read";
1020
2.40k
  ssize_t read_count        = 0;
1021
2.40k
  off64_t file_offset       = 0;
1022
1023
#if defined( HAVE_DEBUG_OUTPUT )
1024
  uint8_t *trailing_data    = NULL;
1025
  size_t trailing_data_size = 0;
1026
#endif
1027
1028
2.40k
  if( internal_file == NULL )
1029
0
  {
1030
0
    libcerror_error_set(
1031
0
     error,
1032
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1033
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1034
0
     "%s: invalid file.",
1035
0
     function );
1036
1037
0
    return( -1 );
1038
0
  }
1039
2.40k
  if( internal_file->io_handle == NULL )
1040
0
  {
1041
0
    libcerror_error_set(
1042
0
     error,
1043
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1044
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1045
0
     "%s: invalid file - missing IO handle.",
1046
0
     function );
1047
1048
0
    return( -1 );
1049
0
  }
1050
2.40k
  if( internal_file->file_information != NULL )
1051
0
  {
1052
0
    libcerror_error_set(
1053
0
     error,
1054
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1055
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1056
0
     "%s: invalid file - file information value already set.",
1057
0
     function );
1058
1059
0
    return( -1 );
1060
0
  }
1061
2.40k
  if( internal_file->link_target_identifier != NULL )
1062
0
  {
1063
0
    libcerror_error_set(
1064
0
     error,
1065
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1066
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1067
0
     "%s: invalid file - link target identifier value already set.",
1068
0
     function );
1069
1070
0
    return( -1 );
1071
0
  }
1072
2.40k
  if( internal_file->location_information != NULL )
1073
0
  {
1074
0
    libcerror_error_set(
1075
0
     error,
1076
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1077
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1078
0
     "%s: invalid file - location information value already set.",
1079
0
     function );
1080
1081
0
    return( -1 );
1082
0
  }
1083
2.40k
  if( internal_file->description != NULL )
1084
0
  {
1085
0
    libcerror_error_set(
1086
0
     error,
1087
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1088
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1089
0
     "%s: invalid file - description value already set.",
1090
0
     function );
1091
1092
0
    return( -1 );
1093
0
  }
1094
2.40k
  if( internal_file->relative_path != NULL )
1095
0
  {
1096
0
    libcerror_error_set(
1097
0
     error,
1098
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1099
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1100
0
     "%s: invalid file - relative path value already set.",
1101
0
     function );
1102
1103
0
    return( -1 );
1104
0
  }
1105
2.40k
  if( internal_file->working_directory != NULL )
1106
0
  {
1107
0
    libcerror_error_set(
1108
0
     error,
1109
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1110
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1111
0
     "%s: invalid file - working directory value already set.",
1112
0
     function );
1113
1114
0
    return( -1 );
1115
0
  }
1116
2.40k
  if( internal_file->command_line_arguments != NULL )
1117
0
  {
1118
0
    libcerror_error_set(
1119
0
     error,
1120
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1121
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1122
0
     "%s: invalid file - command line arguments value already set.",
1123
0
     function );
1124
1125
0
    return( -1 );
1126
0
  }
1127
2.40k
  if( internal_file->icon_location != NULL )
1128
0
  {
1129
0
    libcerror_error_set(
1130
0
     error,
1131
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1132
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1133
0
     "%s: invalid file - icon location value already set.",
1134
0
     function );
1135
1136
0
    return( -1 );
1137
0
  }
1138
2.40k
  if( internal_file->special_folder_location != NULL )
1139
0
  {
1140
0
    libcerror_error_set(
1141
0
     error,
1142
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1143
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1144
0
     "%s: invalid file - special folder location value already set.",
1145
0
     function );
1146
1147
0
    return( -1 );
1148
0
  }
1149
2.40k
  if( internal_file->known_folder_location != NULL )
1150
0
  {
1151
0
    libcerror_error_set(
1152
0
     error,
1153
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1154
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1155
0
     "%s: invalid file - known folder location value already set.",
1156
0
     function );
1157
1158
0
    return( -1 );
1159
0
  }
1160
2.40k
  if( liblnk_file_header_initialize(
1161
2.40k
       &( internal_file->file_information ),
1162
2.40k
       error ) != 1 )
1163
0
  {
1164
0
    libcerror_error_set(
1165
0
     error,
1166
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1167
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1168
0
     "%s: unable to create file header.",
1169
0
     function );
1170
1171
0
    goto on_error;
1172
0
  }
1173
#if defined( HAVE_DEBUG_OUTPUT )
1174
  if( libcnotify_verbose != 0 )
1175
  {
1176
    libcnotify_printf(
1177
     "Reading file header:\n" );
1178
  }
1179
#endif
1180
2.40k
  if( libbfio_handle_get_size(
1181
2.40k
       file_io_handle,
1182
2.40k
       &( internal_file->io_handle->file_size ),
1183
2.40k
       error ) != 1 )
1184
0
  {
1185
0
    libcerror_error_set(
1186
0
     error,
1187
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1188
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1189
0
     "%s: unable to retrieve file size.",
1190
0
     function );
1191
1192
0
    goto on_error;
1193
0
  }
1194
2.40k
  if( liblnk_file_header_read_file_io_handle(
1195
2.40k
       internal_file->file_information,
1196
2.40k
       file_io_handle,
1197
2.40k
       0,
1198
2.40k
       error ) != 1 )
1199
187
  {
1200
187
    libcerror_error_set(
1201
187
     error,
1202
187
     LIBCERROR_ERROR_DOMAIN_IO,
1203
187
     LIBCERROR_IO_ERROR_READ_FAILED,
1204
187
     "%s: unable to read file header.",
1205
187
     function );
1206
1207
187
    goto on_error;
1208
187
  }
1209
2.21k
  file_offset = 76;
1210
1211
2.21k
  if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_IS_UNICODE ) != 0 )
1212
769
  {
1213
769
    internal_file->io_handle->is_unicode = 1;
1214
769
  }
1215
1.44k
  else
1216
1.44k
  {
1217
1.44k
    internal_file->io_handle->is_unicode = 0;
1218
1.44k
  }
1219
2.21k
  if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_LINK_TARGET_IDENTIFIER ) != 0 )
1220
92
  {
1221
92
    if( liblnk_link_target_identifier_initialize(
1222
92
         &( internal_file->link_target_identifier ),
1223
92
         error ) != 1 )
1224
0
    {
1225
0
      libcerror_error_set(
1226
0
       error,
1227
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1228
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1229
0
       "%s: unable to create link target identifier.",
1230
0
       function );
1231
1232
0
      goto on_error;
1233
0
    }
1234
#if defined( HAVE_DEBUG_OUTPUT )
1235
    if( libcnotify_verbose != 0 )
1236
    {
1237
      libcnotify_printf(
1238
       "Reading link target identifier:\n" );
1239
    }
1240
#endif
1241
92
    read_count = liblnk_link_target_identifier_read(
1242
92
                  internal_file->link_target_identifier,
1243
92
                  internal_file->io_handle,
1244
92
                  file_io_handle,
1245
92
                  file_offset,
1246
92
                  error );
1247
1248
92
    if( read_count <= -1 )
1249
33
    {
1250
33
      libcerror_error_set(
1251
33
       error,
1252
33
       LIBCERROR_ERROR_DOMAIN_IO,
1253
33
       LIBCERROR_IO_ERROR_READ_FAILED,
1254
33
       "%s: unable to read link target identifier.",
1255
33
       function );
1256
1257
33
      goto on_error;
1258
33
    }
1259
59
    file_offset += read_count;
1260
59
  }
1261
2.18k
  if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_LOCATION_INFORMATION ) != 0 )
1262
1.53k
  {
1263
1.53k
    if( liblnk_location_information_initialize(
1264
1.53k
         &( internal_file->location_information ),
1265
1.53k
         error ) != 1 )
1266
0
    {
1267
0
      libcerror_error_set(
1268
0
       error,
1269
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1270
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1271
0
       "%s: unable to create location information.",
1272
0
       function );
1273
1274
0
      goto on_error;
1275
0
    }
1276
#if defined( HAVE_DEBUG_OUTPUT )
1277
    if( libcnotify_verbose != 0 )
1278
    {
1279
      libcnotify_printf(
1280
       "Reading location information:\n" );
1281
    }
1282
#endif
1283
1.53k
    read_count = liblnk_location_information_read(
1284
1.53k
                  internal_file->location_information,
1285
1.53k
                  internal_file->io_handle,
1286
1.53k
                  file_io_handle,
1287
1.53k
                  file_offset,
1288
1.53k
                  error );
1289
1290
1.53k
    if( read_count <= -1 )
1291
1.35k
    {
1292
1.35k
      libcerror_error_set(
1293
1.35k
       error,
1294
1.35k
       LIBCERROR_ERROR_DOMAIN_IO,
1295
1.35k
       LIBCERROR_IO_ERROR_READ_FAILED,
1296
1.35k
       "%s: unable to read location information.",
1297
1.35k
       function );
1298
1299
1.35k
      goto on_error;
1300
1.35k
    }
1301
176
    file_offset += read_count;
1302
176
  }
1303
829
  if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_DESCRIPTION_STRING ) != 0 )
1304
188
  {
1305
188
    if( liblnk_data_string_initialize(
1306
188
         &( internal_file->description ),
1307
188
         error ) != 1 )
1308
0
    {
1309
0
      libcerror_error_set(
1310
0
       error,
1311
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1312
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1313
0
       "%s: unable to create description.",
1314
0
       function );
1315
1316
0
      goto on_error;
1317
0
    }
1318
#if defined( HAVE_DEBUG_OUTPUT )
1319
    if( libcnotify_verbose != 0 )
1320
    {
1321
      libcnotify_printf(
1322
       "Reading description data string:\n" );
1323
    }
1324
#endif
1325
188
    if( liblnk_data_string_read_file_io_handle(
1326
188
         internal_file->description,
1327
188
         internal_file->io_handle,
1328
188
         file_io_handle,
1329
188
         file_offset,
1330
188
         0,
1331
188
         error ) != 1 )
1332
130
    {
1333
130
      libcerror_error_set(
1334
130
       error,
1335
130
       LIBCERROR_ERROR_DOMAIN_IO,
1336
130
       LIBCERROR_IO_ERROR_READ_FAILED,
1337
130
       "%s: unable to read description data string.",
1338
130
       function );
1339
1340
130
      goto on_error;
1341
130
    }
1342
58
    file_offset += 2 + internal_file->description->data_size;
1343
58
  }
1344
699
  if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_RELATIVE_PATH_STRING ) != 0 )
1345
79
  {
1346
79
    if( liblnk_data_string_initialize(
1347
79
         &( internal_file->relative_path ),
1348
79
         error ) != 1 )
1349
0
    {
1350
0
      libcerror_error_set(
1351
0
       error,
1352
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1353
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1354
0
       "%s: unable to create relative path.",
1355
0
       function );
1356
1357
0
      goto on_error;
1358
0
    }
1359
#if defined( HAVE_DEBUG_OUTPUT )
1360
    if( libcnotify_verbose != 0 )
1361
    {
1362
      libcnotify_printf(
1363
       "Reading relative path data string:\n" );
1364
    }
1365
#endif
1366
79
    if( liblnk_data_string_read_file_io_handle(
1367
79
         internal_file->relative_path,
1368
79
         internal_file->io_handle,
1369
79
         file_io_handle,
1370
79
         file_offset,
1371
79
         LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1372
79
         error ) != 1 )
1373
29
    {
1374
29
      libcerror_error_set(
1375
29
       error,
1376
29
       LIBCERROR_ERROR_DOMAIN_IO,
1377
29
       LIBCERROR_IO_ERROR_READ_FAILED,
1378
29
       "%s: unable to read relative path data string.",
1379
29
       function );
1380
1381
29
      goto on_error;
1382
29
    }
1383
50
    file_offset += 2 + internal_file->relative_path->data_size;
1384
50
  }
1385
670
  if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_WORKING_DIRECTORY_STRING ) != 0 )
1386
59
  {
1387
59
    if( liblnk_data_string_initialize(
1388
59
         &( internal_file->working_directory ),
1389
59
         error ) != 1 )
1390
0
    {
1391
0
      libcerror_error_set(
1392
0
       error,
1393
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1394
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1395
0
       "%s: unable to create working directory.",
1396
0
       function );
1397
1398
0
      goto on_error;
1399
0
    }
1400
#if defined( HAVE_DEBUG_OUTPUT )
1401
    if( libcnotify_verbose != 0 )
1402
    {
1403
      libcnotify_printf(
1404
       "Reading working directory data string:\n" );
1405
    }
1406
#endif
1407
59
    if( liblnk_data_string_read_file_io_handle(
1408
59
         internal_file->working_directory,
1409
59
         internal_file->io_handle,
1410
59
         file_io_handle,
1411
59
         file_offset,
1412
59
         LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1413
59
         error ) != 1 )
1414
14
    {
1415
14
      libcerror_error_set(
1416
14
       error,
1417
14
       LIBCERROR_ERROR_DOMAIN_IO,
1418
14
       LIBCERROR_IO_ERROR_READ_FAILED,
1419
14
       "%s: unable to read working directory data string.",
1420
14
       function );
1421
1422
14
      goto on_error;
1423
14
    }
1424
45
    file_offset += 2 + internal_file->working_directory->data_size;
1425
45
  }
1426
656
  if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_COMMAND_LINE_ARGUMENTS_STRING ) != 0 )
1427
57
  {
1428
57
    if( liblnk_data_string_initialize(
1429
57
         &( internal_file->command_line_arguments ),
1430
57
         error ) != 1 )
1431
0
    {
1432
0
      libcerror_error_set(
1433
0
       error,
1434
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1435
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1436
0
       "%s: unable to create command line arguments.",
1437
0
       function );
1438
1439
0
      goto on_error;
1440
0
    }
1441
#if defined( HAVE_DEBUG_OUTPUT )
1442
    if( libcnotify_verbose != 0 )
1443
    {
1444
      libcnotify_printf(
1445
       "Reading command line arguments data string:\n" );
1446
    }
1447
#endif
1448
57
    if( liblnk_data_string_read_file_io_handle(
1449
57
         internal_file->command_line_arguments,
1450
57
         internal_file->io_handle,
1451
57
         file_io_handle,
1452
57
         file_offset,
1453
57
         LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1454
57
         error ) != 1 )
1455
18
    {
1456
18
      libcerror_error_set(
1457
18
       error,
1458
18
       LIBCERROR_ERROR_DOMAIN_IO,
1459
18
       LIBCERROR_IO_ERROR_READ_FAILED,
1460
18
       "%s: unable to read command line arguments data string.",
1461
18
       function );
1462
1463
18
      goto on_error;
1464
18
    }
1465
39
    file_offset += 2 + internal_file->command_line_arguments->data_size;
1466
39
  }
1467
638
  if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_ICON_LOCATION_STRING ) != 0 )
1468
46
  {
1469
46
    if( liblnk_data_string_initialize(
1470
46
         &( internal_file->icon_location ),
1471
46
         error ) != 1 )
1472
0
    {
1473
0
      libcerror_error_set(
1474
0
       error,
1475
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1476
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1477
0
       "%s: unable to create icon location.",
1478
0
       function );
1479
1480
0
      goto on_error;
1481
0
    }
1482
#if defined( HAVE_DEBUG_OUTPUT )
1483
    if( libcnotify_verbose != 0 )
1484
    {
1485
      libcnotify_printf(
1486
       "Reading icon location data string:\n" );
1487
    }
1488
#endif
1489
46
    if( liblnk_data_string_read_file_io_handle(
1490
46
         internal_file->icon_location,
1491
46
         internal_file->io_handle,
1492
46
         file_io_handle,
1493
46
         file_offset,
1494
46
         LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1495
46
         error ) != 1 )
1496
10
    {
1497
10
      libcerror_error_set(
1498
10
       error,
1499
10
       LIBCERROR_ERROR_DOMAIN_IO,
1500
10
       LIBCERROR_IO_ERROR_READ_FAILED,
1501
10
       "%s: unable to read icon location data string.",
1502
10
       function );
1503
1504
10
      goto on_error;
1505
10
    }
1506
36
    file_offset += 2 + internal_file->icon_location->data_size;
1507
36
  }
1508
628
  if( file_offset < (off64_t) internal_file->io_handle->file_size )
1509
613
  {
1510
613
    read_count = liblnk_internal_file_read_extra_data_blocks(
1511
613
                  internal_file,
1512
613
                  file_io_handle,
1513
613
                  file_offset,
1514
613
                  error );
1515
1516
613
    if( read_count <= -1 )
1517
127
    {
1518
127
      libcerror_error_set(
1519
127
       error,
1520
127
       LIBCERROR_ERROR_DOMAIN_IO,
1521
127
       LIBCERROR_IO_ERROR_READ_FAILED,
1522
127
       "%s: unable to read extra data blocks.",
1523
127
       function );
1524
1525
127
      goto on_error;
1526
127
    }
1527
486
    file_offset += read_count;
1528
486
  }
1529
501
  internal_file->data_size = (size64_t) file_offset;
1530
1531
#if defined( HAVE_DEBUG_OUTPUT )
1532
  if( libcnotify_verbose != 0 )
1533
  {
1534
    if( file_offset < (off64_t) internal_file->io_handle->file_size )
1535
    {
1536
      trailing_data_size = (size_t) ( internal_file->io_handle->file_size - file_offset );
1537
1538
      if( trailing_data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
1539
      {
1540
        libcerror_error_set(
1541
         error,
1542
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1543
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1544
         "%s: invalid trailing data size value exceed maximum allocation size.",
1545
         function );
1546
1547
        goto on_error;
1548
      }
1549
      trailing_data = (uint8_t *) memory_allocate(
1550
                 sizeof( uint8_t ) * trailing_data_size );
1551
1552
      if( trailing_data == NULL )
1553
      {
1554
        libcerror_error_set(
1555
         error,
1556
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1557
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1558
         "%s: unable to create trailing data.",
1559
         function );
1560
1561
        goto on_error;
1562
      }
1563
      read_count = libbfio_handle_read_buffer(
1564
              file_io_handle,
1565
              trailing_data,
1566
              trailing_data_size,
1567
              error );
1568
1569
      if( read_count != (ssize_t) trailing_data_size )
1570
      {
1571
        libcerror_error_set(
1572
         error,
1573
         LIBCERROR_ERROR_DOMAIN_IO,
1574
         LIBCERROR_IO_ERROR_READ_FAILED,
1575
         "%s: unable to read trailing data.",
1576
         function );
1577
1578
        goto on_error;
1579
      }
1580
      file_offset += read_count;
1581
1582
      libcnotify_printf(
1583
       "%s: trailing data:\n",
1584
       function );
1585
      libcnotify_print_data(
1586
       trailing_data,
1587
       trailing_data_size,
1588
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1589
1590
      memory_free(
1591
       trailing_data );
1592
1593
      trailing_data = NULL;
1594
    }
1595
  }
1596
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1597
1598
501
  return( 1 );
1599
1600
1.90k
on_error:
1601
#if defined( HAVE_DEBUG_OUTPUT )
1602
  if( trailing_data != NULL )
1603
  {
1604
    memory_free(
1605
     trailing_data );
1606
  }
1607
#endif
1608
1.90k
  if( internal_file->known_folder_location != NULL )
1609
9
  {
1610
9
    liblnk_known_folder_location_free(
1611
9
     &( internal_file->known_folder_location ),
1612
9
     NULL );
1613
9
  }
1614
1.90k
  if( internal_file->special_folder_location != NULL )
1615
6
  {
1616
6
    liblnk_special_folder_location_free(
1617
6
     &( internal_file->special_folder_location ),
1618
6
     NULL );
1619
6
  }
1620
1.90k
  if( internal_file->icon_location != NULL )
1621
10
  {
1622
10
    liblnk_data_string_free(
1623
10
     &( internal_file->icon_location ),
1624
10
     NULL );
1625
10
  }
1626
1.90k
  if( internal_file->command_line_arguments != NULL )
1627
21
  {
1628
21
    liblnk_data_string_free(
1629
21
     &( internal_file->command_line_arguments ),
1630
21
     NULL );
1631
21
  }
1632
1.90k
  if( internal_file->working_directory != NULL )
1633
22
  {
1634
22
    liblnk_data_string_free(
1635
22
     &( internal_file->working_directory ),
1636
22
     NULL );
1637
22
  }
1638
1.90k
  if( internal_file->relative_path != NULL )
1639
44
  {
1640
44
    liblnk_data_string_free(
1641
44
     &( internal_file->relative_path ),
1642
44
     NULL );
1643
44
  }
1644
1.90k
  if( internal_file->description != NULL )
1645
150
  {
1646
150
    liblnk_data_string_free(
1647
150
     &( internal_file->description ),
1648
150
     NULL );
1649
150
  }
1650
1.90k
  if( internal_file->location_information != NULL )
1651
1.50k
  {
1652
1.50k
    liblnk_location_information_free(
1653
1.50k
     &( internal_file->location_information ),
1654
1.50k
     NULL );
1655
1.50k
  }
1656
1.90k
  if( internal_file->link_target_identifier != NULL )
1657
60
  {
1658
60
    liblnk_link_target_identifier_free(
1659
60
     &( internal_file->link_target_identifier ),
1660
60
     NULL );
1661
60
  }
1662
1.90k
  if( internal_file->file_information != NULL )
1663
1.90k
  {
1664
1.90k
    liblnk_file_header_free(
1665
1.90k
     &( internal_file->file_information ),
1666
1.90k
     NULL );
1667
1.90k
  }
1668
1.90k
  internal_file->data_size = (size64_t) file_offset;
1669
1670
1.90k
  return( -1 );
1671
628
}
1672
1673
/* Reads the extra data blocks
1674
 * Returns 1 if successful or -1 on error
1675
 */
1676
ssize_t liblnk_internal_file_read_extra_data_blocks(
1677
         liblnk_internal_file_t *internal_file,
1678
         libbfio_handle_t *file_io_handle,
1679
         off64_t file_offset,
1680
         libcerror_error_t **error )
1681
613
{
1682
613
  liblnk_data_block_t *data_block = NULL;
1683
613
  static char *function           = "liblnk_internal_file_read_extra_data_blocks";
1684
613
  ssize_t read_count              = 0;
1685
613
  uint32_t data_block_signature   = 0;
1686
613
  uint32_t data_block_size        = 0;
1687
613
  int entry_index                 = 0;
1688
613
  int result                      = 0;
1689
1690
#if defined( HAVE_DEBUG_OUTPUT )
1691
        libfwps_store_t *property_store = NULL;
1692
#endif
1693
1694
613
  if( internal_file == NULL )
1695
0
  {
1696
0
    libcerror_error_set(
1697
0
     error,
1698
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1699
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1700
0
     "%s: invalid file.",
1701
0
     function );
1702
1703
0
    return( -1 );
1704
0
  }
1705
613
  if( internal_file->io_handle == NULL )
1706
0
  {
1707
0
    libcerror_error_set(
1708
0
     error,
1709
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1710
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1711
0
     "%s: invalid file - missing IO handle.",
1712
0
     function );
1713
1714
0
    return( -1 );
1715
0
  }
1716
613
  if( internal_file->file_information == NULL )
1717
0
  {
1718
0
    libcerror_error_set(
1719
0
     error,
1720
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1721
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1722
0
     "%s: invalid file - missing file information.",
1723
0
     function );
1724
1725
0
    return( -1 );
1726
0
  }
1727
#if defined( HAVE_DEBUG_OUTPUT )
1728
  if( libcnotify_verbose != 0 )
1729
  {
1730
    libcnotify_printf(
1731
     "Reading extra data blocks:\n" );
1732
  }
1733
#endif
1734
400k
  while( file_offset < (off64_t) internal_file->io_handle->file_size )
1735
400k
  {
1736
400k
    if( liblnk_data_block_initialize(
1737
400k
         &data_block,
1738
400k
         error ) != 1 )
1739
0
    {
1740
0
      libcerror_error_set(
1741
0
       error,
1742
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1743
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1744
0
       "%s: unable to create data block.",
1745
0
       function );
1746
1747
0
      goto on_error;
1748
0
    }
1749
400k
    data_block_size = 0;
1750
1751
400k
    result = liblnk_data_block_read_file_io_handle(
1752
400k
              data_block,
1753
400k
              internal_file->io_handle,
1754
400k
              file_io_handle,
1755
400k
              file_offset,
1756
400k
              error );
1757
1758
400k
    if( result != 1 )
1759
181
    {
1760
181
      libcerror_error_set(
1761
181
       error,
1762
181
       LIBCERROR_ERROR_DOMAIN_IO,
1763
181
       LIBCERROR_IO_ERROR_READ_FAILED,
1764
181
       "%s: unable to read data block.",
1765
181
       function );
1766
1767
#if defined( HAVE_DEBUG_OUTPUT )
1768
      if( ( error != NULL )
1769
       && ( *error != NULL ) )
1770
      {
1771
        libcnotify_print_error_backtrace(
1772
         *error );
1773
      }
1774
#endif
1775
181
      libcerror_error_free(
1776
181
       error );
1777
1778
181
      internal_file->io_handle->flags |= LIBLNK_IO_HANDLE_FLAG_IS_CORRUPTED;
1779
181
    }
1780
400k
    else
1781
400k
    {
1782
400k
      if( liblnk_internal_data_block_get_size(
1783
400k
           (liblnk_internal_data_block_t *) data_block,
1784
400k
           &data_block_size,
1785
400k
           error ) != 1 )
1786
0
      {
1787
0
        libcerror_error_set(
1788
0
         error,
1789
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1790
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1791
0
         "%s: unable to retrieve data block size.",
1792
0
         function );
1793
1794
0
        goto on_error;
1795
0
      }
1796
400k
    }
1797
400k
    if( data_block_size == 0 )
1798
193
    {
1799
193
      if( liblnk_internal_data_block_free(
1800
193
           (liblnk_internal_data_block_t **) &data_block,
1801
193
           error ) != 1 )
1802
0
      {
1803
0
        libcerror_error_set(
1804
0
         error,
1805
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1806
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1807
0
         "%s: unable to free data block.",
1808
0
         function );
1809
1810
0
        goto on_error;
1811
0
      }
1812
193
      read_count += 4;
1813
1814
193
      break;
1815
193
    }
1816
400k
    if( liblnk_data_block_get_signature(
1817
400k
         data_block,
1818
400k
         &data_block_signature,
1819
400k
         error ) != 1 )
1820
0
    {
1821
0
      libcerror_error_set(
1822
0
       error,
1823
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1824
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1825
0
       "%s: unable to retrieve data block signature.",
1826
0
       function );
1827
1828
0
      goto on_error;
1829
0
    }
1830
400k
    file_offset += data_block_size;
1831
400k
    read_count  += data_block_size;
1832
1833
400k
    switch( data_block_signature )
1834
400k
    {
1835
461
      case LIBLNK_DATA_BLOCK_SIGNATURE_ENVIRONMENT_VARIABLES_LOCATION:
1836
#if defined( HAVE_DEBUG_OUTPUT )
1837
        if( libcnotify_verbose != 0 )
1838
        {
1839
          libcnotify_printf(
1840
           "Reading environment variables location data block:\n" );
1841
1842
          if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_ENVIRONMENT_VARIABLES_LOCATION_BLOCK ) == 0 )
1843
          {
1844
            libcnotify_printf(
1845
             "%s: environment variables location data block found but data flag was not set\n",
1846
             function );
1847
          }
1848
        }
1849
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1850
1851
461
        if( internal_file->environment_variables_location_data_block == NULL )
1852
33
        {
1853
33
          internal_file->environment_variables_location_data_block = data_block;
1854
33
        }
1855
461
        if( liblnk_strings_data_block_read(
1856
461
             data_block,
1857
461
             error ) != 1 )
1858
14
        {
1859
14
          libcerror_error_set(
1860
14
           error,
1861
14
           LIBCERROR_ERROR_DOMAIN_IO,
1862
14
           LIBCERROR_IO_ERROR_READ_FAILED,
1863
14
           "%s: unable to read strings in environment variables data block.",
1864
14
           function );
1865
1866
14
          goto on_error;
1867
14
        }
1868
447
        break;
1869
1870
558
      case LIBLNK_DATA_BLOCK_SIGNATURE_DISTRIBUTED_LINK_TRACKER_PROPERTIES:
1871
#if defined( HAVE_DEBUG_OUTPUT )
1872
        if( libcnotify_verbose != 0 )
1873
        {
1874
          libcnotify_printf(
1875
           "Reading distributed link tracker properties data block:\n" );
1876
1877
          if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_NO_DISTRIBUTED_LINK_TRACKING_DATA_BLOCK ) != 0 )
1878
          {
1879
            libcnotify_printf(
1880
             "%s: distributed link tracker properties data block found but data flag was not set\n",
1881
             function );
1882
          }
1883
        }
1884
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1885
1886
558
        if( internal_file->distributed_link_tracking_data_block == NULL )
1887
125
        {
1888
125
          internal_file->distributed_link_tracking_data_block = data_block;
1889
125
        }
1890
558
        if( liblnk_distributed_link_tracking_data_block_read(
1891
558
             data_block,
1892
558
             error ) != 1 )
1893
82
        {
1894
82
          libcerror_error_set(
1895
82
           error,
1896
82
           LIBCERROR_ERROR_DOMAIN_IO,
1897
82
           LIBCERROR_IO_ERROR_READ_FAILED,
1898
82
           "%s: unable to read distributed link tracking data block.",
1899
82
           function );
1900
1901
82
          goto on_error;
1902
82
        }
1903
476
        break;
1904
1905
476
      case LIBLNK_DATA_BLOCK_SIGNATURE_SPECIAL_FOLDER_LOCATION:
1906
#if defined( HAVE_DEBUG_OUTPUT )
1907
        if( libcnotify_verbose != 0 )
1908
        {
1909
          libcnotify_printf(
1910
           "Reading special folder location data block:\n" );
1911
        }
1912
#endif
1913
48
        if( liblnk_special_folder_location_initialize(
1914
48
             &( internal_file->special_folder_location ),
1915
48
             error ) != 1 )
1916
1
        {
1917
1
          libcerror_error_set(
1918
1
           error,
1919
1
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1920
1
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1921
1
           "%s: unable to create special folder location.",
1922
1
           function );
1923
1924
1
          goto on_error;
1925
1
        }
1926
47
        if( liblnk_special_folder_location_read_data_block(
1927
47
             internal_file->special_folder_location,
1928
47
             data_block,
1929
47
             error ) != 1 )
1930
5
        {
1931
5
          libcerror_error_set(
1932
5
           error,
1933
5
           LIBCERROR_ERROR_DOMAIN_IO,
1934
5
           LIBCERROR_IO_ERROR_READ_FAILED,
1935
5
           "%s: unable to read special folder location data block.",
1936
5
           function );
1937
1938
5
          goto on_error;
1939
5
        }
1940
42
        break;
1941
1942
221
      case LIBLNK_DATA_BLOCK_SIGNATURE_DARWIN_PROPERTIES:
1943
#if defined( HAVE_DEBUG_OUTPUT )
1944
        if( libcnotify_verbose != 0 )
1945
        {
1946
          libcnotify_printf(
1947
           "Reading darwin application identifier data block:\n" );
1948
1949
          if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_DARWIN_IDENTIFIER ) == 0 )
1950
          {
1951
            libcnotify_printf(
1952
             "%s: darwin application identifier data block found but data flag was not set\n",
1953
             function );
1954
          }
1955
        }
1956
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1957
1958
221
        if( liblnk_strings_data_block_read(
1959
221
             data_block,
1960
221
             error ) != 1 )
1961
11
        {
1962
11
          libcerror_error_set(
1963
11
           error,
1964
11
           LIBCERROR_ERROR_DOMAIN_IO,
1965
11
           LIBCERROR_IO_ERROR_READ_FAILED,
1966
11
           "%s: unable to read Darwin application identifier data block.",
1967
11
           function );
1968
1969
11
          goto on_error;
1970
11
        }
1971
210
        break;
1972
1973
1.34k
      case LIBLNK_DATA_BLOCK_SIGNATURE_ICON_LOCATION:
1974
#if defined( HAVE_DEBUG_OUTPUT )
1975
        if( libcnotify_verbose != 0 )
1976
        {
1977
          libcnotify_printf(
1978
           "Reading icon location data block:\n" );
1979
1980
          if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_ICON_LOCATION_BLOCK ) == 0 )
1981
          {
1982
            libcnotify_printf(
1983
             "%s: icon location data block found but data flag was not set\n",
1984
             function );
1985
          }
1986
        }
1987
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1988
1989
1.34k
        if( liblnk_strings_data_block_read(
1990
1.34k
             data_block,
1991
1.34k
             error ) != 1 )
1992
5
        {
1993
5
          libcerror_error_set(
1994
5
           error,
1995
5
           LIBCERROR_ERROR_DOMAIN_IO,
1996
5
           LIBCERROR_IO_ERROR_READ_FAILED,
1997
5
           "%s: unable to read icon location data block.",
1998
5
           function );
1999
2000
5
          goto on_error;
2001
5
        }
2002
1.33k
        break;
2003
2004
1.33k
      case LIBLNK_DATA_BLOCK_SIGNATURE_KNOWN_FOLDER_LOCATION:
2005
#if defined( HAVE_DEBUG_OUTPUT )
2006
        if( libcnotify_verbose != 0 )
2007
        {
2008
          libcnotify_printf(
2009
           "Reading known folder location data block:\n" );
2010
        }
2011
#endif
2012
25
        if( liblnk_known_folder_location_initialize(
2013
25
             &( internal_file->known_folder_location ),
2014
25
             error ) != 1 )
2015
1
        {
2016
1
          libcerror_error_set(
2017
1
           error,
2018
1
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2019
1
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2020
1
           "%s: unable to create known folder location.",
2021
1
           function );
2022
2023
1
          goto on_error;
2024
1
        }
2025
24
        if( liblnk_known_folder_location_read_data_block(
2026
24
             internal_file->known_folder_location,
2027
24
             data_block,
2028
24
             error ) != 1 )
2029
8
        {
2030
8
          libcerror_error_set(
2031
8
           error,
2032
8
           LIBCERROR_ERROR_DOMAIN_IO,
2033
8
           LIBCERROR_IO_ERROR_READ_FAILED,
2034
8
           "%s: unable to read known folder location data block.",
2035
8
           function );
2036
2037
8
          goto on_error;
2038
8
        }
2039
16
        break;
2040
2041
16
      case LIBLNK_DATA_BLOCK_SIGNATURE_METADATA_PROPERTY_STORE:
2042
#if defined( HAVE_DEBUG_OUTPUT )
2043
        if( libcnotify_verbose != 0 )
2044
        {
2045
          libcnotify_printf(
2046
           "Reading metadata property store data block:\n" );
2047
2048
          if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_METADATA_PROPERTY_STORE_DATA_BLOCK ) == 0 )
2049
          {
2050
            libcnotify_printf(
2051
             "%s: metadata property store data block found but data flag was not set\n",
2052
             function );
2053
          }
2054
        }
2055
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2056
2057
        /* TODO preserve information in file */
2058
2059
#if defined( HAVE_DEBUG_OUTPUT )
2060
        if( libcnotify_verbose != 0 )
2061
        {
2062
/* TODO add support for more than one store */
2063
          if( libfwps_store_initialize(
2064
               &property_store,
2065
               error ) != 1 )
2066
          {
2067
            libcerror_error_set(
2068
             error,
2069
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2070
             LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2071
             "%s: unable to create property store.",
2072
             function );
2073
2074
            goto on_error;
2075
          }
2076
          if( libfwps_store_copy_from_byte_stream(
2077
               property_store,
2078
               &( ( (liblnk_internal_data_block_t *) data_block )->data[ 4 ] ),
2079
               ( (liblnk_internal_data_block_t *) data_block )->data_size,
2080
               internal_file->io_handle->ascii_codepage,
2081
               error ) != 1 )
2082
          {
2083
            libcerror_error_set(
2084
             error,
2085
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2086
             LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2087
             "%s: unable to copy byte stream to property store.",
2088
             function );
2089
2090
            goto on_error;
2091
          }
2092
          if( libfwps_store_free(
2093
               &property_store,
2094
               error ) != 1 )
2095
          {
2096
            libcerror_error_set(
2097
             error,
2098
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2099
             LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2100
             "%s: unable to free property store.",
2101
             function );
2102
2103
            goto on_error;
2104
          }
2105
        }
2106
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2107
2108
0
        break;
2109
2110
397k
      default:
2111
#if defined( HAVE_DEBUG_OUTPUT )
2112
        if( libcnotify_verbose != 0 )
2113
        {
2114
          libcnotify_printf(
2115
           "%s: unsupported extra data block type: 0x%08" PRIx32 ".\n\n",
2116
           function,
2117
           data_block_signature );
2118
        }
2119
#endif
2120
397k
        break;
2121
400k
    }
2122
400k
    if( libcdata_array_append_entry(
2123
400k
         internal_file->data_blocks_array,
2124
400k
         &entry_index,
2125
400k
         (intptr_t *) data_block,
2126
400k
         error ) != 1 )
2127
0
    {
2128
0
      libcerror_error_set(
2129
0
       error,
2130
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2131
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2132
0
       "%s: unable to append data block to array.",
2133
0
       function );
2134
2135
0
      goto on_error;
2136
0
    }
2137
400k
    data_block = NULL;
2138
400k
  }
2139
486
  return( read_count );
2140
2141
127
on_error:
2142
#if defined( HAVE_DEBUG_OUTPUT )
2143
  if( property_store != NULL )
2144
  {
2145
    libfwps_store_free(
2146
     &property_store,
2147
     NULL );
2148
  }
2149
#endif
2150
127
  if( data_block != NULL )
2151
127
  {
2152
127
    liblnk_internal_data_block_free(
2153
127
     (liblnk_internal_data_block_t **) &data_block,
2154
127
     NULL );
2155
127
  }
2156
127
  libcdata_array_empty(
2157
127
   internal_file->data_blocks_array,
2158
127
   (int(*)(intptr_t **, libcerror_error_t **)) &liblnk_internal_data_block_free,
2159
127
   NULL );
2160
2161
127
  internal_file->environment_variables_location_data_block = NULL;
2162
127
  internal_file->distributed_link_tracking_data_block      = NULL;
2163
2164
127
  return( -1 );
2165
613
}
2166
2167
/* Retrieves the file ASCII codepage
2168
 * Returns 1 if successful or -1 on error
2169
 */
2170
int liblnk_file_get_ascii_codepage(
2171
     liblnk_file_t *file,
2172
     int *ascii_codepage,
2173
     libcerror_error_t **error )
2174
0
{
2175
0
  liblnk_internal_file_t *internal_file = NULL;
2176
0
  static char *function                 = "liblnk_file_get_ascii_codepage";
2177
2178
0
  if( file == NULL )
2179
0
  {
2180
0
    libcerror_error_set(
2181
0
     error,
2182
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2183
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2184
0
     "%s: invalid file.",
2185
0
     function );
2186
2187
0
    return( -1 );
2188
0
  }
2189
0
  internal_file = (liblnk_internal_file_t *) file;
2190
2191
0
  if( internal_file->io_handle == NULL )
2192
0
  {
2193
0
    libcerror_error_set(
2194
0
     error,
2195
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2196
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2197
0
     "%s: invalid file - missing IO handle.",
2198
0
     function );
2199
2200
0
    return( -1 );
2201
0
  }
2202
0
  if( ascii_codepage == NULL )
2203
0
  {
2204
0
    libcerror_error_set(
2205
0
     error,
2206
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2207
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2208
0
     "%s: invalid ASCII codepage.",
2209
0
     function );
2210
2211
0
    return( -1 );
2212
0
  }
2213
0
  *ascii_codepage = internal_file->io_handle->ascii_codepage;
2214
2215
0
  return( 1 );
2216
0
}
2217
2218
/* Sets the file ASCII codepage
2219
 * Returns 1 if successful or -1 on error
2220
 */
2221
int liblnk_file_set_ascii_codepage(
2222
     liblnk_file_t *file,
2223
     int ascii_codepage,
2224
     libcerror_error_t **error )
2225
0
{
2226
0
  liblnk_internal_file_t *internal_file = NULL;
2227
0
  static char *function                 = "liblnk_file_set_ascii_codepage";
2228
2229
0
  if( file == NULL )
2230
0
  {
2231
0
    libcerror_error_set(
2232
0
     error,
2233
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2234
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2235
0
     "%s: invalid file.",
2236
0
     function );
2237
2238
0
    return( -1 );
2239
0
  }
2240
0
  internal_file = (liblnk_internal_file_t *) file;
2241
2242
0
  if( internal_file->io_handle == NULL )
2243
0
  {
2244
0
    libcerror_error_set(
2245
0
     error,
2246
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2247
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2248
0
     "%s: invalid file - missing IO handle.",
2249
0
     function );
2250
2251
0
    return( -1 );
2252
0
  }
2253
0
  if( ( ascii_codepage != LIBLNK_CODEPAGE_ASCII )
2254
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_874 )
2255
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_932 )
2256
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_936 )
2257
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_949 )
2258
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_950 )
2259
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_1250 )
2260
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_1251 )
2261
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_1252 )
2262
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_1253 )
2263
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_1254 )
2264
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_1255 )
2265
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_1256 )
2266
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_1257 )
2267
0
   && ( ascii_codepage != LIBLNK_CODEPAGE_WINDOWS_1258 ) )
2268
0
  {
2269
0
    libcerror_error_set(
2270
0
     error,
2271
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2272
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2273
0
     "%s: unsupported ASCII codepage.",
2274
0
     function );
2275
2276
0
    return( -1 );
2277
0
  }
2278
0
  internal_file->io_handle->ascii_codepage = ascii_codepage;
2279
2280
0
  return( 1 );
2281
0
}
2282
2283
/* Determine if the file corrupted
2284
 * Returns 1 if corrupted, 0 if not or -1 on error
2285
 */
2286
int liblnk_file_is_corrupted(
2287
     liblnk_file_t *file,
2288
     libcerror_error_t **error )
2289
0
{
2290
0
  liblnk_internal_file_t *internal_file = NULL;
2291
0
  static char *function                 = "liblnk_file_is_corrupted";
2292
0
  int result                            = 0;
2293
2294
0
  if( file == NULL )
2295
0
  {
2296
0
    libcerror_error_set(
2297
0
     error,
2298
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2299
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2300
0
     "%s: invalid file.",
2301
0
     function );
2302
2303
0
    return( -1 );
2304
0
  }
2305
0
  internal_file = (liblnk_internal_file_t *) file;
2306
2307
0
  if( internal_file->io_handle == NULL )
2308
0
  {
2309
0
    libcerror_error_set(
2310
0
     error,
2311
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2312
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2313
0
     "%s: invalid file - missing IO handle.",
2314
0
     function );
2315
2316
0
    return( -1 );
2317
0
  }
2318
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2319
0
  if( libcthreads_read_write_lock_grab_for_read(
2320
0
       internal_file->read_write_lock,
2321
0
       error ) != 1 )
2322
0
  {
2323
0
    libcerror_error_set(
2324
0
     error,
2325
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2326
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2327
0
     "%s: unable to grab read/write lock for reading.",
2328
0
     function );
2329
2330
0
    return( -1 );
2331
0
  }
2332
0
#endif
2333
0
  if( ( internal_file->io_handle->flags & LIBLNK_IO_HANDLE_FLAG_IS_CORRUPTED ) != 0 )
2334
0
  {
2335
0
    result = 1;
2336
0
  }
2337
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2338
0
  if( libcthreads_read_write_lock_release_for_read(
2339
0
       internal_file->read_write_lock,
2340
0
       error ) != 1 )
2341
0
  {
2342
0
    libcerror_error_set(
2343
0
     error,
2344
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2345
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2346
0
     "%s: unable to release read/write lock for reading.",
2347
0
     function );
2348
2349
0
    return( -1 );
2350
0
  }
2351
0
#endif
2352
0
  return( result );
2353
0
}
2354
2355
/* -------------------------------------------------------------------------
2356
 * Link information functions
2357
 * ------------------------------------------------------------------------- */
2358
2359
/* Retrieves the data flags
2360
 * The data flags contain information about the available link information
2361
 * Returns 1 if successful or -1 on error
2362
 */
2363
int liblnk_file_get_data_flags(
2364
     liblnk_file_t *file,
2365
     uint32_t *data_flags,
2366
     libcerror_error_t **error )
2367
0
{
2368
0
  liblnk_internal_file_t *internal_file = NULL;
2369
0
  static char *function                 = "liblnk_file_get_data_flags";
2370
2371
0
  if( file == NULL )
2372
0
  {
2373
0
    libcerror_error_set(
2374
0
     error,
2375
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2376
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2377
0
     "%s: invalid file.",
2378
0
     function );
2379
2380
0
    return( -1 );
2381
0
  }
2382
0
  internal_file = (liblnk_internal_file_t *) file;
2383
2384
0
  if( internal_file->file_information == NULL )
2385
0
  {
2386
0
    libcerror_error_set(
2387
0
     error,
2388
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2389
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2390
0
     "%s: invalid file - missing file information.",
2391
0
     function );
2392
2393
0
    return( -1 );
2394
0
  }
2395
0
  if( data_flags == NULL )
2396
0
  {
2397
0
    libcerror_error_set(
2398
0
     error,
2399
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2400
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2401
0
     "%s: invalid data flags.",
2402
0
     function );
2403
2404
0
    return( -1 );
2405
0
  }
2406
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2407
0
  if( libcthreads_read_write_lock_grab_for_read(
2408
0
       internal_file->read_write_lock,
2409
0
       error ) != 1 )
2410
0
  {
2411
0
    libcerror_error_set(
2412
0
     error,
2413
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2414
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2415
0
     "%s: unable to grab read/write lock for reading.",
2416
0
     function );
2417
2418
0
    return( -1 );
2419
0
  }
2420
0
#endif
2421
0
  *data_flags = internal_file->file_information->data_flags;
2422
2423
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2424
0
  if( libcthreads_read_write_lock_release_for_read(
2425
0
       internal_file->read_write_lock,
2426
0
       error ) != 1 )
2427
0
  {
2428
0
    libcerror_error_set(
2429
0
     error,
2430
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2431
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2432
0
     "%s: unable to release read/write lock for reading.",
2433
0
     function );
2434
2435
0
    return( -1 );
2436
0
  }
2437
0
#endif
2438
0
  return( 1 );
2439
0
}
2440
2441
/* Retrieves the size of the data
2442
 * Returns 1 if successful or -1 on error
2443
 */
2444
int liblnk_file_get_data_size(
2445
     liblnk_file_t *file,
2446
     size64_t *data_size,
2447
     libcerror_error_t **error )
2448
0
{
2449
0
  liblnk_internal_file_t *internal_file = NULL;
2450
0
  static char *function                 = "liblnk_file_get_data_size";
2451
2452
0
  if( file == NULL )
2453
0
  {
2454
0
    libcerror_error_set(
2455
0
     error,
2456
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2457
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2458
0
     "%s: invalid file.",
2459
0
     function );
2460
2461
0
    return( -1 );
2462
0
  }
2463
0
  internal_file = (liblnk_internal_file_t *) file;
2464
2465
0
  if( data_size == NULL )
2466
0
  {
2467
0
    libcerror_error_set(
2468
0
     error,
2469
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2470
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2471
0
     "%s: invalid data size.",
2472
0
     function );
2473
2474
0
    return( -1 );
2475
0
  }
2476
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2477
0
  if( libcthreads_read_write_lock_grab_for_read(
2478
0
       internal_file->read_write_lock,
2479
0
       error ) != 1 )
2480
0
  {
2481
0
    libcerror_error_set(
2482
0
     error,
2483
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2484
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2485
0
     "%s: unable to grab read/write lock for reading.",
2486
0
     function );
2487
2488
0
    return( -1 );
2489
0
  }
2490
0
#endif
2491
0
  *data_size = internal_file->data_size;
2492
2493
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2494
0
  if( libcthreads_read_write_lock_release_for_read(
2495
0
       internal_file->read_write_lock,
2496
0
       error ) != 1 )
2497
0
  {
2498
0
    libcerror_error_set(
2499
0
     error,
2500
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2501
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2502
0
     "%s: unable to release read/write lock for reading.",
2503
0
     function );
2504
2505
0
    return( -1 );
2506
0
  }
2507
0
#endif
2508
0
  return( 1 );
2509
0
}
2510
2511
/* Determines if the link refers to a file
2512
 * Returns 1 if the link refers to a file, 0 if not or -1 on error
2513
 */
2514
int liblnk_file_link_refers_to_file(
2515
     liblnk_file_t *file,
2516
     libcerror_error_t **error )
2517
0
{
2518
0
  liblnk_internal_file_t *internal_file = NULL;
2519
0
  static char *function                 = "liblnk_file_link_refers_to_file";
2520
0
  int result                            = 0;
2521
2522
0
  if( file == NULL )
2523
0
  {
2524
0
    libcerror_error_set(
2525
0
     error,
2526
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2527
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2528
0
     "%s: invalid file.",
2529
0
     function );
2530
2531
0
    return( -1 );
2532
0
  }
2533
0
  internal_file = (liblnk_internal_file_t *) file;
2534
2535
0
  if( internal_file->io_handle == NULL )
2536
0
  {
2537
0
    libcerror_error_set(
2538
0
     error,
2539
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2540
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2541
0
     "%s: invalid file - missing IO handle.",
2542
0
     function );
2543
2544
0
    return( -1 );
2545
0
  }
2546
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2547
0
  if( libcthreads_read_write_lock_grab_for_read(
2548
0
       internal_file->read_write_lock,
2549
0
       error ) != 1 )
2550
0
  {
2551
0
    libcerror_error_set(
2552
0
     error,
2553
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2554
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2555
0
     "%s: unable to grab read/write lock for reading.",
2556
0
     function );
2557
2558
0
    return( -1 );
2559
0
  }
2560
0
#endif
2561
0
  if( ( internal_file->file_information->data_flags & LIBLNK_DATA_FLAG_HAS_LOCATION_INFORMATION ) != 0 )
2562
0
  {
2563
0
    result = 1;
2564
0
  }
2565
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2566
0
  if( libcthreads_read_write_lock_release_for_read(
2567
0
       internal_file->read_write_lock,
2568
0
       error ) != 1 )
2569
0
  {
2570
0
    libcerror_error_set(
2571
0
     error,
2572
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2573
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2574
0
     "%s: unable to release read/write lock for reading.",
2575
0
     function );
2576
2577
0
    return( -1 );
2578
0
  }
2579
0
#endif
2580
0
  return( result );
2581
0
}
2582
2583
/* Retrieves the 64-bit filetime value containing the linked file's creation date and time
2584
 * The creation time is only set when the link refers to a file
2585
 * Returns 1 if successful or -1 on error
2586
 */
2587
int liblnk_file_get_file_creation_time(
2588
     liblnk_file_t *file,
2589
     uint64_t *filetime,
2590
     libcerror_error_t **error )
2591
0
{
2592
0
  liblnk_internal_file_t *internal_file = NULL;
2593
0
  static char *function                 = "liblnk_file_get_file_creation_time";
2594
2595
0
  if( file == NULL )
2596
0
  {
2597
0
    libcerror_error_set(
2598
0
     error,
2599
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2600
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2601
0
     "%s: invalid file.",
2602
0
     function );
2603
2604
0
    return( -1 );
2605
0
  }
2606
0
  internal_file = (liblnk_internal_file_t *) file;
2607
2608
0
  if( internal_file->file_information == NULL )
2609
0
  {
2610
0
    libcerror_error_set(
2611
0
     error,
2612
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2613
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2614
0
     "%s: invalid file - missing file information.",
2615
0
     function );
2616
2617
0
    return( -1 );
2618
0
  }
2619
0
  if( filetime == NULL )
2620
0
  {
2621
0
    libcerror_error_set(
2622
0
     error,
2623
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2624
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2625
0
     "%s: invalid filetime.",
2626
0
     function );
2627
2628
0
    return( -1 );
2629
0
  }
2630
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2631
0
  if( libcthreads_read_write_lock_grab_for_read(
2632
0
       internal_file->read_write_lock,
2633
0
       error ) != 1 )
2634
0
  {
2635
0
    libcerror_error_set(
2636
0
     error,
2637
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2638
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2639
0
     "%s: unable to grab read/write lock for reading.",
2640
0
     function );
2641
2642
0
    return( -1 );
2643
0
  }
2644
0
#endif
2645
0
  *filetime = internal_file->file_information->creation_time;
2646
2647
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2648
0
  if( libcthreads_read_write_lock_release_for_read(
2649
0
       internal_file->read_write_lock,
2650
0
       error ) != 1 )
2651
0
  {
2652
0
    libcerror_error_set(
2653
0
     error,
2654
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2655
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2656
0
     "%s: unable to release read/write lock for reading.",
2657
0
     function );
2658
2659
0
    return( -1 );
2660
0
  }
2661
0
#endif
2662
0
  return( 1 );
2663
0
}
2664
2665
/* Retrieves the 64-bit filetime value containing the linked file's last modification date and time
2666
 * The modification time is only set when the link refers to a file
2667
 * Returns 1 if successful or -1 on error
2668
 */
2669
int liblnk_file_get_file_modification_time(
2670
     liblnk_file_t *file,
2671
     uint64_t *filetime,
2672
     libcerror_error_t **error )
2673
0
{
2674
0
  liblnk_internal_file_t *internal_file = NULL;
2675
0
  static char *function                 = "liblnk_file_get_file_modification_time";
2676
2677
0
  if( file == NULL )
2678
0
  {
2679
0
    libcerror_error_set(
2680
0
     error,
2681
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2682
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2683
0
     "%s: invalid file.",
2684
0
     function );
2685
2686
0
    return( -1 );
2687
0
  }
2688
0
  internal_file = (liblnk_internal_file_t *) file;
2689
2690
0
  if( internal_file->file_information == NULL )
2691
0
  {
2692
0
    libcerror_error_set(
2693
0
     error,
2694
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2695
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2696
0
     "%s: invalid file - missing file information.",
2697
0
     function );
2698
2699
0
    return( -1 );
2700
0
  }
2701
0
  if( filetime == NULL )
2702
0
  {
2703
0
    libcerror_error_set(
2704
0
     error,
2705
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2706
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2707
0
     "%s: invalid filetime.",
2708
0
     function );
2709
2710
0
    return( -1 );
2711
0
  }
2712
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2713
0
  if( libcthreads_read_write_lock_grab_for_read(
2714
0
       internal_file->read_write_lock,
2715
0
       error ) != 1 )
2716
0
  {
2717
0
    libcerror_error_set(
2718
0
     error,
2719
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2720
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2721
0
     "%s: unable to grab read/write lock for reading.",
2722
0
     function );
2723
2724
0
    return( -1 );
2725
0
  }
2726
0
#endif
2727
0
  *filetime = internal_file->file_information->modification_time;
2728
2729
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2730
0
  if( libcthreads_read_write_lock_release_for_read(
2731
0
       internal_file->read_write_lock,
2732
0
       error ) != 1 )
2733
0
  {
2734
0
    libcerror_error_set(
2735
0
     error,
2736
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2737
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2738
0
     "%s: unable to release read/write lock for reading.",
2739
0
     function );
2740
2741
0
    return( -1 );
2742
0
  }
2743
0
#endif
2744
0
  return( 1 );
2745
0
}
2746
2747
/* Retrieves the 64-bit filetime value containing the linked file's last access date and time
2748
 * The access time is only set when the link refers to a file
2749
 * Returns 1 if successful or -1 on error
2750
 */
2751
int liblnk_file_get_file_access_time(
2752
     liblnk_file_t *file,
2753
     uint64_t *filetime,
2754
     libcerror_error_t **error )
2755
0
{
2756
0
  liblnk_internal_file_t *internal_file = NULL;
2757
0
  static char *function                 = "liblnk_file_get_file_access_time";
2758
2759
0
  if( file == NULL )
2760
0
  {
2761
0
    libcerror_error_set(
2762
0
     error,
2763
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2764
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2765
0
     "%s: invalid file.",
2766
0
     function );
2767
2768
0
    return( -1 );
2769
0
  }
2770
0
  internal_file = (liblnk_internal_file_t *) file;
2771
2772
0
  if( internal_file->file_information == NULL )
2773
0
  {
2774
0
    libcerror_error_set(
2775
0
     error,
2776
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2777
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2778
0
     "%s: invalid file - missing file information.",
2779
0
     function );
2780
2781
0
    return( -1 );
2782
0
  }
2783
0
  if( filetime == NULL )
2784
0
  {
2785
0
    libcerror_error_set(
2786
0
     error,
2787
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2788
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2789
0
     "%s: invalid filetime.",
2790
0
     function );
2791
2792
0
    return( -1 );
2793
0
  }
2794
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2795
0
  if( libcthreads_read_write_lock_grab_for_read(
2796
0
       internal_file->read_write_lock,
2797
0
       error ) != 1 )
2798
0
  {
2799
0
    libcerror_error_set(
2800
0
     error,
2801
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2802
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2803
0
     "%s: unable to grab read/write lock for reading.",
2804
0
     function );
2805
2806
0
    return( -1 );
2807
0
  }
2808
0
#endif
2809
0
  *filetime = internal_file->file_information->access_time;
2810
2811
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2812
0
  if( libcthreads_read_write_lock_release_for_read(
2813
0
       internal_file->read_write_lock,
2814
0
       error ) != 1 )
2815
0
  {
2816
0
    libcerror_error_set(
2817
0
     error,
2818
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2819
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2820
0
     "%s: unable to release read/write lock for reading.",
2821
0
     function );
2822
2823
0
    return( -1 );
2824
0
  }
2825
0
#endif
2826
0
  return( 1 );
2827
0
}
2828
2829
/* Retrieves the linked file's size
2830
 * The file size is only set if the link refers to a file
2831
 * Returns 1 if successful or -1 on error
2832
 */
2833
int liblnk_file_get_file_size(
2834
     liblnk_file_t *file,
2835
     uint32_t *file_size,
2836
     libcerror_error_t **error )
2837
0
{
2838
0
  liblnk_internal_file_t *internal_file = NULL;
2839
0
  static char *function                 = "liblnk_file_get_file_size";
2840
2841
0
  if( file == NULL )
2842
0
  {
2843
0
    libcerror_error_set(
2844
0
     error,
2845
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2846
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2847
0
     "%s: invalid file.",
2848
0
     function );
2849
2850
0
    return( -1 );
2851
0
  }
2852
0
  internal_file = (liblnk_internal_file_t *) file;
2853
2854
0
  if( internal_file->file_information == NULL )
2855
0
  {
2856
0
    libcerror_error_set(
2857
0
     error,
2858
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2859
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2860
0
     "%s: invalid file - missing file information.",
2861
0
     function );
2862
2863
0
    return( -1 );
2864
0
  }
2865
0
  if( file_size == NULL )
2866
0
  {
2867
0
    libcerror_error_set(
2868
0
     error,
2869
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2870
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2871
0
     "%s: invalid file size.",
2872
0
     function );
2873
2874
0
    return( -1 );
2875
0
  }
2876
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2877
0
  if( libcthreads_read_write_lock_grab_for_read(
2878
0
       internal_file->read_write_lock,
2879
0
       error ) != 1 )
2880
0
  {
2881
0
    libcerror_error_set(
2882
0
     error,
2883
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2884
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2885
0
     "%s: unable to grab read/write lock for reading.",
2886
0
     function );
2887
2888
0
    return( -1 );
2889
0
  }
2890
0
#endif
2891
0
  *file_size = internal_file->file_information->file_size;
2892
2893
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2894
0
  if( libcthreads_read_write_lock_release_for_read(
2895
0
       internal_file->read_write_lock,
2896
0
       error ) != 1 )
2897
0
  {
2898
0
    libcerror_error_set(
2899
0
     error,
2900
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2901
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2902
0
     "%s: unable to release read/write lock for reading.",
2903
0
     function );
2904
2905
0
    return( -1 );
2906
0
  }
2907
0
#endif
2908
0
  return( 1 );
2909
0
}
2910
2911
/* Retrieves the icon index
2912
 * Returns 1 if successful or -1 on error
2913
 */
2914
int liblnk_file_get_icon_index(
2915
     liblnk_file_t *file,
2916
     uint32_t *icon_index,
2917
     libcerror_error_t **error )
2918
0
{
2919
0
  liblnk_internal_file_t *internal_file = NULL;
2920
0
  static char *function                 = "liblnk_file_get_icon_index";
2921
2922
0
  if( file == NULL )
2923
0
  {
2924
0
    libcerror_error_set(
2925
0
     error,
2926
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2927
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2928
0
     "%s: invalid file.",
2929
0
     function );
2930
2931
0
    return( -1 );
2932
0
  }
2933
0
  internal_file = (liblnk_internal_file_t *) file;
2934
2935
0
  if( internal_file->file_information == NULL )
2936
0
  {
2937
0
    libcerror_error_set(
2938
0
     error,
2939
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2940
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2941
0
     "%s: invalid file - missing file information.",
2942
0
     function );
2943
2944
0
    return( -1 );
2945
0
  }
2946
0
  if( icon_index == NULL )
2947
0
  {
2948
0
    libcerror_error_set(
2949
0
     error,
2950
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2951
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2952
0
     "%s: invalid icon index.",
2953
0
     function );
2954
2955
0
    return( -1 );
2956
0
  }
2957
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2958
0
  if( libcthreads_read_write_lock_grab_for_read(
2959
0
       internal_file->read_write_lock,
2960
0
       error ) != 1 )
2961
0
  {
2962
0
    libcerror_error_set(
2963
0
     error,
2964
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2965
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2966
0
     "%s: unable to grab read/write lock for reading.",
2967
0
     function );
2968
2969
0
    return( -1 );
2970
0
  }
2971
0
#endif
2972
0
  *icon_index = internal_file->file_information->icon_index;
2973
2974
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
2975
0
  if( libcthreads_read_write_lock_release_for_read(
2976
0
       internal_file->read_write_lock,
2977
0
       error ) != 1 )
2978
0
  {
2979
0
    libcerror_error_set(
2980
0
     error,
2981
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2982
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2983
0
     "%s: unable to release read/write lock for reading.",
2984
0
     function );
2985
2986
0
    return( -1 );
2987
0
  }
2988
0
#endif
2989
0
  return( 1 );
2990
0
}
2991
2992
/* Retrieves the show window value
2993
 * Returns 1 if successful or -1 on error
2994
 */
2995
int liblnk_file_get_show_window_value(
2996
     liblnk_file_t *file,
2997
     uint32_t *show_window_value,
2998
     libcerror_error_t **error )
2999
0
{
3000
0
  liblnk_internal_file_t *internal_file = NULL;
3001
0
  static char *function                 = "liblnk_file_get_show_window_value";
3002
3003
0
  if( file == NULL )
3004
0
  {
3005
0
    libcerror_error_set(
3006
0
     error,
3007
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3008
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3009
0
     "%s: invalid file.",
3010
0
     function );
3011
3012
0
    return( -1 );
3013
0
  }
3014
0
  internal_file = (liblnk_internal_file_t *) file;
3015
3016
0
  if( internal_file->file_information == NULL )
3017
0
  {
3018
0
    libcerror_error_set(
3019
0
     error,
3020
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3021
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3022
0
     "%s: invalid file - missing file information.",
3023
0
     function );
3024
3025
0
    return( -1 );
3026
0
  }
3027
0
  if( show_window_value == NULL )
3028
0
  {
3029
0
    libcerror_error_set(
3030
0
     error,
3031
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3032
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3033
0
     "%s: invalid show window value.",
3034
0
     function );
3035
3036
0
    return( -1 );
3037
0
  }
3038
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3039
0
  if( libcthreads_read_write_lock_grab_for_read(
3040
0
       internal_file->read_write_lock,
3041
0
       error ) != 1 )
3042
0
  {
3043
0
    libcerror_error_set(
3044
0
     error,
3045
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3046
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3047
0
     "%s: unable to grab read/write lock for reading.",
3048
0
     function );
3049
3050
0
    return( -1 );
3051
0
  }
3052
0
#endif
3053
0
  *show_window_value = internal_file->file_information->show_window;
3054
3055
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3056
0
  if( libcthreads_read_write_lock_release_for_read(
3057
0
       internal_file->read_write_lock,
3058
0
       error ) != 1 )
3059
0
  {
3060
0
    libcerror_error_set(
3061
0
     error,
3062
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3063
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3064
0
     "%s: unable to release read/write lock for reading.",
3065
0
     function );
3066
3067
0
    return( -1 );
3068
0
  }
3069
0
#endif
3070
0
  return( 1 );
3071
0
}
3072
3073
/* Retrieves the hot key value
3074
 * Returns 1 if successful or -1 on error
3075
 */
3076
int liblnk_file_get_hot_key_value(
3077
     liblnk_file_t *file,
3078
     uint16_t *hot_key_value,
3079
     libcerror_error_t **error )
3080
0
{
3081
0
  liblnk_internal_file_t *internal_file = NULL;
3082
0
  static char *function                 = "liblnk_file_get_hot_key_value";
3083
3084
0
  if( file == NULL )
3085
0
  {
3086
0
    libcerror_error_set(
3087
0
     error,
3088
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3089
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3090
0
     "%s: invalid file.",
3091
0
     function );
3092
3093
0
    return( -1 );
3094
0
  }
3095
0
  internal_file = (liblnk_internal_file_t *) file;
3096
3097
0
  if( internal_file->file_information == NULL )
3098
0
  {
3099
0
    libcerror_error_set(
3100
0
     error,
3101
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3102
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3103
0
     "%s: invalid file - missing file information.",
3104
0
     function );
3105
3106
0
    return( -1 );
3107
0
  }
3108
0
  if( hot_key_value == NULL )
3109
0
  {
3110
0
    libcerror_error_set(
3111
0
     error,
3112
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3113
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3114
0
     "%s: invalid hot key value.",
3115
0
     function );
3116
3117
0
    return( -1 );
3118
0
  }
3119
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3120
0
  if( libcthreads_read_write_lock_grab_for_read(
3121
0
       internal_file->read_write_lock,
3122
0
       error ) != 1 )
3123
0
  {
3124
0
    libcerror_error_set(
3125
0
     error,
3126
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3127
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3128
0
     "%s: unable to grab read/write lock for reading.",
3129
0
     function );
3130
3131
0
    return( -1 );
3132
0
  }
3133
0
#endif
3134
0
  *hot_key_value = internal_file->file_information->hot_key;
3135
3136
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3137
0
  if( libcthreads_read_write_lock_release_for_read(
3138
0
       internal_file->read_write_lock,
3139
0
       error ) != 1 )
3140
0
  {
3141
0
    libcerror_error_set(
3142
0
     error,
3143
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3144
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3145
0
     "%s: unable to release read/write lock for reading.",
3146
0
     function );
3147
3148
0
    return( -1 );
3149
0
  }
3150
0
#endif
3151
0
  return( 1 );
3152
0
}
3153
3154
/* Retrieves the linked file's attribute flags
3155
 * The file attribute flags are only set if the link refers to a file
3156
 * Returns 1 if successful or -1 on error
3157
 */
3158
int liblnk_file_get_file_attribute_flags(
3159
     liblnk_file_t *file,
3160
     uint32_t *file_attribute_flags,
3161
     libcerror_error_t **error )
3162
0
{
3163
0
  liblnk_internal_file_t *internal_file = NULL;
3164
0
  static char *function                 = "liblnk_file_get_file_attribute_flags";
3165
3166
0
  if( file == NULL )
3167
0
  {
3168
0
    libcerror_error_set(
3169
0
     error,
3170
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3171
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3172
0
     "%s: invalid file.",
3173
0
     function );
3174
3175
0
    return( -1 );
3176
0
  }
3177
0
  internal_file = (liblnk_internal_file_t *) file;
3178
3179
0
  if( internal_file->file_information == NULL )
3180
0
  {
3181
0
    libcerror_error_set(
3182
0
     error,
3183
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3184
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3185
0
     "%s: invalid file - missing file information.",
3186
0
     function );
3187
3188
0
    return( -1 );
3189
0
  }
3190
0
  if( file_attribute_flags == NULL )
3191
0
  {
3192
0
    libcerror_error_set(
3193
0
     error,
3194
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3195
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3196
0
     "%s: invalid file attribute flags.",
3197
0
     function );
3198
3199
0
    return( -1 );
3200
0
  }
3201
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3202
0
  if( libcthreads_read_write_lock_grab_for_read(
3203
0
       internal_file->read_write_lock,
3204
0
       error ) != 1 )
3205
0
  {
3206
0
    libcerror_error_set(
3207
0
     error,
3208
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3209
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3210
0
     "%s: unable to grab read/write lock for reading.",
3211
0
     function );
3212
3213
0
    return( -1 );
3214
0
  }
3215
0
#endif
3216
0
  *file_attribute_flags = internal_file->file_information->file_attribute_flags;
3217
3218
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3219
0
  if( libcthreads_read_write_lock_release_for_read(
3220
0
       internal_file->read_write_lock,
3221
0
       error ) != 1 )
3222
0
  {
3223
0
    libcerror_error_set(
3224
0
     error,
3225
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3226
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3227
0
     "%s: unable to release read/write lock for reading.",
3228
0
     function );
3229
3230
0
    return( -1 );
3231
0
  }
3232
0
#endif
3233
0
  return( 1 );
3234
0
}
3235
3236
/* Retrieves the drive type
3237
 * The drive type is only set if the link refers to a file on a local volume
3238
 * Returns 1 if successful, 0 if value is not available or -1 on error
3239
 */
3240
int liblnk_file_get_drive_type(
3241
     liblnk_file_t *file,
3242
     uint32_t *drive_type,
3243
     libcerror_error_t **error )
3244
0
{
3245
0
  liblnk_internal_file_t *internal_file = NULL;
3246
0
  static char *function                 = "liblnk_file_get_drive_type";
3247
0
  int result                            = 0;
3248
3249
0
  if( file == NULL )
3250
0
  {
3251
0
    libcerror_error_set(
3252
0
     error,
3253
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3254
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3255
0
     "%s: invalid file.",
3256
0
     function );
3257
3258
0
    return( -1 );
3259
0
  }
3260
0
  internal_file = (liblnk_internal_file_t *) file;
3261
3262
0
  if( internal_file->io_handle == NULL )
3263
0
  {
3264
0
    libcerror_error_set(
3265
0
     error,
3266
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3267
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3268
0
     "%s: invalid file - missing IO handle.",
3269
0
     function );
3270
3271
0
    return( -1 );
3272
0
  }
3273
0
  if( drive_type == NULL )
3274
0
  {
3275
0
    libcerror_error_set(
3276
0
     error,
3277
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3278
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3279
0
     "%s: invalid drive type.",
3280
0
     function );
3281
3282
0
    return( -1 );
3283
0
  }
3284
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3285
0
  if( libcthreads_read_write_lock_grab_for_read(
3286
0
       internal_file->read_write_lock,
3287
0
       error ) != 1 )
3288
0
  {
3289
0
    libcerror_error_set(
3290
0
     error,
3291
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3292
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3293
0
     "%s: unable to grab read/write lock for reading.",
3294
0
     function );
3295
3296
0
    return( -1 );
3297
0
  }
3298
0
#endif
3299
0
  if( internal_file->location_information != NULL )
3300
0
  {
3301
0
    *drive_type = internal_file->location_information->drive_type;
3302
3303
0
    result = 1;
3304
0
  }
3305
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3306
0
  if( libcthreads_read_write_lock_release_for_read(
3307
0
       internal_file->read_write_lock,
3308
0
       error ) != 1 )
3309
0
  {
3310
0
    libcerror_error_set(
3311
0
     error,
3312
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3313
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3314
0
     "%s: unable to release read/write lock for reading.",
3315
0
     function );
3316
3317
0
    return( -1 );
3318
0
  }
3319
0
#endif
3320
0
  return( result );
3321
0
}
3322
3323
/* Retrieves the drive serial number
3324
 * The drive serial number is only set if the link refers to a file on a local volume
3325
 * Returns 1 if successful, 0 if value is not available or -1 on error
3326
 */
3327
int liblnk_file_get_drive_serial_number(
3328
     liblnk_file_t *file,
3329
     uint32_t *drive_serial_number,
3330
     libcerror_error_t **error )
3331
0
{
3332
0
  liblnk_internal_file_t *internal_file = NULL;
3333
0
  static char *function                 = "liblnk_file_get_drive_serial_number";
3334
0
  int result                            = 0;
3335
3336
0
  if( file == NULL )
3337
0
  {
3338
0
    libcerror_error_set(
3339
0
     error,
3340
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3341
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3342
0
     "%s: invalid file.",
3343
0
     function );
3344
3345
0
    return( -1 );
3346
0
  }
3347
0
  internal_file = (liblnk_internal_file_t *) file;
3348
3349
0
  if( internal_file->io_handle == NULL )
3350
0
  {
3351
0
    libcerror_error_set(
3352
0
     error,
3353
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3354
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3355
0
     "%s: invalid file - missing IO handle.",
3356
0
     function );
3357
3358
0
    return( -1 );
3359
0
  }
3360
0
  if( drive_serial_number == NULL )
3361
0
  {
3362
0
    libcerror_error_set(
3363
0
     error,
3364
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3365
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3366
0
     "%s: invalid drive serial number.",
3367
0
     function );
3368
3369
0
    return( -1 );
3370
0
  }
3371
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3372
0
  if( libcthreads_read_write_lock_grab_for_read(
3373
0
       internal_file->read_write_lock,
3374
0
       error ) != 1 )
3375
0
  {
3376
0
    libcerror_error_set(
3377
0
     error,
3378
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3379
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3380
0
     "%s: unable to grab read/write lock for reading.",
3381
0
     function );
3382
3383
0
    return( -1 );
3384
0
  }
3385
0
#endif
3386
0
  if( internal_file->location_information != NULL )
3387
0
  {
3388
0
    *drive_serial_number = internal_file->location_information->drive_serial_number;
3389
3390
0
    result = 1;
3391
0
  }
3392
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3393
0
  if( libcthreads_read_write_lock_release_for_read(
3394
0
       internal_file->read_write_lock,
3395
0
       error ) != 1 )
3396
0
  {
3397
0
    libcerror_error_set(
3398
0
     error,
3399
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3400
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3401
0
     "%s: unable to release read/write lock for reading.",
3402
0
     function );
3403
3404
0
    return( -1 );
3405
0
  }
3406
0
#endif
3407
0
  return( result );
3408
0
}
3409
3410
/* TODO add raw string functions */
3411
3412
/* Retrieves the size of the UTF-8 encoded volume label
3413
 * The size includes the end of string character
3414
 * The volume label is only set if the link refers to a file on a local volume
3415
 * Returns 1 if successful, 0 if value is not available or -1 on error
3416
 */
3417
int liblnk_file_get_utf8_volume_label_size(
3418
     liblnk_file_t *file,
3419
     size_t *utf8_string_size,
3420
     libcerror_error_t **error )
3421
0
{
3422
0
  liblnk_internal_file_t *internal_file = NULL;
3423
0
  static char *function                 = "liblnk_file_get_utf8_volume_label_size";
3424
0
  int result                            = 0;
3425
3426
0
  if( file == NULL )
3427
0
  {
3428
0
    libcerror_error_set(
3429
0
     error,
3430
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3431
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3432
0
     "%s: invalid file.",
3433
0
     function );
3434
3435
0
    return( -1 );
3436
0
  }
3437
0
  internal_file = (liblnk_internal_file_t *) file;
3438
3439
0
  if( internal_file->io_handle == NULL )
3440
0
  {
3441
0
    libcerror_error_set(
3442
0
     error,
3443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3444
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3445
0
     "%s: invalid file - missing IO handle.",
3446
0
     function );
3447
3448
0
    return( -1 );
3449
0
  }
3450
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3451
0
  if( libcthreads_read_write_lock_grab_for_read(
3452
0
       internal_file->read_write_lock,
3453
0
       error ) != 1 )
3454
0
  {
3455
0
    libcerror_error_set(
3456
0
     error,
3457
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3458
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3459
0
     "%s: unable to grab read/write lock for reading.",
3460
0
     function );
3461
3462
0
    return( -1 );
3463
0
  }
3464
0
#endif
3465
0
  if( internal_file->location_information != NULL )
3466
0
  {
3467
0
    result = liblnk_location_information_get_utf8_volume_label_size(
3468
0
        internal_file->location_information,
3469
0
        internal_file->io_handle->ascii_codepage,
3470
0
        utf8_string_size,
3471
0
        error );
3472
3473
0
    if( result == -1 )
3474
0
    {
3475
0
      libcerror_error_set(
3476
0
       error,
3477
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3478
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3479
0
       "%s: unable to retrieve UTF-8 volume label string size.",
3480
0
       function );
3481
3482
0
      result = -1;
3483
0
    }
3484
0
  }
3485
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3486
0
  if( libcthreads_read_write_lock_release_for_read(
3487
0
       internal_file->read_write_lock,
3488
0
       error ) != 1 )
3489
0
  {
3490
0
    libcerror_error_set(
3491
0
     error,
3492
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3493
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3494
0
     "%s: unable to release read/write lock for reading.",
3495
0
     function );
3496
3497
0
    return( -1 );
3498
0
  }
3499
0
#endif
3500
0
  return( result );
3501
0
}
3502
3503
/* Retrieves the UTF-8 encoded volume label
3504
 * The size should include the end of string character
3505
 * The volume label is only set if the link refers to a file on a local volume
3506
 * Returns 1 if successful, 0 if value is not available or -1 on error
3507
 */
3508
int liblnk_file_get_utf8_volume_label(
3509
     liblnk_file_t *file,
3510
     uint8_t *utf8_string,
3511
     size_t utf8_string_size,
3512
     libcerror_error_t **error )
3513
0
{
3514
0
  liblnk_internal_file_t *internal_file = NULL;
3515
0
  static char *function                 = "liblnk_file_get_utf8_volume_label";
3516
0
  int result                            = 0;
3517
3518
0
  if( file == NULL )
3519
0
  {
3520
0
    libcerror_error_set(
3521
0
     error,
3522
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3523
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3524
0
     "%s: invalid file.",
3525
0
     function );
3526
3527
0
    return( -1 );
3528
0
  }
3529
0
  internal_file = (liblnk_internal_file_t *) file;
3530
3531
0
  if( internal_file->io_handle == NULL )
3532
0
  {
3533
0
    libcerror_error_set(
3534
0
     error,
3535
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3536
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3537
0
     "%s: invalid file - missing IO handle.",
3538
0
     function );
3539
3540
0
    return( -1 );
3541
0
  }
3542
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3543
0
  if( libcthreads_read_write_lock_grab_for_read(
3544
0
       internal_file->read_write_lock,
3545
0
       error ) != 1 )
3546
0
  {
3547
0
    libcerror_error_set(
3548
0
     error,
3549
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3550
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3551
0
     "%s: unable to grab read/write lock for reading.",
3552
0
     function );
3553
3554
0
    return( -1 );
3555
0
  }
3556
0
#endif
3557
0
  if( internal_file->location_information != NULL )
3558
0
  {
3559
0
    result = liblnk_location_information_get_utf8_volume_label(
3560
0
        internal_file->location_information,
3561
0
        internal_file->io_handle->ascii_codepage,
3562
0
        utf8_string,
3563
0
        utf8_string_size,
3564
0
        error );
3565
3566
0
    if( result == -1 )
3567
0
    {
3568
0
      libcerror_error_set(
3569
0
       error,
3570
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3571
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3572
0
       "%s: unable to retrieve UTF-8 volume label string.",
3573
0
       function );
3574
3575
0
      result = -1;
3576
0
    }
3577
0
  }
3578
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3579
0
  if( libcthreads_read_write_lock_release_for_read(
3580
0
       internal_file->read_write_lock,
3581
0
       error ) != 1 )
3582
0
  {
3583
0
    libcerror_error_set(
3584
0
     error,
3585
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3586
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3587
0
     "%s: unable to release read/write lock for reading.",
3588
0
     function );
3589
3590
0
    return( -1 );
3591
0
  }
3592
0
#endif
3593
0
  return( result );
3594
0
}
3595
3596
/* Retrieves the size of the UTF-16 encoded volume label
3597
 * The size includes the end of string character
3598
 * The volume label is only set if the link refers to a file on a local volume
3599
 * Returns 1 if successful, 0 if value is not available or -1 on error
3600
 */
3601
int liblnk_file_get_utf16_volume_label_size(
3602
     liblnk_file_t *file,
3603
     size_t *utf16_string_size,
3604
     libcerror_error_t **error )
3605
0
{
3606
0
  liblnk_internal_file_t *internal_file = NULL;
3607
0
  static char *function                 = "liblnk_file_get_utf16_volume_label_size";
3608
0
  int result                            = 0;
3609
3610
0
  if( file == NULL )
3611
0
  {
3612
0
    libcerror_error_set(
3613
0
     error,
3614
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3615
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3616
0
     "%s: invalid file.",
3617
0
     function );
3618
3619
0
    return( -1 );
3620
0
  }
3621
0
  internal_file = (liblnk_internal_file_t *) file;
3622
3623
0
  if( internal_file->io_handle == NULL )
3624
0
  {
3625
0
    libcerror_error_set(
3626
0
     error,
3627
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3628
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3629
0
     "%s: invalid file - missing IO handle.",
3630
0
     function );
3631
3632
0
    return( -1 );
3633
0
  }
3634
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3635
0
  if( libcthreads_read_write_lock_grab_for_read(
3636
0
       internal_file->read_write_lock,
3637
0
       error ) != 1 )
3638
0
  {
3639
0
    libcerror_error_set(
3640
0
     error,
3641
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3642
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3643
0
     "%s: unable to grab read/write lock for reading.",
3644
0
     function );
3645
3646
0
    return( -1 );
3647
0
  }
3648
0
#endif
3649
0
  if( internal_file->location_information != NULL )
3650
0
  {
3651
0
    result = liblnk_location_information_get_utf16_volume_label_size(
3652
0
        internal_file->location_information,
3653
0
        internal_file->io_handle->ascii_codepage,
3654
0
        utf16_string_size,
3655
0
        error );
3656
3657
0
    if( result == -1 )
3658
0
    {
3659
0
      libcerror_error_set(
3660
0
       error,
3661
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3662
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3663
0
       "%s: unable to retrieve UTF-16 volume label string size.",
3664
0
       function );
3665
3666
0
      result = -1;
3667
0
    }
3668
0
  }
3669
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3670
0
  if( libcthreads_read_write_lock_release_for_read(
3671
0
       internal_file->read_write_lock,
3672
0
       error ) != 1 )
3673
0
  {
3674
0
    libcerror_error_set(
3675
0
     error,
3676
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3677
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3678
0
     "%s: unable to release read/write lock for reading.",
3679
0
     function );
3680
3681
0
    return( -1 );
3682
0
  }
3683
0
#endif
3684
0
  return( result );
3685
0
}
3686
3687
/* Retrieves the UTF-16 encoded volume label
3688
 * The size should include the end of string character
3689
 * The volume label is only set if the link refers to a file on a local volume
3690
 * Returns 1 if successful, 0 if value is not available or -1 on error
3691
 */
3692
int liblnk_file_get_utf16_volume_label(
3693
     liblnk_file_t *file,
3694
     uint16_t *utf16_string,
3695
     size_t utf16_string_size,
3696
     libcerror_error_t **error )
3697
0
{
3698
0
  liblnk_internal_file_t *internal_file = NULL;
3699
0
  static char *function                 = "liblnk_file_get_utf16_volume_label";
3700
0
  int result                            = 0;
3701
3702
0
  if( file == NULL )
3703
0
  {
3704
0
    libcerror_error_set(
3705
0
     error,
3706
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3707
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3708
0
     "%s: invalid file.",
3709
0
     function );
3710
3711
0
    return( -1 );
3712
0
  }
3713
0
  internal_file = (liblnk_internal_file_t *) file;
3714
3715
0
  if( internal_file->io_handle == NULL )
3716
0
  {
3717
0
    libcerror_error_set(
3718
0
     error,
3719
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3720
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3721
0
     "%s: invalid file - missing IO handle.",
3722
0
     function );
3723
3724
0
    return( -1 );
3725
0
  }
3726
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3727
0
  if( libcthreads_read_write_lock_grab_for_read(
3728
0
       internal_file->read_write_lock,
3729
0
       error ) != 1 )
3730
0
  {
3731
0
    libcerror_error_set(
3732
0
     error,
3733
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3734
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3735
0
     "%s: unable to grab read/write lock for reading.",
3736
0
     function );
3737
3738
0
    return( -1 );
3739
0
  }
3740
0
#endif
3741
0
  if( internal_file->location_information != NULL )
3742
0
  {
3743
0
    result = liblnk_location_information_get_utf16_volume_label(
3744
0
        internal_file->location_information,
3745
0
        internal_file->io_handle->ascii_codepage,
3746
0
        utf16_string,
3747
0
        utf16_string_size,
3748
0
        error );
3749
3750
0
    if( result == -1 )
3751
0
    {
3752
0
      libcerror_error_set(
3753
0
       error,
3754
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3755
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3756
0
       "%s: unable to retrieve UTF-16 volume label string.",
3757
0
       function );
3758
3759
0
      result = -1;
3760
0
    }
3761
0
  }
3762
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3763
0
  if( libcthreads_read_write_lock_release_for_read(
3764
0
       internal_file->read_write_lock,
3765
0
       error ) != 1 )
3766
0
  {
3767
0
    libcerror_error_set(
3768
0
     error,
3769
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3770
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3771
0
     "%s: unable to release read/write lock for reading.",
3772
0
     function );
3773
3774
0
    return( -1 );
3775
0
  }
3776
0
#endif
3777
0
  return( result );
3778
0
}
3779
3780
/* Retrieves the size of the UTF-8 encoded local path
3781
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
3782
 * The size includes the end of string character
3783
 * The local path is only set if the link refers to a file on a local volume
3784
 * Returns 1 if successful, 0 if value is not available or -1 on error
3785
 */
3786
int liblnk_file_get_utf8_local_path_size(
3787
     liblnk_file_t *file,
3788
     size_t *utf8_string_size,
3789
     libcerror_error_t **error )
3790
0
{
3791
0
  liblnk_internal_file_t *internal_file = NULL;
3792
0
  static char *function                 = "liblnk_file_get_utf8_local_path_size";
3793
0
  int result                            = 0;
3794
3795
0
  if( file == NULL )
3796
0
  {
3797
0
    libcerror_error_set(
3798
0
     error,
3799
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3800
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3801
0
     "%s: invalid file.",
3802
0
     function );
3803
3804
0
    return( -1 );
3805
0
  }
3806
0
  internal_file = (liblnk_internal_file_t *) file;
3807
3808
0
  if( internal_file->io_handle == NULL )
3809
0
  {
3810
0
    libcerror_error_set(
3811
0
     error,
3812
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3813
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3814
0
     "%s: invalid file - missing IO handle.",
3815
0
     function );
3816
3817
0
    return( -1 );
3818
0
  }
3819
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3820
0
  if( libcthreads_read_write_lock_grab_for_read(
3821
0
       internal_file->read_write_lock,
3822
0
       error ) != 1 )
3823
0
  {
3824
0
    libcerror_error_set(
3825
0
     error,
3826
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3827
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3828
0
     "%s: unable to grab read/write lock for reading.",
3829
0
     function );
3830
3831
0
    return( -1 );
3832
0
  }
3833
0
#endif
3834
0
  if( internal_file->location_information != NULL )
3835
0
  {
3836
0
    result = liblnk_location_information_get_utf8_local_path_size(
3837
0
        internal_file->location_information,
3838
0
        internal_file->io_handle->ascii_codepage,
3839
0
        utf8_string_size,
3840
0
        error );
3841
3842
0
    if( result == -1 )
3843
0
    {
3844
0
      libcerror_error_set(
3845
0
       error,
3846
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3847
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3848
0
       "%s: unable to retrieve UTF-8 local path string size.",
3849
0
       function );
3850
3851
0
      result = -1;
3852
0
    }
3853
0
  }
3854
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3855
0
  if( libcthreads_read_write_lock_release_for_read(
3856
0
       internal_file->read_write_lock,
3857
0
       error ) != 1 )
3858
0
  {
3859
0
    libcerror_error_set(
3860
0
     error,
3861
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3862
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3863
0
     "%s: unable to release read/write lock for reading.",
3864
0
     function );
3865
3866
0
    return( -1 );
3867
0
  }
3868
0
#endif
3869
0
  return( result );
3870
0
}
3871
3872
/* Retrieves the UTF-8 encoded local path
3873
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
3874
 * The size should include the end of string character
3875
 * The local path is only set if the link refers to a file on a local volume
3876
 * Returns 1 if successful, 0 if value is not available or -1 on error
3877
 */
3878
int liblnk_file_get_utf8_local_path(
3879
     liblnk_file_t *file,
3880
     uint8_t *utf8_string,
3881
     size_t utf8_string_size,
3882
     libcerror_error_t **error )
3883
0
{
3884
0
  liblnk_internal_file_t *internal_file = NULL;
3885
0
  static char *function                 = "liblnk_file_get_utf8_local_path";
3886
0
  int result                            = 0;
3887
3888
0
  if( file == NULL )
3889
0
  {
3890
0
    libcerror_error_set(
3891
0
     error,
3892
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3893
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3894
0
     "%s: invalid file.",
3895
0
     function );
3896
3897
0
    return( -1 );
3898
0
  }
3899
0
  internal_file = (liblnk_internal_file_t *) file;
3900
3901
0
  if( internal_file->io_handle == NULL )
3902
0
  {
3903
0
    libcerror_error_set(
3904
0
     error,
3905
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3906
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3907
0
     "%s: invalid file - missing IO handle.",
3908
0
     function );
3909
3910
0
    return( -1 );
3911
0
  }
3912
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3913
0
  if( libcthreads_read_write_lock_grab_for_read(
3914
0
       internal_file->read_write_lock,
3915
0
       error ) != 1 )
3916
0
  {
3917
0
    libcerror_error_set(
3918
0
     error,
3919
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3920
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3921
0
     "%s: unable to grab read/write lock for reading.",
3922
0
     function );
3923
3924
0
    return( -1 );
3925
0
  }
3926
0
#endif
3927
0
  if( internal_file->location_information != NULL )
3928
0
  {
3929
0
    result = liblnk_location_information_get_utf8_local_path(
3930
0
        internal_file->location_information,
3931
0
        internal_file->io_handle->ascii_codepage,
3932
0
        utf8_string,
3933
0
        utf8_string_size,
3934
0
        error );
3935
3936
0
    if( result == -1 )
3937
0
    {
3938
0
      libcerror_error_set(
3939
0
       error,
3940
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3941
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3942
0
       "%s: unable to retrieve UTF-8 local path string.",
3943
0
       function );
3944
3945
0
      result = -1;
3946
0
    }
3947
0
  }
3948
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
3949
0
  if( libcthreads_read_write_lock_release_for_read(
3950
0
       internal_file->read_write_lock,
3951
0
       error ) != 1 )
3952
0
  {
3953
0
    libcerror_error_set(
3954
0
     error,
3955
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3956
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3957
0
     "%s: unable to release read/write lock for reading.",
3958
0
     function );
3959
3960
0
    return( -1 );
3961
0
  }
3962
0
#endif
3963
0
  return( result );
3964
0
}
3965
3966
/* Retrieves the size of the UTF-16 encoded local path
3967
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
3968
 * The size includes the end of string character
3969
 * The local path is only set if the link refers to a file on a local volume
3970
 * Returns 1 if successful, 0 if value is not available or -1 on error
3971
 */
3972
int liblnk_file_get_utf16_local_path_size(
3973
     liblnk_file_t *file,
3974
     size_t *utf16_string_size,
3975
     libcerror_error_t **error )
3976
0
{
3977
0
  liblnk_internal_file_t *internal_file = NULL;
3978
0
  static char *function                 = "liblnk_file_get_utf16_local_path_size";
3979
0
  int result                            = 0;
3980
3981
0
  if( file == NULL )
3982
0
  {
3983
0
    libcerror_error_set(
3984
0
     error,
3985
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3986
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3987
0
     "%s: invalid file.",
3988
0
     function );
3989
3990
0
    return( -1 );
3991
0
  }
3992
0
  internal_file = (liblnk_internal_file_t *) file;
3993
3994
0
  if( internal_file->io_handle == NULL )
3995
0
  {
3996
0
    libcerror_error_set(
3997
0
     error,
3998
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3999
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4000
0
     "%s: invalid file - missing IO handle.",
4001
0
     function );
4002
4003
0
    return( -1 );
4004
0
  }
4005
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4006
0
  if( libcthreads_read_write_lock_grab_for_read(
4007
0
       internal_file->read_write_lock,
4008
0
       error ) != 1 )
4009
0
  {
4010
0
    libcerror_error_set(
4011
0
     error,
4012
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4013
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4014
0
     "%s: unable to grab read/write lock for reading.",
4015
0
     function );
4016
4017
0
    return( -1 );
4018
0
  }
4019
0
#endif
4020
0
  if( internal_file->location_information != NULL )
4021
0
  {
4022
0
    result = liblnk_location_information_get_utf16_local_path_size(
4023
0
        internal_file->location_information,
4024
0
        internal_file->io_handle->ascii_codepage,
4025
0
        utf16_string_size,
4026
0
        error );
4027
4028
0
    if( result == -1 )
4029
0
    {
4030
0
      libcerror_error_set(
4031
0
       error,
4032
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4033
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4034
0
       "%s: unable to retrieve UTF-16 local path string size.",
4035
0
       function );
4036
4037
0
      result = -1;
4038
0
    }
4039
0
  }
4040
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4041
0
  if( libcthreads_read_write_lock_release_for_read(
4042
0
       internal_file->read_write_lock,
4043
0
       error ) != 1 )
4044
0
  {
4045
0
    libcerror_error_set(
4046
0
     error,
4047
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4048
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4049
0
     "%s: unable to release read/write lock for reading.",
4050
0
     function );
4051
4052
0
    return( -1 );
4053
0
  }
4054
0
#endif
4055
0
  return( result );
4056
0
}
4057
4058
/* Retrieves the UTF-16 encoded local path
4059
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
4060
 * The size should include the end of string character
4061
 * The local path is only set if the link refers to a file on a local volume
4062
 * Returns 1 if successful, 0 if value is not available or -1 on error
4063
 */
4064
int liblnk_file_get_utf16_local_path(
4065
     liblnk_file_t *file,
4066
     uint16_t *utf16_string,
4067
     size_t utf16_string_size,
4068
     libcerror_error_t **error )
4069
0
{
4070
0
  liblnk_internal_file_t *internal_file = NULL;
4071
0
  static char *function                 = "liblnk_file_get_utf16_local_path";
4072
0
  int result                            = 0;
4073
4074
0
  if( file == NULL )
4075
0
  {
4076
0
    libcerror_error_set(
4077
0
     error,
4078
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4079
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4080
0
     "%s: invalid file.",
4081
0
     function );
4082
4083
0
    return( -1 );
4084
0
  }
4085
0
  internal_file = (liblnk_internal_file_t *) file;
4086
4087
0
  if( internal_file->io_handle == NULL )
4088
0
  {
4089
0
    libcerror_error_set(
4090
0
     error,
4091
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4092
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4093
0
     "%s: invalid file - missing IO handle.",
4094
0
     function );
4095
4096
0
    return( -1 );
4097
0
  }
4098
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4099
0
  if( libcthreads_read_write_lock_grab_for_read(
4100
0
       internal_file->read_write_lock,
4101
0
       error ) != 1 )
4102
0
  {
4103
0
    libcerror_error_set(
4104
0
     error,
4105
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4106
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4107
0
     "%s: unable to grab read/write lock for reading.",
4108
0
     function );
4109
4110
0
    return( -1 );
4111
0
  }
4112
0
#endif
4113
0
  if( internal_file->location_information != NULL )
4114
0
  {
4115
0
    result = liblnk_location_information_get_utf16_local_path(
4116
0
        internal_file->location_information,
4117
0
        internal_file->io_handle->ascii_codepage,
4118
0
        utf16_string,
4119
0
        utf16_string_size,
4120
0
        error );
4121
4122
0
    if( result == -1 )
4123
0
    {
4124
0
      libcerror_error_set(
4125
0
       error,
4126
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4127
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4128
0
       "%s: unable to retrieve UTF-16 local path string.",
4129
0
       function );
4130
4131
0
      result = -1;
4132
0
    }
4133
0
  }
4134
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4135
0
  if( libcthreads_read_write_lock_release_for_read(
4136
0
       internal_file->read_write_lock,
4137
0
       error ) != 1 )
4138
0
  {
4139
0
    libcerror_error_set(
4140
0
     error,
4141
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4142
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4143
0
     "%s: unable to release read/write lock for reading.",
4144
0
     function );
4145
4146
0
    return( -1 );
4147
0
  }
4148
0
#endif
4149
0
  return( result );
4150
0
}
4151
4152
/* Retrieves the size of the UTF-8 encoded network path
4153
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
4154
 * The size includes the end of string character
4155
 * The network path is only set if the link refers to a file on a network share
4156
 * Returns 1 if successful, 0 if value is not available or -1 on error
4157
 */
4158
int liblnk_file_get_utf8_network_path_size(
4159
     liblnk_file_t *file,
4160
     size_t *utf8_string_size,
4161
     libcerror_error_t **error )
4162
0
{
4163
0
  liblnk_internal_file_t *internal_file = NULL;
4164
0
  static char *function                 = "liblnk_file_get_utf8_network_path_size";
4165
0
  int result                            = 0;
4166
4167
0
  if( file == NULL )
4168
0
  {
4169
0
    libcerror_error_set(
4170
0
     error,
4171
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4172
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4173
0
     "%s: invalid file.",
4174
0
     function );
4175
4176
0
    return( -1 );
4177
0
  }
4178
0
  internal_file = (liblnk_internal_file_t *) file;
4179
4180
0
  if( internal_file->io_handle == NULL )
4181
0
  {
4182
0
    libcerror_error_set(
4183
0
     error,
4184
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4185
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4186
0
     "%s: invalid file - missing IO handle.",
4187
0
     function );
4188
4189
0
    return( -1 );
4190
0
  }
4191
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4192
0
  if( libcthreads_read_write_lock_grab_for_read(
4193
0
       internal_file->read_write_lock,
4194
0
       error ) != 1 )
4195
0
  {
4196
0
    libcerror_error_set(
4197
0
     error,
4198
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4199
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4200
0
     "%s: unable to grab read/write lock for reading.",
4201
0
     function );
4202
4203
0
    return( -1 );
4204
0
  }
4205
0
#endif
4206
0
  if( internal_file->location_information != NULL )
4207
0
  {
4208
0
    result = liblnk_location_information_get_utf8_network_path_size(
4209
0
        internal_file->location_information,
4210
0
        internal_file->io_handle->ascii_codepage,
4211
0
        utf8_string_size,
4212
0
        error );
4213
4214
0
    if( result == -1 )
4215
0
    {
4216
0
      libcerror_error_set(
4217
0
       error,
4218
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4219
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4220
0
       "%s: unable to retrieve UTF-8 network path string size.",
4221
0
       function );
4222
4223
0
      result = -1;
4224
0
    }
4225
0
  }
4226
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4227
0
  if( libcthreads_read_write_lock_release_for_read(
4228
0
       internal_file->read_write_lock,
4229
0
       error ) != 1 )
4230
0
  {
4231
0
    libcerror_error_set(
4232
0
     error,
4233
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4234
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4235
0
     "%s: unable to release read/write lock for reading.",
4236
0
     function );
4237
4238
0
    return( -1 );
4239
0
  }
4240
0
#endif
4241
0
  return( result );
4242
0
}
4243
4244
/* Retrieves the UTF-8 encoded network path
4245
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
4246
 * The size should include the end of string character
4247
 * The network path is only set if the link refers to a file on a network share
4248
 * Returns 1 if successful, 0 if value is not available or -1 on error
4249
 */
4250
int liblnk_file_get_utf8_network_path(
4251
     liblnk_file_t *file,
4252
     uint8_t *utf8_string,
4253
     size_t utf8_string_size,
4254
     libcerror_error_t **error )
4255
0
{
4256
0
  liblnk_internal_file_t *internal_file = NULL;
4257
0
  static char *function                 = "liblnk_file_get_utf8_network_path";
4258
0
  int result                            = 0;
4259
4260
0
  if( file == NULL )
4261
0
  {
4262
0
    libcerror_error_set(
4263
0
     error,
4264
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4265
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4266
0
     "%s: invalid file.",
4267
0
     function );
4268
4269
0
    return( -1 );
4270
0
  }
4271
0
  internal_file = (liblnk_internal_file_t *) file;
4272
4273
0
  if( internal_file->io_handle == NULL )
4274
0
  {
4275
0
    libcerror_error_set(
4276
0
     error,
4277
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4278
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4279
0
     "%s: invalid file - missing IO handle.",
4280
0
     function );
4281
4282
0
    return( -1 );
4283
0
  }
4284
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4285
0
  if( libcthreads_read_write_lock_grab_for_read(
4286
0
       internal_file->read_write_lock,
4287
0
       error ) != 1 )
4288
0
  {
4289
0
    libcerror_error_set(
4290
0
     error,
4291
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4292
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4293
0
     "%s: unable to grab read/write lock for reading.",
4294
0
     function );
4295
4296
0
    return( -1 );
4297
0
  }
4298
0
#endif
4299
0
  if( internal_file->location_information != NULL )
4300
0
  {
4301
0
    result = liblnk_location_information_get_utf8_network_path(
4302
0
        internal_file->location_information,
4303
0
        internal_file->io_handle->ascii_codepage,
4304
0
        utf8_string,
4305
0
        utf8_string_size,
4306
0
        error );
4307
4308
0
    if( result == -1 )
4309
0
    {
4310
0
      libcerror_error_set(
4311
0
       error,
4312
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4313
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4314
0
       "%s: unable to retrieve UTF-8 network path string.",
4315
0
       function );
4316
4317
0
      result = -1;
4318
0
    }
4319
0
  }
4320
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4321
0
  if( libcthreads_read_write_lock_release_for_read(
4322
0
       internal_file->read_write_lock,
4323
0
       error ) != 1 )
4324
0
  {
4325
0
    libcerror_error_set(
4326
0
     error,
4327
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4328
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4329
0
     "%s: unable to release read/write lock for reading.",
4330
0
     function );
4331
4332
0
    return( -1 );
4333
0
  }
4334
0
#endif
4335
0
  return( result );
4336
0
}
4337
4338
/* Retrieves the size of the UTF-16 encoded network path
4339
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
4340
 * The size includes the end of string character
4341
 * The network path is only set if the link refers to a file on a network share
4342
 * Returns 1 if successful, 0 if value is not available or -1 on error
4343
 */
4344
int liblnk_file_get_utf16_network_path_size(
4345
     liblnk_file_t *file,
4346
     size_t *utf16_string_size,
4347
     libcerror_error_t **error )
4348
0
{
4349
0
  liblnk_internal_file_t *internal_file = NULL;
4350
0
  static char *function                 = "liblnk_file_get_utf16_network_path_size";
4351
0
  int result                            = 0;
4352
4353
0
  if( file == NULL )
4354
0
  {
4355
0
    libcerror_error_set(
4356
0
     error,
4357
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4358
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4359
0
     "%s: invalid file.",
4360
0
     function );
4361
4362
0
    return( -1 );
4363
0
  }
4364
0
  internal_file = (liblnk_internal_file_t *) file;
4365
4366
0
  if( internal_file->io_handle == NULL )
4367
0
  {
4368
0
    libcerror_error_set(
4369
0
     error,
4370
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4371
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4372
0
     "%s: invalid file - missing IO handle.",
4373
0
     function );
4374
4375
0
    return( -1 );
4376
0
  }
4377
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4378
0
  if( libcthreads_read_write_lock_grab_for_read(
4379
0
       internal_file->read_write_lock,
4380
0
       error ) != 1 )
4381
0
  {
4382
0
    libcerror_error_set(
4383
0
     error,
4384
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4385
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4386
0
     "%s: unable to grab read/write lock for reading.",
4387
0
     function );
4388
4389
0
    return( -1 );
4390
0
  }
4391
0
#endif
4392
0
  if( internal_file->location_information != NULL )
4393
0
  {
4394
0
    result = liblnk_location_information_get_utf16_network_path_size(
4395
0
        internal_file->location_information,
4396
0
        internal_file->io_handle->ascii_codepage,
4397
0
        utf16_string_size,
4398
0
        error );
4399
4400
0
    if( result == -1 )
4401
0
    {
4402
0
      libcerror_error_set(
4403
0
       error,
4404
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4405
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4406
0
       "%s: unable to retrieve UTF-16 network path string size.",
4407
0
       function );
4408
4409
0
      result = -1;
4410
0
    }
4411
0
  }
4412
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4413
0
  if( libcthreads_read_write_lock_release_for_read(
4414
0
       internal_file->read_write_lock,
4415
0
       error ) != 1 )
4416
0
  {
4417
0
    libcerror_error_set(
4418
0
     error,
4419
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4420
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4421
0
     "%s: unable to release read/write lock for reading.",
4422
0
     function );
4423
4424
0
    return( -1 );
4425
0
  }
4426
0
#endif
4427
0
  return( result );
4428
0
}
4429
4430
/* Retrieves the UTF-16 encoded network path
4431
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
4432
 * The size should include the end of string character
4433
 * The network path is only set if the link refers to a file on a network share
4434
 * Returns 1 if successful, 0 if value is not available or -1 on error
4435
 */
4436
int liblnk_file_get_utf16_network_path(
4437
     liblnk_file_t *file,
4438
     uint16_t *utf16_string,
4439
     size_t utf16_string_size,
4440
     libcerror_error_t **error )
4441
0
{
4442
0
  liblnk_internal_file_t *internal_file = NULL;
4443
0
  static char *function                 = "liblnk_file_get_utf16_network_path";
4444
0
  int result                            = 0;
4445
4446
0
  if( file == NULL )
4447
0
  {
4448
0
    libcerror_error_set(
4449
0
     error,
4450
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4451
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4452
0
     "%s: invalid file.",
4453
0
     function );
4454
4455
0
    return( -1 );
4456
0
  }
4457
0
  internal_file = (liblnk_internal_file_t *) file;
4458
4459
0
  if( internal_file->io_handle == NULL )
4460
0
  {
4461
0
    libcerror_error_set(
4462
0
     error,
4463
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4464
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4465
0
     "%s: invalid file - missing IO handle.",
4466
0
     function );
4467
4468
0
    return( -1 );
4469
0
  }
4470
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4471
0
  if( libcthreads_read_write_lock_grab_for_read(
4472
0
       internal_file->read_write_lock,
4473
0
       error ) != 1 )
4474
0
  {
4475
0
    libcerror_error_set(
4476
0
     error,
4477
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4478
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4479
0
     "%s: unable to grab read/write lock for reading.",
4480
0
     function );
4481
4482
0
    return( -1 );
4483
0
  }
4484
0
#endif
4485
0
  if( internal_file->location_information != NULL )
4486
0
  {
4487
0
    result = liblnk_location_information_get_utf16_network_path(
4488
0
        internal_file->location_information,
4489
0
        internal_file->io_handle->ascii_codepage,
4490
0
        utf16_string,
4491
0
        utf16_string_size,
4492
0
        error );
4493
4494
0
    if( result == -1 )
4495
0
    {
4496
0
      libcerror_error_set(
4497
0
       error,
4498
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4499
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4500
0
       "%s: unable to retrieve UTF-16 network path string.",
4501
0
       function );
4502
4503
0
      result = -1;
4504
0
    }
4505
0
  }
4506
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4507
0
  if( libcthreads_read_write_lock_release_for_read(
4508
0
       internal_file->read_write_lock,
4509
0
       error ) != 1 )
4510
0
  {
4511
0
    libcerror_error_set(
4512
0
     error,
4513
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4514
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4515
0
     "%s: unable to release read/write lock for reading.",
4516
0
     function );
4517
4518
0
    return( -1 );
4519
0
  }
4520
0
#endif
4521
0
  return( result );
4522
0
}
4523
4524
/* Retrieves the size of the UTF-8 encoded description
4525
 * The size includes the end of string character
4526
 * Returns 1 if successful, 0 if value is not available or -1 on error
4527
 */
4528
int liblnk_file_get_utf8_description_size(
4529
     liblnk_file_t *file,
4530
     size_t *utf8_string_size,
4531
     libcerror_error_t **error )
4532
0
{
4533
0
  liblnk_internal_file_t *internal_file = NULL;
4534
0
  static char *function                 = "liblnk_file_get_utf8_description_size";
4535
0
  int result                            = 0;
4536
4537
0
  if( file == NULL )
4538
0
  {
4539
0
    libcerror_error_set(
4540
0
     error,
4541
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4542
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4543
0
     "%s: invalid file.",
4544
0
     function );
4545
4546
0
    return( -1 );
4547
0
  }
4548
0
  internal_file = (liblnk_internal_file_t *) file;
4549
4550
0
  if( internal_file->io_handle == NULL )
4551
0
  {
4552
0
    libcerror_error_set(
4553
0
     error,
4554
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4555
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4556
0
     "%s: invalid file - missing IO handle.",
4557
0
     function );
4558
4559
0
    return( -1 );
4560
0
  }
4561
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4562
0
  if( libcthreads_read_write_lock_grab_for_read(
4563
0
       internal_file->read_write_lock,
4564
0
       error ) != 1 )
4565
0
  {
4566
0
    libcerror_error_set(
4567
0
     error,
4568
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4569
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4570
0
     "%s: unable to grab read/write lock for reading.",
4571
0
     function );
4572
4573
0
    return( -1 );
4574
0
  }
4575
0
#endif
4576
0
  if( internal_file->description != NULL )
4577
0
  {
4578
0
    result = liblnk_data_string_get_utf8_string_size(
4579
0
              internal_file->description,
4580
0
              internal_file->io_handle->ascii_codepage,
4581
0
              utf8_string_size,
4582
0
              error );
4583
4584
0
    if( result != 1 )
4585
0
    {
4586
0
      libcerror_error_set(
4587
0
       error,
4588
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4589
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4590
0
       "%s: unable to retrieve UTF-8 data string size.",
4591
0
       function );
4592
4593
0
      result = -1;
4594
0
    }
4595
0
  }
4596
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4597
0
  if( libcthreads_read_write_lock_release_for_read(
4598
0
       internal_file->read_write_lock,
4599
0
       error ) != 1 )
4600
0
  {
4601
0
    libcerror_error_set(
4602
0
     error,
4603
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4604
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4605
0
     "%s: unable to release read/write lock for reading.",
4606
0
     function );
4607
4608
0
    return( -1 );
4609
0
  }
4610
0
#endif
4611
0
  return( result );
4612
0
}
4613
4614
/* Retrieves the UTF-8 encoded description
4615
 * The size should include the end of string character
4616
 * Returns 1 if successful, 0 if value is not available or -1 on error
4617
 */
4618
int liblnk_file_get_utf8_description(
4619
     liblnk_file_t *file,
4620
     uint8_t *utf8_string,
4621
     size_t utf8_string_size,
4622
     libcerror_error_t **error )
4623
0
{
4624
0
  liblnk_internal_file_t *internal_file = NULL;
4625
0
  static char *function                 = "liblnk_file_get_utf8_description";
4626
0
  int result                            = 0;
4627
4628
0
  if( file == NULL )
4629
0
  {
4630
0
    libcerror_error_set(
4631
0
     error,
4632
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4633
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4634
0
     "%s: invalid file.",
4635
0
     function );
4636
4637
0
    return( -1 );
4638
0
  }
4639
0
  internal_file = (liblnk_internal_file_t *) file;
4640
4641
0
  if( internal_file->io_handle == NULL )
4642
0
  {
4643
0
    libcerror_error_set(
4644
0
     error,
4645
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4646
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4647
0
     "%s: invalid file - missing IO handle.",
4648
0
     function );
4649
4650
0
    return( -1 );
4651
0
  }
4652
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4653
0
  if( libcthreads_read_write_lock_grab_for_read(
4654
0
       internal_file->read_write_lock,
4655
0
       error ) != 1 )
4656
0
  {
4657
0
    libcerror_error_set(
4658
0
     error,
4659
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4660
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4661
0
     "%s: unable to grab read/write lock for reading.",
4662
0
     function );
4663
4664
0
    return( -1 );
4665
0
  }
4666
0
#endif
4667
0
  if( internal_file->description != NULL )
4668
0
  {
4669
0
    result = liblnk_data_string_get_utf8_string(
4670
0
              internal_file->description,
4671
0
              internal_file->io_handle->ascii_codepage,
4672
0
              utf8_string,
4673
0
              utf8_string_size,
4674
0
              error );
4675
4676
0
    if( result != 1 )
4677
0
    {
4678
0
      libcerror_error_set(
4679
0
       error,
4680
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4681
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4682
0
       "%s: unable to set UTF-8 data string.",
4683
0
       function );
4684
4685
0
      result = -1;
4686
0
    }
4687
0
  }
4688
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4689
0
  if( libcthreads_read_write_lock_release_for_read(
4690
0
       internal_file->read_write_lock,
4691
0
       error ) != 1 )
4692
0
  {
4693
0
    libcerror_error_set(
4694
0
     error,
4695
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4696
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4697
0
     "%s: unable to release read/write lock for reading.",
4698
0
     function );
4699
4700
0
    return( -1 );
4701
0
  }
4702
0
#endif
4703
0
  return( result );
4704
0
}
4705
4706
/* Retrieves the size of the UTF-16 encoded description
4707
 * The size includes the end of string character
4708
 * Returns 1 if successful, 0 if value is not available or -1 on error
4709
 */
4710
int liblnk_file_get_utf16_description_size(
4711
     liblnk_file_t *file,
4712
     size_t *utf16_string_size,
4713
     libcerror_error_t **error )
4714
0
{
4715
0
  liblnk_internal_file_t *internal_file = NULL;
4716
0
  static char *function                 = "liblnk_file_get_utf16_description_size";
4717
0
  int result                            = 0;
4718
4719
0
  if( file == NULL )
4720
0
  {
4721
0
    libcerror_error_set(
4722
0
     error,
4723
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4724
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4725
0
     "%s: invalid file.",
4726
0
     function );
4727
4728
0
    return( -1 );
4729
0
  }
4730
0
  internal_file = (liblnk_internal_file_t *) file;
4731
4732
0
  if( internal_file->io_handle == NULL )
4733
0
  {
4734
0
    libcerror_error_set(
4735
0
     error,
4736
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4737
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4738
0
     "%s: invalid file - missing IO handle.",
4739
0
     function );
4740
4741
0
    return( -1 );
4742
0
  }
4743
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4744
0
  if( libcthreads_read_write_lock_grab_for_read(
4745
0
       internal_file->read_write_lock,
4746
0
       error ) != 1 )
4747
0
  {
4748
0
    libcerror_error_set(
4749
0
     error,
4750
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4751
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4752
0
     "%s: unable to grab read/write lock for reading.",
4753
0
     function );
4754
4755
0
    return( -1 );
4756
0
  }
4757
0
#endif
4758
0
  if( internal_file->description != NULL )
4759
0
  {
4760
0
    result = liblnk_data_string_get_utf16_string_size(
4761
0
              internal_file->description,
4762
0
              internal_file->io_handle->ascii_codepage,
4763
0
              utf16_string_size,
4764
0
              error );
4765
4766
0
    if( result != 1 )
4767
0
    {
4768
0
      libcerror_error_set(
4769
0
       error,
4770
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4771
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4772
0
       "%s: unable to retrieve UTF-16 data string size.",
4773
0
       function );
4774
4775
0
      result = -1;
4776
0
    }
4777
0
  }
4778
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4779
0
  if( libcthreads_read_write_lock_release_for_read(
4780
0
       internal_file->read_write_lock,
4781
0
       error ) != 1 )
4782
0
  {
4783
0
    libcerror_error_set(
4784
0
     error,
4785
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4786
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4787
0
     "%s: unable to release read/write lock for reading.",
4788
0
     function );
4789
4790
0
    return( -1 );
4791
0
  }
4792
0
#endif
4793
0
  return( result );
4794
0
}
4795
4796
/* Retrieves the UTF-16 encoded description
4797
 * The size should include the end of string character
4798
 * Returns 1 if successful, 0 if value is not available or -1 on error
4799
 */
4800
int liblnk_file_get_utf16_description(
4801
     liblnk_file_t *file,
4802
     uint16_t *utf16_string,
4803
     size_t utf16_string_size,
4804
     libcerror_error_t **error )
4805
0
{
4806
0
  liblnk_internal_file_t *internal_file = NULL;
4807
0
  static char *function                 = "liblnk_file_get_utf16_description";
4808
0
  int result                            = 0;
4809
4810
0
  if( file == NULL )
4811
0
  {
4812
0
    libcerror_error_set(
4813
0
     error,
4814
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4815
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4816
0
     "%s: invalid file.",
4817
0
     function );
4818
4819
0
    return( -1 );
4820
0
  }
4821
0
  internal_file = (liblnk_internal_file_t *) file;
4822
4823
0
  if( internal_file->io_handle == NULL )
4824
0
  {
4825
0
    libcerror_error_set(
4826
0
     error,
4827
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4828
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4829
0
     "%s: invalid file - missing IO handle.",
4830
0
     function );
4831
4832
0
    return( -1 );
4833
0
  }
4834
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4835
0
  if( libcthreads_read_write_lock_grab_for_read(
4836
0
       internal_file->read_write_lock,
4837
0
       error ) != 1 )
4838
0
  {
4839
0
    libcerror_error_set(
4840
0
     error,
4841
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4842
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4843
0
     "%s: unable to grab read/write lock for reading.",
4844
0
     function );
4845
4846
0
    return( -1 );
4847
0
  }
4848
0
#endif
4849
0
  if( internal_file->description != NULL )
4850
0
  {
4851
0
    result = liblnk_data_string_get_utf16_string(
4852
0
              internal_file->description,
4853
0
              internal_file->io_handle->ascii_codepage,
4854
0
              utf16_string,
4855
0
              utf16_string_size,
4856
0
              error );
4857
4858
0
    if( result != 1 )
4859
0
    {
4860
0
      libcerror_error_set(
4861
0
       error,
4862
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4863
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4864
0
       "%s: unable to set UTF-16 data string.",
4865
0
       function );
4866
4867
0
      result = -1;
4868
0
    }
4869
0
  }
4870
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4871
0
  if( libcthreads_read_write_lock_release_for_read(
4872
0
       internal_file->read_write_lock,
4873
0
       error ) != 1 )
4874
0
  {
4875
0
    libcerror_error_set(
4876
0
     error,
4877
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4878
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4879
0
     "%s: unable to release read/write lock for reading.",
4880
0
     function );
4881
4882
0
    return( -1 );
4883
0
  }
4884
0
#endif
4885
0
  return( result );
4886
0
}
4887
4888
/* Retrieves the size of the UTF-8 encoded relative path
4889
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
4890
 * The size includes the end of string character
4891
 * Returns 1 if successful, 0 if value is not available or -1 on error
4892
 */
4893
int liblnk_file_get_utf8_relative_path_size(
4894
     liblnk_file_t *file,
4895
     size_t *utf8_string_size,
4896
     libcerror_error_t **error )
4897
0
{
4898
0
  liblnk_internal_file_t *internal_file = NULL;
4899
0
  static char *function                 = "liblnk_file_get_utf8_relative_path_size";
4900
0
  int result                            = 0;
4901
4902
0
  if( file == NULL )
4903
0
  {
4904
0
    libcerror_error_set(
4905
0
     error,
4906
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4907
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4908
0
     "%s: invalid file.",
4909
0
     function );
4910
4911
0
    return( -1 );
4912
0
  }
4913
0
  internal_file = (liblnk_internal_file_t *) file;
4914
4915
0
  if( internal_file->io_handle == NULL )
4916
0
  {
4917
0
    libcerror_error_set(
4918
0
     error,
4919
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4920
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4921
0
     "%s: invalid file - missing IO handle.",
4922
0
     function );
4923
4924
0
    return( -1 );
4925
0
  }
4926
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4927
0
  if( libcthreads_read_write_lock_grab_for_read(
4928
0
       internal_file->read_write_lock,
4929
0
       error ) != 1 )
4930
0
  {
4931
0
    libcerror_error_set(
4932
0
     error,
4933
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4934
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4935
0
     "%s: unable to grab read/write lock for reading.",
4936
0
     function );
4937
4938
0
    return( -1 );
4939
0
  }
4940
0
#endif
4941
0
  if( internal_file->relative_path != NULL )
4942
0
  {
4943
0
    result = liblnk_data_string_get_utf8_path_string_size(
4944
0
              internal_file->relative_path,
4945
0
              internal_file->io_handle->ascii_codepage,
4946
0
              utf8_string_size,
4947
0
              error );
4948
4949
0
    if( result != 1 )
4950
0
    {
4951
0
      libcerror_error_set(
4952
0
       error,
4953
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4954
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4955
0
       "%s: unable to retrieve UTF-8 data string size.",
4956
0
       function );
4957
4958
0
      result = -1;
4959
0
    }
4960
0
  }
4961
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
4962
0
  if( libcthreads_read_write_lock_release_for_read(
4963
0
       internal_file->read_write_lock,
4964
0
       error ) != 1 )
4965
0
  {
4966
0
    libcerror_error_set(
4967
0
     error,
4968
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4969
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4970
0
     "%s: unable to release read/write lock for reading.",
4971
0
     function );
4972
4973
0
    return( -1 );
4974
0
  }
4975
0
#endif
4976
0
  return( result );
4977
0
}
4978
4979
/* Retrieves the UTF-8 encoded relative path
4980
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
4981
 * The size should include the end of string character
4982
 * Returns 1 if successful, 0 if value is not available or -1 on error
4983
 */
4984
int liblnk_file_get_utf8_relative_path(
4985
     liblnk_file_t *file,
4986
     uint8_t *utf8_string,
4987
     size_t utf8_string_size,
4988
     libcerror_error_t **error )
4989
0
{
4990
0
  liblnk_internal_file_t *internal_file = NULL;
4991
0
  static char *function                 = "liblnk_file_get_utf8_relative_path";
4992
0
  int result                            = 0;
4993
4994
0
  if( file == NULL )
4995
0
  {
4996
0
    libcerror_error_set(
4997
0
     error,
4998
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4999
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5000
0
     "%s: invalid file.",
5001
0
     function );
5002
5003
0
    return( -1 );
5004
0
  }
5005
0
  internal_file = (liblnk_internal_file_t *) file;
5006
5007
0
  if( internal_file->io_handle == NULL )
5008
0
  {
5009
0
    libcerror_error_set(
5010
0
     error,
5011
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5012
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5013
0
     "%s: invalid file - missing IO handle.",
5014
0
     function );
5015
5016
0
    return( -1 );
5017
0
  }
5018
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5019
0
  if( libcthreads_read_write_lock_grab_for_read(
5020
0
       internal_file->read_write_lock,
5021
0
       error ) != 1 )
5022
0
  {
5023
0
    libcerror_error_set(
5024
0
     error,
5025
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5026
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5027
0
     "%s: unable to grab read/write lock for reading.",
5028
0
     function );
5029
5030
0
    return( -1 );
5031
0
  }
5032
0
#endif
5033
0
  if( internal_file->relative_path != NULL )
5034
0
  {
5035
0
    result = liblnk_data_string_get_utf8_path_string(
5036
0
              internal_file->relative_path,
5037
0
              internal_file->io_handle->ascii_codepage,
5038
0
              utf8_string,
5039
0
              utf8_string_size,
5040
0
              error );
5041
5042
0
    if( result != 1 )
5043
0
    {
5044
0
      libcerror_error_set(
5045
0
       error,
5046
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5047
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5048
0
       "%s: unable to set UTF-8 data string.",
5049
0
       function );
5050
5051
0
      result = -1;
5052
0
    }
5053
0
  }
5054
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5055
0
  if( libcthreads_read_write_lock_release_for_read(
5056
0
       internal_file->read_write_lock,
5057
0
       error ) != 1 )
5058
0
  {
5059
0
    libcerror_error_set(
5060
0
     error,
5061
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5062
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5063
0
     "%s: unable to release read/write lock for reading.",
5064
0
     function );
5065
5066
0
    return( -1 );
5067
0
  }
5068
0
#endif
5069
0
  return( result );
5070
0
}
5071
5072
/* Retrieves the size of the UTF-16 encoded relative path
5073
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
5074
 * The size includes the end of string character
5075
 * Returns 1 if successful, 0 if value is not available or -1 on error
5076
 */
5077
int liblnk_file_get_utf16_relative_path_size(
5078
     liblnk_file_t *file,
5079
     size_t *utf16_string_size,
5080
     libcerror_error_t **error )
5081
0
{
5082
0
  liblnk_internal_file_t *internal_file = NULL;
5083
0
  static char *function                 = "liblnk_file_get_utf16_relative_path_size";
5084
0
  int result                            = 0;
5085
5086
0
  if( file == NULL )
5087
0
  {
5088
0
    libcerror_error_set(
5089
0
     error,
5090
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5091
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5092
0
     "%s: invalid file.",
5093
0
     function );
5094
5095
0
    return( -1 );
5096
0
  }
5097
0
  internal_file = (liblnk_internal_file_t *) file;
5098
5099
0
  if( internal_file->io_handle == NULL )
5100
0
  {
5101
0
    libcerror_error_set(
5102
0
     error,
5103
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5104
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5105
0
     "%s: invalid file - missing IO handle.",
5106
0
     function );
5107
5108
0
    return( -1 );
5109
0
  }
5110
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5111
0
  if( libcthreads_read_write_lock_grab_for_read(
5112
0
       internal_file->read_write_lock,
5113
0
       error ) != 1 )
5114
0
  {
5115
0
    libcerror_error_set(
5116
0
     error,
5117
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5118
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5119
0
     "%s: unable to grab read/write lock for reading.",
5120
0
     function );
5121
5122
0
    return( -1 );
5123
0
  }
5124
0
#endif
5125
0
  if( internal_file->relative_path != NULL )
5126
0
  {
5127
0
    result = liblnk_data_string_get_utf16_path_string_size(
5128
0
              internal_file->relative_path,
5129
0
              internal_file->io_handle->ascii_codepage,
5130
0
              utf16_string_size,
5131
0
              error );
5132
5133
0
    if( result != 1 )
5134
0
    {
5135
0
      libcerror_error_set(
5136
0
       error,
5137
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5138
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5139
0
       "%s: unable to retrieve UTF-16 data string size.",
5140
0
       function );
5141
5142
0
      result = -1;
5143
0
    }
5144
0
  }
5145
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5146
0
  if( libcthreads_read_write_lock_release_for_read(
5147
0
       internal_file->read_write_lock,
5148
0
       error ) != 1 )
5149
0
  {
5150
0
    libcerror_error_set(
5151
0
     error,
5152
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5153
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5154
0
     "%s: unable to release read/write lock for reading.",
5155
0
     function );
5156
5157
0
    return( -1 );
5158
0
  }
5159
0
#endif
5160
0
  return( result );
5161
0
}
5162
5163
/* Retrieves the UTF-16 encoded relative path
5164
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
5165
 * The size should include the end of string character
5166
 * Returns 1 if successful, 0 if value is not available or -1 on error
5167
 */
5168
int liblnk_file_get_utf16_relative_path(
5169
     liblnk_file_t *file,
5170
     uint16_t *utf16_string,
5171
     size_t utf16_string_size,
5172
     libcerror_error_t **error )
5173
0
{
5174
0
  liblnk_internal_file_t *internal_file = NULL;
5175
0
  static char *function                 = "liblnk_file_get_utf16_relative_path";
5176
0
  int result                            = 0;
5177
5178
0
  if( file == NULL )
5179
0
  {
5180
0
    libcerror_error_set(
5181
0
     error,
5182
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5183
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5184
0
     "%s: invalid file.",
5185
0
     function );
5186
5187
0
    return( -1 );
5188
0
  }
5189
0
  internal_file = (liblnk_internal_file_t *) file;
5190
5191
0
  if( internal_file->io_handle == NULL )
5192
0
  {
5193
0
    libcerror_error_set(
5194
0
     error,
5195
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5196
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5197
0
     "%s: invalid file - missing IO handle.",
5198
0
     function );
5199
5200
0
    return( -1 );
5201
0
  }
5202
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5203
0
  if( libcthreads_read_write_lock_grab_for_read(
5204
0
       internal_file->read_write_lock,
5205
0
       error ) != 1 )
5206
0
  {
5207
0
    libcerror_error_set(
5208
0
     error,
5209
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5210
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5211
0
     "%s: unable to grab read/write lock for reading.",
5212
0
     function );
5213
5214
0
    return( -1 );
5215
0
  }
5216
0
#endif
5217
0
  if( internal_file->relative_path != NULL )
5218
0
  {
5219
0
    result = liblnk_data_string_get_utf16_path_string(
5220
0
              internal_file->relative_path,
5221
0
              internal_file->io_handle->ascii_codepage,
5222
0
              utf16_string,
5223
0
              utf16_string_size,
5224
0
              error );
5225
5226
0
    if( result != 1 )
5227
0
    {
5228
0
      libcerror_error_set(
5229
0
       error,
5230
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5231
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5232
0
       "%s: unable to set UTF-16 data string.",
5233
0
       function );
5234
5235
0
      result = -1;
5236
0
    }
5237
0
  }
5238
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5239
0
  if( libcthreads_read_write_lock_release_for_read(
5240
0
       internal_file->read_write_lock,
5241
0
       error ) != 1 )
5242
0
  {
5243
0
    libcerror_error_set(
5244
0
     error,
5245
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5246
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5247
0
     "%s: unable to release read/write lock for reading.",
5248
0
     function );
5249
5250
0
    return( -1 );
5251
0
  }
5252
0
#endif
5253
0
  return( result );
5254
0
}
5255
5256
/* Retrieves the size of the UTF-8 encoded working directory
5257
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
5258
 * The size includes the end of string character
5259
 * Returns 1 if successful, 0 if value is not available or -1 on error
5260
 */
5261
int liblnk_file_get_utf8_working_directory_size(
5262
     liblnk_file_t *file,
5263
     size_t *utf8_string_size,
5264
     libcerror_error_t **error )
5265
0
{
5266
0
  liblnk_internal_file_t *internal_file = NULL;
5267
0
  static char *function                 = "liblnk_file_get_utf8_working_directory_size";
5268
0
  int result                            = 0;
5269
5270
0
  if( file == NULL )
5271
0
  {
5272
0
    libcerror_error_set(
5273
0
     error,
5274
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5275
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5276
0
     "%s: invalid file.",
5277
0
     function );
5278
5279
0
    return( -1 );
5280
0
  }
5281
0
  internal_file = (liblnk_internal_file_t *) file;
5282
5283
0
  if( internal_file->io_handle == NULL )
5284
0
  {
5285
0
    libcerror_error_set(
5286
0
     error,
5287
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5288
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5289
0
     "%s: invalid file - missing IO handle.",
5290
0
     function );
5291
5292
0
    return( -1 );
5293
0
  }
5294
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5295
0
  if( libcthreads_read_write_lock_grab_for_read(
5296
0
       internal_file->read_write_lock,
5297
0
       error ) != 1 )
5298
0
  {
5299
0
    libcerror_error_set(
5300
0
     error,
5301
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5302
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5303
0
     "%s: unable to grab read/write lock for reading.",
5304
0
     function );
5305
5306
0
    return( -1 );
5307
0
  }
5308
0
#endif
5309
0
  if( internal_file->working_directory != NULL )
5310
0
  {
5311
0
    result = liblnk_data_string_get_utf8_path_string_size(
5312
0
              internal_file->working_directory,
5313
0
              internal_file->io_handle->ascii_codepage,
5314
0
              utf8_string_size,
5315
0
              error );
5316
5317
0
    if( result != 1 )
5318
0
    {
5319
0
      libcerror_error_set(
5320
0
       error,
5321
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5322
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5323
0
       "%s: unable to retrieve UTF-8 data string size.",
5324
0
       function );
5325
5326
0
      result = -1;
5327
0
    }
5328
0
  }
5329
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5330
0
  if( libcthreads_read_write_lock_release_for_read(
5331
0
       internal_file->read_write_lock,
5332
0
       error ) != 1 )
5333
0
  {
5334
0
    libcerror_error_set(
5335
0
     error,
5336
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5337
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5338
0
     "%s: unable to release read/write lock for reading.",
5339
0
     function );
5340
5341
0
    return( -1 );
5342
0
  }
5343
0
#endif
5344
0
  return( result );
5345
0
}
5346
5347
/* Retrieves the UTF-8 encoded working directory
5348
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
5349
 * The size should include the end of string character
5350
 * Returns 1 if successful, 0 if value is not available or -1 on error
5351
 */
5352
int liblnk_file_get_utf8_working_directory(
5353
     liblnk_file_t *file,
5354
     uint8_t *utf8_string,
5355
     size_t utf8_string_size,
5356
     libcerror_error_t **error )
5357
0
{
5358
0
  liblnk_internal_file_t *internal_file = NULL;
5359
0
  static char *function                 = "liblnk_file_get_utf8_working_directory";
5360
0
  int result                            = 0;
5361
5362
0
  if( file == NULL )
5363
0
  {
5364
0
    libcerror_error_set(
5365
0
     error,
5366
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5367
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5368
0
     "%s: invalid file.",
5369
0
     function );
5370
5371
0
    return( -1 );
5372
0
  }
5373
0
  internal_file = (liblnk_internal_file_t *) file;
5374
5375
0
  if( internal_file->io_handle == NULL )
5376
0
  {
5377
0
    libcerror_error_set(
5378
0
     error,
5379
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5380
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5381
0
     "%s: invalid file - missing IO handle.",
5382
0
     function );
5383
5384
0
    return( -1 );
5385
0
  }
5386
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5387
0
  if( libcthreads_read_write_lock_grab_for_read(
5388
0
       internal_file->read_write_lock,
5389
0
       error ) != 1 )
5390
0
  {
5391
0
    libcerror_error_set(
5392
0
     error,
5393
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5394
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5395
0
     "%s: unable to grab read/write lock for reading.",
5396
0
     function );
5397
5398
0
    return( -1 );
5399
0
  }
5400
0
#endif
5401
0
  if( internal_file->working_directory != NULL )
5402
0
  {
5403
0
    result = liblnk_data_string_get_utf8_path_string(
5404
0
              internal_file->working_directory,
5405
0
              internal_file->io_handle->ascii_codepage,
5406
0
              utf8_string,
5407
0
              utf8_string_size,
5408
0
              error );
5409
5410
0
    if( result != 1 )
5411
0
    {
5412
0
      libcerror_error_set(
5413
0
       error,
5414
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5415
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5416
0
       "%s: unable to set UTF-8 data string.",
5417
0
       function );
5418
5419
0
      result = -1;
5420
0
    }
5421
0
  }
5422
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5423
0
  if( libcthreads_read_write_lock_release_for_read(
5424
0
       internal_file->read_write_lock,
5425
0
       error ) != 1 )
5426
0
  {
5427
0
    libcerror_error_set(
5428
0
     error,
5429
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5430
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5431
0
     "%s: unable to release read/write lock for reading.",
5432
0
     function );
5433
5434
0
    return( -1 );
5435
0
  }
5436
0
#endif
5437
0
  return( result );
5438
0
}
5439
5440
/* Retrieves the size of the UTF-16 encoded working directory
5441
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
5442
 * The size includes the end of string character
5443
 * Returns 1 if successful, 0 if value is not available or -1 on error
5444
 */
5445
int liblnk_file_get_utf16_working_directory_size(
5446
     liblnk_file_t *file,
5447
     size_t *utf16_string_size,
5448
     libcerror_error_t **error )
5449
0
{
5450
0
  liblnk_internal_file_t *internal_file = NULL;
5451
0
  static char *function                 = "liblnk_file_get_utf16_working_directory_size";
5452
0
  int result                            = 0;
5453
5454
0
  if( file == NULL )
5455
0
  {
5456
0
    libcerror_error_set(
5457
0
     error,
5458
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5459
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5460
0
     "%s: invalid file.",
5461
0
     function );
5462
5463
0
    return( -1 );
5464
0
  }
5465
0
  internal_file = (liblnk_internal_file_t *) file;
5466
5467
0
  if( internal_file->io_handle == NULL )
5468
0
  {
5469
0
    libcerror_error_set(
5470
0
     error,
5471
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5472
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5473
0
     "%s: invalid file - missing IO handle.",
5474
0
     function );
5475
5476
0
    return( -1 );
5477
0
  }
5478
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5479
0
  if( libcthreads_read_write_lock_grab_for_read(
5480
0
       internal_file->read_write_lock,
5481
0
       error ) != 1 )
5482
0
  {
5483
0
    libcerror_error_set(
5484
0
     error,
5485
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5486
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5487
0
     "%s: unable to grab read/write lock for reading.",
5488
0
     function );
5489
5490
0
    return( -1 );
5491
0
  }
5492
0
#endif
5493
0
  if( internal_file->working_directory != NULL )
5494
0
  {
5495
0
    result = liblnk_data_string_get_utf16_path_string_size(
5496
0
              internal_file->working_directory,
5497
0
              internal_file->io_handle->ascii_codepage,
5498
0
              utf16_string_size,
5499
0
              error );
5500
5501
0
    if( result != 1 )
5502
0
    {
5503
0
      libcerror_error_set(
5504
0
       error,
5505
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5506
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5507
0
       "%s: unable to retrieve UTF-16 data string size.",
5508
0
       function );
5509
5510
0
      result = -1;
5511
0
    }
5512
0
  }
5513
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5514
0
  if( libcthreads_read_write_lock_release_for_read(
5515
0
       internal_file->read_write_lock,
5516
0
       error ) != 1 )
5517
0
  {
5518
0
    libcerror_error_set(
5519
0
     error,
5520
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5521
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5522
0
     "%s: unable to release read/write lock for reading.",
5523
0
     function );
5524
5525
0
    return( -1 );
5526
0
  }
5527
0
#endif
5528
0
  return( result );
5529
0
}
5530
5531
/* Retrieves the UTF-16 encoded working directory
5532
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
5533
 * The size should include the end of string character
5534
 * Returns 1 if successful, 0 if value is not available or -1 on error
5535
 */
5536
int liblnk_file_get_utf16_working_directory(
5537
     liblnk_file_t *file,
5538
     uint16_t *utf16_string,
5539
     size_t utf16_string_size,
5540
     libcerror_error_t **error )
5541
0
{
5542
0
  liblnk_internal_file_t *internal_file = NULL;
5543
0
  static char *function                 = "liblnk_file_get_utf16_working_directory";
5544
0
  int result                            = 0;
5545
5546
0
  if( file == NULL )
5547
0
  {
5548
0
    libcerror_error_set(
5549
0
     error,
5550
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5551
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5552
0
     "%s: invalid file.",
5553
0
     function );
5554
5555
0
    return( -1 );
5556
0
  }
5557
0
  internal_file = (liblnk_internal_file_t *) file;
5558
5559
0
  if( internal_file->io_handle == NULL )
5560
0
  {
5561
0
    libcerror_error_set(
5562
0
     error,
5563
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5564
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5565
0
     "%s: invalid file - missing IO handle.",
5566
0
     function );
5567
5568
0
    return( -1 );
5569
0
  }
5570
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5571
0
  if( libcthreads_read_write_lock_grab_for_read(
5572
0
       internal_file->read_write_lock,
5573
0
       error ) != 1 )
5574
0
  {
5575
0
    libcerror_error_set(
5576
0
     error,
5577
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5578
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5579
0
     "%s: unable to grab read/write lock for reading.",
5580
0
     function );
5581
5582
0
    return( -1 );
5583
0
  }
5584
0
#endif
5585
0
  if( internal_file->working_directory != NULL )
5586
0
  {
5587
0
    result = liblnk_data_string_get_utf16_path_string(
5588
0
              internal_file->working_directory,
5589
0
              internal_file->io_handle->ascii_codepage,
5590
0
              utf16_string,
5591
0
              utf16_string_size,
5592
0
              error );
5593
5594
0
    if( result != 1 )
5595
0
    {
5596
0
      libcerror_error_set(
5597
0
       error,
5598
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5599
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5600
0
       "%s: unable to set UTF-16 data string.",
5601
0
       function );
5602
5603
0
      result = -1;
5604
0
    }
5605
0
  }
5606
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5607
0
  if( libcthreads_read_write_lock_release_for_read(
5608
0
       internal_file->read_write_lock,
5609
0
       error ) != 1 )
5610
0
  {
5611
0
    libcerror_error_set(
5612
0
     error,
5613
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5614
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5615
0
     "%s: unable to release read/write lock for reading.",
5616
0
     function );
5617
5618
0
    return( -1 );
5619
0
  }
5620
0
#endif
5621
0
  return( result );
5622
0
}
5623
5624
/* Retrieves the size of the UTF-8 encoded command line arguments
5625
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
5626
 * The size includes the end of string character
5627
 * Returns 1 if successful, 0 if value is not available or -1 on error
5628
 */
5629
int liblnk_file_get_utf8_command_line_arguments_size(
5630
     liblnk_file_t *file,
5631
     size_t *utf8_string_size,
5632
     libcerror_error_t **error )
5633
0
{
5634
0
  liblnk_internal_file_t *internal_file = NULL;
5635
0
  static char *function                 = "liblnk_file_get_utf8_command_line_arguments_size";
5636
0
  int result                            = 0;
5637
5638
0
  if( file == NULL )
5639
0
  {
5640
0
    libcerror_error_set(
5641
0
     error,
5642
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5643
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5644
0
     "%s: invalid file.",
5645
0
     function );
5646
5647
0
    return( -1 );
5648
0
  }
5649
0
  internal_file = (liblnk_internal_file_t *) file;
5650
5651
0
  if( internal_file->io_handle == NULL )
5652
0
  {
5653
0
    libcerror_error_set(
5654
0
     error,
5655
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5656
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5657
0
     "%s: invalid file - missing IO handle.",
5658
0
     function );
5659
5660
0
    return( -1 );
5661
0
  }
5662
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5663
0
  if( libcthreads_read_write_lock_grab_for_read(
5664
0
       internal_file->read_write_lock,
5665
0
       error ) != 1 )
5666
0
  {
5667
0
    libcerror_error_set(
5668
0
     error,
5669
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5670
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5671
0
     "%s: unable to grab read/write lock for reading.",
5672
0
     function );
5673
5674
0
    return( -1 );
5675
0
  }
5676
0
#endif
5677
0
  if( internal_file->command_line_arguments != NULL )
5678
0
  {
5679
0
    result = liblnk_data_string_get_utf8_path_string_size(
5680
0
              internal_file->command_line_arguments,
5681
0
              internal_file->io_handle->ascii_codepage,
5682
0
              utf8_string_size,
5683
0
              error );
5684
5685
0
    if( result != 1 )
5686
0
    {
5687
0
      libcerror_error_set(
5688
0
       error,
5689
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5690
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5691
0
       "%s: unable to retrieve UTF-8 data string size.",
5692
0
       function );
5693
5694
0
      result = -1;
5695
0
    }
5696
0
  }
5697
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5698
0
  if( libcthreads_read_write_lock_release_for_read(
5699
0
       internal_file->read_write_lock,
5700
0
       error ) != 1 )
5701
0
  {
5702
0
    libcerror_error_set(
5703
0
     error,
5704
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5705
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5706
0
     "%s: unable to release read/write lock for reading.",
5707
0
     function );
5708
5709
0
    return( -1 );
5710
0
  }
5711
0
#endif
5712
0
  return( result );
5713
0
}
5714
5715
/* Retrieves the UTF-8 encoded command line arguments
5716
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
5717
 * The size should include the end of string character
5718
 * Returns 1 if successful, 0 if value is not available or -1 on error
5719
 */
5720
int liblnk_file_get_utf8_command_line_arguments(
5721
     liblnk_file_t *file,
5722
     uint8_t *utf8_string,
5723
     size_t utf8_string_size,
5724
     libcerror_error_t **error )
5725
0
{
5726
0
  liblnk_internal_file_t *internal_file = NULL;
5727
0
  static char *function                 = "liblnk_file_get_utf8_command_line_arguments";
5728
0
  int result                            = 0;
5729
5730
0
  if( file == NULL )
5731
0
  {
5732
0
    libcerror_error_set(
5733
0
     error,
5734
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5735
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5736
0
     "%s: invalid file.",
5737
0
     function );
5738
5739
0
    return( -1 );
5740
0
  }
5741
0
  internal_file = (liblnk_internal_file_t *) file;
5742
5743
0
  if( internal_file->io_handle == NULL )
5744
0
  {
5745
0
    libcerror_error_set(
5746
0
     error,
5747
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5748
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5749
0
     "%s: invalid file - missing IO handle.",
5750
0
     function );
5751
5752
0
    return( -1 );
5753
0
  }
5754
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5755
0
  if( libcthreads_read_write_lock_grab_for_read(
5756
0
       internal_file->read_write_lock,
5757
0
       error ) != 1 )
5758
0
  {
5759
0
    libcerror_error_set(
5760
0
     error,
5761
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5762
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5763
0
     "%s: unable to grab read/write lock for reading.",
5764
0
     function );
5765
5766
0
    return( -1 );
5767
0
  }
5768
0
#endif
5769
0
  if( internal_file->command_line_arguments != NULL )
5770
0
  {
5771
0
    result = liblnk_data_string_get_utf8_path_string(
5772
0
              internal_file->command_line_arguments,
5773
0
              internal_file->io_handle->ascii_codepage,
5774
0
              utf8_string,
5775
0
              utf8_string_size,
5776
0
              error );
5777
5778
0
    if( result != 1 )
5779
0
    {
5780
0
      libcerror_error_set(
5781
0
       error,
5782
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5783
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5784
0
       "%s: unable to set UTF-8 data string.",
5785
0
       function );
5786
5787
0
      result = -1;
5788
0
    }
5789
0
  }
5790
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5791
0
  if( libcthreads_read_write_lock_release_for_read(
5792
0
       internal_file->read_write_lock,
5793
0
       error ) != 1 )
5794
0
  {
5795
0
    libcerror_error_set(
5796
0
     error,
5797
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5798
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5799
0
     "%s: unable to release read/write lock for reading.",
5800
0
     function );
5801
5802
0
    return( -1 );
5803
0
  }
5804
0
#endif
5805
0
  return( result );
5806
0
}
5807
5808
/* Retrieves the size of the UTF-16 encoded command line arguments
5809
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
5810
 * The size includes the end of string character
5811
 * Returns 1 if successful, 0 if value is not available or -1 on error
5812
 */
5813
int liblnk_file_get_utf16_command_line_arguments_size(
5814
     liblnk_file_t *file,
5815
     size_t *utf16_string_size,
5816
     libcerror_error_t **error )
5817
0
{
5818
0
  liblnk_internal_file_t *internal_file = NULL;
5819
0
  static char *function                 = "liblnk_file_get_utf16_command_line_arguments_size";
5820
0
  int result                            = 0;
5821
5822
0
  if( file == NULL )
5823
0
  {
5824
0
    libcerror_error_set(
5825
0
     error,
5826
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5827
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5828
0
     "%s: invalid file.",
5829
0
     function );
5830
5831
0
    return( -1 );
5832
0
  }
5833
0
  internal_file = (liblnk_internal_file_t *) file;
5834
5835
0
  if( internal_file->io_handle == NULL )
5836
0
  {
5837
0
    libcerror_error_set(
5838
0
     error,
5839
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5840
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5841
0
     "%s: invalid file - missing IO handle.",
5842
0
     function );
5843
5844
0
    return( -1 );
5845
0
  }
5846
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5847
0
  if( libcthreads_read_write_lock_grab_for_read(
5848
0
       internal_file->read_write_lock,
5849
0
       error ) != 1 )
5850
0
  {
5851
0
    libcerror_error_set(
5852
0
     error,
5853
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5854
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5855
0
     "%s: unable to grab read/write lock for reading.",
5856
0
     function );
5857
5858
0
    return( -1 );
5859
0
  }
5860
0
#endif
5861
0
  if( internal_file->command_line_arguments != NULL )
5862
0
  {
5863
0
    result = liblnk_data_string_get_utf16_path_string_size(
5864
0
              internal_file->command_line_arguments,
5865
0
              internal_file->io_handle->ascii_codepage,
5866
0
              utf16_string_size,
5867
0
              error );
5868
5869
0
    if( result != 1 )
5870
0
    {
5871
0
      libcerror_error_set(
5872
0
       error,
5873
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5874
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5875
0
       "%s: unable to retrieve UTF-16 data string size.",
5876
0
       function );
5877
5878
0
      result = -1;
5879
0
    }
5880
0
  }
5881
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5882
0
  if( libcthreads_read_write_lock_release_for_read(
5883
0
       internal_file->read_write_lock,
5884
0
       error ) != 1 )
5885
0
  {
5886
0
    libcerror_error_set(
5887
0
     error,
5888
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5889
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5890
0
     "%s: unable to release read/write lock for reading.",
5891
0
     function );
5892
5893
0
    return( -1 );
5894
0
  }
5895
0
#endif
5896
0
  return( result );
5897
0
}
5898
5899
/* Retrieves the UTF-16 encoded command line arguments
5900
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
5901
 * The size should include the end of string character
5902
 * Returns 1 if successful, 0 if value is not available or -1 on error
5903
 */
5904
int liblnk_file_get_utf16_command_line_arguments(
5905
     liblnk_file_t *file,
5906
     uint16_t *utf16_string,
5907
     size_t utf16_string_size,
5908
     libcerror_error_t **error )
5909
0
{
5910
0
  liblnk_internal_file_t *internal_file = NULL;
5911
0
  static char *function                 = "liblnk_file_get_utf16_command_line_arguments";
5912
0
  int result                            = 0;
5913
5914
0
  if( file == NULL )
5915
0
  {
5916
0
    libcerror_error_set(
5917
0
     error,
5918
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5919
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5920
0
     "%s: invalid file.",
5921
0
     function );
5922
5923
0
    return( -1 );
5924
0
  }
5925
0
  internal_file = (liblnk_internal_file_t *) file;
5926
5927
0
  if( internal_file->io_handle == NULL )
5928
0
  {
5929
0
    libcerror_error_set(
5930
0
     error,
5931
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5932
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5933
0
     "%s: invalid file - missing IO handle.",
5934
0
     function );
5935
5936
0
    return( -1 );
5937
0
  }
5938
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5939
0
  if( libcthreads_read_write_lock_grab_for_read(
5940
0
       internal_file->read_write_lock,
5941
0
       error ) != 1 )
5942
0
  {
5943
0
    libcerror_error_set(
5944
0
     error,
5945
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5946
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5947
0
     "%s: unable to grab read/write lock for reading.",
5948
0
     function );
5949
5950
0
    return( -1 );
5951
0
  }
5952
0
#endif
5953
0
  if( internal_file->command_line_arguments != NULL )
5954
0
  {
5955
0
    result = liblnk_data_string_get_utf16_path_string(
5956
0
              internal_file->command_line_arguments,
5957
0
              internal_file->io_handle->ascii_codepage,
5958
0
              utf16_string,
5959
0
              utf16_string_size,
5960
0
              error );
5961
5962
0
    if( result != 1 )
5963
0
    {
5964
0
      libcerror_error_set(
5965
0
       error,
5966
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5967
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5968
0
       "%s: unable to set UTF-16 data string.",
5969
0
       function );
5970
5971
0
      result = -1;
5972
0
    }
5973
0
  }
5974
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
5975
0
  if( libcthreads_read_write_lock_release_for_read(
5976
0
       internal_file->read_write_lock,
5977
0
       error ) != 1 )
5978
0
  {
5979
0
    libcerror_error_set(
5980
0
     error,
5981
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5982
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5983
0
     "%s: unable to release read/write lock for reading.",
5984
0
     function );
5985
5986
0
    return( -1 );
5987
0
  }
5988
0
#endif
5989
0
  return( result );
5990
0
}
5991
5992
/* Retrieves the size of the UTF-8 encoded icon location
5993
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
5994
 * The size includes the end of string character
5995
 * Returns 1 if successful, 0 if value is not available or -1 on error
5996
 */
5997
int liblnk_file_get_utf8_icon_location_size(
5998
     liblnk_file_t *file,
5999
     size_t *utf8_string_size,
6000
     libcerror_error_t **error )
6001
0
{
6002
0
  liblnk_internal_file_t *internal_file = NULL;
6003
0
  static char *function                 = "liblnk_file_get_utf8_icon_location_size";
6004
0
  int result                            = 0;
6005
6006
0
  if( file == NULL )
6007
0
  {
6008
0
    libcerror_error_set(
6009
0
     error,
6010
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6011
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6012
0
     "%s: invalid file.",
6013
0
     function );
6014
6015
0
    return( -1 );
6016
0
  }
6017
0
  internal_file = (liblnk_internal_file_t *) file;
6018
6019
0
  if( internal_file->io_handle == NULL )
6020
0
  {
6021
0
    libcerror_error_set(
6022
0
     error,
6023
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6024
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6025
0
     "%s: invalid file - missing IO handle.",
6026
0
     function );
6027
6028
0
    return( -1 );
6029
0
  }
6030
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6031
0
  if( libcthreads_read_write_lock_grab_for_read(
6032
0
       internal_file->read_write_lock,
6033
0
       error ) != 1 )
6034
0
  {
6035
0
    libcerror_error_set(
6036
0
     error,
6037
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6038
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6039
0
     "%s: unable to grab read/write lock for reading.",
6040
0
     function );
6041
6042
0
    return( -1 );
6043
0
  }
6044
0
#endif
6045
0
  if( internal_file->icon_location != NULL )
6046
0
  {
6047
0
    result = liblnk_data_string_get_utf8_path_string_size(
6048
0
              internal_file->icon_location,
6049
0
              internal_file->io_handle->ascii_codepage,
6050
0
              utf8_string_size,
6051
0
              error );
6052
6053
0
    if( result != 1 )
6054
0
    {
6055
0
      libcerror_error_set(
6056
0
       error,
6057
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6058
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6059
0
       "%s: unable to retrieve UTF-8 data string size.",
6060
0
       function );
6061
6062
0
      result = -1;
6063
0
    }
6064
0
  }
6065
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6066
0
  if( libcthreads_read_write_lock_release_for_read(
6067
0
       internal_file->read_write_lock,
6068
0
       error ) != 1 )
6069
0
  {
6070
0
    libcerror_error_set(
6071
0
     error,
6072
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6073
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6074
0
     "%s: unable to release read/write lock for reading.",
6075
0
     function );
6076
6077
0
    return( -1 );
6078
0
  }
6079
0
#endif
6080
0
  return( result );
6081
0
}
6082
6083
/* Retrieves the UTF-8 encoded icon location
6084
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
6085
 * The size should include the end of string character
6086
 * Returns 1 if successful, 0 if value is not available or -1 on error
6087
 */
6088
int liblnk_file_get_utf8_icon_location(
6089
     liblnk_file_t *file,
6090
     uint8_t *utf8_string,
6091
     size_t utf8_string_size,
6092
     libcerror_error_t **error )
6093
0
{
6094
0
  liblnk_internal_file_t *internal_file = NULL;
6095
0
  static char *function                 = "liblnk_file_get_utf8_icon_location";
6096
0
  int result                            = 0;
6097
6098
0
  if( file == NULL )
6099
0
  {
6100
0
    libcerror_error_set(
6101
0
     error,
6102
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6103
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6104
0
     "%s: invalid file.",
6105
0
     function );
6106
6107
0
    return( -1 );
6108
0
  }
6109
0
  internal_file = (liblnk_internal_file_t *) file;
6110
6111
0
  if( internal_file->io_handle == NULL )
6112
0
  {
6113
0
    libcerror_error_set(
6114
0
     error,
6115
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6116
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6117
0
     "%s: invalid file - missing IO handle.",
6118
0
     function );
6119
6120
0
    return( -1 );
6121
0
  }
6122
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6123
0
  if( libcthreads_read_write_lock_grab_for_read(
6124
0
       internal_file->read_write_lock,
6125
0
       error ) != 1 )
6126
0
  {
6127
0
    libcerror_error_set(
6128
0
     error,
6129
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6130
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6131
0
     "%s: unable to grab read/write lock for reading.",
6132
0
     function );
6133
6134
0
    return( -1 );
6135
0
  }
6136
0
#endif
6137
0
  if( internal_file->icon_location != NULL )
6138
0
  {
6139
0
    result = liblnk_data_string_get_utf8_path_string(
6140
0
              internal_file->icon_location,
6141
0
              internal_file->io_handle->ascii_codepage,
6142
0
              utf8_string,
6143
0
              utf8_string_size,
6144
0
              error );
6145
6146
0
    if( result != 1 )
6147
0
    {
6148
0
      libcerror_error_set(
6149
0
       error,
6150
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6151
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6152
0
       "%s: unable to set UTF-8 data string.",
6153
0
       function );
6154
6155
0
      result = -1;
6156
0
    }
6157
0
  }
6158
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6159
0
  if( libcthreads_read_write_lock_release_for_read(
6160
0
       internal_file->read_write_lock,
6161
0
       error ) != 1 )
6162
0
  {
6163
0
    libcerror_error_set(
6164
0
     error,
6165
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6166
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6167
0
     "%s: unable to release read/write lock for reading.",
6168
0
     function );
6169
6170
0
    return( -1 );
6171
0
  }
6172
0
#endif
6173
0
  return( result );
6174
0
}
6175
6176
/* Retrieves the size of the UTF-16 encoded icon location
6177
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
6178
 * The size includes the end of string character
6179
 * Returns 1 if successful, 0 if value is not available or -1 on error
6180
 */
6181
int liblnk_file_get_utf16_icon_location_size(
6182
     liblnk_file_t *file,
6183
     size_t *utf16_string_size,
6184
     libcerror_error_t **error )
6185
0
{
6186
0
  liblnk_internal_file_t *internal_file = NULL;
6187
0
  static char *function                 = "liblnk_file_get_utf16_icon_location_size";
6188
0
  int result                            = 0;
6189
6190
0
  if( file == NULL )
6191
0
  {
6192
0
    libcerror_error_set(
6193
0
     error,
6194
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6195
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6196
0
     "%s: invalid file.",
6197
0
     function );
6198
6199
0
    return( -1 );
6200
0
  }
6201
0
  internal_file = (liblnk_internal_file_t *) file;
6202
6203
0
  if( internal_file->io_handle == NULL )
6204
0
  {
6205
0
    libcerror_error_set(
6206
0
     error,
6207
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6208
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6209
0
     "%s: invalid file - missing IO handle.",
6210
0
     function );
6211
6212
0
    return( -1 );
6213
0
  }
6214
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6215
0
  if( libcthreads_read_write_lock_grab_for_read(
6216
0
       internal_file->read_write_lock,
6217
0
       error ) != 1 )
6218
0
  {
6219
0
    libcerror_error_set(
6220
0
     error,
6221
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6222
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6223
0
     "%s: unable to grab read/write lock for reading.",
6224
0
     function );
6225
6226
0
    return( -1 );
6227
0
  }
6228
0
#endif
6229
0
  if( internal_file->icon_location != NULL )
6230
0
  {
6231
0
    result = liblnk_data_string_get_utf16_path_string_size(
6232
0
              internal_file->icon_location,
6233
0
              internal_file->io_handle->ascii_codepage,
6234
0
              utf16_string_size,
6235
0
              error );
6236
6237
0
    if( result != 1 )
6238
0
    {
6239
0
      libcerror_error_set(
6240
0
       error,
6241
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6242
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6243
0
       "%s: unable to retrieve UTF-16 data string size.",
6244
0
       function );
6245
6246
0
      result = -1;
6247
0
    }
6248
0
  }
6249
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6250
0
  if( libcthreads_read_write_lock_release_for_read(
6251
0
       internal_file->read_write_lock,
6252
0
       error ) != 1 )
6253
0
  {
6254
0
    libcerror_error_set(
6255
0
     error,
6256
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6257
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6258
0
     "%s: unable to release read/write lock for reading.",
6259
0
     function );
6260
6261
0
    return( -1 );
6262
0
  }
6263
0
#endif
6264
0
  return( result );
6265
0
}
6266
6267
/* Retrieves the UTF-16 encoded icon location
6268
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
6269
 * The size should include the end of string character
6270
 * Returns 1 if successful, 0 if value is not available or -1 on error
6271
 */
6272
int liblnk_file_get_utf16_icon_location(
6273
     liblnk_file_t *file,
6274
     uint16_t *utf16_string,
6275
     size_t utf16_string_size,
6276
     libcerror_error_t **error )
6277
0
{
6278
0
  liblnk_internal_file_t *internal_file = NULL;
6279
0
  static char *function                 = "liblnk_file_get_utf16_icon_location";
6280
0
  int result                            = 0;
6281
6282
0
  if( file == NULL )
6283
0
  {
6284
0
    libcerror_error_set(
6285
0
     error,
6286
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6287
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6288
0
     "%s: invalid file.",
6289
0
     function );
6290
6291
0
    return( -1 );
6292
0
  }
6293
0
  internal_file = (liblnk_internal_file_t *) file;
6294
6295
0
  if( internal_file->io_handle == NULL )
6296
0
  {
6297
0
    libcerror_error_set(
6298
0
     error,
6299
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6300
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6301
0
     "%s: invalid file - missing IO handle.",
6302
0
     function );
6303
6304
0
    return( -1 );
6305
0
  }
6306
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6307
0
  if( libcthreads_read_write_lock_grab_for_read(
6308
0
       internal_file->read_write_lock,
6309
0
       error ) != 1 )
6310
0
  {
6311
0
    libcerror_error_set(
6312
0
     error,
6313
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6314
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6315
0
     "%s: unable to grab read/write lock for reading.",
6316
0
     function );
6317
6318
0
    return( -1 );
6319
0
  }
6320
0
#endif
6321
0
  if( internal_file->icon_location != NULL )
6322
0
  {
6323
0
    result = liblnk_data_string_get_utf16_path_string(
6324
0
              internal_file->icon_location,
6325
0
              internal_file->io_handle->ascii_codepage,
6326
0
              utf16_string,
6327
0
              utf16_string_size,
6328
0
              error );
6329
6330
0
    if( result != 1 )
6331
0
    {
6332
0
      libcerror_error_set(
6333
0
       error,
6334
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6335
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6336
0
       "%s: unable to set UTF-16 data string.",
6337
0
       function );
6338
6339
0
      result = -1;
6340
0
    }
6341
0
  }
6342
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6343
0
  if( libcthreads_read_write_lock_release_for_read(
6344
0
       internal_file->read_write_lock,
6345
0
       error ) != 1 )
6346
0
  {
6347
0
    libcerror_error_set(
6348
0
     error,
6349
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6350
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6351
0
     "%s: unable to release read/write lock for reading.",
6352
0
     function );
6353
6354
0
    return( -1 );
6355
0
  }
6356
0
#endif
6357
0
  return( result );
6358
0
}
6359
6360
/* Retrieves the size of the UTF-8 encoded environment variables location
6361
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
6362
 * The size includes the end of string character
6363
 * Returns 1 if successful, 0 if value is not available or -1 on error
6364
 */
6365
int liblnk_file_get_utf8_environment_variables_location_size(
6366
     liblnk_file_t *file,
6367
     size_t *utf8_string_size,
6368
     libcerror_error_t **error )
6369
0
{
6370
0
  liblnk_internal_file_t *internal_file = NULL;
6371
0
  static char *function                 = "liblnk_file_get_utf8_environment_variables_location_size";
6372
0
  int result                            = 0;
6373
6374
0
  if( file == NULL )
6375
0
  {
6376
0
    libcerror_error_set(
6377
0
     error,
6378
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6379
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6380
0
     "%s: invalid file.",
6381
0
     function );
6382
6383
0
    return( -1 );
6384
0
  }
6385
0
  internal_file = (liblnk_internal_file_t *) file;
6386
6387
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6388
0
  if( libcthreads_read_write_lock_grab_for_read(
6389
0
       internal_file->read_write_lock,
6390
0
       error ) != 1 )
6391
0
  {
6392
0
    libcerror_error_set(
6393
0
     error,
6394
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6395
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6396
0
     "%s: unable to grab read/write lock for reading.",
6397
0
     function );
6398
6399
0
    return( -1 );
6400
0
  }
6401
0
#endif
6402
0
  if( internal_file->environment_variables_location_data_block != NULL )
6403
0
  {
6404
0
    result = liblnk_strings_data_block_get_utf8_path_string_size(
6405
0
              internal_file->environment_variables_location_data_block,
6406
0
              utf8_string_size,
6407
0
              error );
6408
6409
0
    if( result != 1 )
6410
0
    {
6411
0
      libcerror_error_set(
6412
0
       error,
6413
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6414
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6415
0
       "%s: unable to retrieve UTF-8 data string size.",
6416
0
       function );
6417
6418
0
      result = -1;
6419
0
    }
6420
0
  }
6421
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6422
0
  if( libcthreads_read_write_lock_release_for_read(
6423
0
       internal_file->read_write_lock,
6424
0
       error ) != 1 )
6425
0
  {
6426
0
    libcerror_error_set(
6427
0
     error,
6428
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6429
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6430
0
     "%s: unable to release read/write lock for reading.",
6431
0
     function );
6432
6433
0
    return( -1 );
6434
0
  }
6435
0
#endif
6436
0
  return( result );
6437
0
}
6438
6439
/* Retrieves the UTF-8 encoded environment variables location
6440
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
6441
 * The size should include the end of string character
6442
 * Returns 1 if successful, 0 if value is not available or -1 on error
6443
 */
6444
int liblnk_file_get_utf8_environment_variables_location(
6445
     liblnk_file_t *file,
6446
     uint8_t *utf8_string,
6447
     size_t utf8_string_size,
6448
     libcerror_error_t **error )
6449
0
{
6450
0
  liblnk_internal_file_t *internal_file = NULL;
6451
0
  static char *function                 = "liblnk_file_get_utf8_environment_variables_location";
6452
0
  int result                            = 0;
6453
6454
0
  if( file == NULL )
6455
0
  {
6456
0
    libcerror_error_set(
6457
0
     error,
6458
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6459
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6460
0
     "%s: invalid file.",
6461
0
     function );
6462
6463
0
    return( -1 );
6464
0
  }
6465
0
  internal_file = (liblnk_internal_file_t *) file;
6466
6467
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6468
0
  if( libcthreads_read_write_lock_grab_for_read(
6469
0
       internal_file->read_write_lock,
6470
0
       error ) != 1 )
6471
0
  {
6472
0
    libcerror_error_set(
6473
0
     error,
6474
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6475
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6476
0
     "%s: unable to grab read/write lock for reading.",
6477
0
     function );
6478
6479
0
    return( -1 );
6480
0
  }
6481
0
#endif
6482
0
  if( internal_file->environment_variables_location_data_block != NULL )
6483
0
  {
6484
0
    result = liblnk_strings_data_block_get_utf8_path_string(
6485
0
              internal_file->environment_variables_location_data_block,
6486
0
              utf8_string,
6487
0
              utf8_string_size,
6488
0
              error );
6489
6490
0
    if( result != 1 )
6491
0
    {
6492
0
      libcerror_error_set(
6493
0
       error,
6494
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6495
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6496
0
       "%s: unable to set UTF-8 data string.",
6497
0
       function );
6498
6499
0
      result = -1;
6500
0
    }
6501
0
  }
6502
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6503
0
  if( libcthreads_read_write_lock_release_for_read(
6504
0
       internal_file->read_write_lock,
6505
0
       error ) != 1 )
6506
0
  {
6507
0
    libcerror_error_set(
6508
0
     error,
6509
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6510
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6511
0
     "%s: unable to release read/write lock for reading.",
6512
0
     function );
6513
6514
0
    return( -1 );
6515
0
  }
6516
0
#endif
6517
0
  return( result );
6518
0
}
6519
6520
/* Retrieves the size of the UTF-16 encoded environment variables location
6521
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
6522
 * The size includes the end of string character
6523
 * Returns 1 if successful, 0 if value is not available or -1 on error
6524
 */
6525
int liblnk_file_get_utf16_environment_variables_location_size(
6526
     liblnk_file_t *file,
6527
     size_t *utf16_string_size,
6528
     libcerror_error_t **error )
6529
0
{
6530
0
  liblnk_internal_file_t *internal_file = NULL;
6531
0
  static char *function                 = "liblnk_file_get_utf16_environment_variables_location_size";
6532
0
  int result                            = 0;
6533
6534
0
  if( file == NULL )
6535
0
  {
6536
0
    libcerror_error_set(
6537
0
     error,
6538
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6539
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6540
0
     "%s: invalid file.",
6541
0
     function );
6542
6543
0
    return( -1 );
6544
0
  }
6545
0
  internal_file = (liblnk_internal_file_t *) file;
6546
6547
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6548
0
  if( libcthreads_read_write_lock_grab_for_read(
6549
0
       internal_file->read_write_lock,
6550
0
       error ) != 1 )
6551
0
  {
6552
0
    libcerror_error_set(
6553
0
     error,
6554
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6555
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6556
0
     "%s: unable to grab read/write lock for reading.",
6557
0
     function );
6558
6559
0
    return( -1 );
6560
0
  }
6561
0
#endif
6562
0
  if( internal_file->environment_variables_location_data_block != NULL )
6563
0
  {
6564
0
    result = liblnk_strings_data_block_get_utf16_path_string_size(
6565
0
              internal_file->environment_variables_location_data_block,
6566
0
              utf16_string_size,
6567
0
              error );
6568
6569
0
    if( result != 1 )
6570
0
    {
6571
0
      libcerror_error_set(
6572
0
       error,
6573
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6574
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6575
0
       "%s: unable to retrieve UTF-16 data string size.",
6576
0
       function );
6577
6578
0
      result = -1;
6579
0
    }
6580
0
  }
6581
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6582
0
  if( libcthreads_read_write_lock_release_for_read(
6583
0
       internal_file->read_write_lock,
6584
0
       error ) != 1 )
6585
0
  {
6586
0
    libcerror_error_set(
6587
0
     error,
6588
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6589
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6590
0
     "%s: unable to release read/write lock for reading.",
6591
0
     function );
6592
6593
0
    return( -1 );
6594
0
  }
6595
0
#endif
6596
0
  return( result );
6597
0
}
6598
6599
/* Retrieves the UTF-16 encoded environment variables location
6600
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
6601
 * The size should include the end of string character
6602
 * Returns 1 if successful, 0 if value is not available or -1 on error
6603
 */
6604
int liblnk_file_get_utf16_environment_variables_location(
6605
     liblnk_file_t *file,
6606
     uint16_t *utf16_string,
6607
     size_t utf16_string_size,
6608
     libcerror_error_t **error )
6609
0
{
6610
0
  liblnk_internal_file_t *internal_file = NULL;
6611
0
  static char *function                 = "liblnk_file_get_utf16_environment_variables_location";
6612
0
  int result                            = 0;
6613
6614
0
  if( file == NULL )
6615
0
  {
6616
0
    libcerror_error_set(
6617
0
     error,
6618
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6619
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6620
0
     "%s: invalid file.",
6621
0
     function );
6622
6623
0
    return( -1 );
6624
0
  }
6625
0
  internal_file = (liblnk_internal_file_t *) file;
6626
6627
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6628
0
  if( libcthreads_read_write_lock_grab_for_read(
6629
0
       internal_file->read_write_lock,
6630
0
       error ) != 1 )
6631
0
  {
6632
0
    libcerror_error_set(
6633
0
     error,
6634
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6635
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6636
0
     "%s: unable to grab read/write lock for reading.",
6637
0
     function );
6638
6639
0
    return( -1 );
6640
0
  }
6641
0
#endif
6642
0
  if( internal_file->environment_variables_location_data_block != NULL )
6643
0
  {
6644
0
    result = liblnk_strings_data_block_get_utf16_path_string(
6645
0
              internal_file->environment_variables_location_data_block,
6646
0
              utf16_string,
6647
0
              utf16_string_size,
6648
0
              error );
6649
6650
0
    if( result != 1 )
6651
0
    {
6652
0
      libcerror_error_set(
6653
0
       error,
6654
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6655
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6656
0
       "%s: unable to set UTF-16 data string.",
6657
0
       function );
6658
6659
0
      result = -1;
6660
0
    }
6661
0
  }
6662
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6663
0
  if( libcthreads_read_write_lock_release_for_read(
6664
0
       internal_file->read_write_lock,
6665
0
       error ) != 1 )
6666
0
  {
6667
0
    libcerror_error_set(
6668
0
     error,
6669
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6670
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6671
0
     "%s: unable to release read/write lock for reading.",
6672
0
     function );
6673
6674
0
    return( -1 );
6675
0
  }
6676
0
#endif
6677
0
  return( result );
6678
0
}
6679
6680
/* Retrieves the link target identifier data size
6681
 * The link target identifier contains a shell item (identifier) list
6682
 * Returns 1 if successful, 0 if value is not available or -1 on error
6683
 */
6684
int liblnk_file_get_link_target_identifier_data_size(
6685
     liblnk_file_t *file,
6686
     size_t *data_size,
6687
     libcerror_error_t **error )
6688
0
{
6689
0
  liblnk_internal_file_t *internal_file = NULL;
6690
0
  static char *function                 = "liblnk_file_get_link_target_identifier_data_size";
6691
0
  int result                            = 0;
6692
6693
0
  if( file == NULL )
6694
0
  {
6695
0
    libcerror_error_set(
6696
0
     error,
6697
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6698
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6699
0
     "%s: invalid file.",
6700
0
     function );
6701
6702
0
    return( -1 );
6703
0
  }
6704
0
  internal_file = (liblnk_internal_file_t *) file;
6705
6706
0
  if( internal_file->io_handle == NULL )
6707
0
  {
6708
0
    libcerror_error_set(
6709
0
     error,
6710
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6711
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6712
0
     "%s: invalid file - missing IO handle.",
6713
0
     function );
6714
6715
0
    return( -1 );
6716
0
  }
6717
0
  if( data_size == NULL )
6718
0
  {
6719
0
    libcerror_error_set(
6720
0
     error,
6721
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6722
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6723
0
     "%s: invalid data size.",
6724
0
     function );
6725
6726
0
    return( -1 );
6727
0
  }
6728
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6729
0
  if( libcthreads_read_write_lock_grab_for_read(
6730
0
       internal_file->read_write_lock,
6731
0
       error ) != 1 )
6732
0
  {
6733
0
    libcerror_error_set(
6734
0
     error,
6735
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6736
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6737
0
     "%s: unable to grab read/write lock for reading.",
6738
0
     function );
6739
6740
0
    return( -1 );
6741
0
  }
6742
0
#endif
6743
0
  if( internal_file->link_target_identifier != NULL )
6744
0
  {
6745
0
    *data_size = internal_file->link_target_identifier->data_size;
6746
6747
0
    result = 1;
6748
0
  }
6749
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6750
0
  if( libcthreads_read_write_lock_release_for_read(
6751
0
       internal_file->read_write_lock,
6752
0
       error ) != 1 )
6753
0
  {
6754
0
    libcerror_error_set(
6755
0
     error,
6756
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6757
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6758
0
     "%s: unable to release read/write lock for reading.",
6759
0
     function );
6760
6761
0
    return( -1 );
6762
0
  }
6763
0
#endif
6764
0
  return( result );
6765
0
}
6766
6767
/* Retrieves the link target identifier data
6768
 * The link target identifier contains a shell item (identifier) list
6769
 * Returns 1 if successful, 0 if value is not available or -1 on error
6770
 */
6771
int liblnk_file_copy_link_target_identifier_data(
6772
     liblnk_file_t *file,
6773
     uint8_t *data,
6774
     size_t data_size,
6775
     libcerror_error_t **error )
6776
0
{
6777
0
  liblnk_internal_file_t *internal_file = NULL;
6778
0
  static char *function                 = "liblnk_file_copy_link_target_identifier_data";
6779
0
  int result                            = 0;
6780
6781
0
  if( file == NULL )
6782
0
  {
6783
0
    libcerror_error_set(
6784
0
     error,
6785
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6786
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6787
0
     "%s: invalid file.",
6788
0
     function );
6789
6790
0
    return( -1 );
6791
0
  }
6792
0
  internal_file = (liblnk_internal_file_t *) file;
6793
6794
0
  if( internal_file->io_handle == NULL )
6795
0
  {
6796
0
    libcerror_error_set(
6797
0
     error,
6798
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6799
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6800
0
     "%s: invalid file - missing IO handle.",
6801
0
     function );
6802
6803
0
    return( -1 );
6804
0
  }
6805
0
  if( data == NULL )
6806
0
  {
6807
0
    libcerror_error_set(
6808
0
     error,
6809
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6810
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6811
0
     "%s: invalid data.",
6812
0
     function );
6813
6814
0
    return( -1 );
6815
0
  }
6816
0
  if( data_size > (size_t) SSIZE_MAX )
6817
0
  {
6818
0
    libcerror_error_set(
6819
0
     error,
6820
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6821
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
6822
0
     "%s: invalid data size value exceeds maximum.",
6823
0
     function );
6824
6825
0
    return( -1 );
6826
0
  }
6827
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6828
0
  if( libcthreads_read_write_lock_grab_for_read(
6829
0
       internal_file->read_write_lock,
6830
0
       error ) != 1 )
6831
0
  {
6832
0
    libcerror_error_set(
6833
0
     error,
6834
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6835
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6836
0
     "%s: unable to grab read/write lock for reading.",
6837
0
     function );
6838
6839
0
    return( -1 );
6840
0
  }
6841
0
#endif
6842
0
  if( internal_file->link_target_identifier != NULL )
6843
0
  {
6844
0
    result = 1;
6845
6846
0
    if( data_size < internal_file->link_target_identifier->data_size )
6847
0
    {
6848
0
      libcerror_error_set(
6849
0
       error,
6850
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6851
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
6852
0
       "%s: data value too small.",
6853
0
       function );
6854
6855
0
      result = -1;
6856
0
    }
6857
0
    else if( memory_copy(
6858
0
              data,
6859
0
              internal_file->link_target_identifier->data,
6860
0
              internal_file->link_target_identifier->data_size ) == NULL )
6861
0
    {
6862
0
      libcerror_error_set(
6863
0
       error,
6864
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
6865
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
6866
0
       "%s: unable to copy link target identifier data.",
6867
0
       function );
6868
6869
0
      result = -1;
6870
0
    }
6871
0
  }
6872
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6873
0
  if( libcthreads_read_write_lock_release_for_read(
6874
0
       internal_file->read_write_lock,
6875
0
       error ) != 1 )
6876
0
  {
6877
0
    libcerror_error_set(
6878
0
     error,
6879
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6880
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6881
0
     "%s: unable to release read/write lock for reading.",
6882
0
     function );
6883
6884
0
    return( -1 );
6885
0
  }
6886
0
#endif
6887
0
  return( result );
6888
0
}
6889
6890
/* -------------------------------------------------------------------------
6891
 * Distributed link tracking data functions
6892
 * ------------------------------------------------------------------------- */
6893
6894
/* Determines if the file contains distributed link tracking data
6895
 * Returns 1 if the file contains such data, 0 if not or -1 on error
6896
 */
6897
int liblnk_file_has_distributed_link_tracking_data(
6898
     liblnk_file_t *file,
6899
     libcerror_error_t **error )
6900
0
{
6901
0
  liblnk_internal_file_t *internal_file = NULL;
6902
0
  static char *function                 = "liblnk_file_has_distributed_link_tracking_data";
6903
0
  int result                            = 0;
6904
6905
0
  if( file == NULL )
6906
0
  {
6907
0
    libcerror_error_set(
6908
0
     error,
6909
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6910
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6911
0
     "%s: invalid file.",
6912
0
     function );
6913
6914
0
    return( -1 );
6915
0
  }
6916
0
  internal_file = (liblnk_internal_file_t *) file;
6917
6918
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6919
0
  if( libcthreads_read_write_lock_grab_for_read(
6920
0
       internal_file->read_write_lock,
6921
0
       error ) != 1 )
6922
0
  {
6923
0
    libcerror_error_set(
6924
0
     error,
6925
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6926
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6927
0
     "%s: unable to grab read/write lock for reading.",
6928
0
     function );
6929
6930
0
    return( -1 );
6931
0
  }
6932
0
#endif
6933
0
  if( internal_file->distributed_link_tracking_data_block != NULL )
6934
0
  {
6935
0
    result = 1;
6936
0
  }
6937
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6938
0
  if( libcthreads_read_write_lock_release_for_read(
6939
0
       internal_file->read_write_lock,
6940
0
       error ) != 1 )
6941
0
  {
6942
0
    libcerror_error_set(
6943
0
     error,
6944
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6945
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6946
0
     "%s: unable to release read/write lock for reading.",
6947
0
     function );
6948
6949
0
    return( -1 );
6950
0
  }
6951
0
#endif
6952
0
  return( result );
6953
0
}
6954
6955
/* Retrieves the size of the UTF-8 encoded machine identifier
6956
 * The size includes the end of string character
6957
 * Returns 1 if successful, 0 if value is not available or -1 on error
6958
 */
6959
int liblnk_file_get_utf8_machine_identifier_size(
6960
     liblnk_file_t *file,
6961
     size_t *utf8_string_size,
6962
     libcerror_error_t **error )
6963
0
{
6964
0
  liblnk_internal_file_t *internal_file = NULL;
6965
0
  static char *function                 = "liblnk_file_get_utf8_machine_identifier_size";
6966
0
  int result                            = 0;
6967
6968
0
  if( file == NULL )
6969
0
  {
6970
0
    libcerror_error_set(
6971
0
     error,
6972
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6973
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6974
0
     "%s: invalid file.",
6975
0
     function );
6976
6977
0
    return( -1 );
6978
0
  }
6979
0
  internal_file = (liblnk_internal_file_t *) file;
6980
6981
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
6982
0
  if( libcthreads_read_write_lock_grab_for_read(
6983
0
       internal_file->read_write_lock,
6984
0
       error ) != 1 )
6985
0
  {
6986
0
    libcerror_error_set(
6987
0
     error,
6988
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6989
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6990
0
     "%s: unable to grab read/write lock for reading.",
6991
0
     function );
6992
6993
0
    return( -1 );
6994
0
  }
6995
0
#endif
6996
0
  if( internal_file->distributed_link_tracking_data_block != NULL )
6997
0
  {
6998
0
    result = liblnk_distributed_link_tracking_data_block_get_utf8_machine_identifier_size(
6999
0
              internal_file->distributed_link_tracking_data_block,
7000
0
              utf8_string_size,
7001
0
              error );
7002
7003
0
    if( result != 1 )
7004
0
    {
7005
0
      libcerror_error_set(
7006
0
       error,
7007
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7008
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7009
0
       "%s: unable to retrieve UTF-8 machine identifier string size.",
7010
0
       function );
7011
7012
0
      result = -1;
7013
0
    }
7014
0
  }
7015
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7016
0
  if( libcthreads_read_write_lock_release_for_read(
7017
0
       internal_file->read_write_lock,
7018
0
       error ) != 1 )
7019
0
  {
7020
0
    libcerror_error_set(
7021
0
     error,
7022
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7023
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7024
0
     "%s: unable to release read/write lock for reading.",
7025
0
     function );
7026
7027
0
    return( -1 );
7028
0
  }
7029
0
#endif
7030
0
  return( result );
7031
0
}
7032
7033
/* Retrieves the UTF-8 encoded machine identifier
7034
 * The size should include the end of string character
7035
 * Returns 1 if successful, 0 if value is not available or -1 on error
7036
 */
7037
int liblnk_file_get_utf8_machine_identifier(
7038
     liblnk_file_t *file,
7039
     uint8_t *utf8_string,
7040
     size_t utf8_string_size,
7041
     libcerror_error_t **error )
7042
0
{
7043
0
  liblnk_internal_file_t *internal_file = NULL;
7044
0
  static char *function                 = "liblnk_file_get_utf8_machine_identifier";
7045
0
  int result                            = 0;
7046
7047
0
  if( file == NULL )
7048
0
  {
7049
0
    libcerror_error_set(
7050
0
     error,
7051
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7052
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7053
0
     "%s: invalid file.",
7054
0
     function );
7055
7056
0
    return( -1 );
7057
0
  }
7058
0
  internal_file = (liblnk_internal_file_t *) file;
7059
7060
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7061
0
  if( libcthreads_read_write_lock_grab_for_read(
7062
0
       internal_file->read_write_lock,
7063
0
       error ) != 1 )
7064
0
  {
7065
0
    libcerror_error_set(
7066
0
     error,
7067
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7068
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7069
0
     "%s: unable to grab read/write lock for reading.",
7070
0
     function );
7071
7072
0
    return( -1 );
7073
0
  }
7074
0
#endif
7075
0
  if( internal_file->distributed_link_tracking_data_block != NULL )
7076
0
  {
7077
0
    result = liblnk_distributed_link_tracking_data_block_get_utf8_machine_identifier(
7078
0
              internal_file->distributed_link_tracking_data_block,
7079
0
              utf8_string,
7080
0
              utf8_string_size,
7081
0
              error );
7082
7083
0
    if( result != 1 )
7084
0
    {
7085
0
      libcerror_error_set(
7086
0
       error,
7087
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7088
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7089
0
       "%s: unable to retrieve UTF-8 machine identifier string.",
7090
0
       function );
7091
7092
0
      result = -1;
7093
0
    }
7094
0
  }
7095
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7096
0
  if( libcthreads_read_write_lock_release_for_read(
7097
0
       internal_file->read_write_lock,
7098
0
       error ) != 1 )
7099
0
  {
7100
0
    libcerror_error_set(
7101
0
     error,
7102
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7103
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7104
0
     "%s: unable to release read/write lock for reading.",
7105
0
     function );
7106
7107
0
    return( -1 );
7108
0
  }
7109
0
#endif
7110
0
  return( result );
7111
0
}
7112
7113
/* Retrieves the size of the UTF-16 encoded machine identifier
7114
 * The size includes the end of string character
7115
 * Returns 1 if successful, 0 if value is not available or -1 on error
7116
 */
7117
int liblnk_file_get_utf16_machine_identifier_size(
7118
     liblnk_file_t *file,
7119
     size_t *utf16_string_size,
7120
     libcerror_error_t **error )
7121
0
{
7122
0
  liblnk_internal_file_t *internal_file = NULL;
7123
0
  static char *function                 = "liblnk_file_get_utf16_machine_identifier_size";
7124
0
  int result                            = 0;
7125
7126
0
  if( file == NULL )
7127
0
  {
7128
0
    libcerror_error_set(
7129
0
     error,
7130
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7131
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7132
0
     "%s: invalid file.",
7133
0
     function );
7134
7135
0
    return( -1 );
7136
0
  }
7137
0
  internal_file = (liblnk_internal_file_t *) file;
7138
7139
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7140
0
  if( libcthreads_read_write_lock_grab_for_read(
7141
0
       internal_file->read_write_lock,
7142
0
       error ) != 1 )
7143
0
  {
7144
0
    libcerror_error_set(
7145
0
     error,
7146
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7147
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7148
0
     "%s: unable to grab read/write lock for reading.",
7149
0
     function );
7150
7151
0
    return( -1 );
7152
0
  }
7153
0
#endif
7154
0
  if( internal_file->distributed_link_tracking_data_block != NULL )
7155
0
  {
7156
0
    result = liblnk_distributed_link_tracking_data_block_get_utf16_machine_identifier_size(
7157
0
              internal_file->distributed_link_tracking_data_block,
7158
0
              utf16_string_size,
7159
0
              error );
7160
7161
0
    if( result != 1 )
7162
0
    {
7163
0
      libcerror_error_set(
7164
0
       error,
7165
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7166
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7167
0
       "%s: unable to retrieve UTF-16 machine identifier string size.",
7168
0
       function );
7169
7170
0
      result = -1;
7171
0
    }
7172
0
  }
7173
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7174
0
  if( libcthreads_read_write_lock_release_for_read(
7175
0
       internal_file->read_write_lock,
7176
0
       error ) != 1 )
7177
0
  {
7178
0
    libcerror_error_set(
7179
0
     error,
7180
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7181
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7182
0
     "%s: unable to release read/write lock for reading.",
7183
0
     function );
7184
7185
0
    return( -1 );
7186
0
  }
7187
0
#endif
7188
0
  return( result );
7189
0
}
7190
7191
/* Retrieves the UTF-16 encoded machine identifier
7192
 * The size should include the end of string character
7193
 * Returns 1 if successful, 0 if value is not available or -1 on error
7194
 */
7195
int liblnk_file_get_utf16_machine_identifier(
7196
     liblnk_file_t *file,
7197
     uint16_t *utf16_string,
7198
     size_t utf16_string_size,
7199
     libcerror_error_t **error )
7200
0
{
7201
0
  liblnk_internal_file_t *internal_file = NULL;
7202
0
  static char *function                 = "liblnk_file_get_utf16_machine_identifier";
7203
0
  int result                            = 0;
7204
7205
0
  if( file == NULL )
7206
0
  {
7207
0
    libcerror_error_set(
7208
0
     error,
7209
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7210
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7211
0
     "%s: invalid file.",
7212
0
     function );
7213
7214
0
    return( -1 );
7215
0
  }
7216
0
  internal_file = (liblnk_internal_file_t *) file;
7217
7218
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7219
0
  if( libcthreads_read_write_lock_grab_for_read(
7220
0
       internal_file->read_write_lock,
7221
0
       error ) != 1 )
7222
0
  {
7223
0
    libcerror_error_set(
7224
0
     error,
7225
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7226
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7227
0
     "%s: unable to grab read/write lock for reading.",
7228
0
     function );
7229
7230
0
    return( -1 );
7231
0
  }
7232
0
#endif
7233
0
  if( internal_file->distributed_link_tracking_data_block != NULL )
7234
0
  {
7235
0
    result = liblnk_distributed_link_tracking_data_block_get_utf16_machine_identifier(
7236
0
              internal_file->distributed_link_tracking_data_block,
7237
0
              utf16_string,
7238
0
              utf16_string_size,
7239
0
              error );
7240
7241
0
    if( result != 1 )
7242
0
    {
7243
0
      libcerror_error_set(
7244
0
       error,
7245
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7246
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7247
0
       "%s: unable to retrieve UTF-16 machine identifier string.",
7248
0
       function );
7249
7250
0
      result = -1;
7251
0
    }
7252
0
  }
7253
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7254
0
  if( libcthreads_read_write_lock_release_for_read(
7255
0
       internal_file->read_write_lock,
7256
0
       error ) != 1 )
7257
0
  {
7258
0
    libcerror_error_set(
7259
0
     error,
7260
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7261
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7262
0
     "%s: unable to release read/write lock for reading.",
7263
0
     function );
7264
7265
0
    return( -1 );
7266
0
  }
7267
0
#endif
7268
0
  return( result );
7269
0
}
7270
7271
/* Retrieves the droid volume identifier
7272
 * The identifier is a GUID stored in little-endian and is 16 bytes of size
7273
 * Returns 1 if successful, 0 if value is not available or -1 on error
7274
 */
7275
int liblnk_file_get_droid_volume_identifier(
7276
     liblnk_file_t *file,
7277
     uint8_t *guid_data,
7278
     size_t guid_data_size,
7279
     libcerror_error_t **error )
7280
0
{
7281
0
  liblnk_internal_file_t *internal_file = NULL;
7282
0
  static char *function                 = "liblnk_file_get_droid_volume_identifier";
7283
0
  int result                            = 0;
7284
7285
0
  if( file == NULL )
7286
0
  {
7287
0
    libcerror_error_set(
7288
0
     error,
7289
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7290
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7291
0
     "%s: invalid file.",
7292
0
     function );
7293
7294
0
    return( -1 );
7295
0
  }
7296
0
  internal_file = (liblnk_internal_file_t *) file;
7297
7298
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7299
0
  if( libcthreads_read_write_lock_grab_for_read(
7300
0
       internal_file->read_write_lock,
7301
0
       error ) != 1 )
7302
0
  {
7303
0
    libcerror_error_set(
7304
0
     error,
7305
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7306
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7307
0
     "%s: unable to grab read/write lock for reading.",
7308
0
     function );
7309
7310
0
    return( -1 );
7311
0
  }
7312
0
#endif
7313
0
  if( internal_file->distributed_link_tracking_data_block != NULL )
7314
0
  {
7315
0
    result = liblnk_distributed_link_tracking_data_block_get_droid_volume_identifier(
7316
0
              internal_file->distributed_link_tracking_data_block,
7317
0
              guid_data,
7318
0
              guid_data_size,
7319
0
              error );
7320
7321
0
    if( result != 1 )
7322
0
    {
7323
0
      libcerror_error_set(
7324
0
       error,
7325
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
7326
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
7327
0
       "%s: unable to copy droid volume identifier.",
7328
0
       function );
7329
7330
0
      result = -1;
7331
0
    }
7332
0
  }
7333
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7334
0
  if( libcthreads_read_write_lock_release_for_read(
7335
0
       internal_file->read_write_lock,
7336
0
       error ) != 1 )
7337
0
  {
7338
0
    libcerror_error_set(
7339
0
     error,
7340
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7341
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7342
0
     "%s: unable to release read/write lock for reading.",
7343
0
     function );
7344
7345
0
    return( -1 );
7346
0
  }
7347
0
#endif
7348
0
  return( result );
7349
0
}
7350
7351
/* Retrieves the droid file identifier
7352
 * The identifier is a GUID stored in little-endian and is 16 bytes of size
7353
 * Returns 1 if successful, 0 if value is not available or -1 on error
7354
 */
7355
int liblnk_file_get_droid_file_identifier(
7356
     liblnk_file_t *file,
7357
     uint8_t *guid_data,
7358
     size_t guid_data_size,
7359
     libcerror_error_t **error )
7360
0
{
7361
0
  liblnk_internal_file_t *internal_file = NULL;
7362
0
  static char *function                 = "liblnk_file_get_droid_file_identifier";
7363
0
  int result                            = 0;
7364
7365
0
  if( file == NULL )
7366
0
  {
7367
0
    libcerror_error_set(
7368
0
     error,
7369
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7370
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7371
0
     "%s: invalid file.",
7372
0
     function );
7373
7374
0
    return( -1 );
7375
0
  }
7376
0
  internal_file = (liblnk_internal_file_t *) file;
7377
7378
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7379
0
  if( libcthreads_read_write_lock_grab_for_read(
7380
0
       internal_file->read_write_lock,
7381
0
       error ) != 1 )
7382
0
  {
7383
0
    libcerror_error_set(
7384
0
     error,
7385
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7386
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7387
0
     "%s: unable to grab read/write lock for reading.",
7388
0
     function );
7389
7390
0
    return( -1 );
7391
0
  }
7392
0
#endif
7393
0
  if( internal_file->distributed_link_tracking_data_block != NULL )
7394
0
  {
7395
0
    result = liblnk_distributed_link_tracking_data_block_get_droid_file_identifier(
7396
0
              internal_file->distributed_link_tracking_data_block,
7397
0
              guid_data,
7398
0
              guid_data_size,
7399
0
              error );
7400
7401
0
    if( result != 1 )
7402
0
    {
7403
0
      libcerror_error_set(
7404
0
       error,
7405
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
7406
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
7407
0
       "%s: unable to copy droid file identifier.",
7408
0
       function );
7409
7410
0
      result = -1;
7411
0
    }
7412
0
  }
7413
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7414
0
  if( libcthreads_read_write_lock_release_for_read(
7415
0
       internal_file->read_write_lock,
7416
0
       error ) != 1 )
7417
0
  {
7418
0
    libcerror_error_set(
7419
0
     error,
7420
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7421
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7422
0
     "%s: unable to release read/write lock for reading.",
7423
0
     function );
7424
7425
0
    return( -1 );
7426
0
  }
7427
0
#endif
7428
0
  return( result );
7429
0
}
7430
7431
/* Retrieves the birth droid volume identifier
7432
 * The identifier is a GUID stored in little-endian and is 16 bytes of size
7433
 * Returns 1 if successful, 0 if value is not available or -1 on error
7434
 */
7435
int liblnk_file_get_birth_droid_volume_identifier(
7436
     liblnk_file_t *file,
7437
     uint8_t *guid_data,
7438
     size_t guid_data_size,
7439
     libcerror_error_t **error )
7440
0
{
7441
0
  liblnk_internal_file_t *internal_file = NULL;
7442
0
  static char *function                 = "liblnk_file_get_birth_droid_volume_identifier";
7443
0
  int result                            = 0;
7444
7445
0
  if( file == NULL )
7446
0
  {
7447
0
    libcerror_error_set(
7448
0
     error,
7449
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7450
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7451
0
     "%s: invalid file.",
7452
0
     function );
7453
7454
0
    return( -1 );
7455
0
  }
7456
0
  internal_file = (liblnk_internal_file_t *) file;
7457
7458
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7459
0
  if( libcthreads_read_write_lock_grab_for_read(
7460
0
       internal_file->read_write_lock,
7461
0
       error ) != 1 )
7462
0
  {
7463
0
    libcerror_error_set(
7464
0
     error,
7465
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7466
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7467
0
     "%s: unable to grab read/write lock for reading.",
7468
0
     function );
7469
7470
0
    return( -1 );
7471
0
  }
7472
0
#endif
7473
0
  if( internal_file->distributed_link_tracking_data_block != NULL )
7474
0
  {
7475
0
    result = liblnk_distributed_link_tracking_data_block_get_birth_droid_volume_identifier(
7476
0
              internal_file->distributed_link_tracking_data_block,
7477
0
              guid_data,
7478
0
              guid_data_size,
7479
0
              error );
7480
7481
0
    if( result != 1 )
7482
0
    {
7483
0
      libcerror_error_set(
7484
0
       error,
7485
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
7486
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
7487
0
       "%s: unable to copy birth droid volume identifier.",
7488
0
       function );
7489
7490
0
      result = -1;
7491
0
    }
7492
0
  }
7493
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7494
0
  if( libcthreads_read_write_lock_release_for_read(
7495
0
       internal_file->read_write_lock,
7496
0
       error ) != 1 )
7497
0
  {
7498
0
    libcerror_error_set(
7499
0
     error,
7500
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7501
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7502
0
     "%s: unable to release read/write lock for reading.",
7503
0
     function );
7504
7505
0
    return( -1 );
7506
0
  }
7507
0
#endif
7508
0
  return( result );
7509
0
}
7510
7511
/* Retrieves the birth droid file identifier
7512
 * The identifier is a GUID stored in little-endian and is 16 bytes of size
7513
 * Returns 1 if successful, 0 if value is not available or -1 on error
7514
 */
7515
int liblnk_file_get_birth_droid_file_identifier(
7516
     liblnk_file_t *file,
7517
     uint8_t *guid_data,
7518
     size_t guid_data_size,
7519
     libcerror_error_t **error )
7520
0
{
7521
0
  liblnk_internal_file_t *internal_file = NULL;
7522
0
  static char *function                 = "liblnk_file_get_birth_droid_file_identifier";
7523
0
  int result                            = 0;
7524
7525
0
  if( file == NULL )
7526
0
  {
7527
0
    libcerror_error_set(
7528
0
     error,
7529
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7530
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7531
0
     "%s: invalid file.",
7532
0
     function );
7533
7534
0
    return( -1 );
7535
0
  }
7536
0
  internal_file = (liblnk_internal_file_t *) file;
7537
7538
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7539
0
  if( libcthreads_read_write_lock_grab_for_read(
7540
0
       internal_file->read_write_lock,
7541
0
       error ) != 1 )
7542
0
  {
7543
0
    libcerror_error_set(
7544
0
     error,
7545
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7546
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7547
0
     "%s: unable to grab read/write lock for reading.",
7548
0
     function );
7549
7550
0
    return( -1 );
7551
0
  }
7552
0
#endif
7553
0
  if( internal_file->distributed_link_tracking_data_block != NULL )
7554
0
  {
7555
0
    result = liblnk_distributed_link_tracking_data_block_get_birth_droid_file_identifier(
7556
0
              internal_file->distributed_link_tracking_data_block,
7557
0
              guid_data,
7558
0
              guid_data_size,
7559
0
              error );
7560
7561
0
    if( result != 1 )
7562
0
    {
7563
0
      libcerror_error_set(
7564
0
       error,
7565
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
7566
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
7567
0
       "%s: unable to copy birth droid file identifier.",
7568
0
       function );
7569
7570
0
      result = -1;
7571
0
    }
7572
0
  }
7573
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7574
0
  if( libcthreads_read_write_lock_release_for_read(
7575
0
       internal_file->read_write_lock,
7576
0
       error ) != 1 )
7577
0
  {
7578
0
    libcerror_error_set(
7579
0
     error,
7580
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7581
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7582
0
     "%s: unable to release read/write lock for reading.",
7583
0
     function );
7584
7585
0
    return( -1 );
7586
0
  }
7587
0
#endif
7588
0
  return( result );
7589
0
}
7590
7591
/* -------------------------------------------------------------------------
7592
 * Data block functions
7593
 * ------------------------------------------------------------------------- */
7594
7595
/* Retrieves the number of (extra) data blocks
7596
 * Returns 1 if successful or -1 on error
7597
 */
7598
int liblnk_file_get_number_of_data_blocks(
7599
     liblnk_file_t *file,
7600
     int *number_of_data_blocks,
7601
     libcerror_error_t **error )
7602
0
{
7603
0
  liblnk_internal_file_t *internal_file = NULL;
7604
0
  static char *function                 = "liblnk_file_get_number_of_data_blocks";
7605
0
  int result                            = 1;
7606
7607
0
  if( file == NULL )
7608
0
  {
7609
0
    libcerror_error_set(
7610
0
     error,
7611
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7612
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7613
0
     "%s: invalid file.",
7614
0
     function );
7615
7616
0
    return( -1 );
7617
0
  }
7618
0
  internal_file = (liblnk_internal_file_t *) file;
7619
7620
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7621
0
  if( libcthreads_read_write_lock_grab_for_read(
7622
0
       internal_file->read_write_lock,
7623
0
       error ) != 1 )
7624
0
  {
7625
0
    libcerror_error_set(
7626
0
     error,
7627
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7628
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7629
0
     "%s: unable to grab read/write lock for reading.",
7630
0
     function );
7631
7632
0
    return( -1 );
7633
0
  }
7634
0
#endif
7635
0
  if( libcdata_array_get_number_of_entries(
7636
0
       internal_file->data_blocks_array,
7637
0
       number_of_data_blocks,
7638
0
       error ) != 1 )
7639
0
  {
7640
0
    libcerror_error_set(
7641
0
     error,
7642
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7643
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7644
0
     "%s: unable to retrieve number of data blocks.",
7645
0
     function );
7646
7647
0
    result = -1;
7648
0
  }
7649
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7650
0
  if( libcthreads_read_write_lock_release_for_read(
7651
0
       internal_file->read_write_lock,
7652
0
       error ) != 1 )
7653
0
  {
7654
0
    libcerror_error_set(
7655
0
     error,
7656
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7657
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7658
0
     "%s: unable to release read/write lock for reading.",
7659
0
     function );
7660
7661
0
    return( -1 );
7662
0
  }
7663
0
#endif
7664
0
  return( result );
7665
0
}
7666
7667
/* Retrieves a specific (extra) data block
7668
 * Returns 1 if successful or -1 on error
7669
 */
7670
int liblnk_file_get_data_block_by_index(
7671
     liblnk_file_t *file,
7672
     int data_block_index,
7673
     liblnk_data_block_t **data_block,
7674
     libcerror_error_t **error )
7675
0
{
7676
0
  liblnk_internal_file_t *internal_file = NULL;
7677
0
  static char *function                 = "liblnk_file_get_data_block_by_index";
7678
0
  int result                            = 1;
7679
7680
0
  if( file == NULL )
7681
0
  {
7682
0
    libcerror_error_set(
7683
0
     error,
7684
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7685
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7686
0
     "%s: invalid file.",
7687
0
     function );
7688
7689
0
    return( -1 );
7690
0
  }
7691
0
  internal_file = (liblnk_internal_file_t *) file;
7692
7693
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7694
0
  if( libcthreads_read_write_lock_grab_for_read(
7695
0
       internal_file->read_write_lock,
7696
0
       error ) != 1 )
7697
0
  {
7698
0
    libcerror_error_set(
7699
0
     error,
7700
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7701
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7702
0
     "%s: unable to grab read/write lock for reading.",
7703
0
     function );
7704
7705
0
    return( -1 );
7706
0
  }
7707
0
#endif
7708
0
  if( libcdata_array_get_entry_by_index(
7709
0
       internal_file->data_blocks_array,
7710
0
       data_block_index,
7711
0
       (intptr_t **) data_block,
7712
0
       error ) != 1 )
7713
0
  {
7714
0
    libcerror_error_set(
7715
0
     error,
7716
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7717
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7718
0
     "%s: unable to retrieve data block: %d.",
7719
0
     function,
7720
0
     data_block_index );
7721
7722
0
    result = -1;
7723
0
  }
7724
0
#if defined( HAVE_LIBLNK_MULTI_THREAD_SUPPORT )
7725
0
  if( libcthreads_read_write_lock_release_for_read(
7726
0
       internal_file->read_write_lock,
7727
0
       error ) != 1 )
7728
0
  {
7729
0
    libcerror_error_set(
7730
0
     error,
7731
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7732
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7733
0
     "%s: unable to release read/write lock for reading.",
7734
0
     function );
7735
7736
0
    return( -1 );
7737
0
  }
7738
0
#endif
7739
0
  return( result );
7740
0
}
7741