DISK: Change auto disk format open logic to include RAW

Previously auto format detection first attempted a VHD open.  If that
failed, it falls back to a SIMH open which uses C RTL fopen, fread, fwrite
and fclose.  Now a RAW format open is attempted which will often
succeed, not only on CDROM devices, but most normal files can also
be opened in RAW mode which will to direct OS I/O (open, erad, write
and close or CreateFile, ReadFile, WriteFile, CloseHandle).

As discussed in #533
This commit is contained in:
Mark Pizzolato 2018-04-07 22:15:14 -07:00
parent 28e4311039
commit 6263378df4

View file

@ -1522,11 +1522,21 @@ else
switch (DK_GET_FMT (uptr)) { /* case on format */ switch (DK_GET_FMT (uptr)) { /* case on format */
case DKUF_F_STD: /* SIMH format */ case DKUF_F_STD: /* SIMH format */
if (NULL == (uptr->fileref = sim_vhd_disk_open (cptr, "rb"))) { if (NULL == (uptr->fileref = sim_vhd_disk_open (cptr, "rb"))) { /* Try VHD */
if (errno == EBADF) /* VHD but broken */ if (errno == EBADF) /* VHD but broken */
return SCPE_OPENERR; return SCPE_OPENERR;
open_function = sim_fopen; if (NULL == (uptr->fileref = sim_os_disk_open_raw (cptr, "rb"))) {
size_function = sim_fsize_ex; open_function = sim_fopen;
size_function = sim_fsize_ex;
break;
}
sim_disk_set_fmt (uptr, 0, "RAW", NULL); /* set file format to RAW */
sim_os_disk_close_raw (uptr->fileref); /* close raw file*/
open_function = sim_os_disk_open_raw;
size_function = sim_os_disk_size_raw;
storage_function = sim_os_disk_info_raw;
auto_format = TRUE;
uptr->fileref = NULL;
break; break;
} }
sim_disk_set_fmt (uptr, 0, "VHD", NULL); /* set file format to VHD */ sim_disk_set_fmt (uptr, 0, "VHD", NULL); /* set file format to VHD */
@ -2296,7 +2306,10 @@ static FILE *sim_os_disk_open_raw (const char *rawdevicename, const char *openmo
HANDLE Handle; HANDLE Handle;
DWORD DesiredAccess = 0; DWORD DesiredAccess = 0;
uint32 is_cdrom; uint32 is_cdrom;
char *tmpname = (char *)malloc (2 + strlen (rawdevicename));
if (tmpname == NULL)
return NULL;
if (strchr (openmode, 'r')) if (strchr (openmode, 'r'))
DesiredAccess |= GENERIC_READ; DesiredAccess |= GENERIC_READ;
if (strchr (openmode, 'w') || strchr (openmode, '+')) if (strchr (openmode, 'w') || strchr (openmode, '+'))
@ -2305,37 +2318,26 @@ if (strchr (openmode, 'w') || strchr (openmode, '+'))
escape sequence. This only affecdts RAW device names and UNC paths. escape sequence. This only affecdts RAW device names and UNC paths.
We handle the RAW device name case here by prepending paths beginning We handle the RAW device name case here by prepending paths beginning
with \.\ with an extra \. */ with \.\ with an extra \. */
if (!memcmp ("\\.\\", rawdevicename, 3)) { if ((!memcmp ("\\.\\", rawdevicename, 3)) ||
char *tmpname = (char *)malloc (2 + strlen (rawdevicename)); (!memcmp ("/./", rawdevicename, 3))) {
if (tmpname == NULL)
return NULL;
*tmpname = '\\'; *tmpname = '\\';
strcpy (tmpname + 1, rawdevicename); strcpy (tmpname + 1, rawdevicename);
Handle = CreateFileA (tmpname, DesiredAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_WRITE_THROUGH, NULL); }
free (tmpname); else
if (Handle != INVALID_HANDLE_VALUE) { strcpy (tmpname, rawdevicename);
if ((sim_os_disk_info_raw ((FILE *)Handle, NULL, NULL, &is_cdrom)) || Handle = CreateFileA (tmpname, DesiredAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_WRITE_THROUGH, NULL);
(DesiredAccess & GENERIC_WRITE) && is_cdrom) { free (tmpname);
CloseHandle (Handle); if (Handle != INVALID_HANDLE_VALUE) {
errno = EACCES; if ((sim_os_disk_info_raw ((FILE *)Handle, NULL, NULL, &is_cdrom)) ||
return NULL; (DesiredAccess & GENERIC_WRITE) && is_cdrom) {
} CloseHandle (Handle);
return (FILE *)Handle; errno = EACCES;
return NULL;
} }
return (FILE *)Handle;
} }
Handle = CreateFileA (rawdevicename, DesiredAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_WRITE_THROUGH, NULL); _set_errno_from_status (GetLastError ());
if (Handle == INVALID_HANDLE_VALUE) { return NULL;
_set_errno_from_status (GetLastError ());
return NULL;
}
if ((sim_os_disk_info_raw ((FILE *)Handle, NULL, NULL, &is_cdrom)) ||
(DesiredAccess & GENERIC_WRITE) && is_cdrom) {
CloseHandle (Handle);
errno = EACCES;
return NULL;
}
return (FILE *)Handle;
} }
static int sim_os_disk_close_raw (FILE *f) static int sim_os_disk_close_raw (FILE *f)