Coverage Report

Created: 2025-12-05 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfsapfs/libfsapfs/libfsapfs_attributes.c
Line
Count
Source
1
/*
2
 * (Extended) attribute functions
3
 *
4
 * Copyright (C) 2018-2025, 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 <types.h>
24
25
#include "libfsapfs_attribute_values.h"
26
#include "libfsapfs_attributes.h"
27
#include "libfsapfs_data_stream.h"
28
#include "libfsapfs_encryption_context.h"
29
#include "libfsapfs_file_extent.h"
30
#include "libfsapfs_file_system_btree.h"
31
#include "libfsapfs_io_handle.h"
32
#include "libfsapfs_libbfio.h"
33
#include "libfsapfs_libcdata.h"
34
#include "libfsapfs_libcerror.h"
35
#include "libfsapfs_libfdata.h"
36
37
/* Retrieves the attribute value data file extents
38
 * Returns 1 if successful or -1 on error
39
 */
40
int libfsapfs_attributes_get_file_extents(
41
     libfsapfs_attribute_values_t *attribute_values,
42
     libbfio_handle_t *file_io_handle,
43
     libfsapfs_file_system_btree_t *file_system_btree,
44
     uint64_t transaction_identifier,
45
     libcerror_error_t **error )
46
0
{
47
0
  static char *function = "libfsapfs_attributes_get_file_extents";
48
0
  int result            = 0;
49
50
0
  if( attribute_values == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid attribute values.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
0
  if( attribute_values->value_data_file_extents != NULL )
62
0
  {
63
0
    libcerror_error_set(
64
0
     error,
65
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
66
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
67
0
     "%s: invalid attribute values - value data file extents value already set.",
68
0
     function );
69
70
0
    return( -1 );
71
0
  }
72
0
  if( libcdata_array_initialize(
73
0
       &( attribute_values->value_data_file_extents ),
74
0
       0,
75
0
       error ) != 1 )
76
0
  {
77
0
    libcerror_error_set(
78
0
     error,
79
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
80
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
81
0
     "%s: unable to create value data file extents array.",
82
0
     function );
83
84
0
    goto on_error;
85
0
  }
86
0
  result = libfsapfs_file_system_btree_get_file_extents(
87
0
      file_system_btree,
88
0
      file_io_handle,
89
0
      attribute_values->value_data_stream_identifier,
90
0
      transaction_identifier,
91
0
      attribute_values->value_data_file_extents,
92
0
      error );
93
94
0
  if( result == -1 )
95
0
  {
96
0
    libcerror_error_set(
97
0
     error,
98
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
99
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
100
0
     "%s: unable to retrieve value data file extents from file system B-tree.",
101
0
     function );
102
103
0
    goto on_error;
104
0
  }
105
0
  return( 1 );
106
107
0
on_error:
108
0
  if( attribute_values->value_data_file_extents != NULL )
109
0
  {
110
0
    libcdata_array_free(
111
0
     &( attribute_values->value_data_file_extents ),
112
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libfsapfs_file_extent_free,
113
0
     NULL );
114
0
  }
115
0
  return( -1 );
116
0
}
117
118
/* Retrieves the attribute value data stream
119
 * Returns 1 if successful or -1 on error
120
 */
121
int libfsapfs_attributes_get_data_stream(
122
     libfsapfs_attribute_values_t *attribute_values,
123
     libfsapfs_io_handle_t *io_handle,
124
     libbfio_handle_t *file_io_handle,
125
     libfsapfs_encryption_context_t *encryption_context,
126
     libfsapfs_file_system_btree_t *file_system_btree,
127
     uint64_t transaction_identifier,
128
     libfdata_stream_t **data_stream,
129
     libcerror_error_t **error )
130
5
{
131
5
  static char *function = "libfsapfs_attributes_get_data_stream";
132
133
5
  if( attribute_values == NULL )
134
0
  {
135
0
    libcerror_error_set(
136
0
     error,
137
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
138
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
139
0
     "%s: invalid attribute values.",
140
0
     function );
141
142
0
    return( -1 );
143
0
  }
144
5
  if( ( attribute_values->flags & 0x0001 ) != 0 )
145
0
  {
146
0
    if( attribute_values->value_data_file_extents == NULL )
147
0
    {
148
0
      if( libfsapfs_attributes_get_file_extents(
149
0
           attribute_values,
150
0
           file_io_handle,
151
0
           file_system_btree,
152
0
           transaction_identifier,
153
0
           error ) != 1 )
154
0
      {
155
0
        libcerror_error_set(
156
0
         error,
157
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
158
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
159
0
         "%s: unable to retrieve attribute value data file extents.",
160
0
         function );
161
162
0
        return( -1 );
163
0
      }
164
0
    }
165
0
    if( libfsapfs_data_stream_initialize_from_file_extents(
166
0
         data_stream,
167
0
         io_handle,
168
0
         encryption_context,
169
0
         attribute_values->value_data_file_extents,
170
0
         attribute_values->value_data_size,
171
0
         0,
172
0
         error ) != 1 )
173
0
    {
174
0
      libcerror_error_set(
175
0
       error,
176
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
177
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
178
0
       "%s: unable to create value data stream from file extents.",
179
0
       function );
180
181
0
      return( -1 );
182
0
    }
183
0
  }
184
5
  else if( ( attribute_values->flags & 0x0002 ) != 0 )
185
5
  {
186
5
    if( libfsapfs_data_stream_initialize_from_data(
187
5
         data_stream,
188
5
         attribute_values->value_data,
189
5
         (size_t) attribute_values->value_data_size,
190
5
         error ) != 1 )
191
0
    {
192
0
      libcerror_error_set(
193
0
       error,
194
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
195
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
196
0
       "%s: unable to create value data stream from data.",
197
0
       function );
198
199
0
      return( -1 );
200
0
    }
201
5
  }
202
5
  return( 1 );
203
5
}
204