/** Copyright (c) 2006-2007 by Roland Riegel <feedback@roland-riegel.de>** This file is free software; you can redistribute it and/or modify* it under the terms of either the GNU General Public License version 2* or the GNU Lesser General Public License version 2.1, both as* published by the Free Software Foundation.*/#include "partition.h"#include "partition_config.h"#include "sd-reader_config.h"#include <string.h>#if USE_DYNAMIC_MEMORY#include <stdlib.h>#endif/*** \addtogroup partition Partition table support** Support for reading partition tables and access to partitions.** @{*//*** \file* Partition table implementation (license: GPLv2 or LGPLv2.1)** \author Roland Riegel*//*** \addtogroup partition_config Configuration of partition table support* Preprocessor defines to configure the partition support.*/#if !USE_DYNAMIC_MEMORYstatic struct partition_struct partition_handles[PARTITION_COUNT];#endif/*** Opens a partition.** Opens a partition by its index number and returns a partition* handle which describes the opened partition.** \note This function does not support extended partitions.** \param[in] device_read A function pointer which is used to read from the disk.* \param[in] device_read_interval A function pointer which is used to read in constant intervals from the disk.* \param[in] device_write A function pointer which is used to write to the disk.* \param[in] device_write_interval A function pointer which is used to write a data stream to disk.* \param[in] index The index of the partition which should be opened, range 0 to 3.* A negative value is allowed as well. In this case, the partition opened is* not checked for existance, begins at offset zero, has a length of zero* and is of an unknown type.* \returns 0 on failure, a partition descriptor on success.* \see partition_close*/struct partition_struct* partition_open(device_read_t device_read, device_read_interval_t device_read_interval, device_write_t device_write, device_write_interval_t device_write_interval, int8_t index){struct partition_struct* new_partition = 0;uint8_t buffer[0x10];if(!device_read || !device_read_interval || index >= 4)return 0;if(index >= 0){/* read specified partition table index */if(!device_read(0x01be + index * 0x10, buffer, sizeof(buffer)))return 0;/* abort on empty partition entry */if(buffer[4] == 0x00)return 0;}/* allocate partition descriptor */#if USE_DYNAMIC_MEMORYnew_partition = malloc(sizeof(*new_partition));if(!new_partition)return 0;#elsenew_partition = partition_handles;uint8_t i;for(i = 0; i < PARTITION_COUNT; ++i){if(new_partition->type == PARTITION_TYPE_FREE)break;++new_partition;}if(i >= PARTITION_COUNT)return 0;#endifmemset(new_partition, 0, sizeof(*new_partition));/* fill partition descriptor */new_partition->device_read = device_read;new_partition->device_read_interval = device_read_interval;new_partition->device_write = device_write;new_partition->device_write_interval = device_write_interval;if(index >= 0){new_partition->type = buffer[4];new_partition->offset = ((uint32_t) buffer[8]) |((uint32_t) buffer[9] << 8) |((uint32_t) buffer[10] << 16) |((uint32_t) buffer[11] << 24);new_partition->length = ((uint32_t) buffer[12]) |((uint32_t) buffer[13] << 8) |((uint32_t) buffer[14] << 16) |((uint32_t) buffer[15] << 24);}else{new_partition->type = 0xff;}return new_partition;}/*** Closes a partition.** This function destroys a partition descriptor which was* previously obtained from a call to partition_open().* When this function returns, the given descriptor will be* invalid.** \param[in] partition The partition descriptor to destroy.* \returns 0 on failure, 1 on success.* \see partition_open*/uint8_t partition_close(struct partition_struct* partition){if(!partition)return 0;/* destroy partition descriptor */#if USE_DYNAMIC_MEMORYfree(partition);#elsepartition->type = PARTITION_TYPE_FREE;#endifreturn 1;}/*** @}*/