Added a per-drive FailReadOnly flag, and removed the global
--failreadonly option.
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 81025f1..0355f60 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -660,7 +660,7 @@
if (!strcmp(DOSFS_Devices[i].name,"NUL"))
return FILE_CreateFile( "/dev/null", access,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, 0, -1 );
+ OPEN_EXISTING, 0, -1, TRUE );
if (!strcmp(DOSFS_Devices[i].name,"CON")) {
HFILE to_dup;
HFILE handle;
@@ -697,7 +697,7 @@
DOSFS_Devices[i].name,devname);
r = FILE_CreateFile( devname, access,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, 0, -1 );
+ OPEN_EXISTING, 0, -1, TRUE );
TRACE_(file)("Create_File return %08X\n",r);
return r;
}
diff --git a/files/drive.c b/files/drive.c
index 14d12d0..eda5db4 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -60,7 +60,6 @@
char *dos_cwd; /* cwd in DOS format without leading or trailing \ */
char *unix_cwd; /* cwd in Unix format without leading or trailing / */
char *device; /* raw device path */
- BOOL read_volinfo; /* read the volume info from the device ? */
char label_conf[12]; /* drive label as cfg'd in wine.conf */
char label_read[12]; /* drive label as read from device */
DWORD serial_conf; /* drive serial number as cfg'd in wine.conf */
@@ -208,11 +207,13 @@
if (buffer[0])
{
drive->device = HEAP_strdupA( GetProcessHeap(), 0, buffer );
- drive->read_volinfo =
- (BOOL)PROFILE_GetWineIniInt( name, "ReadVolInfo", 1);
+ if (PROFILE_GetWineIniBool( name, "ReadVolInfo", 1))
+ drive->flags |= DRIVE_READ_VOL_INFO;
}
- else
- drive->read_volinfo = FALSE;
+
+ /* Get the FailReadOnly flag */
+ if (PROFILE_GetWineIniBool( name, "FailReadOnly", 0 ))
+ drive->flags |= DRIVE_FAIL_READ_ONLY;
/* Make the first hard disk the current drive */
if ((DRIVE_CurDrive == -1) && (drive->type == TYPE_HD))
@@ -564,7 +565,7 @@
CDROM_Close(&wcda);
}
}
- if ((!read) && (DOSDrives[drive].read_volinfo))
+ if ((!read) && (DOSDrives[drive].flags & DRIVE_READ_VOL_INFO))
{
if (DRIVE_ReadSuperblock(drive,(char *) buff))
ERR("Invalid or unreadable superblock on %s (%c:).\n",
@@ -599,7 +600,7 @@
if (!DRIVE_IsValid( drive )) return 0;
- if (DOSDrives[drive].read_volinfo)
+ if (DOSDrives[drive].flags & DRIVE_READ_VOL_INFO)
{
switch(DOSDrives[drive].type)
{
@@ -633,7 +634,7 @@
if (!DRIVE_IsValid( drive )) return 0;
- if (DOSDrives[drive].read_volinfo)
+ if (DOSDrives[drive].flags & DRIVE_READ_VOL_INFO)
{
if ((DOSDrives[drive].type != TYPE_FLOPPY) &&
(DOSDrives[drive].type != TYPE_HD)) return 0;
diff --git a/files/file.c b/files/file.c
index f10a9bd..206667f 100644
--- a/files/file.c
+++ b/files/file.c
@@ -42,7 +42,6 @@
#include "global.h"
#include "heap.h"
#include "msdos.h"
-#include "options.h"
#include "ldt.h"
#include "process.h"
#include "task.h"
@@ -322,11 +321,13 @@
* Implementation of CreateFile. Takes a Unix path name.
*/
HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
- LPSECURITY_ATTRIBUTES sa, DWORD creation,
- DWORD attributes, HANDLE template )
+ LPSECURITY_ATTRIBUTES sa, DWORD creation,
+ DWORD attributes, HANDLE template, BOOL fail_read_only )
{
+ DWORD err;
struct create_file_request *req = get_req_buffer();
+ restart:
req->access = access;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req->sharing = sharing;
@@ -334,22 +335,19 @@
req->attrs = attributes;
lstrcpynA( req->name, filename, server_remaining(req->name) );
SetLastError(0);
- server_call( REQ_CREATE_FILE );
+ err = server_call( REQ_CREATE_FILE );
/* If write access failed, retry without GENERIC_WRITE */
- if ((req->handle == -1) && !Options.failReadOnly &&
- (access & GENERIC_WRITE))
+ if ((req->handle == -1) && !fail_read_only && (access & GENERIC_WRITE))
{
- DWORD lasterror = GetLastError();
-
- if ((lasterror == ERROR_ACCESS_DENIED) ||
- (lasterror == ERROR_WRITE_PROTECT)) {
+ if ((err == ERROR_ACCESS_DENIED) || (err == ERROR_WRITE_PROTECT))
+ {
TRACE("Write access failed for file '%s', trying without "
"write access", filename);
- return FILE_CreateFile( filename, access & ~GENERIC_WRITE, sharing,
- sa, creation, attributes, template );
- }
+ access &= ~GENERIC_WRITE;
+ goto restart;
+ }
}
if (req->handle == -1)
@@ -491,7 +489,8 @@
}
return FILE_CreateFile( full_name.long_name, access, sharing,
- sa, creation, attributes, template );
+ sa, creation, attributes, template,
+ DRIVE_GetFlags(full_name.drive) & DRIVE_FAIL_READ_ONLY );
}
@@ -917,7 +916,8 @@
}
hFileRet = FILE_CreateFile( full_name.long_name, access, sharing,
- NULL, OPEN_EXISTING, 0, -1 );
+ NULL, OPEN_EXISTING, 0, -1,
+ DRIVE_GetFlags(full_name.drive) & DRIVE_FAIL_READ_ONLY );
if (hFileRet == HFILE_ERROR) goto not_found;
GetFileTime( hFileRet, NULL, NULL, &filetime );