From c1ec955152b48b7938d20e9cba8b6e67479c2e73 Mon Sep 17 00:00:00 2001 From: Javier Date: Sun, 1 Nov 2026 02:07:26 +0100 Subject: add a signature mechanism for ioctl control strings --- dos/chud.c | 52 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) (limited to 'dos/chud.c') diff --git a/dos/chud.c b/dos/chud.c index c6d728c..498d97b 100644 --- a/dos/chud.c +++ b/dos/chud.c @@ -20,11 +20,13 @@ #include #include #include +#include #include #include #include #include "inc/mbr.h" +#include "inc/dosapi.h" #include "inc/dosdrv.h" #include "chudisk.h" @@ -56,11 +58,10 @@ static int ioctl_read_control(uint8_t drive, void *buffer, int len) regs.x.dx = FP_OFF(buffer); intdos(®s, ®s); - if (regs.x.cflag) { - return -1; + return -1; // Generic error, but errno should be properly set } else { - return regs.x.ax; + return regs.x.ax; // Number of bytes read } } @@ -74,7 +75,6 @@ static int ioctl_write_control(uint8_t drive, void *buffer, int len) regs.x.dx = FP_OFF(buffer); intdos(®s, ®s); - if (regs.x.cflag) { return -1; } else { @@ -98,9 +98,34 @@ static int ioctl_read_abs_sector(uint8_t drive, void *buffer, uint32_t sector, i regs.h.cl = CHUDISK_IOCTL_DISK_READ_ABS_SECTOR; regs.x.dx = FP_OFF(&ciod); - intdos(®s, ®s); - - return regs.x.cflag ? -1 : 0; + if (intdos(®s, ®s) == 0) { + return 0; + } else { + struct DOSERROR err; + // Get the extended error from DOS, more useful than a simple EACCES + // and translate to watcom's errno + switch (dosexterr(&err)) { + case DOS_ERROR_INVALID_FUNCTION: + errno = EINVAL; + break; + case DOS_ERROR_FILE_NOT_FOUND: + case DOS_ERROR_PATH_NOT_FOUND: + errno = ENOENT; + break; + case DOS_ERROR_INVALID_DRIVE: + errno = ENODEV; + break; + case DOS_ERROR_READ_FAULT: + case DOS_ERROR_WRITE_FAULT: + case DOS_ERROR_GEN_FAILURE: + errno = EIO; + break; + default: + errno = EFAULT; + break; + } + return -errno; + } } static void dos_disk_reset() @@ -123,6 +148,11 @@ static int parse_chudisk_control_string(const char *b, int len) } i = 0; #endif + // signature + if (b[i] != 'C' || b[i+1] != 'H') { + return -1; + } + i+=2; while (i < len) { char c = b[i++]; switch (c) { @@ -345,7 +375,7 @@ static void usage() int main(int argc, const char *argv[]) { - static char buffer[16]; + static char buffer[32]; int i; unsigned part; @@ -399,10 +429,12 @@ int main(int argc, const char *argv[]) dos_disk_reset(); // Flush caches before we swap the drive... i = 0; - buffer[i++] = 'S'; + buffer[i++] = 'C'; // Signature + buffer[i++] = 'H'; + buffer[i++] = 'S'; // Partition start sector memcpy(&buffer[i], &partinfo[part-1].start_sector, sizeof(uint32_t)); i+=sizeof(uint32_t); - buffer[i++] = 'L'; + buffer[i++] = 'L'; // Partition len memcpy(&buffer[i], &partinfo[part-1].num_sectors, sizeof(uint32_t)); i+=sizeof(uint32_t); buffer[i] = '\0'; -- cgit v1.2.3