1 /*
2  * Memory range IO handle 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_libcerror.h"
32 #include "libbfio_memory_range_io_handle.h"
33 
34 /* Creates a memory range IO handle
35  * Make sure the value memory_range_io_handle is referencing, is set to NULL
36  * Returns 1 if successful or -1 on error
37  */
libbfio_memory_range_io_handle_initialize(libbfio_memory_range_io_handle_t ** memory_range_io_handle,libcerror_error_t ** error)38 int libbfio_memory_range_io_handle_initialize(
39      libbfio_memory_range_io_handle_t **memory_range_io_handle,
40      libcerror_error_t **error )
41 {
42 	static char *function = "libbfio_memory_range_io_handle_initialize";
43 
44 	if( memory_range_io_handle == NULL )
45 	{
46 		libcerror_error_set(
47 		 error,
48 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50 		 "%s: invalid memory range IO handle.",
51 		 function );
52 
53 		return( -1 );
54 	}
55 	if( *memory_range_io_handle != NULL )
56 	{
57 		libcerror_error_set(
58 		 error,
59 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
60 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
61 		 "%s: invalid memory range IO handle value already set.",
62 		 function );
63 
64 		return( -1 );
65 	}
66 	*memory_range_io_handle = memory_allocate_structure(
67 	                           libbfio_memory_range_io_handle_t );
68 
69 	if( *memory_range_io_handle == NULL )
70 	{
71 		libcerror_error_set(
72 		 error,
73 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
74 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
75 		 "%s: unable to create memory range IO handle.",
76 		 function );
77 
78 		goto on_error;
79 	}
80 	if( memory_set(
81 	     *memory_range_io_handle,
82 	     0,
83 	     sizeof( libbfio_memory_range_io_handle_t ) ) == NULL )
84 	{
85 		libcerror_error_set(
86 		 error,
87 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
88 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
89 		 "%s: unable to clear memory range IO handle.",
90 		 function );
91 
92 		goto on_error;
93 	}
94 	return( 1 );
95 
96 on_error:
97 	if( *memory_range_io_handle != NULL )
98 	{
99 		memory_free(
100 		 *memory_range_io_handle );
101 
102 		*memory_range_io_handle = NULL;
103 	}
104 	return( -1 );
105 }
106 
107 /* Frees a memory range IO handle
108  * Returns 1 if succesful or -1 on error
109  */
libbfio_memory_range_io_handle_free(libbfio_memory_range_io_handle_t ** memory_range_io_handle,libcerror_error_t ** error)110 int libbfio_memory_range_io_handle_free(
111      libbfio_memory_range_io_handle_t **memory_range_io_handle,
112      libcerror_error_t **error )
113 {
114 	static char *function = "libbfio_memory_range_io_handle_free";
115 
116 	if( memory_range_io_handle == NULL )
117 	{
118 		libcerror_error_set(
119 		 error,
120 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
121 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
122 		 "%s: invalid memory range IO handle.",
123 		 function );
124 
125 		return( -1 );
126 	}
127 	if( *memory_range_io_handle != NULL )
128 	{
129 		memory_free(
130 		 *memory_range_io_handle );
131 
132 		*memory_range_io_handle = NULL;
133 	}
134 	return( 1 );
135 }
136 
137 /* Clones (duplicates) the memory range IO handle and its attributes
138  * Returns 1 if succesful or -1 on error
139  */
libbfio_memory_range_io_handle_clone(libbfio_memory_range_io_handle_t ** destination_memory_range_io_handle,libbfio_memory_range_io_handle_t * source_memory_range_io_handle,libcerror_error_t ** error)140 int libbfio_memory_range_io_handle_clone(
141      libbfio_memory_range_io_handle_t **destination_memory_range_io_handle,
142      libbfio_memory_range_io_handle_t *source_memory_range_io_handle,
143      libcerror_error_t **error )
144 {
145 	static char *function = "libbfio_memory_range_io_handle_clone";
146 
147 	if( destination_memory_range_io_handle == NULL )
148 	{
149 		libcerror_error_set(
150 		 error,
151 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
152 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
153 		 "%s: invalid destination memory range IO handle.",
154 		 function );
155 
156 		return( -1 );
157 	}
158 	if( *destination_memory_range_io_handle != NULL )
159 	{
160 		libcerror_error_set(
161 		 error,
162 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
163 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
164 		 "%s: destination memory range IO handle already set.",
165 		 function );
166 
167 		return( -1 );
168 	}
169 	if( source_memory_range_io_handle == NULL )
170 	{
171 		*destination_memory_range_io_handle = NULL;
172 
173 		return( 1 );
174 	}
175 	if( libbfio_memory_range_io_handle_initialize(
176 	     destination_memory_range_io_handle,
177 	     error ) != 1 )
178 	{
179 		libcerror_error_set(
180 		 error,
181 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
182 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
183 		 "%s: unable to create memory range IO handle.",
184 		 function );
185 
186 		return( -1 );
187 	}
188 	if( *destination_memory_range_io_handle == NULL )
189 	{
190 		libcerror_error_set(
191 		 error,
192 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
193 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
194 		 "%s: missing destination memory range IO handle.",
195 		 function );
196 
197 		return( -1 );
198 	}
199 	( *destination_memory_range_io_handle )->range_start  = source_memory_range_io_handle->range_start;
200 	( *destination_memory_range_io_handle )->range_size   = source_memory_range_io_handle->range_size;
201 	( *destination_memory_range_io_handle )->range_offset = source_memory_range_io_handle->range_offset;
202 	( *destination_memory_range_io_handle )->access_flags = source_memory_range_io_handle->access_flags;
203 
204 	return( 1 );
205 }
206 
207 /* Retrieves the range of the memory range IO handle
208  * Returns 1 if succesful or -1 on error
209  */
libbfio_memory_range_io_handle_get(libbfio_memory_range_io_handle_t * memory_range_io_handle,uint8_t ** range_start,size_t * range_size,libcerror_error_t ** error)210 int libbfio_memory_range_io_handle_get(
211      libbfio_memory_range_io_handle_t *memory_range_io_handle,
212      uint8_t **range_start,
213      size_t *range_size,
214      libcerror_error_t **error )
215 {
216 	static char *function = "libbfio_memory_range_io_handle_get";
217 
218 	if( memory_range_io_handle == NULL )
219 	{
220 		libcerror_error_set(
221 		 error,
222 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
223 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
224 		 "%s: invalid memory range IO handle.",
225 		 function );
226 
227 		return( -1 );
228 	}
229 	if( range_start == NULL )
230 	{
231 		libcerror_error_set(
232 		 error,
233 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
234 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
235 		 "%s: invalid range start.",
236 		 function );
237 
238 		return( -1 );
239 	}
240 	if( range_size == NULL )
241 	{
242 		libcerror_error_set(
243 		 error,
244 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
245 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
246 		 "%s: invalid range size.",
247 		 function );
248 
249 		return( -1 );
250 	}
251 	*range_start = memory_range_io_handle->range_start;
252 	*range_size  = memory_range_io_handle->range_size;
253 
254 	return( 1 );
255 }
256 
257 /* Sets the range of the memory range IO handle
258  * Returns 1 if succesful or -1 on error
259  */
libbfio_memory_range_io_handle_set(libbfio_memory_range_io_handle_t * memory_range_io_handle,uint8_t * range_start,size_t range_size,libcerror_error_t ** error)260 int libbfio_memory_range_io_handle_set(
261      libbfio_memory_range_io_handle_t *memory_range_io_handle,
262      uint8_t *range_start,
263      size_t range_size,
264      libcerror_error_t **error )
265 {
266 	static char *function = "libbfio_memory_range_io_handle_set";
267 
268 	if( memory_range_io_handle == NULL )
269 	{
270 		libcerror_error_set(
271 		 error,
272 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
273 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
274 		 "%s: invalid memory range IO handle.",
275 		 function );
276 
277 		return( -1 );
278 	}
279 	if( range_start == NULL )
280 	{
281 		libcerror_error_set(
282 		 error,
283 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
284 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
285 		 "%s: invalid range start.",
286 		 function );
287 
288 		return( -1 );
289 	}
290 	if( range_size > (size_t) SSIZE_MAX )
291 	{
292 		libcerror_error_set(
293 		 error,
294 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
295 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
296 		 "%s: invalid range size value exceeds maximum.",
297 		 function );
298 
299 		return( -1 );
300 	}
301 	memory_range_io_handle->range_start = range_start;
302 	memory_range_io_handle->range_size  = range_size;
303 
304 	return( 1 );
305 }
306 
307 /* Opens the memory range IO handle
308  * Returns 1 if successful or -1 on error
309  */
libbfio_memory_range_io_handle_open(libbfio_memory_range_io_handle_t * memory_range_io_handle,int access_flags,libcerror_error_t ** error)310 int libbfio_memory_range_io_handle_open(
311      libbfio_memory_range_io_handle_t *memory_range_io_handle,
312      int access_flags,
313      libcerror_error_t **error )
314 {
315 	static char *function = "libbfio_memory_range_io_handle_open";
316 
317 	if( memory_range_io_handle == NULL )
318 	{
319 		libcerror_error_set(
320 		 error,
321 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
322 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
323 		 "%s: invalid memory range IO handle.",
324 		 function );
325 
326 		return( -1 );
327 	}
328 	if( memory_range_io_handle->range_start == NULL )
329 	{
330 		libcerror_error_set(
331 		 error,
332 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
333 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
334 		 "%s: invalid memory range IO handle - missing range start.",
335 		 function );
336 
337 		return( -1 );
338 	}
339 	if( memory_range_io_handle->is_open != 0 )
340 	{
341 		libcerror_error_set(
342 		 error,
343 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
344 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
345 		 "%s: invalid memory range IO handle - already open.",
346 		 function );
347 
348 		return( -1 );
349 	}
350 	/* Either read or write flag should be set
351 	 */
352 	if( ( ( access_flags & LIBBFIO_ACCESS_FLAG_READ ) == 0 )
353 	 && ( ( access_flags & LIBBFIO_ACCESS_FLAG_WRITE ) == 0 ) )
354 	{
355 		libcerror_error_set(
356 		 error,
357 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
358 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
359 		 "%s: unsupported access flags: 0x%02x.",
360 		 function );
361 
362 		return( -1 );
363 	}
364 	memory_range_io_handle->range_offset = 0;
365 	memory_range_io_handle->access_flags = access_flags;
366 	memory_range_io_handle->is_open      = 1;
367 
368 	return( 1 );
369 }
370 
371 /* Closes the memory range IO handle
372  * Returns 0 if successful or -1 on error
373  */
libbfio_memory_range_io_handle_close(libbfio_memory_range_io_handle_t * memory_range_io_handle,libcerror_error_t ** error)374 int libbfio_memory_range_io_handle_close(
375      libbfio_memory_range_io_handle_t *memory_range_io_handle,
376      libcerror_error_t **error )
377 {
378 	static char *function = "libbfio_memory_range_io_handle_close";
379 
380 	if( memory_range_io_handle == NULL )
381 	{
382 		libcerror_error_set(
383 		 error,
384 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
385 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
386 		 "%s: invalid memory range IO handle.",
387 		 function );
388 
389 		return( -1 );
390 	}
391 	if( memory_range_io_handle->range_start == NULL )
392 	{
393 		libcerror_error_set(
394 		 error,
395 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
396 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
397 		 "%s: invalid memory range IO handle - missing range start.",
398 		 function );
399 
400 		return( -1 );
401 	}
402 	if( memory_range_io_handle->is_open == 0 )
403 	{
404 		libcerror_error_set(
405 		 error,
406 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
407 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
408 		 "%s: invalid memory range IO handle - not open.",
409 		 function );
410 
411 		return( -1 );
412 	}
413 	memory_range_io_handle->is_open = 0;
414 
415 	return( 0 );
416 }
417 
418 /* Reads a buffer from the memory range IO handle
419  * Returns the number of bytes read if successful, or -1 on error
420  */
libbfio_memory_range_io_handle_read_buffer(libbfio_memory_range_io_handle_t * memory_range_io_handle,uint8_t * buffer,size_t size,libcerror_error_t ** error)421 ssize_t libbfio_memory_range_io_handle_read_buffer(
422          libbfio_memory_range_io_handle_t *memory_range_io_handle,
423          uint8_t *buffer,
424          size_t size,
425          libcerror_error_t **error )
426 {
427 	static char *function = "libbfio_memory_range_io_handle_read_buffer";
428 	size_t read_size      = 0;
429 
430 	if( memory_range_io_handle == NULL )
431 	{
432 		libcerror_error_set(
433 		 error,
434 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
435 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
436 		 "%s: invalid memory range IO handle.",
437 		 function );
438 
439 		return( -1 );
440 	}
441 	if( memory_range_io_handle->range_start == NULL )
442 	{
443 		libcerror_error_set(
444 		 error,
445 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
446 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
447 		 "%s: invalid memory range IO handle - invalid range start.",
448 		 function );
449 
450 		return( -1 );
451 	}
452 	if( memory_range_io_handle->is_open == 0 )
453 	{
454 		libcerror_error_set(
455 		 error,
456 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
457 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
458 		 "%s: invalid memory range IO handle - not open.",
459 		 function );
460 
461 		return( -1 );
462 	}
463 	if( ( memory_range_io_handle->access_flags & LIBBFIO_ACCESS_FLAG_READ ) == 0 )
464 	{
465 		libcerror_error_set(
466 		 error,
467 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
468 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
469 		 "%s: invalid memory range IO handle - no read access.",
470 		 function );
471 
472 		return( -1 );
473 	}
474 	if( buffer == NULL )
475 	{
476 		libcerror_error_set(
477 		 error,
478 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
479 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
480 		 "%s: invalid buffer.",
481 		 function );
482 
483 		return( -1 );
484 	}
485 	if( size > (size_t) SSIZE_MAX )
486 	{
487 		libcerror_error_set(
488 		 error,
489 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
490 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
491 		 "%s: invalid size value exceeds maximum.",
492 		 function );
493 
494 		return( -1 );
495 	}
496 	if( memory_range_io_handle->range_offset > memory_range_io_handle->range_size )
497 	{
498 		libcerror_error_set(
499 		 error,
500 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
501 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
502 		 "%s: invalid range offset value out of bounds.",
503 		 function );
504 
505 		return( -1 );
506 	}
507 	/* Check if the end of the data was reached
508 	 */
509 	if( memory_range_io_handle->range_offset >= memory_range_io_handle->range_size )
510 	{
511 		return( 0 );
512 	}
513 	/* Check the amount of data available
514 	 */
515 	read_size = memory_range_io_handle->range_size - memory_range_io_handle->range_offset;
516 
517 	/* Cannot read more data than available
518 	 */
519 	if( read_size > size )
520 	{
521 		read_size = size;
522 	}
523 	if( memory_copy(
524 	     buffer,
525 	     &( memory_range_io_handle->range_start[ memory_range_io_handle->range_offset ] ),
526 	     read_size ) == NULL )
527 	{
528 		libcerror_error_set(
529 		 error,
530 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
531 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
532 		 "%s: unable to read buffer from memory range.",
533 		 function );
534 
535 		return( -1 );
536 	}
537 	memory_range_io_handle->range_offset += read_size;
538 
539 	return( (ssize_t) read_size );
540 }
541 
542 /* Writes a buffer to the memory range IO handle
543  * Returns the number of bytes written if successful, or -1 on error
544  */
libbfio_memory_range_io_handle_write_buffer(libbfio_memory_range_io_handle_t * memory_range_io_handle,const uint8_t * buffer,size_t size,libcerror_error_t ** error)545 ssize_t libbfio_memory_range_io_handle_write_buffer(
546          libbfio_memory_range_io_handle_t *memory_range_io_handle,
547          const uint8_t *buffer,
548          size_t size,
549          libcerror_error_t **error )
550 {
551 	static char *function = "libbfio_memory_range_io_handle_write_buffer";
552 	size_t write_size     = 0;
553 
554 	if( memory_range_io_handle == NULL )
555 	{
556 		libcerror_error_set(
557 		 error,
558 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
559 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
560 		 "%s: invalid memory range IO handle.",
561 		 function );
562 
563 		return( -1 );
564 	}
565 	if( memory_range_io_handle->range_start == NULL )
566 	{
567 		libcerror_error_set(
568 		 error,
569 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
570 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
571 		 "%s: invalid memory range IO handle - invalid range start.",
572 		 function );
573 
574 		return( -1 );
575 	}
576 	if( memory_range_io_handle->is_open == 0 )
577 	{
578 		libcerror_error_set(
579 		 error,
580 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
581 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
582 		 "%s: invalid memory range IO handle - not open.",
583 		 function );
584 
585 		return( -1 );
586 	}
587 	if( ( memory_range_io_handle->access_flags & LIBBFIO_ACCESS_FLAG_WRITE ) == 0 )
588 	{
589 		libcerror_error_set(
590 		 error,
591 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
592 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
593 		 "%s: invalid memory range IO handle - no write access.",
594 		 function );
595 
596 		return( -1 );
597 	}
598 	if( buffer == NULL )
599 	{
600 		libcerror_error_set(
601 		 error,
602 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
603 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
604 		 "%s: invalid buffer.",
605 		 function );
606 
607 		return( -1 );
608 	}
609 	if( size > (size_t) SSIZE_MAX )
610 	{
611 		libcerror_error_set(
612 		 error,
613 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
614 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
615 		 "%s: invalid size value exceeds maximum.",
616 		 function );
617 
618 		return( -1 );
619 	}
620 	if( memory_range_io_handle->range_offset > memory_range_io_handle->range_size )
621 	{
622 		libcerror_error_set(
623 		 error,
624 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
625 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
626 		 "%s: invalid range offset value out of bounds.",
627 		 function );
628 
629 		return( -1 );
630 	}
631 	/* Check if the end of the data was reached
632 	 */
633 	if( memory_range_io_handle->range_offset >= memory_range_io_handle->range_size )
634 	{
635 		return( 0 );
636 	}
637 	/* Check the amount of data available
638 	 */
639 	write_size = memory_range_io_handle->range_size - memory_range_io_handle->range_offset;
640 
641 	/* Cannot write more data than available
642 	 */
643 	if( write_size > size )
644 	{
645 		write_size = size;
646 	}
647 	if( memory_copy(
648 	     &( memory_range_io_handle->range_start[ memory_range_io_handle->range_offset ] ),
649 	     buffer,
650 	     write_size ) == NULL )
651 	{
652 		libcerror_error_set(
653 		 error,
654 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
655 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
656 		 "%s: unable to write buffer to memory range.",
657 		 function );
658 
659 		return( -1 );
660 	}
661 	memory_range_io_handle->range_offset += write_size;
662 
663 	return( (ssize_t) write_size );
664 }
665 
666 /* Seeks a certain offset within the memory range IO handle
667  * Returns the offset if the seek is successful or -1 on error
668  */
libbfio_memory_range_io_handle_seek_offset(libbfio_memory_range_io_handle_t * memory_range_io_handle,off64_t offset,int whence,libcerror_error_t ** error)669 off64_t libbfio_memory_range_io_handle_seek_offset(
670          libbfio_memory_range_io_handle_t *memory_range_io_handle,
671          off64_t offset,
672          int whence,
673          libcerror_error_t **error )
674 {
675 	static char *function = "libbfio_memory_range_io_handle_seek_offset";
676 
677 	if( memory_range_io_handle == NULL )
678 	{
679 		libcerror_error_set(
680 		 error,
681 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
682 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
683 		 "%s: invalid memory range IO handle.",
684 		 function );
685 
686 		return( -1 );
687 	}
688 	if( memory_range_io_handle->range_start == NULL )
689 	{
690 		libcerror_error_set(
691 		 error,
692 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
693 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
694 		 "%s: invalid memory range IO handle - invalid range start.",
695 		 function );
696 
697 		return( -1 );
698 	}
699 	if( memory_range_io_handle->is_open == 0 )
700 	{
701 		libcerror_error_set(
702 		 error,
703 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
704 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
705 		 "%s: invalid memory range IO handle - not open.",
706 		 function );
707 
708 		return( -1 );
709 	}
710 	if( offset > (off64_t) INT64_MAX )
711 	{
712 		libcerror_error_set(
713 		 error,
714 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
715 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
716 		 "%s: invalid offset value exceeds maximum.",
717 		 function );
718 
719 		return( -1 );
720 	}
721 	if( ( whence != SEEK_CUR )
722 	 && ( whence != SEEK_END )
723 	 && ( whence != SEEK_SET ) )
724 	{
725 		libcerror_error_set(
726 		 error,
727 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
728 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
729 		 "%s: unsupported whence.",
730 		 function );
731 
732 		return( -1 );
733 	}
734 	if( whence == SEEK_CUR )
735 	{
736 		offset += memory_range_io_handle->range_offset;
737 	}
738 	else if( whence == SEEK_END )
739 	{
740 		offset += memory_range_io_handle->range_size;
741 	}
742 	if( offset < 0 )
743 	{
744 		libcerror_error_set(
745 		 error,
746 		 LIBCERROR_ERROR_DOMAIN_IO,
747 		 LIBCERROR_IO_ERROR_SEEK_FAILED,
748 		 "%s: unable to seek offset.",
749 		 function );
750 
751 		return( -1 );
752 	}
753 	if( offset > (off64_t) SSIZE_MAX )
754 	{
755 		libcerror_error_set(
756 		 error,
757 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
758 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
759 		 "%s: invalid offset value exceeds maximum.",
760 		 function );
761 
762 		return( -1 );
763 	}
764 	memory_range_io_handle->range_offset = (size_t) offset;
765 
766 	return( offset );
767 }
768 
769 /* Function to determine if a memory range exists
770  * Returns 1 if the memory range exists, 0 if not or -1 on error
771  */
libbfio_memory_range_io_handle_exists(libbfio_memory_range_io_handle_t * memory_range_io_handle,libcerror_error_t ** error)772 int libbfio_memory_range_io_handle_exists(
773      libbfio_memory_range_io_handle_t *memory_range_io_handle,
774      libcerror_error_t **error )
775 {
776 	static char *function = "libbfio_memory_range_io_handle_exists";
777 
778 	if( memory_range_io_handle == NULL )
779 	{
780 		libcerror_error_set(
781 		 error,
782 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
783 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
784 		 "%s: invalid memory range IO handle.",
785 		 function );
786 
787 		return( -1 );
788 	}
789 	if( memory_range_io_handle->range_start == NULL )
790 	{
791 		return( 0 );
792 	}
793 	return( 1 );
794 }
795 
796 /* Check if the memory range is open
797  * Returns 1 if open, 0 if not or -1 on error
798  */
libbfio_memory_range_io_handle_is_open(libbfio_memory_range_io_handle_t * memory_range_io_handle,libcerror_error_t ** error)799 int libbfio_memory_range_io_handle_is_open(
800      libbfio_memory_range_io_handle_t *memory_range_io_handle,
801      libcerror_error_t **error )
802 {
803 	static char *function = "libbfio_memory_range_io_handle_is_open";
804 
805 	if( memory_range_io_handle == NULL )
806 	{
807 		libcerror_error_set(
808 		 error,
809 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
810 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
811 		 "%s: invalid memory range IO handle.",
812 		 function );
813 
814 		return( -1 );
815 	}
816 	if( ( memory_range_io_handle->range_start == NULL )
817 	 || ( memory_range_io_handle->is_open == 0 ) )
818 	{
819 		return( 0 );
820 	}
821 	return( 1 );
822 }
823 
824 /* Retrieves the memory range size
825  * Returns 1 if successful or -1 on error
826  */
libbfio_memory_range_io_handle_get_size(libbfio_memory_range_io_handle_t * memory_range_io_handle,size64_t * size,libcerror_error_t ** error)827 int libbfio_memory_range_io_handle_get_size(
828      libbfio_memory_range_io_handle_t *memory_range_io_handle,
829      size64_t *size,
830      libcerror_error_t **error )
831 {
832 	static char *function = "libbfio_memory_range_io_handle_get_size";
833 
834 	if( memory_range_io_handle == NULL )
835 	{
836 		libcerror_error_set(
837 		 error,
838 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
839 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
840 		 "%s: invalid memory range IO handle.",
841 		 function );
842 
843 		return( -1 );
844 	}
845 	if( memory_range_io_handle->range_start == NULL )
846 	{
847 		libcerror_error_set(
848 		 error,
849 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
850 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
851 		 "%s: invalid memory range IO handle - invalid range start.",
852 		 function );
853 
854 		return( -1 );
855 	}
856 	if( size == NULL )
857 	{
858 		libcerror_error_set(
859 		 error,
860 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
861 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
862 		 "%s: invalid size.",
863 		 function );
864 
865 		return( -1 );
866 	}
867 	*size = (size64_t) memory_range_io_handle->range_size;
868 
869 	return( 1 );
870 }
871 
872