Add function to retrieve CHS geometry from AaruFormat image

This commit is contained in:
2025-10-04 23:12:31 +01:00
parent d9312f4121
commit 806fa49d41
3 changed files with 138 additions and 4 deletions

View File

@@ -133,7 +133,8 @@ add_library(aaruformat SHARED include/aaruformat/consts.h include/aaruformat/enu
src/checksum/sha256.c src/checksum/sha256.c
include/sha256.h include/sha256.h
src/lisa_tag.c src/lisa_tag.c
include/aaruformat/structs/lisa_tag.h) include/aaruformat/structs/lisa_tag.h
src/metadata.c)
include_directories(include include/aaruformat 3rdparty/uthash/include 3rdparty/uthash/src) include_directories(include include/aaruformat 3rdparty/uthash/include 3rdparty/uthash/src)

View File

@@ -96,7 +96,8 @@ AARU_EXPORT int32_t AARU_CALL aaruf_write_sector(void *context, uint64_t sector_
const uint8_t *data, uint8_t sector_status, uint32_t length); const uint8_t *data, uint8_t sector_status, uint32_t length);
AARU_EXPORT int32_t AARU_CALL aaruf_write_sector_long(void *context, uint64_t sector_address, bool negative, AARU_EXPORT int32_t AARU_CALL aaruf_write_sector_long(void *context, uint64_t sector_address, bool negative,
const uint8_t *data, uint8_t sector_status, uint32_t length); const uint8_t *data, uint8_t sector_status, uint32_t length);
AARU_EXPORT int32_t AARU_CALL write_media_tag(void *context, const uint8_t *data, const int32_t type, const uint32_t length); AARU_EXPORT int32_t AARU_CALL write_media_tag(void *context, const uint8_t *data, const int32_t type,
const uint32_t length);
AARU_EXPORT int32_t AARU_CALL aaruf_verify_image(void *context); AARU_EXPORT int32_t AARU_CALL aaruf_verify_image(void *context);
@@ -136,11 +137,12 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_track_sector(void *context, uint8_t *da
uint32_t *length, uint8_t track); uint32_t *length, uint8_t track);
AARU_LOCAL int32_t AARU_CALL aaruf_get_media_tag_type_for_datatype(int32_t type); AARU_LOCAL int32_t AARU_CALL aaruf_get_media_tag_type_for_datatype(int32_t type);
AARU_LOCAL int32_t AARU_CALL aaruf_get_datatype_for_media_tag_type(int32_t tag_type); AARU_LOCAL int32_t AARU_CALL aaruf_get_datatype_for_media_tag_type(int32_t tag_type);
AARU_LOCAL int32_t AARU_CALL aaruf_get_xml_mediatype(int32_t type); AARU_LOCAL int32_t AARU_CALL aaruf_get_xml_mediatype(int32_t type);
AARU_EXPORT int32_t AARU_CALL aaruf_get_geometry(const void *context, uint32_t *cylinders, uint32_t *heads,
uint32_t *sectors_per_track);
AARU_EXPORT spamsum_ctx *AARU_CALL aaruf_spamsum_init(void); AARU_EXPORT spamsum_ctx *AARU_CALL aaruf_spamsum_init(void);
AARU_EXPORT int AARU_CALL aaruf_spamsum_update(spamsum_ctx *ctx, const uint8_t *data, uint32_t len); AARU_EXPORT int AARU_CALL aaruf_spamsum_update(spamsum_ctx *ctx, const uint8_t *data, uint32_t len);
AARU_EXPORT int AARU_CALL aaruf_spamsum_final(spamsum_ctx *ctx, uint8_t *result); AARU_EXPORT int AARU_CALL aaruf_spamsum_final(spamsum_ctx *ctx, uint8_t *result);

131
src/metadata.c Normal file
View File

@@ -0,0 +1,131 @@
/*
* This file is part of the Aaru Data Preservation Suite.
* Copyright (c) 2019-2025 Natalia Portillo.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include "aaruformat.h"
#include "log.h"
/**
* @brief Retrieves the logical CHS geometry from the AaruFormat image.
*
* Reads the Cylinder-Head-Sector (CHS) geometry information from the image's geometry
* block and returns the values through output parameters. The geometry block contains
* legacy-style logical addressing parameters that describe how the storage medium was
* originally organized in terms of cylinders, heads (tracks per cylinder), and sectors
* per track. This information is essential for software that requires CHS addressing
* or for accurately representing the original medium's logical structure.
*
* @param context Pointer to the aaruformat context (must be a valid, opened image context).
* @param cylinders Pointer to store the number of cylinders. Updated on success.
* @param heads Pointer to store the number of heads (tracks per cylinder). Updated on success.
* @param sectors_per_track Pointer to store the number of sectors per track. Updated on success.
*
* @return Returns one of the following status codes:
* @retval AARUF_STATUS_OK (0) Successfully retrieved geometry information. This is returned when:
* - The context is valid and properly initialized
* - The geometry block is present in the image (identifier == GeometryBlock)
* - All three output parameters are successfully populated with geometry values
* - The cylinders parameter contains the total number of cylinders
* - The heads parameter contains the number of heads per cylinder
* - The sectors_per_track parameter contains the number of sectors per track
*
* @retval AARUF_ERROR_NOT_AARUFORMAT (-1) The context is invalid. This occurs when:
* - The context parameter is NULL
* - The context magic number doesn't match AARU_MAGIC (invalid context type)
* - The context was not properly initialized by aaruf_open() or aaruf_create()
*
* @retval AARUF_ERROR_CANNOT_READ_BLOCK (-6) The geometry block is not present. This occurs when:
* - The image was created without geometry information
* - The geometryBlock.identifier field doesn't equal GeometryBlock
* - The geometry block was not found during image opening
* - The image format doesn't support or require CHS geometry
*
* @note Geometry Interpretation:
* - Total logical sectors = cylinders × heads × sectors_per_track
* - Sector size is not included in the geometry block and must be obtained separately
* (typically 512 bytes for most block devices, but can vary)
* - The geometry represents logical addressing, not necessarily physical medium geometry
* - Modern storage devices often report translated or synthetic geometry values
*
* @note CHS Addressing Context:
* - CHS addressing was historically used for hard disk drives and floppy disks
* - Legacy BIOS and older operating systems relied on CHS parameters
* - LBA (Logical Block Addressing) has largely replaced CHS for modern devices
* - Some disk image formats and emulators still require CHS information
*
* @note Geometry Block Availability:
* - Not all image types contain geometry blocks
* - Optical media (CDs, DVDs) typically don't have CHS geometry
* - Modern large-capacity drives may not have meaningful CHS values
* - Check the return value to determine if geometry is available
*
* @note Parameter Validation:
* - All output parameters must be non-NULL valid pointers
* - The function does not validate the geometry values themselves
* - Geometry values of zero or unusually large values may indicate issues
*
* @warning The output parameters are only modified on success (AARUF_STATUS_OK).
* On error, their values remain unchanged. Initialize them before calling
* if default values are needed on failure.
*
* @warning This function reads from the in-memory geometry block loaded during
* aaruf_open(). It does not perform file I/O operations.
*
* @warning Geometry values may not accurately represent physical device geometry,
* especially for modern drives with zone-based recording or flash storage.
*/
int32_t aaruf_get_geometry(const void *context, uint32_t *cylinders, uint32_t *heads, uint32_t *sectors_per_track)
{
TRACE("Entering aaruf_get_geometry(%p, %u, %u, %u)", context, *cylinders, *heads, *sectors_per_track);
const aaruformatContext *ctx = NULL;
if(context == NULL)
{
FATAL("Invalid context");
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_AARUFORMAT");
return AARUF_ERROR_NOT_AARUFORMAT;
}
ctx = context;
// Not a libaaruformat context
if(ctx->magic != AARU_MAGIC)
{
FATAL("Invalid context");
TRACE("Exiting aaruf_read_sector_long() = AARUF_ERROR_NOT_AARUFORMAT");
return AARUF_ERROR_NOT_AARUFORMAT;
}
if(ctx->geometryBlock.identifier != GeometryBlock)
{
FATAL("No geometry block present");
TRACE("Exiting aaruf_get_geometry() = AARUF_ERROR_CANNOT_READ_BLOCK");
return AARUF_ERROR_CANNOT_READ_BLOCK;
}
*cylinders = ctx->geometryBlock.cylinders;
*heads = ctx->geometryBlock.heads;
*sectors_per_track = ctx->geometryBlock.sectorsPerTrack;
return AARUF_STATUS_OK;
}