diff --git a/libmap/Makefile b/libmap/Makefile new file mode 100644 index 0000000..89c5154 --- /dev/null +++ b/libmap/Makefile @@ -0,0 +1,40 @@ +# +# (c) 2005-2007 Laurent Vivier +# + +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 diff --git a/libmap/libmap.h b/libmap/libmap.h new file mode 100644 index 0000000..59ef752 --- /dev/null +++ b/libmap/libmap.h @@ -0,0 +1,129 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#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 diff --git a/libmap/map_bootblock_get_type.c b/libmap/map_bootblock_get_type.c new file mode 100644 index 0000000..2ef8e1b --- /dev/null +++ b/libmap/map_bootblock_get_type.c @@ -0,0 +1,23 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#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; +} diff --git a/libmap/map_bootblock_is_valid.c b/libmap/map_bootblock_is_valid.c new file mode 100644 index 0000000..a157270 --- /dev/null +++ b/libmap/map_bootblock_is_valid.c @@ -0,0 +1,12 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include "libmap.h" + +int map_bootblock_is_valid(char *bootblock) +{ + return (bootblock[0] == 0x4C) && (bootblock[1] == 0x4B); +} diff --git a/libmap/map_bootblock_read.c b/libmap/map_bootblock_read.c new file mode 100644 index 0000000..782bfd4 --- /dev/null +++ b/libmap/map_bootblock_read.c @@ -0,0 +1,35 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include +#include +#include +#include +#include + +#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; +} diff --git a/libmap/map_bootblock_write.c b/libmap/map_bootblock_write.c new file mode 100644 index 0000000..d5400ae --- /dev/null +++ b/libmap/map_bootblock_write.c @@ -0,0 +1,35 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include +#include +#include +#include +#include + +#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; +} diff --git a/libmap/map_close.c b/libmap/map_close.c new file mode 100644 index 0000000..53aa93b --- /dev/null +++ b/libmap/map_close.c @@ -0,0 +1,16 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include +#include + +#include "libmap.h" + +void map_close(map_t *map) +{ + close(map->fd); + free(map); +} diff --git a/libmap/map_dev.c b/libmap/map_dev.c new file mode 100644 index 0000000..55644ad --- /dev/null +++ b/libmap/map_dev.c @@ -0,0 +1,17 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#include "libmap.h" + +char* map_dev(map_t *map) +{ + if (!map_partition_is_valid(map)) + return NULL; + + return map->name; +} diff --git a/libmap/map_geometry.c b/libmap/map_geometry.c new file mode 100644 index 0000000..3bfe788 --- /dev/null +++ b/libmap/map_geometry.c @@ -0,0 +1,18 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#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; +} diff --git a/libmap/map_get_bootinfo.c b/libmap/map_get_bootinfo.c new file mode 100644 index 0000000..0c983e3 --- /dev/null +++ b/libmap/map_get_bootinfo.c @@ -0,0 +1,26 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#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; +} diff --git a/libmap/map_get_driver_info.c b/libmap/map_get_driver_info.c new file mode 100644 index 0000000..e9d0ea5 --- /dev/null +++ b/libmap/map_get_driver_info.c @@ -0,0 +1,23 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#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; +} diff --git a/libmap/map_get_driver_number.c b/libmap/map_get_driver_number.c new file mode 100644 index 0000000..a57b90b --- /dev/null +++ b/libmap/map_get_driver_number.c @@ -0,0 +1,15 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#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); +} diff --git a/libmap/map_get_driver_signature.c b/libmap/map_get_driver_signature.c new file mode 100644 index 0000000..14b9c2f --- /dev/null +++ b/libmap/map_get_driver_signature.c @@ -0,0 +1,17 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#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); +} diff --git a/libmap/map_get_number.c b/libmap/map_get_number.c new file mode 100644 index 0000000..9e12195 --- /dev/null +++ b/libmap/map_get_number.c @@ -0,0 +1,15 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include +#include + +#include "libmap.h" + +int map_get_number(map_t *map) +{ + return read_long((u_int32_t*)&map->partition.MapBlkCnt); +} diff --git a/libmap/map_get_partition_geometry.c b/libmap/map_get_partition_geometry.c new file mode 100644 index 0000000..cc5b8e4 --- /dev/null +++ b/libmap/map_get_partition_geometry.c @@ -0,0 +1,18 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#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; +} diff --git a/libmap/map_get_partition_name.c b/libmap/map_get_partition_name.c new file mode 100644 index 0000000..a359c0f --- /dev/null +++ b/libmap/map_get_partition_name.c @@ -0,0 +1,17 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#include "libmap.h" + +char* map_get_partition_name(map_t *map) +{ + if (!map_partition_is_valid(map)) + return NULL; + + return map->partition.PartName; +} diff --git a/libmap/map_get_partition_type.c b/libmap/map_get_partition_type.c new file mode 100644 index 0000000..b10ebe8 --- /dev/null +++ b/libmap/map_get_partition_type.c @@ -0,0 +1,17 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#include "libmap.h" + +char* map_get_partition_type(map_t *map) +{ + if (!map_partition_is_valid(map)) + return NULL; + + return map->partition.PartType; +} diff --git a/libmap/map_has_apple_driver.c b/libmap/map_has_apple_driver.c new file mode 100644 index 0000000..2d81bd6 --- /dev/null +++ b/libmap/map_has_apple_driver.c @@ -0,0 +1,43 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +/* + * See http://developer.apple.com/technotes/tn/tn1189.html + * + */ + +#include + +#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; +} diff --git a/libmap/map_is_valid.c b/libmap/map_is_valid.c new file mode 100644 index 0000000..2bab4f4 --- /dev/null +++ b/libmap/map_is_valid.c @@ -0,0 +1,12 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include "libmap.h" + +int map_is_valid(map_t *map) +{ + return read_short((u_int16_t*)&map->drivers.Sig) == DD_SIGNATURE; +} diff --git a/libmap/map_open.c b/libmap/map_open.c new file mode 100644 index 0000000..b8a5075 --- /dev/null +++ b/libmap/map_open.c @@ -0,0 +1,55 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/libmap/map_partition_get_flags.c b/libmap/map_partition_get_flags.c new file mode 100644 index 0000000..4dd05f1 --- /dev/null +++ b/libmap/map_partition_get_flags.c @@ -0,0 +1,12 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include "libmap.h" + +int map_partition_get_flags(map_t *map) +{ + return read_long((u_int32_t*)&map->partition.PartStatus); +} diff --git a/libmap/map_partition_is_bootable.c b/libmap/map_partition_is_bootable.c new file mode 100644 index 0000000..58ad380 --- /dev/null +++ b/libmap/map_partition_is_bootable.c @@ -0,0 +1,13 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include "libmap.h" + +int map_partition_is_bootable(map_t *map) +{ + return (map_partition_get_flags(map) & + kPartitionAUXIsBootValid) == kPartitionAUXIsBootValid; +} diff --git a/libmap/map_partition_is_startup.c b/libmap/map_partition_is_startup.c new file mode 100644 index 0000000..e412450 --- /dev/null +++ b/libmap/map_partition_is_startup.c @@ -0,0 +1,13 @@ +/* + * + * (c) 2004 Laurent Vivier + * + */ + +#include "libmap.h" + +int map_partition_is_startup(map_t *map) +{ + return (map_partition_get_flags(map) + & kPartitionIsStartup) == kPartitionIsStartup; +} diff --git a/libmap/map_partition_is_valid.c b/libmap/map_partition_is_valid.c new file mode 100644 index 0000000..929d4ff --- /dev/null +++ b/libmap/map_partition_is_valid.c @@ -0,0 +1,12 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include "libmap.h" + +int map_partition_is_valid(map_t *map) +{ + return read_short((u_int16_t*)&map->partition.Sig) == MAP_SIGNATURE; +} diff --git a/libmap/map_partition_set_bootable.c b/libmap/map_partition_set_bootable.c new file mode 100644 index 0000000..12a0ee4 --- /dev/null +++ b/libmap/map_partition_set_bootable.c @@ -0,0 +1,24 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#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; +} diff --git a/libmap/map_partition_set_flags.c b/libmap/map_partition_set_flags.c new file mode 100644 index 0000000..902b885 --- /dev/null +++ b/libmap/map_partition_set_flags.c @@ -0,0 +1,14 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include "libmap.h" + +int map_partition_set_flags(map_t *map, int flags) +{ + write_long((u_int32_t*)&map->partition.PartStatus, flags); + + return 0; +} diff --git a/libmap/map_partition_set_startup.c b/libmap/map_partition_set_startup.c new file mode 100644 index 0000000..1f097b9 --- /dev/null +++ b/libmap/map_partition_set_startup.c @@ -0,0 +1,22 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#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; +} diff --git a/libmap/map_read.c b/libmap/map_read.c new file mode 100644 index 0000000..1500b78 --- /dev/null +++ b/libmap/map_read.c @@ -0,0 +1,36 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include +#include + +#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; +} diff --git a/libmap/map_seek_driver_partition.c b/libmap/map_seek_driver_partition.c new file mode 100644 index 0000000..350c1ef --- /dev/null +++ b/libmap/map_seek_driver_partition.c @@ -0,0 +1,28 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#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; +} diff --git a/libmap/map_set_bootinfo.c b/libmap/map_set_bootinfo.c new file mode 100644 index 0000000..27a2473 --- /dev/null +++ b/libmap/map_set_bootinfo.c @@ -0,0 +1,27 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#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; +} diff --git a/libmap/map_set_driver_info.c b/libmap/map_set_driver_info.c new file mode 100644 index 0000000..da0b3d3 --- /dev/null +++ b/libmap/map_set_driver_info.c @@ -0,0 +1,23 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#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; +} diff --git a/libmap/map_set_driver_number.c b/libmap/map_set_driver_number.c new file mode 100644 index 0000000..e43546b --- /dev/null +++ b/libmap/map_set_driver_number.c @@ -0,0 +1,20 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#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; +} diff --git a/libmap/map_set_partition_name.c b/libmap/map_set_partition_name.c new file mode 100644 index 0000000..4d08e99 --- /dev/null +++ b/libmap/map_set_partition_name.c @@ -0,0 +1,22 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#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; +} diff --git a/libmap/map_set_partition_type.c b/libmap/map_set_partition_type.c new file mode 100644 index 0000000..d0883cc --- /dev/null +++ b/libmap/map_set_partition_type.c @@ -0,0 +1,22 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include + +#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; +} diff --git a/libmap/map_set_startup.c b/libmap/map_set_startup.c new file mode 100644 index 0000000..51281cb --- /dev/null +++ b/libmap/map_set_startup.c @@ -0,0 +1,58 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include +#include +#include +#include +#include + +#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; +} diff --git a/libmap/map_write.c b/libmap/map_write.c new file mode 100644 index 0000000..bf4c276 --- /dev/null +++ b/libmap/map_write.c @@ -0,0 +1,33 @@ +/* + * + * (c) 2004-2007 Laurent Vivier + * + */ + +#include +#include + +#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; +}