1 /*
2  * File range functions
3  *
4  * Copyright (C) 2009-2020, 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 <memory.h>
24 #include <types.h>
25 
26 #if defined( HAVE_UNISTD_H )
27 #include <unistd.h>
28 #endif
29 
30 #include "libbfio_definitions.h"
31 #include "libbfio_file_range.h"
32 #include "libbfio_file_range_io_handle.h"
33 #include "libbfio_handle.h"
34 #include "libbfio_libcerror.h"
35 #include "libbfio_types.h"
36 
37 /* Creates a file range handle
38  * Make sure the value handle is referencing, is set to NULL
39  * Returns 1 if successful or -1 on error
40  */
libbfio_file_range_initialize(libbfio_handle_t ** handle,libcerror_error_t ** error)41 int libbfio_file_range_initialize(
42      libbfio_handle_t **handle,
43      libcerror_error_t **error )
44 {
45 	libbfio_file_range_io_handle_t *file_range_io_handle = NULL;
46 	static char *function                                = "libbfio_range_file_initialize";
47 
48 	if( handle == NULL )
49 	{
50 		libcerror_error_set(
51 		 error,
52 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
53 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
54 		 "%s: invalid handle.",
55 		 function );
56 
57 		return( -1 );
58 	}
59 	if( *handle != NULL )
60 	{
61 		libcerror_error_set(
62 		 error,
63 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
64 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
65 		 "%s: invalid handle value already set.",
66 		 function );
67 
68 		return( -1 );
69 	}
70 	if( libbfio_file_range_io_handle_initialize(
71 	     &file_range_io_handle,
72 	     error ) != 1 )
73 	{
74 		libcerror_error_set(
75 		 error,
76 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
77 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
78 		 "%s: unable to create file range IO handle.",
79 		 function );
80 
81 		goto on_error;
82 	}
83 	if( libbfio_handle_initialize(
84 	     handle,
85 	     (intptr_t *) file_range_io_handle,
86 	     (int (*)(intptr_t **, libcerror_error_t **)) libbfio_file_range_io_handle_free,
87 	     (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) libbfio_file_range_io_handle_clone,
88 	     (int (*)(intptr_t *, int, libcerror_error_t **)) libbfio_file_range_io_handle_open,
89 	     (int (*)(intptr_t *, libcerror_error_t **)) libbfio_file_range_io_handle_close,
90 	     (ssize_t (*)(intptr_t *, uint8_t *, size_t, libcerror_error_t **)) libbfio_file_range_io_handle_read_buffer,
91 	     (ssize_t (*)(intptr_t *, const uint8_t *, size_t, libcerror_error_t **)) libbfio_file_range_io_handle_write_buffer,
92 	     (off64_t (*)(intptr_t *, off64_t, int, libcerror_error_t **)) libbfio_file_range_io_handle_seek_offset,
93 	     (int (*)(intptr_t *, libcerror_error_t **)) libbfio_file_range_io_handle_exists,
94 	     (int (*)(intptr_t *, libcerror_error_t **)) libbfio_file_range_io_handle_is_open,
95 	     (int (*)(intptr_t *, size64_t *, libcerror_error_t **)) libbfio_file_range_io_handle_get_size,
96 	     LIBBFIO_FLAG_IO_HANDLE_MANAGED | LIBBFIO_FLAG_IO_HANDLE_CLONE_BY_FUNCTION,
97 	     error ) != 1 )
98 	{
99 		libcerror_error_set(
100 		 error,
101 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
102 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
103 		 "%s: unable to create handle.",
104 		 function );
105 
106 		goto on_error;
107 	}
108 	return( 1 );
109 
110 on_error:
111 	if( file_range_io_handle != NULL )
112 	{
113 		libbfio_file_range_io_handle_free(
114 		 &file_range_io_handle,
115 		 NULL );
116 	}
117 	return( -1 );
118 }
119 
120 /* Retrieves the name size of the file range handle
121  * The name size includes the end of string character
122  * Returns 1 if succesful or -1 on error
123  */
libbfio_file_range_get_name_size(libbfio_handle_t * handle,size_t * name_size,libcerror_error_t ** error)124 int libbfio_file_range_get_name_size(
125      libbfio_handle_t *handle,
126      size_t *name_size,
127      libcerror_error_t **error )
128 {
129 	libbfio_internal_handle_t *internal_handle = NULL;
130 	static char *function                      = "libbfio_file_range_get_name_size";
131 
132 	if( handle == NULL )
133 	{
134 		libcerror_error_set(
135 		 error,
136 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
137 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
138 		 "%s: invalid handle.",
139 		 function );
140 
141 		return( -1 );
142 	}
143 	internal_handle = (libbfio_internal_handle_t *) handle;
144 
145 	if( libbfio_file_range_io_handle_get_name_size(
146 	     (libbfio_file_range_io_handle_t *) internal_handle->io_handle,
147 	     name_size,
148 	     error ) != 1 )
149 	{
150 		libcerror_error_set(
151 		 error,
152 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
153 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
154 		 "%s: unable to retrieve name size from file IO handle.",
155 		 function );
156 
157 		return( -1 );
158 	}
159 	return( 1 );
160 }
161 
162 /* Retrieves the name of the file range handle
163  * The name size should include the end of string character
164  * Returns 1 if succesful or -1 on error
165  */
libbfio_file_range_get_name(libbfio_handle_t * handle,char * name,size_t name_size,libcerror_error_t ** error)166 int libbfio_file_range_get_name(
167      libbfio_handle_t *handle,
168      char *name,
169      size_t name_size,
170      libcerror_error_t **error )
171 {
172 	libbfio_internal_handle_t *internal_handle = NULL;
173 	static char *function                      = "libbfio_file_range_get_name";
174 
175 	if( handle == NULL )
176 	{
177 		libcerror_error_set(
178 		 error,
179 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
180 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
181 		 "%s: invalid handle.",
182 		 function );
183 
184 		return( -1 );
185 	}
186 	internal_handle = (libbfio_internal_handle_t *) handle;
187 
188 	if( libbfio_file_range_io_handle_get_name(
189 	     (libbfio_file_range_io_handle_t *) internal_handle->io_handle,
190 	     name,
191 	     name_size,
192 	     error ) != 1 )
193 	{
194 		libcerror_error_set(
195 		 error,
196 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
197 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
198 		 "%s: unable to retrieve name from file IO handle.",
199 		 function );
200 
201 		return( -1 );
202 	}
203 	return( 1 );
204 }
205 
206 /* Sets the name for the file range handle
207  * Returns 1 if succesful or -1 on error
208  */
libbfio_file_range_set_name(libbfio_handle_t * handle,const char * name,size_t name_length,libcerror_error_t ** error)209 int libbfio_file_range_set_name(
210      libbfio_handle_t *handle,
211      const char *name,
212      size_t name_length,
213      libcerror_error_t **error )
214 {
215 	libbfio_internal_handle_t *internal_handle = NULL;
216 	static char *function                      = "libbfio_file_range_set_name";
217 
218 	if( handle == NULL )
219 	{
220 		libcerror_error_set(
221 		 error,
222 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
223 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
224 		 "%s: invalid handle.",
225 		 function );
226 
227 		return( -1 );
228 	}
229 	internal_handle = (libbfio_internal_handle_t *) handle;
230 
231 	if( libbfio_file_range_io_handle_set_name(
232 	     (libbfio_file_range_io_handle_t *) internal_handle->io_handle,
233 	     name,
234 	     name_length,
235 	     error ) != 1 )
236 	{
237 		libcerror_error_set(
238 		 error,
239 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
240 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
241 		 "%s: unable to set name in file IO handle.",
242 		 function );
243 
244 		return( -1 );
245 	}
246 	return( 1 );
247 }
248 
249 #if defined( HAVE_WIDE_CHARACTER_TYPE )
250 
251 /* Retrieves the name size of the file range handle
252  * The name size includes the end of string character
253  * Returns 1 if succesful or -1 on error
254  */
libbfio_file_range_get_name_size_wide(libbfio_handle_t * handle,size_t * name_size,libcerror_error_t ** error)255 int libbfio_file_range_get_name_size_wide(
256      libbfio_handle_t *handle,
257      size_t *name_size,
258      libcerror_error_t **error )
259 {
260 	libbfio_internal_handle_t *internal_handle = NULL;
261 	static char *function                      = "libbfio_file_range_get_name_size_wide";
262 
263 	if( handle == NULL )
264 	{
265 		libcerror_error_set(
266 		 error,
267 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
268 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
269 		 "%s: invalid handle.",
270 		 function );
271 
272 		return( -1 );
273 	}
274 	internal_handle = (libbfio_internal_handle_t *) handle;
275 
276 	if( libbfio_file_range_io_handle_get_name_size_wide(
277 	     (libbfio_file_range_io_handle_t *) internal_handle->io_handle,
278 	     name_size,
279 	     error ) != 1 )
280 	{
281 		libcerror_error_set(
282 		 error,
283 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
284 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
285 		 "%s: unable to retrieve name size from file IO handle.",
286 		 function );
287 
288 		return( -1 );
289 	}
290 	return( 1 );
291 }
292 
293 /* Retrieves the name of the file range handle
294  * The name size should include the end of string character
295  * Returns 1 if succesful or -1 on error
296  */
libbfio_file_range_get_name_wide(libbfio_handle_t * handle,wchar_t * name,size_t name_size,libcerror_error_t ** error)297 int libbfio_file_range_get_name_wide(
298      libbfio_handle_t *handle,
299      wchar_t *name,
300      size_t name_size,
301      libcerror_error_t **error )
302 {
303 	libbfio_internal_handle_t *internal_handle = NULL;
304 	static char *function                      = "libbfio_file_range_get_name_wide";
305 
306 	if( handle == NULL )
307 	{
308 		libcerror_error_set(
309 		 error,
310 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
311 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
312 		 "%s: invalid handle.",
313 		 function );
314 
315 		return( -1 );
316 	}
317 	internal_handle = (libbfio_internal_handle_t *) handle;
318 
319 	if( libbfio_file_range_io_handle_get_name_wide(
320 	     (libbfio_file_range_io_handle_t *) internal_handle->io_handle,
321 	     name,
322 	     name_size,
323 	     error ) != 1 )
324 	{
325 		libcerror_error_set(
326 		 error,
327 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
328 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
329 		 "%s: unable to retrieve name from file IO handle.",
330 		 function );
331 
332 		return( -1 );
333 	}
334 	return( 1 );
335 }
336 
337 /* Sets the name for the file range handle
338  * Returns 1 if succesful or -1 on error
339  */
libbfio_file_range_set_name_wide(libbfio_handle_t * handle,const wchar_t * name,size_t name_length,libcerror_error_t ** error)340 int libbfio_file_range_set_name_wide(
341      libbfio_handle_t *handle,
342      const wchar_t *name,
343      size_t name_length,
344      libcerror_error_t **error )
345 {
346 	libbfio_internal_handle_t *internal_handle = NULL;
347 	static char *function                      = "libbfio_file_range_set_name_wide";
348 
349 	if( handle == NULL )
350 	{
351 		libcerror_error_set(
352 		 error,
353 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
354 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
355 		 "%s: invalid handle.",
356 		 function );
357 
358 		return( -1 );
359 	}
360 	internal_handle = (libbfio_internal_handle_t *) handle;
361 
362 	if( libbfio_file_range_io_handle_set_name_wide(
363 	     (libbfio_file_range_io_handle_t *) internal_handle->io_handle,
364 	     name,
365 	     name_length,
366 	     error ) != 1 )
367 	{
368 		libcerror_error_set(
369 		 error,
370 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
371 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
372 		 "%s: unable to set name in file IO handle.",
373 		 function );
374 
375 		return( -1 );
376 	}
377 	return( 1 );
378 }
379 
380 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
381 
382 /* Retrieves the range of the file range handle
383  * Returns 1 if succesful or -1 on error
384  */
libbfio_file_range_get(libbfio_handle_t * handle,off64_t * range_offset,size64_t * range_size,libcerror_error_t ** error)385 int libbfio_file_range_get(
386      libbfio_handle_t *handle,
387      off64_t *range_offset,
388      size64_t *range_size,
389      libcerror_error_t **error )
390 {
391 	libbfio_internal_handle_t *internal_handle = NULL;
392 	static char *function                      = "libbfio_file_range_get";
393 
394 	if( handle == NULL )
395 	{
396 		libcerror_error_set(
397 		 error,
398 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
399 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
400 		 "%s: invalid handle.",
401 		 function );
402 
403 		return( -1 );
404 	}
405 	internal_handle = (libbfio_internal_handle_t *) handle;
406 
407 	if( libbfio_file_range_io_handle_get(
408 	     (libbfio_file_range_io_handle_t *) internal_handle->io_handle,
409 	     range_offset,
410 	     range_size,
411 	     error ) != 1 )
412 	{
413 		libcerror_error_set(
414 		 error,
415 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
416 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
417 		 "%s: unable to retrieve range from file IO handle.",
418 		 function );
419 
420 		return( -1 );
421 	}
422 	return( 1 );
423 }
424 
425 /* Sets the range of the file range handle
426  * A range size of 0 represents that the range continues until the end of the file
427  * Returns 1 if succesful or -1 on error
428  */
libbfio_file_range_set(libbfio_handle_t * handle,off64_t range_offset,size64_t range_size,libcerror_error_t ** error)429 int libbfio_file_range_set(
430      libbfio_handle_t *handle,
431      off64_t range_offset,
432      size64_t range_size,
433      libcerror_error_t **error )
434 {
435 	libbfio_internal_handle_t *internal_handle = NULL;
436 	static char *function                      = "libbfio_file_range_set";
437 
438 	if( handle == NULL )
439 	{
440 		libcerror_error_set(
441 		 error,
442 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
443 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
444 		 "%s: invalid handle.",
445 		 function );
446 
447 		return( -1 );
448 	}
449 	internal_handle = (libbfio_internal_handle_t *) handle;
450 
451 	if( libbfio_file_range_io_handle_set(
452 	     (libbfio_file_range_io_handle_t *) internal_handle->io_handle,
453 	     range_offset,
454 	     range_size,
455 	     error ) != 1 )
456 	{
457 		libcerror_error_set(
458 		 error,
459 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
460 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
461 		 "%s: unable to set range in file IO handle.",
462 		 function );
463 
464 		return( -1 );
465 	}
466 	return( 1 );
467 }
468 
469