Coverage Report

Created: 2026-07-10 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libodraw/libodraw/libodraw_track_value.c
Line
Count
Source
1
/*
2
 * Track value functions
3
 *
4
 * Copyright (C) 2010-2026, 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 "libodraw_definitions.h"
27
#include "libodraw_libcerror.h"
28
#include "libodraw_track_value.h"
29
30
/* Creates a track value
31
 * Make sure the value track_value is referencing, is set to NULL
32
 * Returns 1 if successful or -1 on error
33
 */
34
int libodraw_track_value_initialize(
35
     libodraw_track_value_t **track_value,
36
     libcerror_error_t **error )
37
24.7k
{
38
24.7k
  static char *function = "libodraw_track_value_initialize";
39
40
24.7k
  if( track_value == NULL )
41
0
  {
42
0
    libcerror_error_set(
43
0
     error,
44
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
45
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
46
0
     "%s: invalid track value.",
47
0
     function );
48
49
0
    return( -1 );
50
0
  }
51
24.7k
  if( *track_value != NULL )
52
0
  {
53
0
    libcerror_error_set(
54
0
     error,
55
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
56
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
57
0
     "%s: invalid track value value already set.",
58
0
     function );
59
60
0
    return( -1 );
61
0
  }
62
24.7k
  *track_value = memory_allocate_structure(
63
24.7k
      libodraw_track_value_t );
64
65
24.7k
  if( *track_value == NULL )
66
0
  {
67
0
    libcerror_error_set(
68
0
     error,
69
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
70
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
71
0
     "%s: unable to create track value.",
72
0
     function );
73
74
0
    goto on_error;
75
0
  }
76
24.7k
  if( memory_set(
77
24.7k
       *track_value,
78
24.7k
       0,
79
24.7k
       sizeof( libodraw_track_value_t ) ) == NULL )
80
0
  {
81
0
    libcerror_error_set(
82
0
     error,
83
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
84
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
85
0
     "%s: unable to clear track value.",
86
0
     function );
87
88
0
    goto on_error;
89
0
  }
90
24.7k
  return( 1 );
91
92
0
on_error:
93
0
  if( *track_value != NULL )
94
0
  {
95
0
    memory_free(
96
0
     *track_value );
97
98
0
    *track_value = NULL;
99
0
  }
100
0
  return( -1 );
101
24.7k
}
102
103
/* Frees a track value
104
 * Returns 1 if successful or -1 on error
105
 */
106
int libodraw_track_value_free(
107
     libodraw_track_value_t **track_value,
108
     libcerror_error_t **error )
109
24.7k
{
110
24.7k
  static char *function = "libodraw_track_value_free";
111
112
24.7k
  if( track_value == NULL )
113
0
  {
114
0
    libcerror_error_set(
115
0
     error,
116
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
117
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
118
0
     "%s: invalid track value.",
119
0
     function );
120
121
0
    return( -1 );
122
0
  }
123
24.7k
  if( *track_value != NULL )
124
24.7k
  {
125
24.7k
    memory_free(
126
24.7k
     *track_value );
127
128
24.7k
    *track_value = NULL;
129
24.7k
  }
130
24.7k
  return( 1 );
131
24.7k
}
132
133
/* Retrieves a track value
134
 * Returns 1 if successful or -1 on error
135
 */
136
int libodraw_track_value_get(
137
     libodraw_track_value_t *track_value,
138
     uint64_t *start_sector,
139
     uint64_t *number_of_sectors,
140
     uint8_t *type,
141
     int *data_file_index,
142
     uint64_t *data_file_start_sector,
143
     libcerror_error_t **error )
144
0
{
145
0
  static char *function = "libodraw_track_value_get";
146
147
0
  if( track_value == NULL )
148
0
  {
149
0
    libcerror_error_set(
150
0
     error,
151
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
152
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
153
0
     "%s: invalid track value.",
154
0
     function );
155
156
0
    return( -1 );
157
0
  }
158
0
  if( start_sector == NULL )
159
0
  {
160
0
    libcerror_error_set(
161
0
     error,
162
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
163
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
164
0
     "%s: invalid start sector.",
165
0
     function );
166
167
0
    return( -1 );
168
0
  }
169
0
  if( number_of_sectors == NULL )
170
0
  {
171
0
    libcerror_error_set(
172
0
     error,
173
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
174
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
175
0
     "%s: invalid number of sectors.",
176
0
     function );
177
178
0
    return( -1 );
179
0
  }
180
0
  if( type == NULL )
181
0
  {
182
0
    libcerror_error_set(
183
0
     error,
184
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
185
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
186
0
     "%s: invalid type.",
187
0
     function );
188
189
0
    return( -1 );
190
0
  }
191
0
  if( data_file_index == NULL )
192
0
  {
193
0
    libcerror_error_set(
194
0
     error,
195
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
196
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
197
0
     "%s: invalid data file index.",
198
0
     function );
199
200
0
    return( -1 );
201
0
  }
202
0
  if( data_file_start_sector == NULL )
203
0
  {
204
0
    libcerror_error_set(
205
0
     error,
206
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
207
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
208
0
     "%s: invalid data file start sector.",
209
0
     function );
210
211
0
    return( -1 );
212
0
  }
213
0
  *start_sector           = track_value->start_sector;
214
0
  *number_of_sectors      = track_value->number_of_sectors;
215
0
  *type                   = track_value->type;
216
0
  *data_file_index        = track_value->data_file_index;
217
0
  *data_file_start_sector = track_value->data_file_start_sector;
218
219
0
  return( 1 );
220
0
}
221
222
/* Sets a track value
223
 * Returns 1 if successful or -1 on error
224
 */
225
int libodraw_track_value_set(
226
     libodraw_track_value_t *track_value,
227
     uint64_t start_sector,
228
     uint64_t number_of_sectors,
229
     uint8_t type,
230
     int data_file_index,
231
     uint64_t data_file_start_sector,
232
     libcerror_error_t **error )
233
24.7k
{
234
24.7k
  static char *function = "libodraw_track_value_set";
235
236
24.7k
  if( track_value == NULL )
237
0
  {
238
0
    libcerror_error_set(
239
0
     error,
240
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
241
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
242
0
     "%s: invalid track value.",
243
0
     function );
244
245
0
    return( -1 );
246
0
  }
247
24.7k
  if( start_sector > (uint64_t) INT64_MAX )
248
0
  {
249
0
    libcerror_error_set(
250
0
     error,
251
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
252
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
253
0
     "%s: invalid start sector value exceeds maximum.",
254
0
     function );
255
256
0
    return( -1 );
257
0
  }
258
24.7k
  if( number_of_sectors > (uint64_t) INT64_MAX )
259
0
  {
260
0
    libcerror_error_set(
261
0
     error,
262
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
263
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
264
0
     "%s: invalid number of sectors value exceeds maximum.",
265
0
     function );
266
267
0
    return( -1 );
268
0
  }
269
24.7k
  if( ( type != LIBODRAW_TRACK_TYPE_UNKNOWN )
270
3.25k
   && ( type != LIBODRAW_TRACK_TYPE_AUDIO )
271
1.87k
   && ( type != LIBODRAW_TRACK_TYPE_CDG )
272
1.55k
   && ( type != LIBODRAW_TRACK_TYPE_MODE1_2048 )
273
1.35k
   && ( type != LIBODRAW_TRACK_TYPE_MODE1_2352 )
274
1.16k
   && ( type != LIBODRAW_TRACK_TYPE_MODE2_2048 )
275
970
   && ( type != LIBODRAW_TRACK_TYPE_MODE2_2324 )
276
776
   && ( type != LIBODRAW_TRACK_TYPE_MODE2_2336 )
277
582
   && ( type != LIBODRAW_TRACK_TYPE_MODE2_2352 )
278
388
   && ( type != LIBODRAW_TRACK_TYPE_CDI_2336 )
279
194
   && ( type != LIBODRAW_TRACK_TYPE_CDI_2352 ) )
280
0
  {
281
0
    libcerror_error_set(
282
0
     error,
283
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
284
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
285
0
     "%s: unsupported type.",
286
0
     function );
287
288
0
    return( -1 );
289
0
  }
290
24.7k
  if( data_file_index < 0 )
291
56
  {
292
56
    libcerror_error_set(
293
56
     error,
294
56
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
295
56
     LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
296
56
     "%s: invalid data file index value less than zero.",
297
56
     function );
298
299
56
    return( -1 );
300
56
  }
301
24.7k
  if( data_file_start_sector > (uint64_t) INT64_MAX )
302
31
  {
303
31
    libcerror_error_set(
304
31
     error,
305
31
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
306
31
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
307
31
     "%s: invalid data file start sector value exceeds maximum.",
308
31
     function );
309
310
31
    return( -1 );
311
31
  }
312
24.6k
  if( data_file_start_sector > start_sector )
313
0
  {
314
0
    libcerror_error_set(
315
0
     error,
316
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
317
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
318
0
     "%s: data file start sector value out of bounds.",
319
0
     function );
320
321
0
    return( -1 );
322
0
  }
323
24.6k
  switch( type )
324
24.6k
  {
325
193
    case LIBODRAW_TRACK_TYPE_MODE1_2048:
326
386
    case LIBODRAW_TRACK_TYPE_MODE2_2048:
327
386
      track_value->bytes_per_sector = 2048;
328
329
386
      break;
330
331
193
    case LIBODRAW_TRACK_TYPE_MODE2_2324:
332
193
      track_value->bytes_per_sector = 2324;
333
334
193
      break;
335
336
193
    case LIBODRAW_TRACK_TYPE_MODE2_2336:
337
386
    case LIBODRAW_TRACK_TYPE_CDI_2336:
338
386
      track_value->bytes_per_sector = 2336;
339
340
386
      break;
341
342
1.38k
    case LIBODRAW_TRACK_TYPE_AUDIO:
343
1.57k
    case LIBODRAW_TRACK_TYPE_MODE1_2352:
344
1.76k
    case LIBODRAW_TRACK_TYPE_MODE2_2352:
345
1.96k
    case LIBODRAW_TRACK_TYPE_CDI_2352:
346
1.96k
      track_value->bytes_per_sector = 2352;
347
348
1.96k
      break;
349
350
322
    case LIBODRAW_TRACK_TYPE_CDG:
351
322
      track_value->bytes_per_sector = 2448;
352
353
322
      break;
354
24.6k
  }
355
24.6k
  track_value->start_sector           = start_sector;
356
24.6k
  track_value->end_sector             = start_sector + number_of_sectors;
357
24.6k
  track_value->number_of_sectors      = number_of_sectors;
358
24.6k
  track_value->type                   = type;
359
24.6k
  track_value->data_file_index        = data_file_index;
360
24.6k
  track_value->data_file_start_sector = data_file_start_sector;
361
24.6k
  track_value->data_file_offset       = data_file_start_sector * track_value->bytes_per_sector;
362
363
24.6k
  return( 1 );
364
24.6k
}
365
366
/* Retrieves the bytes per sector
367
 * Returns 1 if successful or -1 on error
368
 */
369
int libodraw_track_value_get_bytes_per_sector(
370
     libodraw_track_value_t *track_value,
371
     uint32_t *bytes_per_sector,
372
     libcerror_error_t **error )
373
0
{
374
0
  static char *function = "libodraw_track_value_get_bytes_per_sector";
375
376
0
  if( track_value == NULL )
377
0
  {
378
0
    libcerror_error_set(
379
0
     error,
380
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
381
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
382
0
     "%s: invalid track value.",
383
0
     function );
384
385
0
    return( -1 );
386
0
  }
387
0
  if( bytes_per_sector == NULL )
388
0
  {
389
0
    libcerror_error_set(
390
0
     error,
391
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
392
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
393
0
     "%s: invalid bytes per sector.",
394
0
     function );
395
396
0
    return( -1 );
397
0
  }
398
0
  *bytes_per_sector = track_value->bytes_per_sector;
399
400
0
  return( 1 );
401
0
}
402