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:
parent
28e4311039
commit
6263378df4
1 changed files with 33 additions and 31 deletions
64
sim_disk.c
64
sim_disk.c
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue