Coverage Report

Created: 2023-06-07 06:53

/src/libesedb/libesedb/libesedb_root_page_header.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Root page header functions
3
 *
4
 * Copyright (C) 2009-2023, 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 "libesedb_libcerror.h"
28
#include "libesedb_libcnotify.h"
29
#include "libesedb_root_page_header.h"
30
31
#include "esedb_page_values.h"
32
33
/* Creates a root page header
34
 * Make sure the value root_page_header is referencing, is set to NULL
35
 * Returns 1 if successful or -1 on error
36
 */
37
int libesedb_root_page_header_initialize(
38
     libesedb_root_page_header_t **root_page_header,
39
     libcerror_error_t **error )
40
0
{
41
0
  static char *function = "libesedb_root_page_header_initialize";
42
43
0
  if( root_page_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 root page header.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
0
  if( *root_page_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 root page header value already set.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
0
  *root_page_header = memory_allocate_structure(
66
0
                       libesedb_root_page_header_t );
67
68
0
  if( *root_page_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 root page header.",
75
0
     function );
76
77
0
    goto on_error;
78
0
  }
79
0
  if( memory_set(
80
0
       *root_page_header,
81
0
       0,
82
0
       sizeof( libesedb_root_page_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 root page header.",
89
0
     function );
90
91
0
    goto on_error;
92
0
  }
93
0
  return( 1 );
94
95
0
on_error:
96
0
  if( *root_page_header != NULL )
97
0
  {
98
0
    memory_free(
99
0
     *root_page_header );
100
101
0
    *root_page_header = NULL;
102
0
  }
103
0
  return( -1 );
104
0
}
105
106
/* Frees a root page header
107
 * Returns 1 if successful or -1 on error
108
 */
109
int libesedb_root_page_header_free(
110
     libesedb_root_page_header_t **root_page_header,
111
     libcerror_error_t **error )
112
0
{
113
0
  static char *function = "libesedb_root_page_header_free";
114
115
0
  if( root_page_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 root page header.",
122
0
     function );
123
124
0
    return( -1 );
125
0
  }
126
0
  if( *root_page_header != NULL )
127
0
  {
128
    /* The data is referenced and freed elsewhere
129
     */
130
0
    memory_free(
131
0
     *root_page_header );
132
133
0
    *root_page_header = NULL;
134
0
  }
135
0
  return( 1 );
136
0
}
137
138
/* Reads a root page header
139
 * Returns 1 if successful or -1 on error
140
 */
141
int libesedb_root_page_header_read_data(
142
     libesedb_root_page_header_t *root_page_header,
143
     const uint8_t *data,
144
     size_t data_size,
145
     libcerror_error_t **error )
146
0
{
147
0
  static char *function = "libesedb_root_page_header_read_data";
148
149
#if defined( HAVE_DEBUG_OUTPUT )
150
  uint32_t value_32bit  = 0;
151
#endif
152
153
0
  if( root_page_header == NULL )
154
0
  {
155
0
    libcerror_error_set(
156
0
     error,
157
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
158
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
159
0
     "%s: invalid root page header.",
160
0
     function );
161
162
0
    return( -1 );
163
0
  }
164
0
  if( data == NULL )
165
0
  {
166
0
    libcerror_error_set(
167
0
     error,
168
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
169
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
170
0
     "%s: invalid data.",
171
0
     function );
172
173
0
    return( -1 );
174
0
  }
175
0
  if( ( data_size != sizeof( esedb_root_page_header_t ) )
176
0
   && ( data_size != sizeof( esedb_extended_root_page_header_t ) ) )
177
0
  {
178
0
    libcerror_error_set(
179
0
     error,
180
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
181
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
182
0
     "%s: invalid data size value out of bounds.",
183
0
     function );
184
185
0
    return( -1 );
186
0
  }
187
#if defined( HAVE_DEBUG_OUTPUT )
188
  if( libcnotify_verbose != 0 )
189
  {
190
    libcnotify_printf(
191
     "%s: root page header:\n",
192
     function );
193
    libcnotify_print_data(
194
     data,
195
     data_size,
196
     0 );
197
  }
198
#endif
199
0
  byte_stream_copy_to_uint32_little_endian(
200
0
   ( (esedb_root_page_header_t *) data )->initial_number_of_pages,
201
0
   root_page_header->initial_number_of_pages );
202
203
0
  if( data_size == sizeof( esedb_root_page_header_t ) )
204
0
  {
205
0
    byte_stream_copy_to_uint32_little_endian(
206
0
     ( (esedb_root_page_header_t *) data )->extent_space,
207
0
     root_page_header->extent_space );
208
209
0
    byte_stream_copy_to_uint32_little_endian(
210
0
     ( (esedb_root_page_header_t *) data )->space_tree_page_number,
211
0
     root_page_header->space_tree_page_number );
212
0
  }
213
0
  else if( data_size == sizeof( esedb_extended_root_page_header_t ) )
214
0
  {
215
0
    byte_stream_copy_to_uint32_little_endian(
216
0
     ( (esedb_extended_root_page_header_t *) data )->extent_space,
217
0
     root_page_header->extent_space );
218
219
0
    byte_stream_copy_to_uint32_little_endian(
220
0
     ( (esedb_extended_root_page_header_t *) data )->space_tree_page_number,
221
0
     root_page_header->space_tree_page_number );
222
0
  }
223
#if defined( HAVE_DEBUG_OUTPUT )
224
  if( libcnotify_verbose != 0 )
225
  {
226
    libcnotify_printf(
227
     "%s: initial number of pages\t\t: %" PRIu32 "\n",
228
     function,
229
     root_page_header->initial_number_of_pages );
230
231
    if( data_size == sizeof( esedb_extended_root_page_header_t ) )
232
    {
233
      libcnotify_printf(
234
       "%s: unknown1\t\t\t\t: 0x%02" PRIx8 "\n",
235
       function,
236
       ( (esedb_extended_root_page_header_t *) data )->unknown1 );
237
    }
238
    byte_stream_copy_to_uint32_little_endian(
239
     ( (esedb_root_page_header_t *) data )->parent_father_data_page_number,
240
     value_32bit );
241
    libcnotify_printf(
242
     "%s: parent FDP number\t\t\t: %" PRIu32 "\n",
243
     function,
244
     value_32bit );
245
246
    libcnotify_printf(
247
     "%s: extent space\t\t\t: %" PRIu32 "\n",
248
     function,
249
     root_page_header->extent_space );
250
251
    libcnotify_printf(
252
     "%s: space tree page number\t\t: %" PRIu32 " (0x%08" PRIx32 ")\n",
253
     function,
254
     root_page_header->space_tree_page_number,
255
     root_page_header->space_tree_page_number );
256
257
    libcnotify_printf(
258
     "%s: primary extent\t\t\t: %" PRIu32 "-%c\n",
259
     function,
260
     root_page_header->initial_number_of_pages,
261
     ( root_page_header->extent_space == 0 ? 's' : 'm' ) );
262
263
    if( data_size == sizeof( esedb_extended_root_page_header_t ) )
264
    {
265
      byte_stream_copy_to_uint32_little_endian(
266
       ( (esedb_extended_root_page_header_t *) data )->unknown2,
267
       value_32bit );
268
      libcnotify_printf(
269
       "%s: unknown2\t\t\t\t: 0x%08" PRIx32 "\n",
270
       function,
271
       value_32bit );
272
273
      byte_stream_copy_to_uint32_little_endian(
274
       ( (esedb_extended_root_page_header_t *) data )->unknown3,
275
       value_32bit );
276
      libcnotify_printf(
277
       "%s: unknown3\t\t\t\t: 0x%08" PRIx32 "\n",
278
       function,
279
       value_32bit );
280
    }
281
    libcnotify_printf(
282
     "\n" );
283
  }
284
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
285
286
0
  return( 1 );
287
0
}
288