New API call iso_write_opts_set_system_area() acts like mkisofs option -G
This commit is contained in:
parent
f0f378c38f
commit
f13167335a
@ -73,6 +73,9 @@ void ecma119_image_free(Ecma119Image *t)
|
|||||||
if (t->output_charset != NULL)
|
if (t->output_charset != NULL)
|
||||||
free(t->output_charset);
|
free(t->output_charset);
|
||||||
|
|
||||||
|
if (t->system_area_data != NULL)
|
||||||
|
free(t->system_area_data);
|
||||||
|
|
||||||
#ifdef Libisofs_with_checksumS
|
#ifdef Libisofs_with_checksumS
|
||||||
if (t->checksum_ctx != NULL) { /* dispose checksum context */
|
if (t->checksum_ctx != NULL) { /* dispose checksum context */
|
||||||
char md5[16];
|
char md5[16];
|
||||||
@ -1127,6 +1130,17 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->eltorito = (src->bootcat == NULL ? 0 : 1);
|
target->eltorito = (src->bootcat == NULL ? 0 : 1);
|
||||||
target->catalog = src->bootcat;
|
target->catalog = src->bootcat;
|
||||||
|
|
||||||
|
target->system_area_data = NULL;
|
||||||
|
if(opts->system_area_data != NULL) {
|
||||||
|
target->system_area_data = calloc(32768, 1);
|
||||||
|
if (target->system_area_data == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
|
memcpy(target->system_area_data, opts->system_area_data, 32768);
|
||||||
|
}
|
||||||
|
target->system_area_options = opts->system_area_options;
|
||||||
|
|
||||||
target->input_charset = strdup(iso_get_local_charset(0));
|
target->input_charset = strdup(iso_get_local_charset(0));
|
||||||
if (target->input_charset == NULL) {
|
if (target->input_charset == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
@ -1700,6 +1714,8 @@ void iso_write_opts_free(IsoWriteOpts *opts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(opts->output_charset);
|
free(opts->output_charset);
|
||||||
|
if(opts->system_area_data != NULL)
|
||||||
|
free(opts->system_area_data);
|
||||||
free(opts);
|
free(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2085,3 +2101,28 @@ int iso_write_opts_get_data_start(IsoWriteOpts *opts, uint32_t *data_start,
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param data Either NULL or 32 kB of data. Do not submit less bytes !
|
||||||
|
* @param options bit0 = apply GRUB protective msdos label
|
||||||
|
* @param flag bit0 = invalidate any attached system area data
|
||||||
|
* same as data == NULL
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
||||||
|
int options, int flag)
|
||||||
|
{
|
||||||
|
if (data == NULL || (flag & 1)) { /* Disable */
|
||||||
|
if (opts->system_area_data != NULL)
|
||||||
|
free(opts->system_area_data);
|
||||||
|
opts->system_area_data = NULL;
|
||||||
|
} else {
|
||||||
|
if (opts->system_area_data == NULL) {
|
||||||
|
opts->system_area_data = calloc(32768, 1);
|
||||||
|
if (opts->system_area_data == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
memcpy(opts->system_area_data, data, 32768);
|
||||||
|
}
|
||||||
|
opts->system_area_options = options & 1;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -298,6 +298,11 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
char *scdbackup_tag_written;
|
char *scdbackup_tag_written;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See ecma119_image : System Area related information
|
||||||
|
*/
|
||||||
|
char *system_area_data;
|
||||||
|
int system_area_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ecma119_image Ecma119Image;
|
typedef struct ecma119_image Ecma119Image;
|
||||||
@ -436,6 +441,22 @@ struct ecma119_image
|
|||||||
IsoFileSrc *cat; /**< location of the boot catalog in the new image */
|
IsoFileSrc *cat; /**< location of the boot catalog in the new image */
|
||||||
IsoFileSrc *bootimg; /**< location of the boot image in the new image */
|
IsoFileSrc *bootimg; /**< location of the boot image in the new image */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System Area related information
|
||||||
|
*/
|
||||||
|
/* Content of an embedded boot image. Valid if not NULL.
|
||||||
|
* In that case it must point to a memory buffer at least 32 kB.
|
||||||
|
*/
|
||||||
|
char *system_area_data;
|
||||||
|
/*
|
||||||
|
* bit0= make bytes 446 - 512 of the system area a partition
|
||||||
|
* table which reserves partition 1 from byte 63*512 to the
|
||||||
|
* end of the ISO image. Assumed are 63 secs/hed, 255 head/cyl.
|
||||||
|
* (GRUB protective msdos label.)
|
||||||
|
* This works with and without system_area_data.
|
||||||
|
*/
|
||||||
|
int system_area_options;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Number of pad blocks that we need to write. Padding blocks are blocks
|
* Number of pad blocks that we need to write. Padding blocks are blocks
|
||||||
* filled by 0s that we put between the directory structures and the file
|
* filled by 0s that we put between the directory structures and the file
|
||||||
|
@ -333,9 +333,11 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
boot->image = (IsoFile*)imgfile;
|
boot->image = (IsoFile*)imgfile;
|
||||||
iso_node_ref(imgfile); /* get our ref */
|
iso_node_ref(imgfile); /* get our ref */
|
||||||
boot->bootable = 1;
|
boot->bootable = 1;
|
||||||
|
boot->isolinux_options = 0;
|
||||||
boot->type = boot_media_type;
|
boot->type = boot_media_type;
|
||||||
boot->load_size = load_sectors;
|
|
||||||
boot->partition_type = partition_type;
|
boot->partition_type = partition_type;
|
||||||
|
boot->load_seg = 0;
|
||||||
|
boot->load_size = load_sectors;
|
||||||
|
|
||||||
if (bootimg) {
|
if (bootimg) {
|
||||||
*bootimg = boot;
|
*bootimg = boot;
|
||||||
|
@ -39,7 +39,8 @@ struct el_torito_boot_image {
|
|||||||
/**
|
/**
|
||||||
* isolinux options
|
* isolinux options
|
||||||
* bit 0 -> whether to patch image
|
* bit 0 -> whether to patch image
|
||||||
* bit 1 -> whether to create isolinux image
|
* bit 1 -> whether to put built-in isolinux 3.72 isohybrid-MBR into image
|
||||||
|
* System Area (deprecated)
|
||||||
*/
|
*/
|
||||||
unsigned int isolinux_options:2;
|
unsigned int isolinux_options:2;
|
||||||
unsigned char type; /**< The type of image */
|
unsigned char type; /**< The type of image */
|
||||||
|
@ -1680,6 +1680,32 @@ int iso_write_opts_set_overwrite_buf(IsoWriteOpts *opts, uint8_t *overwrite);
|
|||||||
*/
|
*/
|
||||||
int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
|
int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach 32 kB of binary data which shall get written to the first 32 kB
|
||||||
|
* of the ISO image, the ECMA-119 System Area. This space is intended for
|
||||||
|
* system dependent boot software, e.g. a Master Boot Record which allows to
|
||||||
|
* boot from USB sticks or hard disks. ECMA-119 makes no own assumptions or
|
||||||
|
* prescriptions about the byte content.
|
||||||
|
*
|
||||||
|
* If system area data are given or options bit0 is set, then bit1 of
|
||||||
|
* el_torito_set_isolinux_options() is automatically disabled.
|
||||||
|
* @param data
|
||||||
|
* Either NULL or 32 kB of data. Do not submit less bytes !
|
||||||
|
* @param options
|
||||||
|
* Can cause manipulations of submitted data before they get written:
|
||||||
|
* bit0= apply a --protective-msdos-label as of grub-mkisofs.
|
||||||
|
* This means to patch bytes 446 to 512 of the system area so
|
||||||
|
* that one partition is defined which begins at the second
|
||||||
|
* 512-byte block of the image and ends where the image ends.
|
||||||
|
* @param flag
|
||||||
|
* bit0 = invalidate any attached system area data. Same as data == NULL
|
||||||
|
* @return
|
||||||
|
* ISO_SUCCESS or error
|
||||||
|
* @since 0.6.30
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
||||||
|
int options, int flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire the start address of the file data blocks after having used
|
* Inquire the start address of the file data blocks after having used
|
||||||
* IsoWriteOpts with iso_image_create_burn_source().
|
* IsoWriteOpts with iso_image_create_burn_source().
|
||||||
@ -2325,19 +2351,27 @@ void el_torito_set_no_bootable(ElToritoBootImage *bootimg);
|
|||||||
void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
|
void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies options for IsoLinux boot images. This should only be used with
|
* Specifies options for ISOLINUX or GRUB boot images. This should only be used
|
||||||
* isolinux boot images.
|
* if the type of boot image is known.
|
||||||
*
|
*
|
||||||
* @param options
|
* @param options
|
||||||
* bitmask style flag. The following values are defined:
|
* bitmask style flag. The following values are defined:
|
||||||
*
|
*
|
||||||
* bit 0 -> 1 to patch the image, 0 to not
|
* bit 0 -> 1 to patch the boot info table of the boot image.
|
||||||
* Patching the image involves the writing of a 56 bytes
|
* 1 does the same as mkisofs option -boot-info-table.
|
||||||
* boot information table at offset 8 of the boot image file.
|
* Needed for ISOLINUX and for GRUB rescue boot images.
|
||||||
* The original boot image file will not be modified. This is
|
* The table is located at byte 8 of the boot image file.
|
||||||
* needed to allow isolinux images to be bootable.
|
* Its size is 56 bytes.
|
||||||
* bit 1 -> 1 to generate an hybrid image with MBR, 0 to not
|
* The original boot image file on disk will not be modified.
|
||||||
* An hybrid image is a boot image that boots from either
|
*
|
||||||
|
* bit 1 -> 1 to generate a ISOLINUX isohybrid image with MBR.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* @deprecated since 31 Mar 2010:
|
||||||
|
* The author of syslinux, H. Peter Anvin requested that this
|
||||||
|
* feature shall not be used any more. He intends to cease
|
||||||
|
* support for the MBR template that is included in libisofs.
|
||||||
|
* ----------------------------------------------------------
|
||||||
|
* A hybrid image is a boot image that boots from either
|
||||||
* CD/DVD media or from disk-like media, e.g. USB stick.
|
* CD/DVD media or from disk-like media, e.g. USB stick.
|
||||||
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
||||||
* IMPORTANT: The application has to take care that the image
|
* IMPORTANT: The application has to take care that the image
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Vreixo Formoso
|
* Copyright (c) 2008 Vreixo Formoso
|
||||||
|
* Copyright (c) 2010 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -12,28 +13,104 @@
|
|||||||
#include "filesrc.h"
|
#include "filesrc.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
||||||
*
|
* See libisofs/make_isohybrid_mbr.c
|
||||||
* It is assumed that the caller has verified the readiness of the boot image
|
* Deprecated.
|
||||||
* by checking for 0xfb 0xc0 0x78 0x70 at bytes 0x40 to 0x43 of isolinux.bin.
|
|
||||||
*
|
|
||||||
* @param bin_lba The predicted LBA of isolinux.bin within the emerging ISO.
|
|
||||||
* @param img_blocks The predicted number of 2048 byte blocks in the ISO.
|
|
||||||
* It will get rounded up to full MBs and that many blocks
|
|
||||||
* must really be written as ISO 9660 image.
|
|
||||||
* @param mbr A buffer of at least 512 bytes to take the result which is
|
|
||||||
* to be written as the very beginning of the ISO.
|
|
||||||
* @param flag unused yet, submit 0
|
|
||||||
* @return <0 = fatal, 0 = failed , 1 = ok , 2 = ok with size warning
|
|
||||||
*/
|
*/
|
||||||
int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the gesture of grub-mkisofs --protective-msdos-label as explained by
|
||||||
|
Vladimir Serbinenko <phcoder@gmail.com>, 2 April 2010, on grub-devel@gnu.org
|
||||||
|
"Currently we use first and not last entry. You need to:
|
||||||
|
1) Zero-fill 446-510
|
||||||
|
2) Put 0x55, 0xAA into 510-512
|
||||||
|
3) Put 0x80 (for bootable partition), 0, 2, 0 (C/H/S of the start), 0xcd
|
||||||
|
(partition type), [3 bytes of C/H/S end], 0x01, 0x00, 0x00, 0x00 (LBA
|
||||||
|
start in little endian), [LBA end in little endian] at 446-462
|
||||||
|
"
|
||||||
|
|
||||||
|
"C/H/S end" means the CHS address of the last block in the partition.
|
||||||
|
It seems that not "[LBA end in little endian]" but "number of blocks"
|
||||||
|
should go into bytes 458-461. But with a start lba of 1, this is the
|
||||||
|
same number.
|
||||||
|
See also http://en.wikipedia.org/wiki/Master_boot_record
|
||||||
|
*/
|
||||||
|
int make_grub_msdos_label(int img_blocks, uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
uint8_t *wpt;
|
||||||
|
unsigned long end_lba, secs, end_sec, end_head, end_cyl;
|
||||||
|
int sph = 63, hpc = 255, i;
|
||||||
|
|
||||||
|
/* Partition table unit is 512 bytes per sector, ECMA-119 unit is 2048 */
|
||||||
|
if (img_blocks >= 0x40000000)
|
||||||
|
img_blocks = 0x40000000 - 1; /* truncate rather than roll over */
|
||||||
|
secs = end_lba = img_blocks * 4 - 1; /* last valid 512-lba */
|
||||||
|
end_cyl = secs / (sph * hpc);
|
||||||
|
secs -= end_cyl * sph * hpc;
|
||||||
|
end_head = secs / sph;
|
||||||
|
end_sec = secs - end_head * sph + 1; /* Sector count starts by 1 */
|
||||||
|
if (end_cyl >= 1024) {
|
||||||
|
end_cyl = 1023;
|
||||||
|
end_head = hpc - 1;
|
||||||
|
end_sec = sph;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1) Zero-fill 446-510 */
|
||||||
|
wpt = buf + 446;
|
||||||
|
memset(wpt, 0, 64);
|
||||||
|
|
||||||
|
/* 2) Put 0x55, 0xAA into 510-512 (actually 510-511) */
|
||||||
|
buf[510] = 0x55;
|
||||||
|
buf[511] = 0xAA;
|
||||||
|
|
||||||
|
/* 3) Put 0x80 (for bootable partition), */
|
||||||
|
*(wpt++) = 0x80;
|
||||||
|
|
||||||
|
/* 0, 2, 0 (C/H/S of the start), */
|
||||||
|
*(wpt++) = 0;
|
||||||
|
*(wpt++) = 2;
|
||||||
|
*(wpt++) = 0;
|
||||||
|
|
||||||
|
/* 0xcd (partition type) */
|
||||||
|
*(wpt++) = 0xcd;
|
||||||
|
|
||||||
|
/* [3 bytes of C/H/S end], */
|
||||||
|
*(wpt++) = end_head;
|
||||||
|
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = end_cyl & 0xff;
|
||||||
|
|
||||||
|
|
||||||
|
/* 0x01, 0x00, 0x00, 0x00 (LBA start in little endian), */
|
||||||
|
*(wpt++) = 0x01;
|
||||||
|
*(wpt++) = 0x00;
|
||||||
|
*(wpt++) = 0x00;
|
||||||
|
*(wpt++) = 0x00;
|
||||||
|
|
||||||
|
/* [LBA end in little endian] */
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
/* at 446-462 */
|
||||||
|
if (wpt - buf != 462) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"libisofs: program error in make_grub_msdos_label: \"assert 462\"\n");
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
int img_blocks;
|
||||||
|
|
||||||
if ((t == NULL) || (buf == NULL)) {
|
if ((t == NULL) || (buf == NULL)) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
@ -41,26 +118,29 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
/* set buf to 0s */
|
/* set buf to 0s */
|
||||||
memset(buf, 0, 16 * BLOCK_SIZE);
|
memset(buf, 0, 16 * BLOCK_SIZE);
|
||||||
|
|
||||||
if (t->catalog != NULL && t->catalog->image->isolinux_options & 0x02) {
|
|
||||||
/* We need to write a MBR for an hybrid image */
|
|
||||||
int ret;
|
|
||||||
int img_blocks;
|
|
||||||
|
|
||||||
img_blocks = t->curblock;
|
img_blocks = t->curblock;
|
||||||
ret = make_isohybrid_mbr(t->bootimg->sections[0].block, &img_blocks, (char*)buf, 0);
|
if (t->system_area_data != NULL) {
|
||||||
|
/* Write more or less opaque boot image */
|
||||||
|
memcpy(buf, t->system_area_data, 16 * BLOCK_SIZE);
|
||||||
|
|
||||||
/*
|
} else if (t->catalog != NULL &&
|
||||||
API description of el_torito_set_isolinux_options() prescribes
|
(t->catalog->image->isolinux_options & 0x0a) == 0x02) {
|
||||||
to pad to full MB.
|
/* Check for isolinux image with magic number of 3.72 and produce
|
||||||
So this is not urgent any more :
|
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
||||||
|
|
||||||
// FIXME the new img_blocks size should be taken into account
|
|
||||||
*/
|
*/
|
||||||
|
ret = make_isohybrid_mbr(t->bootimg->sections[0].block,
|
||||||
|
&img_blocks, (char*)buf, 0);
|
||||||
if (ret != 1) {
|
if (ret != 1) {
|
||||||
/* error, it should never happen */
|
/* error, it should never happen */
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
if (t->system_area_options & 1) {
|
||||||
|
/* Write GRUB protective msdos label, i.e. a isimple partition table */
|
||||||
|
ret = make_grub_msdos_label(img_blocks, buf, 0);
|
||||||
|
if (ret != 1) /* error should never happen */
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user