From 0d1beebfd1874dc9629f3c485d1ef93b7ce2d406 Mon Sep 17 00:00:00 2001 From: Jonathan Campbell Date: Thu, 8 Feb 2018 00:29:25 -0800 Subject: [PATCH] add mount -ro option, to mount a local folder readonly, update DOS kernel to support returning "write protect" error code --- include/dos_inc.h | 1 + include/dos_system.h | 1 + src/dos/dos_programs.cpp | 7 +++++++ src/dos/drive_local.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/dos/drives.cpp | 1 + 5 files changed, 50 insertions(+) diff --git a/include/dos_inc.h b/include/dos_inc.h index 8b7ff0988..0ba36307c 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -320,6 +320,7 @@ static INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { #define DOSERR_REMOVE_CURRENT_DIRECTORY 16 #define DOSERR_NOT_SAME_DEVICE 17 #define DOSERR_NO_MORE_FILES 18 +#define DOSERR_WRITE_PROTECTED 19 #define DOSERR_FILE_ALREADY_EXISTS 80 diff --git a/include/dos_system.h b/include/dos_system.h index ce045b7cb..345fcc44b 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -268,6 +268,7 @@ public: virtual const char * GetInfo(void); char * GetBaseDir(void); + bool readonly; char curdir[DOS_PATHLENGTH]; char info[256]; /* Can be overridden for example in iso images */ diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 025bc2690..e3cb49152 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -246,6 +246,12 @@ public: return; } + bool readonly = false; + if (cmd->FindExist("-ro",true)) + readonly = true; + if (cmd->FindExist("-rw",true)) + readonly = false; + std::string type="dir"; cmd->FindString("-t",type,true); bool iscdrom = (type =="cdrom"); //Used for mscdex bug cdrom label name emulation @@ -456,6 +462,7 @@ public: LOG_MSG("ERROR:This build does not support physfs"); } else { newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid); + newdrive->readonly = readonly; } } } else { diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 42d84b9f1..084f55c78 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -347,6 +347,11 @@ char *CodePageHostToGuest(const host_cnv_char_t *s) { } bool localDrive::FileCreate(DOS_File * * file,const char * name,Bit16u /*attributes*/) { + if (readonly) { + DOS_SetError(DOSERR_WRITE_PROTECTED); + return false; + } + //TODO Maybe care for attributes but not likely char newname[CROSS_LEN]; strcpy(newname,basedir); @@ -360,6 +365,7 @@ bool localDrive::FileCreate(DOS_File * * file,const char * name,Bit16u /*attribu host_cnv_char_t *host_name = CodePageGuestToHost(temp_name); if (host_name == NULL) { LOG_MSG("%s: Filename '%s' from guest is non-representable on the host filesystem through code page conversion",__FUNCTION__,newname); + DOS_SetError(DOSERR_FILE_NOT_FOUND); // FIXME return false; } @@ -398,6 +404,13 @@ bool localDrive::FileCreate(DOS_File * * file,const char * name,Bit16u /*attribu } bool localDrive::FileOpen(DOS_File * * file,const char * name,Bit32u flags) { + if (readonly) { + if ((flags&0xf) == OPEN_WRITE || (flags&0xf) == OPEN_READWRITE) { + DOS_SetError(DOSERR_WRITE_PROTECTED); + return false; + } + } + const host_cnv_char_t * type; switch (flags&0xf) { case OPEN_READ: type = _HT("rb"); break; @@ -434,6 +447,7 @@ bool localDrive::FileOpen(DOS_File * * file,const char * name,Bit32u flags) { host_cnv_char_t *host_name = CodePageGuestToHost(newname); if (host_name == NULL) { LOG_MSG("%s: Filename '%s' from guest is non-representable on the host filesystem through code page conversion",__FUNCTION__,newname); + DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } @@ -519,6 +533,11 @@ bool localDrive::GetSystemFilename(char *sysName, char const * const dosName) { } bool localDrive::FileUnlink(const char * name) { + if (readonly) { + DOS_SetError(DOSERR_WRITE_PROTECTED); + return false; + } + char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); @@ -529,6 +548,7 @@ bool localDrive::FileUnlink(const char * name) { host_cnv_char_t *host_name = CodePageGuestToHost(fullname); if (host_name == NULL) { LOG_MSG("%s: Filename '%s' from guest is non-representable on the host filesystem through code page conversion",__FUNCTION__,fullname); + DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } @@ -706,6 +726,7 @@ bool localDrive::GetFileAttr(const char * name,Bit16u * attr) { host_cnv_char_t *host_name = CodePageGuestToHost(newname); if (host_name == NULL) { LOG_MSG("%s: Filename '%s' from guest is non-representable on the host filesystem through code page conversion",__FUNCTION__,newname); + DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } @@ -720,6 +741,11 @@ bool localDrive::GetFileAttr(const char * name,Bit16u * attr) { } bool localDrive::MakeDir(const char * dir) { + if (readonly) { + DOS_SetError(DOSERR_WRITE_PROTECTED); + return false; + } + char newdir[CROSS_LEN]; strcpy(newdir,basedir); strcat(newdir,dir); @@ -731,6 +757,7 @@ bool localDrive::MakeDir(const char * dir) { host_cnv_char_t *host_name = CodePageGuestToHost(temp_name); if (host_name == NULL) { LOG_MSG("%s: Filename '%s' from guest is non-representable on the host filesystem through code page conversion",__FUNCTION__,newdir); + DOS_SetError(DOSERR_FILE_NOT_FOUND); // FIXME return false; } @@ -745,6 +772,11 @@ bool localDrive::MakeDir(const char * dir) { } bool localDrive::RemoveDir(const char * dir) { + if (readonly) { + DOS_SetError(DOSERR_WRITE_PROTECTED); + return false; + } + char newdir[CROSS_LEN]; strcpy(newdir,basedir); strcat(newdir,dir); @@ -756,6 +788,7 @@ bool localDrive::RemoveDir(const char * dir) { host_cnv_char_t *host_name = CodePageGuestToHost(temp_name); if (host_name == NULL) { LOG_MSG("%s: Filename '%s' from guest is non-representable on the host filesystem through code page conversion",__FUNCTION__,newdir); + DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } @@ -795,6 +828,11 @@ bool localDrive::TestDir(const char * dir) { } bool localDrive::Rename(const char * oldname,const char * newname) { + if (readonly) { + DOS_SetError(DOSERR_WRITE_PROTECTED); + return false; + } + host_cnv_char_t *ht; char newold[CROSS_LEN]; @@ -813,6 +851,7 @@ bool localDrive::Rename(const char * oldname,const char * newname) { ht = CodePageGuestToHost(newold); if (ht == NULL) { LOG_MSG("%s: Filename '%s' from guest is non-representable on the host filesystem through code page conversion",__FUNCTION__,newold); + DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } host_cnv_char_t *o_temp_name = ht_strdup(ht); @@ -822,6 +861,7 @@ bool localDrive::Rename(const char * oldname,const char * newname) { if (ht == NULL) { free(o_temp_name); LOG_MSG("%s: Filename '%s' from guest is non-representable on the host filesystem through code page conversion",__FUNCTION__,newnew); + DOS_SetError(DOSERR_FILE_NOT_FOUND); // FIXME return false; } host_cnv_char_t *n_temp_name = ht_strdup(ht); diff --git a/src/dos/drives.cpp b/src/dos/drives.cpp index 0929e527b..6226ac8e1 100644 --- a/src/dos/drives.cpp +++ b/src/dos/drives.cpp @@ -111,6 +111,7 @@ void Set_Label(char const * const input, char * const output, bool cdrom) { DOS_Drive::DOS_Drive() { + readonly=false; curdir[0]=0; info[0]=0; }