Coverage Report

Created: 2026-01-13 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvhdi/libvhdi/libvhdi_file_information.c
Line
Count
Source
1
/*
2
 * File information functions
3
 *
4
 * Copyright (C) 2012-2025, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libvhdi_debug.h"
28
#include "libvhdi_definitions.h"
29
#include "libvhdi_file_information.h"
30
#include "libvhdi_libbfio.h"
31
#include "libvhdi_libcerror.h"
32
#include "libvhdi_libcnotify.h"
33
#include "libvhdi_libuna.h"
34
35
#include "vhdi_file_information.h"
36
37
/* Creates file information
38
 * Make sure the value file_information is referencing, is set to NULL
39
 * Returns 1 if successful or -1 on error
40
 */
41
int libvhdi_file_information_initialize(
42
     libvhdi_file_information_t **file_information,
43
     libcerror_error_t **error )
44
1.41k
{
45
1.41k
  static char *function = "libvhdi_file_information_initialize";
46
47
1.41k
  if( file_information == NULL )
48
0
  {
49
0
    libcerror_error_set(
50
0
     error,
51
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53
0
     "%s: invalid file information.",
54
0
     function );
55
56
0
    return( -1 );
57
0
  }
58
1.41k
  if( *file_information != NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
63
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64
0
     "%s: invalid file information value already set.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
1.41k
  *file_information = memory_allocate_structure(
70
1.41k
                       libvhdi_file_information_t );
71
72
1.41k
  if( *file_information == NULL )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
77
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
78
0
     "%s: unable to create file information.",
79
0
     function );
80
81
0
    goto on_error;
82
0
  }
83
1.41k
  if( memory_set(
84
1.41k
       *file_information,
85
1.41k
       0,
86
1.41k
       sizeof( libvhdi_file_information_t ) ) == NULL )
87
0
  {
88
0
    libcerror_error_set(
89
0
     error,
90
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
91
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
92
0
     "%s: unable to clear file information.",
93
0
     function );
94
95
0
    goto on_error;
96
0
  }
97
1.41k
  return( 1 );
98
99
0
on_error:
100
0
  if( *file_information != NULL )
101
0
  {
102
0
    memory_free(
103
0
     *file_information );
104
105
0
    *file_information = NULL;
106
0
  }
107
0
  return( -1 );
108
1.41k
}
109
110
/* Frees file information
111
 * Returns 1 if successful or -1 on error
112
 */
113
int libvhdi_file_information_free(
114
     libvhdi_file_information_t **file_information,
115
     libcerror_error_t **error )
116
1.41k
{
117
1.41k
  static char *function = "libvhdi_file_information_free";
118
119
1.41k
  if( file_information == NULL )
120
0
  {
121
0
    libcerror_error_set(
122
0
     error,
123
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
124
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
125
0
     "%s: invalid file information.",
126
0
     function );
127
128
0
    return( -1 );
129
0
  }
130
1.41k
  if( *file_information != NULL )
131
1.41k
  {
132
1.41k
    memory_free(
133
1.41k
     *file_information );
134
135
1.41k
    *file_information = NULL;
136
1.41k
  }
137
1.41k
  return( 1 );
138
1.41k
}
139
140
/* Reads the file information data
141
 * Returns 1 if successful, 0 if signature does not match or -1 on error
142
 */
143
int libvhdi_file_information_read_data(
144
     libvhdi_file_information_t *file_information,
145
     const uint8_t *data,
146
     size_t data_size,
147
     libcerror_error_t **error )
148
1.38k
{
149
1.38k
  static char *function = "libvhdi_file_information_read_data";
150
151
1.38k
  if( file_information == NULL )
152
0
  {
153
0
    libcerror_error_set(
154
0
     error,
155
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
156
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
157
0
     "%s: invalid file information.",
158
0
     function );
159
160
0
    return( -1 );
161
0
  }
162
1.38k
  if( data == NULL )
163
0
  {
164
0
    libcerror_error_set(
165
0
     error,
166
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
167
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
168
0
     "%s: invalid data.",
169
0
     function );
170
171
0
    return( -1 );
172
0
  }
173
1.38k
  if( ( data_size < sizeof( vhdi_file_information_t ) )
174
1.38k
   || ( data_size > (size_t) SSIZE_MAX ) )
175
0
  {
176
0
    libcerror_error_set(
177
0
     error,
178
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
179
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
180
0
     "%s: invalid data size value out of bounds.",
181
0
     function );
182
183
0
    return( -1 );
184
0
  }
185
#if defined( HAVE_DEBUG_OUTPUT )
186
  if( libcnotify_verbose != 0 )
187
  {
188
    libcnotify_printf(
189
     "%s: file information data:\n",
190
     function );
191
    libcnotify_print_data(
192
     data,
193
     sizeof( vhdi_file_information_t ),
194
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
195
  }
196
#endif
197
1.38k
  if( memory_compare(
198
1.38k
       ( (vhdi_file_information_t *) data )->signature,
199
1.38k
       "vhdxfile",
200
1.38k
       8 ) != 0 )
201
567
  {
202
567
    return( 0 );
203
567
  }
204
818
  if( memory_copy(
205
818
       file_information->creator,
206
818
       ( (vhdi_file_information_t *) data )->creator,
207
818
       512 ) == NULL )
208
0
  {
209
0
    libcerror_error_set(
210
0
     error,
211
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
212
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
213
0
     "%s: unable to copy creator.",
214
0
     function );
215
216
0
    return( -1 );
217
0
  }
218
#if defined( HAVE_DEBUG_OUTPUT )
219
  if( libcnotify_verbose != 0 )
220
  {
221
    libcnotify_printf(
222
     "%s: signature\t\t\t\t: %c%c%c%c%c%c%c%c\n",
223
     function,
224
     ( (vhdi_file_information_t *) data )->signature[ 0 ],
225
     ( (vhdi_file_information_t *) data )->signature[ 1 ],
226
     ( (vhdi_file_information_t *) data )->signature[ 2 ],
227
     ( (vhdi_file_information_t *) data )->signature[ 3 ],
228
     ( (vhdi_file_information_t *) data )->signature[ 4 ],
229
     ( (vhdi_file_information_t *) data )->signature[ 5 ],
230
     ( (vhdi_file_information_t *) data )->signature[ 6 ],
231
     ( (vhdi_file_information_t *) data )->signature[ 7 ] );
232
233
    if( libvhdi_debug_print_utf16_string_value(
234
         function,
235
         "creator\t\t\t\t",
236
         file_information->creator,
237
         512,
238
         LIBUNA_ENDIAN_LITTLE,
239
         error ) != 1 )
240
    {
241
      libcerror_error_set(
242
       error,
243
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
244
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
245
       "%s: unable to print UTF-16 string value.",
246
       function );
247
248
      return( -1 );
249
    }
250
    libcnotify_printf(
251
     "\n" );
252
  }
253
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
254
255
818
  return( 1 );
256
818
}
257
258
/* Reads the file information
259
 * Returns 1 if successful, 0 if signature does not match or -1 on error
260
 */
261
int libvhdi_file_information_read_file_io_handle(
262
     libvhdi_file_information_t *file_information,
263
     libbfio_handle_t *file_io_handle,
264
     off64_t file_offset,
265
     libcerror_error_t **error )
266
1.41k
{
267
1.41k
  uint8_t file_information_data[ sizeof( vhdi_file_information_t ) ];
268
269
1.41k
  static char *function = "libvhdi_file_information_read_file_io_handle";
270
1.41k
  ssize_t read_count    = 0;
271
1.41k
  int result            = 0;
272
273
1.41k
  if( file_information == NULL )
274
0
  {
275
0
    libcerror_error_set(
276
0
     error,
277
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
278
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
279
0
     "%s: invalid file information.",
280
0
     function );
281
282
0
    return( -1 );
283
0
  }
284
#if defined( HAVE_DEBUG_OUTPUT )
285
  if( libcnotify_verbose != 0 )
286
  {
287
    libcnotify_printf(
288
     "%s: reading file information at offset: %" PRIi64 " (0x%08" PRIx64 ").\n",
289
     function,
290
     file_offset,
291
     file_offset );
292
  }
293
#endif
294
1.41k
  read_count = libbfio_handle_read_buffer_at_offset(
295
1.41k
                file_io_handle,
296
1.41k
                file_information_data,
297
1.41k
                sizeof( vhdi_file_information_t ),
298
1.41k
                file_offset,
299
1.41k
                error );
300
301
1.41k
  if( read_count != (ssize_t) sizeof( vhdi_file_information_t ) )
302
26
  {
303
26
    libcerror_error_set(
304
26
     error,
305
26
     LIBCERROR_ERROR_DOMAIN_IO,
306
26
     LIBCERROR_IO_ERROR_READ_FAILED,
307
26
     "%s: unable to read file information data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
308
26
     function,
309
26
     file_offset,
310
26
     file_offset );
311
312
26
    return( -1 );
313
26
  }
314
1.38k
  result = libvhdi_file_information_read_data(
315
1.38k
            file_information,
316
1.38k
            file_information_data,
317
1.38k
            sizeof( vhdi_file_information_t ),
318
1.38k
            error );
319
320
1.38k
  if( result == -1 )
321
0
  {
322
0
    libcerror_error_set(
323
0
     error,
324
0
     LIBCERROR_ERROR_DOMAIN_IO,
325
0
     LIBCERROR_IO_ERROR_READ_FAILED,
326
0
     "%s: unable to read file information.",
327
0
     function );
328
329
0
    return( -1 );
330
0
  }
331
1.38k
  return( result );
332
1.38k
}
333