1 /*
2 * Block data handle functions
3 *
4 * Copyright (C) 2020-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 <memory.h>
24 #include <types.h>
25
26 #include "libfsxfs_block_data_handle.h"
27 #include "libfsxfs_libbfio.h"
28 #include "libfsxfs_libcerror.h"
29 #include "libfsxfs_libfdata.h"
30 #include "libfsxfs_unused.h"
31
32 /* Reads data from the current offset into a buffer
33 * Callback for the cluster block data stream
34 * Returns the number of bytes read or -1 on error
35 */
libfsxfs_block_data_handle_read_segment_data(intptr_t * data_handle LIBFSXFS_ATTRIBUTE_UNUSED,libbfio_handle_t * file_io_handle,int segment_index LIBFSXFS_ATTRIBUTE_UNUSED,int segment_file_index LIBFSXFS_ATTRIBUTE_UNUSED,uint8_t * segment_data,size_t segment_data_size,uint32_t segment_flags,uint8_t read_flags LIBFSXFS_ATTRIBUTE_UNUSED,libcerror_error_t ** error)36 ssize_t libfsxfs_block_data_handle_read_segment_data(
37 intptr_t *data_handle LIBFSXFS_ATTRIBUTE_UNUSED,
38 libbfio_handle_t *file_io_handle,
39 int segment_index LIBFSXFS_ATTRIBUTE_UNUSED,
40 int segment_file_index LIBFSXFS_ATTRIBUTE_UNUSED,
41 uint8_t *segment_data,
42 size_t segment_data_size,
43 uint32_t segment_flags,
44 uint8_t read_flags LIBFSXFS_ATTRIBUTE_UNUSED,
45 libcerror_error_t **error )
46 {
47 static char *function = "libfsxfs_block_data_handle_read_segment_data";
48 ssize_t read_count = 0;
49
50 LIBFSXFS_UNREFERENCED_PARAMETER( data_handle )
51 LIBFSXFS_UNREFERENCED_PARAMETER( segment_index )
52 LIBFSXFS_UNREFERENCED_PARAMETER( segment_file_index )
53 LIBFSXFS_UNREFERENCED_PARAMETER( read_flags )
54
55 if( segment_data == NULL )
56 {
57 libcerror_error_set(
58 error,
59 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
60 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
61 "%s: invalid segment data.",
62 function );
63
64 return( -1 );
65 }
66 if( segment_data_size > (size_t) SSIZE_MAX )
67 {
68 libcerror_error_set(
69 error,
70 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
71 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
72 "%s: invalid segment data size value exceeds maximum.",
73 function );
74
75 return( -1 );
76 }
77 if( ( segment_flags & LIBFDATA_RANGE_FLAG_IS_SPARSE ) != 0 )
78 {
79 if( memory_set(
80 segment_data,
81 0,
82 segment_data_size ) == NULL )
83 {
84 libcerror_error_set(
85 error,
86 LIBCERROR_ERROR_DOMAIN_MEMORY,
87 LIBCERROR_MEMORY_ERROR_SET_FAILED,
88 "%s: unable to clear segment data.",
89 function );
90
91 return( -1 );
92 }
93 read_count = (ssize_t) segment_data_size;
94 }
95 else
96 {
97 read_count = libbfio_handle_read_buffer(
98 file_io_handle,
99 segment_data,
100 segment_data_size,
101 error );
102
103 if( read_count < 0 )
104 {
105 libcerror_error_set(
106 error,
107 LIBCERROR_ERROR_DOMAIN_IO,
108 LIBCERROR_IO_ERROR_READ_FAILED,
109 "%s: unable to read segment data.",
110 function );
111
112 return( -1 );
113 }
114 }
115 return( read_count );
116 }
117
118 /* Seeks a certain offset of the data
119 * Callback for the cluster block data stream
120 * Returns the offset if seek is successful or -1 on error
121 */
libfsxfs_block_data_handle_seek_segment_offset(intptr_t * data_handle LIBFSXFS_ATTRIBUTE_UNUSED,libbfio_handle_t * file_io_handle,int segment_index LIBFSXFS_ATTRIBUTE_UNUSED,int segment_file_index LIBFSXFS_ATTRIBUTE_UNUSED,off64_t segment_offset,libcerror_error_t ** error)122 off64_t libfsxfs_block_data_handle_seek_segment_offset(
123 intptr_t *data_handle LIBFSXFS_ATTRIBUTE_UNUSED,
124 libbfio_handle_t *file_io_handle,
125 int segment_index LIBFSXFS_ATTRIBUTE_UNUSED,
126 int segment_file_index LIBFSXFS_ATTRIBUTE_UNUSED,
127 off64_t segment_offset,
128 libcerror_error_t **error )
129 {
130 static char *function = "libfsxfs_block_data_handle_seek_segment_offset";
131
132 LIBFSXFS_UNREFERENCED_PARAMETER( data_handle )
133 LIBFSXFS_UNREFERENCED_PARAMETER( segment_index )
134 LIBFSXFS_UNREFERENCED_PARAMETER( segment_file_index )
135
136 if( segment_offset < 0 )
137 {
138 libcerror_error_set(
139 error,
140 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
141 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
142 "%s: invalid segment offset value out of bounds.",
143 function );
144
145 return( -1 );
146 }
147 if( libbfio_handle_seek_offset(
148 file_io_handle,
149 segment_offset,
150 SEEK_SET,
151 error ) == -1 )
152 {
153 libcerror_error_set(
154 error,
155 LIBCERROR_ERROR_DOMAIN_IO,
156 LIBCERROR_IO_ERROR_SEEK_FAILED,
157 "%s: unable to seek segment offset: %" PRIi64 " (0x%08" PRIx64 ").",
158 function,
159 segment_offset,
160 segment_offset );
161
162 return( -1 );
163 }
164 return( segment_offset );
165 }
166
167