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