162 lines
4.7 KiB
C
162 lines
4.7 KiB
C
|
|
/*
|
|
* Copyright (c) 2006-2010 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_MEMORY
|
|
static 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. Use this in case you want to open the whole device
|
|
* as a single partition (e.g. for "super floppy" use).
|
|
* \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_MEMORY
|
|
new_partition = malloc(sizeof(*new_partition));
|
|
if(!new_partition)
|
|
return 0;
|
|
#else
|
|
new_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;
|
|
#endif
|
|
|
|
memset(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_MEMORY
|
|
free(partition);
|
|
partition=NULL;
|
|
#else
|
|
partition->type = PARTITION_TYPE_FREE;
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|