Coverage Report

Created: 2025-09-05 06:58

/src/libvhdi/libvhdi/libvhdi_region_table_header.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Region table header functions
3
 *
4
 * Copyright (C) 2012-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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libvhdi_libcerror.h"
28
#include "libvhdi_libcnotify.h"
29
#include "libvhdi_region_table_header.h"
30
31
#include "vhdi_region_table.h"
32
33
/* Creates region table header
34
 * Make sure the value region_table_header is referencing, is set to NULL
35
 * Returns 1 if successful or -1 on error
36
 */
37
int libvhdi_region_table_header_initialize(
38
     libvhdi_region_table_header_t **region_table_header,
39
     libcerror_error_t **error )
40
1.21k
{
41
1.21k
  static char *function = "libvhdi_region_table_header_initialize";
42
43
1.21k
  if( region_table_header == NULL )
44
0
  {
45
0
    libcerror_error_set(
46
0
     error,
47
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
48
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
49
0
     "%s: invalid region table header.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
1.21k
  if( *region_table_header != NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
59
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
60
0
     "%s: invalid region table header value already set.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
1.21k
  *region_table_header = memory_allocate_structure(
66
1.21k
                          libvhdi_region_table_header_t );
67
68
1.21k
  if( *region_table_header == NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
73
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
74
0
     "%s: unable to create region table header.",
75
0
     function );
76
77
0
    goto on_error;
78
0
  }
79
1.21k
  if( memory_set(
80
1.21k
       *region_table_header,
81
1.21k
       0,
82
1.21k
       sizeof( libvhdi_region_table_header_t ) ) == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
87
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
88
0
     "%s: unable to clear region table header.",
89
0
     function );
90
91
0
    goto on_error;
92
0
  }
93
1.21k
  return( 1 );
94
95
0
on_error:
96
0
  if( *region_table_header != NULL )
97
0
  {
98
0
    memory_free(
99
0
     *region_table_header );
100
101
0
    *region_table_header = NULL;
102
0
  }
103
0
  return( -1 );
104
1.21k
}
105
106
/* Frees region table header
107
 * Returns 1 if successful or -1 on error
108
 */
109
int libvhdi_region_table_header_free(
110
     libvhdi_region_table_header_t **region_table_header,
111
     libcerror_error_t **error )
112
1.21k
{
113
1.21k
  static char *function = "libvhdi_region_table_header_free";
114
115
1.21k
  if( region_table_header == NULL )
116
0
  {
117
0
    libcerror_error_set(
118
0
     error,
119
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
120
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
121
0
     "%s: invalid region table header.",
122
0
     function );
123
124
0
    return( -1 );
125
0
  }
126
1.21k
  if( *region_table_header != NULL )
127
1.21k
  {
128
1.21k
    memory_free(
129
1.21k
     *region_table_header );
130
131
1.21k
    *region_table_header = NULL;
132
1.21k
  }
133
1.21k
  return( 1 );
134
1.21k
}
135
136
/* Reads the region table header data
137
 * Returns 1 if successful or -1 on error
138
 */
139
int libvhdi_region_table_header_read_data(
140
     libvhdi_region_table_header_t *region_table_header,
141
     const uint8_t *data,
142
     size_t data_size,
143
     libcerror_error_t **error )
144
1.21k
{
145
1.21k
  static char *function = "libvhdi_region_table_header_read_data";
146
147
#if defined( HAVE_DEBUG_OUTPUT )
148
  uint32_t value_32bit  = 0;
149
#endif
150
151
1.21k
  if( region_table_header == 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 region table header.",
158
0
     function );
159
160
0
    return( -1 );
161
0
  }
162
1.21k
  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.21k
  if( ( data_size < sizeof( vhdi_region_table_header_t ) )
174
1.21k
   || ( 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: region table header data:\n",
190
     function );
191
    libcnotify_print_data(
192
     data,
193
     sizeof( vhdi_region_table_header_t ),
194
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
195
  }
196
#endif
197
1.21k
  if( memory_compare(
198
1.21k
       ( (vhdi_region_table_header_t *) data )->signature,
199
1.21k
       "regi",
200
1.21k
       4 ) != 0 )
201
3
  {
202
3
    libcerror_error_set(
203
3
     error,
204
3
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
205
3
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
206
3
     "%s: unsupported signature.",
207
3
     function );
208
209
3
    return( -1 );
210
3
  }
211
1.20k
  byte_stream_copy_to_uint32_little_endian(
212
1.20k
   ( (vhdi_region_table_header_t *) data )->checksum,
213
1.20k
   region_table_header->checksum );
214
215
1.20k
  byte_stream_copy_to_uint32_little_endian(
216
1.20k
   ( (vhdi_region_table_header_t *) data )->number_of_entries,
217
1.20k
   region_table_header->number_of_entries );
218
219
#if defined( HAVE_DEBUG_OUTPUT )
220
  if( libcnotify_verbose != 0 )
221
  {
222
    libcnotify_printf(
223
     "%s: signature\t\t\t: %c%c%c%c\n",
224
     function,
225
     ( (vhdi_region_table_header_t *) data )->signature[ 0 ],
226
     ( (vhdi_region_table_header_t *) data )->signature[ 1 ],
227
     ( (vhdi_region_table_header_t *) data )->signature[ 2 ],
228
     ( (vhdi_region_table_header_t *) data )->signature[ 3 ] );
229
230
    libcnotify_printf(
231
     "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n",
232
     function,
233
     region_table_header->checksum );
234
235
    libcnotify_printf(
236
     "%s: number of entries\t\t: %" PRIu32 "\n",
237
     function,
238
     region_table_header->number_of_entries );
239
240
    byte_stream_copy_to_uint32_little_endian(
241
     ( (vhdi_region_table_header_t *) data )->unknown1,
242
     value_32bit );
243
    libcnotify_printf(
244
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
245
     function,
246
     value_32bit );
247
248
    libcnotify_printf(
249
     "\n" );
250
  }
251
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
252
253
1.20k
  if( region_table_header->number_of_entries > 2047 )
254
25
  {
255
25
    libcerror_error_set(
256
25
     error,
257
25
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
258
25
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
259
25
     "%s: unsupported number of entries: %" PRIu16 ".",
260
25
     function,
261
25
     region_table_header->number_of_entries );
262
263
25
    return( -1 );
264
25
  }
265
1.18k
  return( 1 );
266
1.20k
}
267