move emile_map_* from libemile to libmap, rename partition.h to libmap.h

This commit is contained in:
Laurent Vivier 2007-10-02 14:21:34 +00:00
parent 2ebda90890
commit d39a68703e
36 changed files with 962 additions and 0 deletions

40
libmap/Makefile Normal file
View File

@ -0,0 +1,40 @@
#
# (c) 2005-2007 Laurent Vivier <Laurent@lvivier.info>
#
TOP = $(shell pwd)
VPATH=$(TOP)
TARGET = native
CFLAGS += -nostdlib -nodefaultlibs -Wall -Werror -Wno-multichar
ifeq ($(TARGET), m68k-linux)
68000FLAGS = -m68000 -Wa,-m68000
CFLAGS += -fpic -O2 -Os
endif
LIBRARY = libmap.a
SOURCES = map_bootblock_get_type.c map_bootblock_is_valid.c \
map_bootblock_read.c map_bootblock_write.c map_close.c map_dev.c \
map_geometry.c map_get_bootinfo.c map_get_driver_info.c \
map_get_driver_number.c map_get_driver_signature.c map_get_number.c \
map_get_partition_geometry.c map_get_partition_name.c \
map_get_partition_type.c map_has_apple_driver.c map_is_valid.c \
map_open.c map_partition_get_flags.c map_partition_is_bootable.c \
map_partition_is_startup.c map_partition_is_valid.c \
map_partition_set_bootable.c map_partition_set_flags.c \
map_partition_set_startup.c map_read.c map_seek_driver_partition.c \
map_set_bootinfo.c map_set_driver_info.c map_set_driver_number.c \
map_set_partition_name.c map_set_partition_type.c map_set_startup.c \
map_write.c
HEADERS = libmap.h
all:
test -d $(TARGET) || mkdir $(TARGET)
cd $(TARGET) && make -f $(TOP)/Makefile $(LIBRARY) TOP=$(TOP)
include $(TOP)/../tools.mk
include $(TOP)/../Rules.mk

129
libmap/libmap.h Normal file
View File

@ -0,0 +1,129 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <sys/types.h>
#ifndef _PARTITION_H
#define _PARTITION_H
static __attribute__((used)) char* partition_header = "$CVSHeader$";
enum {
kPartitionAUXIsValid= 0x00000001,
kPartitionAUXIsAllocated = 0x00000002,
kPartitionAUXIsInUse= 0x00000004,
kPartitionAUXIsBootValid = 0x00000008,
kPartitionAUXIsReadable = 0x00000010,
kPartitionAUXIsWriteable = 0x00000020,
kPartitionAUXIsBootCodePositionIndependent = 0x00000040,
kPartitionIsMountedAtStartup = 0x40000000,
kPartitionIsStartup = 0x80000000,
kPartitionIsChainCompatible = 0x00000100,
kPartitionIsRealDeviceDriver = 0x00000200,
kPartitionCanChainToNext = 0x00000400,
};
/* Constants for the Type field */
enum {
kDriverTypeMacSCSI = 0x0001,
kDriverTypeMacATA = 0x0701,
kDriverTypeMacSCSIChained = 0xFFFF,
kDriverTypeMacATAChained = 0xF8FF
};
struct DriverInfo {
int32_t Block;
int16_t Size;
int16_t Type;
} __attribute__((packed));
#define DD_MAX_DRIVER 61
struct DriverDescriptor {
int16_t Sig;
int16_t BlkSize;
int32_t BlkCount;
int16_t DevType;
int16_t DevId;
int32_t Data;
int16_t DrvrCount;
struct DriverInfo DrvInfo[DD_MAX_DRIVER];
int8_t Pad[6];
} __attribute__((packed));
#define ASSERT_DD(a) if ( sizeof(struct DriverDescriptor) != 512 ) { a }
/* Driver signatures, stored in the first four byte of pmPad. */
enum {
kPatchDriverSignature = 0x70744452, /* 'ptDR', SCSI and ATA[PI] patch driver */
kSCSIDriverSignature = 0x00010600, /* SCSI hard disk driver */
kATADriverSignature = 0x77696b69, /*'wiki', ATA hard disk driver */
kSCSICDDriverSignature = 0x43447672, /* 'CDvr', SCSI CD-ROM driver */
kATAPIDriverSignature = 0x41545049, /* 'ATPI', ATAPI CD-ROM driver */
kDriveSetupHFSSignature = 0x44535531, /* 'DSU1', Drive Setup HFS partition */
};
enum {
kPatchMesh = 0x6d657368, /* 'mesh', fixes MESH bug */
kPatchSCSI = 0x73637369, /* 'scsi' enable booting from CDROM */
kPatchRuby = 0x72756279, /* 'ruby', volume larger than 2GB */
kPatchSnag = 0x736e6167, /* 'snag', enable C key to boot CDROM */
};
struct Partition {
int16_t Sig;
int16_t SigPad;
int32_t MapBlkCnt;
int32_t PyPartStart;
int32_t PartBlkCnt;
char PartName[32];
char PartType[32];
int32_t LgDataStart;
int32_t DataCnt;
int32_t PartStatus;
int32_t LgBootStart;
int32_t BootSize;
int32_t BootAddr;
int32_t BootAddr2;
int32_t BootEntry;
int32_t BootEntry2;
int32_t BootCksum;
char Processor[16];
int16_t Pad[188];
} __attribute__((packed));
#define ASSERT_P(a) if ( sizeof(struct Partition) != 512 ) { a }
#define DD_SIGNATURE 0x4552
#define MAP_SIGNATURE 0x504D
#define APPLE_PARTITION_MAP "Apple_partition_map"
#define APPLE_DRIVER "Apple_Driver"
#define APPLE_DRIVER43 "Apple_Driver43"
#define APPLE_MFS "Apple_MFS"
#define APPLE_HFS "Apple_HFS"
#define APPLE_UNIX_SVR2 "Apple_Unix_SVR2"
#define APPLE_PRODOS "Apple_PRODOS"
#define APPLE_FREE "Apple_Free"
#define APPLE_SCRATCH "Apple_Scratch"
#define APPLE_DRIVER_ATA "Apple_Driver_ATA"
#define APPLE_DRIVER_ATAPI "Apple_Driver_ATAPI"
#define APPLE_DRIVER43_CD "Apple_Driver43_CD"
#define APPLE_FWDRIVER "Apple_FWDriver"
#define APPLE_VOID "Apple_Void"
#define APPLE_PATCHES "Apple_Patches"
#define MAP_NAME_LEN 256
typedef struct {
int fd;
char name[MAP_NAME_LEN];
int current;
struct DriverDescriptor drivers;
struct Partition partition;
} emile_map_t;
#endif

View File

@ -0,0 +1,23 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <string.h>
#include "libmap.h"
int map_bootblock_get_type(char* bootblock)
{
if (!map_bootblock_is_valid(bootblock))
return INVALID_BOOTBLOCK;
if (strcmp(&bootblock[11], "System") == 0)
return APPLE_BOOTBLOCK;
if (strcmp(&bootblock[11], "Mac Bootloader") == 0)
return EMILE_BOOTBLOCK;
return UNKNOWN_BOOTBLOCK;
}

View File

@ -0,0 +1,12 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_bootblock_is_valid(char *bootblock)
{
return (bootblock[0] == 0x4C) && (bootblock[1] == 0x4B);
}

View File

@ -0,0 +1,35 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "libmap.h"
int map_bootblock_read(map_t* map, char* bootblock)
{
off_t offset;
int ret;
int fd;
if (!map_partition_is_valid(map))
return -1;
fd = open(map->name, O_RDONLY);
if (fd == -1)
return -1;
offset = read_long((u_int32_t*)&map->partition.PyPartStart) * 512;
lseek(fd, offset, SEEK_SET);
ret = read(fd, bootblock, BOOTBLOCK_SIZE);
close(fd);
return ret;
}

View File

@ -0,0 +1,35 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "libmap.h"
int map_bootblock_write(map_t* map, char* bootblock)
{
char name[MAP_NAME_LEN];
int ret;
int fd;
if (!map_partition_is_valid(map))
return -1;
sprintf(name, "%s%d", map->name, map->current + 1);
fd = open(name, O_WRONLY);
if (fd == -1)
return -1;
ret = write(fd, bootblock, BOOTBLOCK_SIZE);
close(fd);
return ret;
}

16
libmap/map_close.c Normal file
View File

@ -0,0 +1,16 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdlib.h>
#include <unistd.h>
#include "libmap.h"
void map_close(map_t *map)
{
close(map->fd);
free(map);
}

17
libmap/map_dev.c Normal file
View File

@ -0,0 +1,17 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdio.h>
#include "libmap.h"
char* map_dev(map_t *map)
{
if (!map_partition_is_valid(map))
return NULL;
return map->name;
}

18
libmap/map_geometry.c Normal file
View File

@ -0,0 +1,18 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_geometry(map_t *map, int *block_size, int *block_count)
{
if (!map_is_valid(map))
return -1;
*block_size = read_short((u_int16_t*)&map->drivers.BlkSize);
*block_count = read_long((u_int32_t*)&map->drivers.BlkCount);
return 0;
}

26
libmap/map_get_bootinfo.c Normal file
View File

@ -0,0 +1,26 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <string.h>
#include "libmap.h"
int map_get_bootinfo(map_t *map, int* bootstart, int *bootsize,
int *bootaddr, int *bootentry, int* checksum,
char* processor)
{
if (!map_is_valid(map))
return -1;
*bootstart = read_long((u_int32_t*)&map->partition.LgBootStart);
*bootsize = read_long((u_int32_t*)&map->partition.BootSize);
*bootaddr = read_long((u_int32_t*)&map->partition.BootAddr);
*bootentry = read_long((u_int32_t*)&map->partition.BootEntry);
*checksum = read_long((u_int32_t*)&map->partition.BootCksum);
strcpy(processor, map->partition.Processor);
return 0;
}

View File

@ -0,0 +1,23 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_get_driver_info(map_t *map, int number,
int *block, int *size, int* type)
{
if (!map_is_valid(map))
return -1;
if (number > map_get_driver_number(map))
return -1;
*block = read_long((u_int32_t*)&map->drivers.DrvInfo[number].Block);
*size = read_short((u_int16_t*)&map->drivers.DrvInfo[number].Size);
*type = read_short((u_int16_t*)&map->drivers.DrvInfo[number].Type);
return 0;
}

View File

@ -0,0 +1,15 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_get_driver_number(map_t *map)
{
if (!map_is_valid(map))
return -1;
return read_short((u_int16_t*)&map->drivers.DrvrCount);
}

View File

@ -0,0 +1,17 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdio.h>
#include "libmap.h"
unsigned long map_get_driver_signature(map_t* map)
{
if (!map_partition_is_valid(map))
return 0;
return read_long((u_int32_t*)map->partition.Pad);
}

15
libmap/map_get_number.c Normal file
View File

@ -0,0 +1,15 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdlib.h>
#include <unistd.h>
#include "libmap.h"
int map_get_number(map_t *map)
{
return read_long((u_int32_t*)&map->partition.MapBlkCnt);
}

View File

@ -0,0 +1,18 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_get_partition_geometry(map_t *map, int *start, int *count)
{
if (!map_partition_is_valid(map))
return -1;
*start = read_long((u_int32_t*)&map->partition.PyPartStart);
*count = read_long((u_int32_t*)&map->partition.PartBlkCnt);
return 0;
}

View File

@ -0,0 +1,17 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdio.h>
#include "libmap.h"
char* map_get_partition_name(map_t *map)
{
if (!map_partition_is_valid(map))
return NULL;
return map->partition.PartName;
}

View File

@ -0,0 +1,17 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdio.h>
#include "libmap.h"
char* map_get_partition_type(map_t *map)
{
if (!map_partition_is_valid(map))
return NULL;
return map->partition.PartType;
}

View File

@ -0,0 +1,43 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
/*
* See http://developer.apple.com/technotes/tn/tn1189.html
*
*/
#include <string.h>
#include "libmap.h"
int emile_is_apple_driver(map_t *map)
{
return strncmp(map->partition.PartType,
APPLE_DRIVER, strlen(APPLE_DRIVER)) == 0;
}
int map_has_apple_driver(map_t *map)
{
int block, size, type, part;
int i;
int ret;
for (i = 0; i < map_get_driver_number(map); i++)
{
map_get_driver_info(map, i, &block, &size, &type);
part = map_seek_driver_partition(map, block);
ret = map_read(map, part);
if (ret == -1)
return -1;
if (emile_is_apple_driver(map))
return 1;
}
return 0;
}

12
libmap/map_is_valid.c Normal file
View File

@ -0,0 +1,12 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_is_valid(map_t *map)
{
return read_short((u_int16_t*)&map->drivers.Sig) == DD_SIGNATURE;
}

55
libmap/map_open.c Normal file
View File

@ -0,0 +1,55 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "libmap.h"
map_t* map_open(char *dev, int flags)
{
map_t *map;
int ret;
ASSERT_DD(printf("INTERNAL ERROR: Bad Block 0 size structure\n");
return NULL;)
ASSERT_P(printf("INTERNAL ERROR: Bad Partition size structure\n");
return NULL;)
map = (map_t*)malloc(sizeof(map_t));
if (map == NULL)
return NULL;
map->fd = open(dev, flags);
if (map->fd == -1)
{
free(map);
return NULL;
}
strncpy(map->name, dev, MAP_NAME_LEN);
map->name[MAP_NAME_LEN - 1] = 0;
ret = read(map->fd, &map->drivers, sizeof(map->drivers));
if (ret == -1)
{
free(map);
return NULL;
}
ret = read(map->fd, &map->partition, sizeof(map->partition));
if (ret == -1)
{
free(map);
return NULL;
}
map->current = 0;
return map;
}

View File

@ -0,0 +1,12 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_partition_get_flags(map_t *map)
{
return read_long((u_int32_t*)&map->partition.PartStatus);
}

View File

@ -0,0 +1,13 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_partition_is_bootable(map_t *map)
{
return (map_partition_get_flags(map) &
kPartitionAUXIsBootValid) == kPartitionAUXIsBootValid;
}

View File

@ -0,0 +1,13 @@
/*
*
* (c) 2004 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_partition_is_startup(map_t *map)
{
return (map_partition_get_flags(map)
& kPartitionIsStartup) == kPartitionIsStartup;
}

View File

@ -0,0 +1,12 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_partition_is_valid(map_t *map)
{
return read_short((u_int16_t*)&map->partition.Sig) == MAP_SIGNATURE;
}

View File

@ -0,0 +1,24 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_partition_set_bootable(map_t *map, int enable)
{
if (!map_partition_is_valid(map))
return -1;
if (enable)
map_partition_set_flags(map,
kPartitionAUXIsValid | kPartitionAUXIsAllocated |
kPartitionAUXIsInUse | kPartitionAUXIsReadable |
kPartitionAUXIsWriteable | kPartitionIsMountedAtStartup | 0x80);
else
map_partition_set_flags(map,
map_partition_get_flags(map) & ~kPartitionIsMountedAtStartup);
return 0;
}

View File

@ -0,0 +1,14 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_partition_set_flags(map_t *map, int flags)
{
write_long((u_int32_t*)&map->partition.PartStatus, flags);
return 0;
}

View File

@ -0,0 +1,22 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_partition_set_startup(map_t *map, int enable)
{
if (!map_partition_is_valid(map))
return -1;
if (enable)
map_partition_set_flags(map,
map_partition_get_flags(map) | kPartitionIsStartup);
else
map_partition_set_flags(map,
map_partition_get_flags(map) & ~kPartitionIsStartup);
return 0;
}

36
libmap/map_read.c Normal file
View File

@ -0,0 +1,36 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <sys/types.h>
#include <unistd.h>
#include "libmap.h"
int map_read(map_t *map, int part)
{
off_t offset;
int ret;
if (map->current == part)
return part;
if (part > read_long((u_int32_t*)&map->partition.MapBlkCnt))
return -1;
offset = part * sizeof(struct Partition) + sizeof(struct DriverDescriptor);
ret = lseek(map->fd, offset, SEEK_SET);
if (ret != offset)
return -1;
ret = read(map->fd, &map->partition, sizeof(struct Partition));
if (ret != sizeof(struct Partition))
return -1;
map->current = part;
return part;
}

View File

@ -0,0 +1,28 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_seek_driver_partition(map_t *map, int base)
{
int start;
int count;
int i;
int ret;
for (i = 0; i < map_get_number(map); i++)
{
ret = map_read(map, i);
if (ret == -1)
return -1;
map_get_partition_geometry(map, &start, &count);
if (base == start)
return i;
}
return -1;
}

27
libmap/map_set_bootinfo.c Normal file
View File

@ -0,0 +1,27 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <string.h>
#include "libmap.h"
int map_set_bootinfo(map_t *map, int bootstart, int bootsize,
int bootaddr, int bootentry, int checksum,
char* processor)
{
if (!map_is_valid(map))
return -1;
write_long((u_int32_t*)&map->partition.LgBootStart, bootstart);
write_long((u_int32_t*)&map->partition.BootSize, bootsize);
write_long((u_int32_t*)&map->partition.BootAddr, bootaddr);
write_long((u_int32_t*)&map->partition.BootEntry, bootentry);
write_long((u_int32_t*)&map->partition.BootCksum, checksum);
memset(map->partition.Processor, 0, sizeof(map->partition.Processor));
strcpy(map->partition.Processor, processor);
return 0;
}

View File

@ -0,0 +1,23 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_set_driver_info(map_t *map, int number,
int block, int size, int type)
{
if (!map_is_valid(map))
return -1;
if (number >= DD_MAX_DRIVER)
return -1;
write_long((u_int32_t*)&map->drivers.DrvInfo[number].Block, block);
write_short((u_int16_t*)&map->drivers.DrvInfo[number].Size, size);
write_short((u_int16_t*)&map->drivers.DrvInfo[number].Type, type);
return 0;
}

View File

@ -0,0 +1,20 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include "libmap.h"
int map_set_driver_number(map_t *map, int number)
{
if (!map_is_valid(map))
return -1;
if (number >= DD_MAX_DRIVER)
return -1;
write_short((u_int16_t*)&map->drivers.DrvrCount, number);
return 0;
}

View File

@ -0,0 +1,22 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <string.h>
#include "libmap.h"
int map_set_partition_name(map_t *map, char* name)
{
if (!map_partition_is_valid(map))
return -1;
if (strlen(name) > 31)
return -1;
strncpy(map->partition.PartName, name, 32);
return 0;
}

View File

@ -0,0 +1,22 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <string.h>
#include "libmap.h"
int map_set_partition_type(map_t *map, char* type)
{
if (!map_partition_is_valid(map))
return -1;
if (strlen(type) > 31)
return -1;
strncpy(map->partition.PartType, type, 32);
return 0;
}

58
libmap/map_set_startup.c Normal file
View File

@ -0,0 +1,58 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "libmap.h"
int map_set_startup(char* dev_name, int partition)
{
map_t* map;
char *part_type;
int ret;
int i;
map = map_open(dev_name, O_RDWR);
if (map == NULL)
return -1;
/* check partition type */
ret = map_read(map, partition);
if (ret == -1)
return -1;
part_type = map_get_partition_type(map);
if (strcmp(part_type, APPLE_HFS) != 0) {
fprintf(stderr,
"ERROR: a startup partition must be of type Apple_HFS\n");
return -1;
}
for (i = 0; i < map_get_number(map); i++)
{
ret = map_read(map, i);
if (ret == -1)
return -1;
part_type = map_get_partition_type(map);
if (strcmp(part_type, APPLE_HFS) == 0)
{
map_partition_set_bootable(map, i == partition);
map_partition_set_startup(map, i == partition);
ret = map_write(map, i);
if (ret == -1)
return -1;
}
}
map_close(map);
return 0;
}

33
libmap/map_write.c Normal file
View File

@ -0,0 +1,33 @@
/*
*
* (c) 2004-2007 Laurent Vivier <Laurent@lvivier.info>
*
*/
#include <sys/types.h>
#include <unistd.h>
#include "libmap.h"
int map_write(map_t *map, int part)
{
off_t offset;
int ret;
if (part > map->partition.MapBlkCnt)
return -1;
offset = part * sizeof(struct Partition) + sizeof(struct DriverDescriptor);
ret = lseek(map->fd, offset, SEEK_SET);
if (ret != offset)
return -1;
ret = write(map->fd, &map->partition, sizeof(struct Partition));
if (ret != sizeof(struct Partition))
return -1;
map->current = part;
return part;
}