1 /*
2 * The object map descriptor functions
3 *
4 * Copyright (C) 2018-2021, 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 "libfsapfs_object_map_descriptor.h"
28 #include "libfsapfs_libcerror.h"
29 #include "libfsapfs_libcnotify.h"
30
31 #include "fsapfs_object_map.h"
32
33 /* Creates physical_map_entry
34 * Make sure the value object_map_descriptor is referencing, is set to NULL
35 * Returns 1 if successful or -1 on error
36 */
libfsapfs_object_map_descriptor_initialize(libfsapfs_object_map_descriptor_t ** object_map_descriptor,libcerror_error_t ** error)37 int libfsapfs_object_map_descriptor_initialize(
38 libfsapfs_object_map_descriptor_t **object_map_descriptor,
39 libcerror_error_t **error )
40 {
41 static char *function = "libfsapfs_object_map_descriptor_initialize";
42
43 if( object_map_descriptor == NULL )
44 {
45 libcerror_error_set(
46 error,
47 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
48 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
49 "%s: invalid object map descriptor.",
50 function );
51
52 return( -1 );
53 }
54 if( *object_map_descriptor != NULL )
55 {
56 libcerror_error_set(
57 error,
58 LIBCERROR_ERROR_DOMAIN_RUNTIME,
59 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
60 "%s: invalid object map descriptor value already set.",
61 function );
62
63 return( -1 );
64 }
65 *object_map_descriptor = memory_allocate_structure(
66 libfsapfs_object_map_descriptor_t );
67
68 if( *object_map_descriptor == NULL )
69 {
70 libcerror_error_set(
71 error,
72 LIBCERROR_ERROR_DOMAIN_MEMORY,
73 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
74 "%s: unable to create object map descriptor.",
75 function );
76
77 goto on_error;
78 }
79 if( memory_set(
80 *object_map_descriptor,
81 0,
82 sizeof( libfsapfs_object_map_descriptor_t ) ) == NULL )
83 {
84 libcerror_error_set(
85 error,
86 LIBCERROR_ERROR_DOMAIN_MEMORY,
87 LIBCERROR_MEMORY_ERROR_SET_FAILED,
88 "%s: unable to clear object map descriptor.",
89 function );
90
91 goto on_error;
92 }
93 return( 1 );
94
95 on_error:
96 if( *object_map_descriptor != NULL )
97 {
98 memory_free(
99 *object_map_descriptor );
100
101 *object_map_descriptor = NULL;
102 }
103 return( -1 );
104 }
105
106 /* Frees object map descriptor
107 * Returns 1 if successful or -1 on error
108 */
libfsapfs_object_map_descriptor_free(libfsapfs_object_map_descriptor_t ** object_map_descriptor,libcerror_error_t ** error)109 int libfsapfs_object_map_descriptor_free(
110 libfsapfs_object_map_descriptor_t **object_map_descriptor,
111 libcerror_error_t **error )
112 {
113 static char *function = "libfsapfs_object_map_descriptor_free";
114
115 if( object_map_descriptor == NULL )
116 {
117 libcerror_error_set(
118 error,
119 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
120 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
121 "%s: invalid object map descriptor.",
122 function );
123
124 return( -1 );
125 }
126 if( *object_map_descriptor != NULL )
127 {
128 memory_free(
129 *object_map_descriptor );
130
131 *object_map_descriptor = NULL;
132 }
133 return( 1 );
134 }
135
136 /* Reads the object map descriptor B-tree key data
137 * Returns 1 if successful or -1 on error
138 */
libfsapfs_object_map_descriptor_read_key_data(libfsapfs_object_map_descriptor_t * object_map_descriptor,const uint8_t * data,size_t data_size,libcerror_error_t ** error)139 int libfsapfs_object_map_descriptor_read_key_data(
140 libfsapfs_object_map_descriptor_t *object_map_descriptor,
141 const uint8_t *data,
142 size_t data_size,
143 libcerror_error_t **error )
144 {
145 static char *function = "libfsapfs_object_map_descriptor_read_key_data";
146
147 if( object_map_descriptor == NULL )
148 {
149 libcerror_error_set(
150 error,
151 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
152 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
153 "%s: invalid object map descriptor.",
154 function );
155
156 return( -1 );
157 }
158 if( data == NULL )
159 {
160 libcerror_error_set(
161 error,
162 LIBCERROR_ERROR_DOMAIN_RUNTIME,
163 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
164 "%s: invalid data.",
165 function );
166
167 return( -1 );
168 }
169 if( ( data_size < sizeof( fsapfs_object_map_btree_key_t ) )
170 || ( data_size > (size_t) SSIZE_MAX ) )
171 {
172 libcerror_error_set(
173 error,
174 LIBCERROR_ERROR_DOMAIN_RUNTIME,
175 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
176 "%s: invalid data size value out of bounds.",
177 function );
178
179 return( -1 );
180 }
181 #if defined( HAVE_DEBUG_OUTPUT )
182 if( libcnotify_verbose != 0 )
183 {
184 libcnotify_printf(
185 "%s: object map B-tree key data:\n",
186 function );
187 libcnotify_print_data(
188 data,
189 sizeof( fsapfs_object_map_btree_key_t ),
190 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
191 }
192 #endif
193 byte_stream_copy_to_uint64_little_endian(
194 ( (fsapfs_object_map_btree_key_t *) data )->object_identifier,
195 object_map_descriptor->identifier );
196
197 byte_stream_copy_to_uint64_little_endian(
198 ( (fsapfs_object_map_btree_key_t *) data )->object_transaction_identifier,
199 object_map_descriptor->transaction_identifier );
200
201 #if defined( HAVE_DEBUG_OUTPUT )
202 if( libcnotify_verbose != 0 )
203 {
204 libcnotify_printf(
205 "%s: object identifier\t\t: %" PRIu64 "\n",
206 function,
207 object_map_descriptor->identifier );
208
209 libcnotify_printf(
210 "%s: object transaction identifier\t: %" PRIu64 "\n",
211 function,
212 object_map_descriptor->transaction_identifier );
213
214 libcnotify_printf(
215 "\n" );
216 }
217 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
218
219 return( 1 );
220 }
221
222 /* Reads the object map descriptor B-tree value data
223 * Returns 1 if successful or -1 on error
224 */
libfsapfs_object_map_descriptor_read_value_data(libfsapfs_object_map_descriptor_t * object_map_descriptor,const uint8_t * data,size_t data_size,libcerror_error_t ** error)225 int libfsapfs_object_map_descriptor_read_value_data(
226 libfsapfs_object_map_descriptor_t *object_map_descriptor,
227 const uint8_t *data,
228 size_t data_size,
229 libcerror_error_t **error )
230 {
231 static char *function = "libfsapfs_object_map_descriptor_read_value_data";
232
233 if( object_map_descriptor == NULL )
234 {
235 libcerror_error_set(
236 error,
237 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
238 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
239 "%s: invalid object map descriptor.",
240 function );
241
242 return( -1 );
243 }
244 if( data == NULL )
245 {
246 libcerror_error_set(
247 error,
248 LIBCERROR_ERROR_DOMAIN_RUNTIME,
249 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
250 "%s: invalid data.",
251 function );
252
253 return( -1 );
254 }
255 if( ( data_size < sizeof( fsapfs_object_map_btree_value_t ) )
256 || ( data_size > (size_t) SSIZE_MAX ) )
257 {
258 libcerror_error_set(
259 error,
260 LIBCERROR_ERROR_DOMAIN_RUNTIME,
261 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
262 "%s: invalid data size value out of bounds.",
263 function );
264
265 return( -1 );
266 }
267 #if defined( HAVE_DEBUG_OUTPUT )
268 if( libcnotify_verbose != 0 )
269 {
270 libcnotify_printf(
271 "%s: object map B-tree value data:\n",
272 function );
273 libcnotify_print_data(
274 data,
275 sizeof( fsapfs_object_map_btree_value_t ),
276 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
277 }
278 #endif
279 byte_stream_copy_to_uint32_little_endian(
280 ( (fsapfs_object_map_btree_value_t *) data )->object_flags,
281 object_map_descriptor->flags );
282
283 byte_stream_copy_to_uint32_little_endian(
284 ( (fsapfs_object_map_btree_value_t *) data )->object_size,
285 object_map_descriptor->size );
286
287 byte_stream_copy_to_uint64_little_endian(
288 ( (fsapfs_object_map_btree_value_t *) data )->object_physical_address,
289 object_map_descriptor->physical_address );
290
291 #if defined( HAVE_DEBUG_OUTPUT )
292 if( libcnotify_verbose != 0 )
293 {
294 libcnotify_printf(
295 "%s: object flags\t\t\t: 0x%04" PRIx32 "\n",
296 function,
297 object_map_descriptor->flags );
298
299 libcnotify_printf(
300 "%s: object size\t\t\t: %" PRIu32 "\n",
301 function,
302 object_map_descriptor->size );
303
304 libcnotify_printf(
305 "%s: object physical address\t: %" PRIu64 "\n",
306 function,
307 object_map_descriptor->physical_address );
308
309 libcnotify_printf(
310 "\n" );
311 }
312 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
313
314 return( 1 );
315 }
316
317