From 827ed4b146b17ae6a808e8943bf06888b924cb69 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sat, 20 Oct 2018 12:53:52 +0200 Subject: [PATCH] [NTVDM] Allow opening files with write access on CDROM Some applications, run on a CDROM, may attempt to open a file with write access. CDFS driver will deny such request in ReactOS (but also in Windows NT). Then, to restore that behavior from old Windows (9X), our ntvdm, as Microsoft ntvdm will attempt to reopen the file only with read access, if opening failed because of denied access and if the file is on a CDROM. CORE-15211 --- subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c | 28 ++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c b/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c index d5b01ce7fbf..641ab62ed93 100644 --- a/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c +++ b/subsystems/mvdm/ntvdm/dos/dos32krnl/dos.c @@ -161,6 +161,21 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory) return TRUE; } +static BOOLEAN DosIsFileOnCdRom(VOID) +{ + UINT DriveType; + CHAR RootPathName[4]; + + /* Construct a simple :\ string to get drive type */ + RootPathName[0] = Sda->CurrentDrive + 'A'; + RootPathName[1] = ':'; + RootPathName[2] = '\\'; + RootPathName[3] = ANSI_NULL; + + DriveType = GetDriveTypeA(RootPathName); + return (DriveType == DRIVE_CDROM); +} + /* PUBLIC FUNCTIONS ***********************************************************/ BOOLEAN DosControlBreak(VOID) @@ -950,8 +965,19 @@ VOID WINAPI DosInt21h(LPWORD Stack) case 0x3D: { WORD FileHandle; + BYTE AccessShareModes = getAL(); LPCSTR FileName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getDX()); - WORD ErrorCode = DosOpenFile(&FileHandle, FileName, getAL()); + WORD ErrorCode = DosOpenFile(&FileHandle, FileName, AccessShareModes); + + /* + * Check if we failed because we attempted to open a file for write + * on a CDROM drive. In that situation, attempt to reopen for read + */ + if (ErrorCode == ERROR_ACCESS_DENIED && + (AccessShareModes & 0x03) != 0 && DosIsFileOnCdRom()) + { + ErrorCode = DosOpenFile(&FileHandle, FileName, 0); + } if (ErrorCode == ERROR_SUCCESS) {