DISK: Add robust disk container validation

This commit is contained in:
Mark Pizzolato 2020-04-11 13:01:48 -07:00
parent 3950478e00
commit 049ba32505
3 changed files with 286 additions and 51 deletions

2
scp.c
View file

@ -805,7 +805,7 @@ const struct scp_error {
{"SIGTERM", "SIGTERM received"},
{"FSSIZE", "File System size larger than disk size"},
{"RUNTIME", "Run time limit exhausted"},
{"INCOMPVHD", "Incompatible VHD Container"},
{"INCOMPDSK", "Incompatible Disk Container"},
};
const size_t size_map[] = { sizeof (int8),

View file

@ -433,7 +433,7 @@ typedef uint32 t_addr;
#define SCPE_SIGTERM (SCPE_BASE + 48) /* SIGTERM has been received */
#define SCPE_FSSIZE (SCPE_BASE + 49) /* File System size larger than disk size */
#define SCPE_RUNTIME (SCPE_BASE + 50) /* Run Time Limit Exhausted */
#define SCPE_INCOMPVHD (SCPE_BASE + 51) /* Incompatible VHD Container */
#define SCPE_INCOMPDSK (SCPE_BASE + 51) /* Incompatible Disk Container */
#define SCPE_MAX_ERR (SCPE_BASE + 51) /* Maximum SCPE Error Value */
#define SCPE_KFLAG 0x10000000 /* tti data flag */

View file

@ -86,17 +86,79 @@ Internal routines:
#include <pthread.h>
#endif
/* Newly created SIMH (and possibly RAW) disk containers */
/* will have this data as the last 512 bytes of the container */
/* It will not be considered part of the data in the container */
/* Previously existing containers will have this appended to */
/* the end of the container if they are opened for write */
struct simh_disk_footer {
uint8 Signature[4]; /* must be 'simh' */
uint8 CreatingSimulator[64]; /* name of simulator */
uint8 DriveType[16];
uint32 SectorSize;
uint32 SectorCount;
uint32 TransferElementSize;
uint8 CreationTime[28]; /* Result of ctime() */
uint8 FooterVersion; /* Initially 0 */
uint8 AccessFormat; /* 1 - SIMH, 2 - RAW */
uint8 Reserved[382]; /* Currently unused */
uint32 Checksum; /* CRC32 of the prior 508 bytes */
};
/* OS Independent Disk Virtual Disk (VHD) I/O support */
#if (defined (VMS) && !(defined (__ALPHA) || defined (__ia64)))
#define DONT_DO_VHD_SUPPORT /* VAX/VMS compilers don't have 64 bit integers */
#endif
#if defined(_WIN32) || defined (__ALPHA) || defined (__ia64) || defined (VMS)
#ifndef __BYTE_ORDER__
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#endif
#endif
#ifndef __BYTE_ORDER__
#define __BYTE_ORDER__ UNKNOWN
#endif
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
static uint32
NtoHl(uint32 value)
{
uint8 *l = (uint8 *)&value;
return (uint32)l[3] | ((uint32)l[2]<<8) | ((uint32)l[1]<<16) | ((uint32)l[0]<<24);
}
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
static uint32
NtoHl(uint32 value)
{
return value;
}
#else
static uint32
NtoHl(uint32 value)
{
uint8 *l = (uint8 *)&value;
if (sim_end)
return l[3] | (l[2]<<8) | (l[1]<<16) | (l[0]<<24);
return value;
}
#endif
struct disk_context {
t_offset container_size; /* Size of the data portion (of the pseudo disk) */
DEVICE *dptr; /* Device for unit (access to debug flags) */
uint32 dbit; /* debugging bit */
uint32 sector_size; /* Disk Sector Size (of the pseudo disk) */
uint32 capac_factor; /* Units of Capacity (8 = quadword, 2 = word, 1 = byte) */
uint32 xfer_element_size; /* Disk Bus Transfer size (1 - byte, 2 - word, 4 - longword) */
uint32 storage_sector_size;/* Sector size of the containing storage */
uint32 removable; /* Removable device flag */
uint32 is_cdrom; /* Host system CDROM Device */
uint32 media_removed; /* Media not available flag */
uint32 auto_format; /* Format determined dynamically */
struct simh_disk_footer
*footer;
#if defined _WIN32
HANDLE disk_handle; /* OS specific Raw device handle */
#endif
@ -276,7 +338,7 @@ static t_stat sim_vhd_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *
static t_stat sim_vhd_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects);
static t_stat sim_vhd_disk_clearerr (UNIT *uptr);
static t_stat sim_vhd_disk_set_dtype (FILE *f, const char *dtype, uint32 SectorSize, uint32 xfer_element_size);
static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size);
static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size, char sim_name[64]);
static t_stat sim_os_disk_implemented_raw (void);
static FILE *sim_os_disk_open_raw (const char *rawdevicename, const char *openmode);
static int sim_os_disk_close_raw (FILE *f);
@ -285,7 +347,9 @@ static t_offset sim_os_disk_size_raw (FILE *f);
static t_stat sim_os_disk_unload_raw (FILE *f);
static t_bool sim_os_disk_isavailable_raw (FILE *f);
static t_stat sim_os_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects);
static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *bytesread, uint32 bytes);
static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects);
static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *byteswritten, uint32 bytes);
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom);
static char *HostPathToVhdPath (const char *szHostPath, char *szVhdPath, size_t VhdPathSize);
static char *VhdPathToHostPath (const char *szVhdPath, char *szHostPath, size_t HostPathSize);
@ -451,22 +515,13 @@ return (uptr->flags & DKUF_WRP)? TRUE: FALSE;
t_offset sim_disk_size (UNIT *uptr)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
t_offset physical_size, filesystem_size;
t_bool saved_quiet = sim_quiet;
switch (DK_GET_FMT (uptr)) { /* case on format */
case DKUF_F_STD: /* SIMH format */
physical_size = sim_fsize_ex (uptr->fileref);
break;
case DKUF_F_VHD: /* VHD format */
physical_size = sim_vhd_disk_size (uptr->fileref);
break;
case DKUF_F_RAW: /* Raw Physical Disk Access */
physical_size = sim_os_disk_size_raw (uptr->fileref);
break;
default:
if ((uptr->flags & UNIT_ATT) == 0)
return (t_offset)-1;
}
physical_size = ctx->container_size;
sim_quiet = TRUE;
filesystem_size = get_filesystem_size (uptr);
sim_quiet = saved_quiet;
@ -2024,6 +2079,98 @@ for (i = 0; checks[i] != NULL; i++) {
return ret_val;
}
static t_stat get_disk_footer (UNIT *uptr)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
struct simh_disk_footer *f = (struct simh_disk_footer *)calloc (1, sizeof (*f));
t_offset container_size;
t_offset sim_fsize_ex (FILE *fptr);
uint32 bytesread;
if (f == NULL)
return SCPE_MEM;
switch (DK_GET_FMT (uptr)) { /* case on format */
case DKUF_F_STD: /* SIMH format */
container_size = sim_fsize_ex (uptr->fileref);
if ((container_size != (t_offset)-1) && (container_size > sizeof (*f)) &&
(sim_fseeko (uptr->fileref, container_size - sizeof (*f), SEEK_SET) == 0) &&
(sizeof (*f) == sim_fread (f, 1, sizeof (*f), uptr->fileref)))
break;
free (f);
f = NULL;
break;
case DKUF_F_RAW: /* RAW format */
container_size = sim_os_disk_size_raw (uptr->fileref);
if ((container_size != (t_offset)-1) && (container_size > sizeof (*f)) &&
(sim_os_disk_read (uptr, container_size - sizeof (*f), (uint8 *)f, &bytesread, sizeof (*f)) == SCPE_OK) &&
(bytesread == sizeof (*f)))
break;
free (f);
f = NULL;
break;
case DKUF_F_VHD: /* VHD format */
memcpy (f->Signature, "simh", 4);
strncpy ((char *)f->DriveType, sim_vhd_disk_get_dtype (uptr->fileref, &f->SectorSize, &f->TransferElementSize, (char *)f->CreatingSimulator), sizeof (f->DriveType));
container_size = sim_vhd_disk_size (uptr->fileref);
f->SectorCount = (uint32)(container_size / f->SectorSize);
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
break;
}
if (f) {
if (f->Checksum != NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)))) {
free (f);
f = NULL;
}
else {
ctx->footer = f;
container_size -= sizeof (*f);
}
}
ctx->container_size = container_size;
return SCPE_OK;
}
static t_stat store_disk_footer (UNIT *uptr, const char *dtype)
{
DEVICE *dptr;
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
struct simh_disk_footer *f;
time_t now = time (NULL);
t_offset total_sectors;
if ((dptr = find_dev_from_unit (uptr)) == NULL)
return SCPE_NOATT;
if (uptr->flags & UNIT_RO)
return SCPE_RO;
f = (struct simh_disk_footer *)calloc (1, sizeof (*f));
f->AccessFormat = DK_GET_FMT (uptr);
total_sectors = (((t_offset)uptr->capac) * ctx->capac_factor * ((dptr->flags & DEV_SECTORS) ? 512 : 1)) / ctx->sector_size;
memcpy (f->Signature, "simh", 4);
strncpy ((char *)f->CreatingSimulator, sim_name, sizeof (f->CreatingSimulator));
strncpy ((char *)f->DriveType, dtype, sizeof (f->DriveType));
f->SectorSize = NtoHl (ctx->sector_size);
f->SectorCount = NtoHl ((uint32)total_sectors);
f->TransferElementSize = NtoHl (ctx->xfer_element_size);
strncpy ((char*)f->CreationTime, ctime (&now), sizeof (f->CreationTime));
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
free (ctx->footer);
ctx->footer = f;
switch (f->AccessFormat) {
case DKUF_F_STD: /* SIMH format */
sim_fseeko ((FILE *)uptr->fileref, total_sectors * ctx->sector_size, SEEK_SET);
sim_fwrite (f, sizeof (*f), 1, (FILE *)uptr->fileref);
break;
case DKUF_F_VHD: /* VHD format */
break;
case DKUF_F_RAW: /* Raw Physical Disk Access */
sim_os_disk_write (uptr, total_sectors * ctx->sector_size, (uint8 *)f, NULL, sizeof (*f));
break;
default:
break;
}
return SCPE_OK;
}
t_stat sim_disk_attach (UNIT *uptr, const char *cptr, size_t sector_size, size_t xfer_element_size, t_bool dontchangecapac,
uint32 dbit, const char *dtype, uint32 pdp11tracksize, int completion_delay)
{
@ -2320,31 +2467,40 @@ else { /* normal */
}
} /* end if null */
} /* end else */
if (DK_GET_FMT (uptr) == DKUF_F_VHD) {
if ((DK_GET_FMT (uptr) == DKUF_F_VHD) || (ctx->footer)) {
uint32 sector_size, xfer_element_size;
char created_name[64];
const char *container_dtype = ctx->footer ? (char *)ctx->footer->DriveType : sim_vhd_disk_get_dtype (uptr->fileref, &sector_size, &xfer_element_size, created_name);
if ((created) && dtype)
if (ctx->footer) {
sector_size = NtoHl (ctx->footer->SectorSize);
xfer_element_size = NtoHl (ctx->footer->TransferElementSize);
}
if ((DK_GET_FMT (uptr) == DKUF_F_VHD) && created && dtype)
sim_vhd_disk_set_dtype (uptr->fileref, dtype, ctx->sector_size, ctx->xfer_element_size);
if (dtype && strcmp (dtype, sim_vhd_disk_get_dtype (uptr->fileref, &sector_size, &xfer_element_size))) {
if (dtype) {
char cmd[32];
t_stat r = SCPE_OK;
if (((sector_size == 0) || (sector_size == ctx->sector_size)) &&
((xfer_element_size == 0) || (xfer_element_size == ctx->xfer_element_size))) {
sprintf (cmd, "%s%d %s", dptr->name, (int)(uptr-dptr->units), sim_vhd_disk_get_dtype (uptr->fileref, NULL, NULL));
sprintf (cmd, "%s%d %s", dptr->name, (int)(uptr-dptr->units), sim_vhd_disk_get_dtype (uptr->fileref, NULL, NULL, NULL));
r = set_cmd (0, cmd);
if (r != SCPE_OK)
r = sim_messagef (r, "Can't set %s%d to drive type %s\n", dptr->name, (int)(uptr-dptr->units), sim_vhd_disk_get_dtype (uptr->fileref, NULL, NULL));
r = sim_messagef (r, "Can't set %s%d to drive type %s\n", dptr->name, (int)(uptr-dptr->units), sim_vhd_disk_get_dtype (uptr->fileref, NULL, NULL, NULL));
}
else
r = sim_messagef (SCPE_INCOMPVHD, "VHD incompatible with %s simulator\n", sim_name);
r = sim_messagef (SCPE_INCOMPDSK, "Disk created by the %s simulator is incompatible with the %s simulator\n", created_name, sim_name);
if (r != SCPE_OK) {
uptr->flags |= UNIT_ATT;
sim_disk_detach (uptr); /* report error now */
sprintf (cmd, "%s%d %s", dptr->name, (int)(uptr-dptr->units), dtype);/* restore original dtype */
set_cmd (0, cmd);
return r;
}
}
}
uptr->flags = uptr->flags | UNIT_ATT;
uptr->flags |= UNIT_ATT;
uptr->pos = 0;
/* Get Device attributes if they are available */
@ -2356,8 +2512,8 @@ if ((created) && (!copied)) {
uint8 *secbuf = (uint8 *)calloc (128, ctx->sector_size); /* alloc temp sector buf */
/*
On a newly created disk, we write a zero sector to the last and the
first sectors. This serves 3 purposes:
On a newly created disk, we write zeros to the whole disk.
This serves 3 purposes:
1) it avoids strange allocation delays writing newly allocated
storage at the end of the disk during simulator operation
2) it allocates storage for the whole disk at creation time to
@ -2421,7 +2577,6 @@ if ((created) && (!copied)) {
if (pdp11tracksize)
sim_disk_pdp11_bad_block (uptr, pdp11tracksize, sector_size/sizeof(uint16));
}
if (sim_switches & SWMASK ('K')) {
t_stat r = SCPE_OK;
t_lba lba, sect;
@ -2471,8 +2626,12 @@ if (sim_switches & SWMASK ('K')) {
uptr->dynflags |= UNIT_DISK_CHK;
}
if (get_disk_footer (uptr) != SCPE_OK) {
sim_disk_detach (uptr);
return SCPE_OPENERR;
}
filesystem_size = get_filesystem_size (uptr);
container_size = size_function (uptr->fileref);
container_size = sim_disk_size (uptr);
current_unit_size = ((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1);
if (container_size && (container_size != (t_offset)-1)) {
if (dontchangecapac) {
@ -2507,14 +2666,17 @@ if (container_size && (container_size != (t_offset)-1)) {
return SCPE_FSSIZE;
}
}
if ((container_size < current_unit_size) &&
((DKUF_F_VHD == DK_GET_FMT (uptr)) || (0 != (uptr->flags & UNIT_RO)))) {
if ((container_size != current_unit_size) &&
((DKUF_F_VHD == DK_GET_FMT (uptr)) || (0 != (uptr->flags & UNIT_RO)) ||
(ctx->footer))) {
if (!sim_quiet) {
int32 saved_switches = sim_switches;
const char *container_dtype = ctx->footer ? (const char *)ctx->footer->DriveType : "";
sim_switches = SWMASK ('R');
uptr->capac = (t_addr)(container_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1)));
sim_printf ("%s%d: non expandable disk container '%s' is smaller than simulated device (%s < ", sim_dname (dptr), (int)(uptr-dptr->units), cptr, sprint_capac (dptr, uptr));
sim_printf ("%s%d: non expandable %s disk container '%s' is %s than simulated device (%s %s ",
sim_dname (dptr), (int)(uptr-dptr->units), container_dtype, cptr, (container_size < current_unit_size) ? "smaller" : "larger", sprint_capac (dptr, uptr), (container_size < current_unit_size) ? "<" : ">");
uptr->capac = saved_capac;
sim_printf ("%s)\n", sprint_capac (dptr, uptr));
sim_switches = saved_switches;
@ -2523,7 +2685,7 @@ if (container_size && (container_size != (t_offset)-1)) {
return SCPE_OPENERR;
}
}
else { /* Autosize */
else { /* Autosize by changing capacity */
if (filesystem_size != (t_offset)-1) { /* Known file system data size AND */
if (filesystem_size > container_size) /* Data size greater than container size? */
container_size = filesystem_size + /* Use file system data size */
@ -2539,6 +2701,9 @@ if (container_size && (container_size != (t_offset)-1)) {
}
}
if (dtype && (created || (ctx->footer == NULL)))
store_disk_footer (uptr, dtype);
#if defined (SIM_ASYNCH_IO)
sim_disk_set_async (uptr, completion_delay);
#endif
@ -2595,6 +2760,7 @@ uptr->dynflags &= ~(UNIT_NO_FIO | UNIT_DISK_CHK);
free (uptr->filename);
uptr->filename = NULL;
uptr->fileref = NULL;
free (ctx->footer);
free (uptr->disk_ctx);
uptr->disk_ctx = NULL;
uptr->io_flush = NULL;
@ -3396,6 +3562,28 @@ _set_errno_from_status (GetLastError ());
return SCPE_IOERR;
}
static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *bytesread, uint32 bytes)
{
OVERLAPPED pos;
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_read(unit=%d, addr=0x%X, bytes=%u)\n", (int)(uptr-ctx->dptr->units), (uint32)addr, bytes);
memset (&pos, 0, sizeof (pos));
pos.Offset = (DWORD)addr;
pos.OffsetHigh = (DWORD)(addr >> 32);
if (ReadFile ((HANDLE)(uptr->fileref), buf, (DWORD)bytes, (LPDWORD)bytesread, &pos))
return SCPE_OK;
if (ERROR_HANDLE_EOF == GetLastError ()) { /* Return 0's for reads past EOF */
memset (buf, 0, bytes);
if (bytesread)
*bytesread = bytes;
return SCPE_OK;
}
_set_errno_from_status (GetLastError ());
return SCPE_IOERR;
}
static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects)
{
OVERLAPPED pos;
@ -3417,6 +3605,22 @@ _set_errno_from_status (GetLastError ());
return SCPE_IOERR;
}
static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *byteswritten, uint32 bytes)
{
OVERLAPPED pos;
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_write(unit=%d, lba=0x%X, bytes=%u)\n", (int)(uptr-ctx->dptr->units), (uint32)addr, bytes);
memset (&pos, 0, sizeof (pos));
pos.Offset = (DWORD)addr;
pos.OffsetHigh = (DWORD)(addr >> 32);
if (WriteFile ((HANDLE)(uptr->fileref), buf, bytes, (LPDWORD)byteswritten, &pos))
return SCPE_OK;
_set_errno_from_status (GetLastError ());
return SCPE_IOERR;
}
#elif defined (__linux) || defined (__linux__) || defined (__APPLE__)|| defined (__sun) || defined (__sun__) || defined (__hpux) || defined (_AIX)
#include <sys/types.h>
@ -3530,6 +3734,24 @@ if (sectsread)
return SCPE_OK;
}
static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *rbytesread, uint32 bytes)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
ssize_t bytesread;
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_read(unit=%d, addr=0x%X, bytes=%u)\n", (int)(uptr-ctx->dptr->units), (uint32)addr, bytes);
bytesread = pread((int)((long)uptr->fileref), buf, bytes, (off_t)addr);
if (bytesread < 0) {
if (rbytesread)
*rbytesread = 0;
return SCPE_IOERR;
}
if (rbytesread)
*rbytesread = bytesread;
return SCPE_OK;
}
static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
@ -3550,6 +3772,24 @@ if (sectswritten)
return SCPE_OK;
}
static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *rbyteswritten, uint32 bytes)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
ssize_t byteswritten;
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_write(unit=%d, addr=0x%X, bytes=%u)\n", (int)(uptr-ctx->dptr->units), (uint32)addr, bytes);
byteswritten = pwrite((int)((long)uptr->fileref), buf, bytes, (off_t)addr);
if (byteswritten < 0) {
if (rbyteswritten)
*rbyteswritten = 0;
return SCPE_IOERR;
}
if (rbyteswritten)
*rbyteswritten = byteswritten;
return SCPE_OK;
}
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom)
{
if (sector_size) {
@ -3624,11 +3864,21 @@ static t_stat sim_os_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *s
return SCPE_NOFNC;
}
static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *bytesread, uint32 bytes)
{
return SCPE_NOFNC;
}
static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects)
{
return SCPE_NOFNC;
}
static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *byteswritten, uint32 bytes)
{
return SCPE_NOFNC;
}
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom)
{
return SCPE_NOFNC;
@ -3708,7 +3958,7 @@ static t_stat sim_vhd_disk_set_dtype (FILE *f, const char *dtype)
return SCPE_NOFNC;
}
static const char *sim_vhd_disk_get_dtype (FILE *f)
static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size, char sim_name[64])
{
return NULL;
}
@ -4021,10 +4271,6 @@ typedef struct _VHD_DynamicDiskHeader {
#define VHD_DT_Dynamic 3 /* Dynamic hard disk */
#define VHD_DT_Differencing 4 /* Differencing hard disk */
static uint32 NtoHl(uint32 value);
static uint64 NtoHll(uint64 value);
typedef struct VHD_IOData *VHDHANDLE;
static t_stat ReadFilePosition(FILE *File, void *buf, size_t bufsize, size_t *bytesread, uint64 position)
@ -4080,13 +4326,6 @@ return ~sum;
#define __BYTE_ORDER__ UNKNOWN
#endif
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
static uint32
NtoHl(uint32 value)
{
uint8 *l = (uint8 *)&value;
return (uint32)l[3] | ((uint32)l[2]<<8) | ((uint32)l[1]<<16) | ((uint32)l[0]<<24);
}
static uint64
NtoHll(uint64 value)
{
@ -4096,12 +4335,6 @@ uint32 lowresult = (uint64)l[7] | ((uint64)l[6]<<8) | ((uint64)l[5]<<16) | ((uin
return (highresult << 32) | lowresult;
}
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
static uint32
NtoHl(uint32 value)
{
return value;
}
static uint64
NtoHll(uint64 value)
{
@ -4364,7 +4597,7 @@ memset (hVHD->Footer.DriveType, '\0', sizeof hVHD->Footer.DriveType);
memcpy (hVHD->Footer.DriveType, dtype, ((1+strlen (dtype)) < sizeof (hVHD->Footer.DriveType)) ? (1+strlen (dtype)) : sizeof (hVHD->Footer.DriveType));
hVHD->Footer.DriveSectorSize = NtoHl (SectorSize);
hVHD->Footer.DriveTransferElementSize = NtoHl (xfer_element_size);
strncpy (hVHD->Footer.CreatingSimulator, sim_name, sizeof (hVHD->Footer.CreatingSimulator));
strncpy ((char *)hVHD->Footer.CreatingSimulator, sim_name, sizeof (hVHD->Footer.CreatingSimulator));
hVHD->Footer.Checksum = 0;
hVHD->Footer.Checksum = NtoHl (CalculateVhdFooterChecksum (&hVHD->Footer, sizeof(hVHD->Footer)));
@ -4410,7 +4643,7 @@ if (Status)
return SCPE_OK;
}
static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size)
static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size, char sim_name[64])
{
VHDHANDLE hVHD = (VHDHANDLE)f;
@ -4418,6 +4651,8 @@ if (SectorSize)
*SectorSize = NtoHl (hVHD->Footer.DriveSectorSize);
if (xfer_element_size)
*xfer_element_size = NtoHl (hVHD->Footer.DriveTransferElementSize);
if (sim_name)
memcpy (sim_name, hVHD->Footer.CreatingSimulator, 64);
return (char *)(&hVHD->Footer.DriveType[0]);
}