aboutsummaryrefslogtreecommitdiff
path: root/dos/chud.c
diff options
context:
space:
mode:
Diffstat (limited to 'dos/chud.c')
-rw-r--r--dos/chud.c52
1 files changed, 42 insertions, 10 deletions
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 <stdlib.h>
#include <stdint.h>
#include <string.h>
+#include <errno.h>
#include <dos.h>
#include <dosfunc.h>
#include <io.h>
#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(&regs, &regs);
-
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(&regs, &regs);
-
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(&regs, &regs);
-
- return regs.x.cflag ? -1 : 0;
+ if (intdos(&regs, &regs) == 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';