Commit fbace6ee authored by Alexandre Julliard's avatar Alexandre Julliard

Added a per-drive FailReadOnly flag, and removed the global

--failreadonly option.
parent 8a971bfe
...@@ -97,6 +97,12 @@ You definitely don't want to use "unix" unless you intend to port programs using ...@@ -97,6 +97,12 @@ You definitely don't want to use "unix" unless you intend to port programs using
.br .br
Always try to avoid using FAT16. Use VFAT/FAT32 OS file system driver instead ! Always try to avoid using FAT16. Use VFAT/FAT32 OS file system driver instead !
.PP .PP
.I format: FailReadOnly=<boolean>
.br
Read-only files may not be opened in write mode (the default is to
allow opening read-only files for writing, because most Windows
programs always request read-write access, even on CD-ROM drives...).
.PP
.B [wine] .B [wine]
.br .br
.I format: windows = <directory> .I format: windows = <directory>
......
...@@ -215,11 +215,6 @@ Specify the DOS version ...@@ -215,11 +215,6 @@ Specify the DOS version
should imitate (e.g. 6.22) This option should imitate (e.g. 6.22) This option
is only valid when used in conjunction with --winver win31. is only valid when used in conjunction with --winver win31.
.TP .TP
.I --failreadonly
Read only files may not be opened in write mode (the default is to
allow opening read-only files for writing, because most Windows
programs always request read-write access, even on CD-ROM drives...).
.TP
.I --language xx .I --language xx
Set the language to Set the language to
.I xx .I xx
......
...@@ -660,7 +660,7 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access ) ...@@ -660,7 +660,7 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access )
if (!strcmp(DOSFS_Devices[i].name,"NUL")) if (!strcmp(DOSFS_Devices[i].name,"NUL"))
return FILE_CreateFile( "/dev/null", access, return FILE_CreateFile( "/dev/null", access,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, -1 ); OPEN_EXISTING, 0, -1, TRUE );
if (!strcmp(DOSFS_Devices[i].name,"CON")) { if (!strcmp(DOSFS_Devices[i].name,"CON")) {
HFILE to_dup; HFILE to_dup;
HFILE handle; HFILE handle;
...@@ -697,7 +697,7 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access ) ...@@ -697,7 +697,7 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access )
DOSFS_Devices[i].name,devname); DOSFS_Devices[i].name,devname);
r = FILE_CreateFile( devname, access, r = FILE_CreateFile( devname, access,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, -1 ); OPEN_EXISTING, 0, -1, TRUE );
TRACE_(file)("Create_File return %08X\n",r); TRACE_(file)("Create_File return %08X\n",r);
return r; return r;
} }
......
...@@ -60,7 +60,6 @@ typedef struct ...@@ -60,7 +60,6 @@ typedef struct
char *dos_cwd; /* cwd in DOS format without leading or trailing \ */ char *dos_cwd; /* cwd in DOS format without leading or trailing \ */
char *unix_cwd; /* cwd in Unix format without leading or trailing / */ char *unix_cwd; /* cwd in Unix format without leading or trailing / */
char *device; /* raw device path */ 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_conf[12]; /* drive label as cfg'd in wine.conf */
char label_read[12]; /* drive label as read from device */ char label_read[12]; /* drive label as read from device */
DWORD serial_conf; /* drive serial number as cfg'd in wine.conf */ DWORD serial_conf; /* drive serial number as cfg'd in wine.conf */
...@@ -208,11 +207,13 @@ int DRIVE_Init(void) ...@@ -208,11 +207,13 @@ int DRIVE_Init(void)
if (buffer[0]) if (buffer[0])
{ {
drive->device = HEAP_strdupA( GetProcessHeap(), 0, buffer ); drive->device = HEAP_strdupA( GetProcessHeap(), 0, buffer );
drive->read_volinfo = if (PROFILE_GetWineIniBool( name, "ReadVolInfo", 1))
(BOOL)PROFILE_GetWineIniInt( 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 */ /* Make the first hard disk the current drive */
if ((DRIVE_CurDrive == -1) && (drive->type == TYPE_HD)) if ((DRIVE_CurDrive == -1) && (drive->type == TYPE_HD))
...@@ -564,7 +565,7 @@ const char * DRIVE_GetLabel( int drive ) ...@@ -564,7 +565,7 @@ const char * DRIVE_GetLabel( int drive )
CDROM_Close(&wcda); CDROM_Close(&wcda);
} }
} }
if ((!read) && (DOSDrives[drive].read_volinfo)) if ((!read) && (DOSDrives[drive].flags & DRIVE_READ_VOL_INFO))
{ {
if (DRIVE_ReadSuperblock(drive,(char *) buff)) if (DRIVE_ReadSuperblock(drive,(char *) buff))
ERR("Invalid or unreadable superblock on %s (%c:).\n", ERR("Invalid or unreadable superblock on %s (%c:).\n",
...@@ -599,7 +600,7 @@ char buff[DRIVE_SUPER]; ...@@ -599,7 +600,7 @@ char buff[DRIVE_SUPER];
if (!DRIVE_IsValid( drive )) return 0; if (!DRIVE_IsValid( drive )) return 0;
if (DOSDrives[drive].read_volinfo) if (DOSDrives[drive].flags & DRIVE_READ_VOL_INFO)
{ {
switch(DOSDrives[drive].type) switch(DOSDrives[drive].type)
{ {
...@@ -633,7 +634,7 @@ int DRIVE_SetSerialNumber( int drive, DWORD serial ) ...@@ -633,7 +634,7 @@ int DRIVE_SetSerialNumber( int drive, DWORD serial )
if (!DRIVE_IsValid( drive )) return 0; 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) && if ((DOSDrives[drive].type != TYPE_FLOPPY) &&
(DOSDrives[drive].type != TYPE_HD)) return 0; (DOSDrives[drive].type != TYPE_HD)) return 0;
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "global.h" #include "global.h"
#include "heap.h" #include "heap.h"
#include "msdos.h" #include "msdos.h"
#include "options.h"
#include "ldt.h" #include "ldt.h"
#include "process.h" #include "process.h"
#include "task.h" #include "task.h"
...@@ -322,11 +321,13 @@ HFILE FILE_DupUnixHandle( int fd, DWORD access ) ...@@ -322,11 +321,13 @@ HFILE FILE_DupUnixHandle( int fd, DWORD access )
* Implementation of CreateFile. Takes a Unix path name. * Implementation of CreateFile. Takes a Unix path name.
*/ */
HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation, LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template ) DWORD attributes, HANDLE template, BOOL fail_read_only )
{ {
DWORD err;
struct create_file_request *req = get_req_buffer(); struct create_file_request *req = get_req_buffer();
restart:
req->access = access; req->access = access;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req->sharing = sharing; req->sharing = sharing;
...@@ -334,22 +335,19 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, ...@@ -334,22 +335,19 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
req->attrs = attributes; req->attrs = attributes;
lstrcpynA( req->name, filename, server_remaining(req->name) ); lstrcpynA( req->name, filename, server_remaining(req->name) );
SetLastError(0); SetLastError(0);
server_call( REQ_CREATE_FILE ); err = server_call( REQ_CREATE_FILE );
/* If write access failed, retry without GENERIC_WRITE */ /* If write access failed, retry without GENERIC_WRITE */
if ((req->handle == -1) && !Options.failReadOnly && if ((req->handle == -1) && !fail_read_only && (access & GENERIC_WRITE))
(access & GENERIC_WRITE))
{ {
DWORD lasterror = GetLastError(); if ((err == ERROR_ACCESS_DENIED) || (err == ERROR_WRITE_PROTECT))
{
if ((lasterror == ERROR_ACCESS_DENIED) ||
(lasterror == ERROR_WRITE_PROTECT)) {
TRACE("Write access failed for file '%s', trying without " TRACE("Write access failed for file '%s', trying without "
"write access", filename); "write access", filename);
return FILE_CreateFile( filename, access & ~GENERIC_WRITE, sharing, access &= ~GENERIC_WRITE;
sa, creation, attributes, template ); goto restart;
} }
} }
if (req->handle == -1) if (req->handle == -1)
...@@ -491,7 +489,8 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing, ...@@ -491,7 +489,8 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
} }
return FILE_CreateFile( full_name.long_name, access, sharing, 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 @@ found: ...@@ -917,7 +916,8 @@ found:
} }
hFileRet = FILE_CreateFile( full_name.long_name, access, sharing, 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; if (hFileRet == HFILE_ERROR) goto not_found;
GetFileTime( hFileRet, NULL, NULL, &filetime ); GetFileTime( hFileRet, NULL, NULL, &filetime );
......
...@@ -26,6 +26,8 @@ typedef enum ...@@ -26,6 +26,8 @@ typedef enum
#define DRIVE_SHORT_NAMES 0x0002 /* Drive fs has 8.3 file names */ #define DRIVE_SHORT_NAMES 0x0002 /* Drive fs has 8.3 file names */
#define DRIVE_CASE_SENSITIVE 0x0004 /* Drive fs is case sensitive */ #define DRIVE_CASE_SENSITIVE 0x0004 /* Drive fs is case sensitive */
#define DRIVE_CASE_PRESERVING 0x0008 /* Drive fs is case preserving */ #define DRIVE_CASE_PRESERVING 0x0008 /* Drive fs is case preserving */
#define DRIVE_FAIL_READ_ONLY 0x0010 /* Fail opening read-only files for writing */
#define DRIVE_READ_VOL_INFO 0x0020 /* Try to read volume info from the device? */
extern int DRIVE_Init(void); extern int DRIVE_Init(void);
extern int DRIVE_IsValid( int drive ); extern int DRIVE_IsValid( int drive );
......
...@@ -36,8 +36,8 @@ extern HFILE FILE_DupUnixHandle( int fd, DWORD access ); ...@@ -36,8 +36,8 @@ extern HFILE FILE_DupUnixHandle( int fd, DWORD access );
extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info ); extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info );
extern HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 ); extern HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 );
extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation, LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template ); DWORD attributes, HANDLE template, BOOL fail_read_only );
extern HFILE FILE_CreateDevice( int client_id, DWORD access, extern HFILE FILE_CreateDevice( int client_id, DWORD access,
LPSECURITY_ATTRIBUTES sa ); LPSECURITY_ATTRIBUTES sa );
extern LPVOID FILE_dommap( int unix_handle, LPVOID start, extern LPVOID FILE_dommap( int unix_handle, LPVOID start,
......
...@@ -62,8 +62,6 @@ struct options ...@@ -62,8 +62,6 @@ struct options
char *dllFlags; /* -dll flags (hack for Winelib support) */ char *dllFlags; /* -dll flags (hack for Winelib support) */
int synchronous; /* X synchronous mode */ int synchronous; /* X synchronous mode */
int debug; int debug;
int failReadOnly; /* Opening a read only file will fail
if write access is requested */
WINE_LANGUAGE language; /* Current language */ WINE_LANGUAGE language; /* Current language */
int managed; /* Managed windows */ int managed; /* Managed windows */
char * configFileName; /* Command line config file */ char * configFileName; /* Command line config file */
......
...@@ -90,7 +90,6 @@ struct options Options = ...@@ -90,7 +90,6 @@ struct options Options =
NULL, /* dllFlags */ NULL, /* dllFlags */
FALSE, /* synchronous */ FALSE, /* synchronous */
FALSE, /* debug */ FALSE, /* debug */
FALSE, /* failReadOnly */
0, /* language */ 0, /* language */
FALSE, /* Managed windows */ FALSE, /* Managed windows */
NULL /* Alternate config file name */ NULL /* Alternate config file name */
......
...@@ -49,8 +49,6 @@ static const struct option option_table[] = ...@@ -49,8 +49,6 @@ static const struct option option_table[] =
"--dll name Enable or disable built-in DLLs" }, "--dll name Enable or disable built-in DLLs" },
{ "dosver", 0, 1, VERSION_ParseDosVersion, { "dosver", 0, 1, VERSION_ParseDosVersion,
"--dosver x.xx DOS version to imitate (e.g. 6.22). Only valid with --winver win31" }, "--dosver x.xx DOS version to imitate (e.g. 6.22). Only valid with --winver win31" },
{ "failreadonly", 0, 0, do_failreadonly,
"--failreadonly Read only files may not be opened in write mode" },
{ "help", 'h', 0, do_help, { "help", 'h', 0, do_help,
"--help,-h Show this help message" }, "--help,-h Show this help message" },
{ "language", 0, 1, MAIN_ParseLanguageOption, { "language", 0, 1, MAIN_ParseLanguageOption,
...@@ -89,11 +87,6 @@ static void do_debug( const char *arg ) ...@@ -89,11 +87,6 @@ static void do_debug( const char *arg )
Options.debug = TRUE; Options.debug = TRUE;
} }
static void do_failreadonly( const char *arg )
{
Options.failReadOnly = TRUE;
}
static void do_desktop( const char *arg ) static void do_desktop( const char *arg )
{ {
Options.desktopGeometry = strdup( arg ); Options.desktopGeometry = strdup( arg );
......
...@@ -203,7 +203,7 @@ static void save_key( HKEY hkey, const char *filename ) ...@@ -203,7 +203,7 @@ static void save_key( HKEY hkey, const char *filename )
{ {
sprintf( p, "reg%04x.tmp", count++ ); sprintf( p, "reg%04x.tmp", count++ );
handle = FILE_CreateFile( name, GENERIC_WRITE, 0, NULL, handle = FILE_CreateFile( name, GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, -1 ); CREATE_NEW, FILE_ATTRIBUTE_NORMAL, -1, TRUE );
if (handle != INVALID_HANDLE_VALUE) break; if (handle != INVALID_HANDLE_VALUE) break;
if ((ret = GetLastError()) != ERROR_ALREADY_EXISTS) break; if ((ret = GetLastError()) != ERROR_ALREADY_EXISTS) break;
} }
...@@ -628,7 +628,7 @@ static int _wine_loadsubreg( FILE *F, HKEY hkey, const char *fn ) ...@@ -628,7 +628,7 @@ static int _wine_loadsubreg( FILE *F, HKEY hkey, const char *fn )
{ {
HANDLE file; HANDLE file;
if ((file = FILE_CreateFile( fn, GENERIC_READ, 0, NULL, OPEN_EXISTING, if ((file = FILE_CreateFile( fn, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, -1 )) != INVALID_HANDLE_VALUE) FILE_ATTRIBUTE_NORMAL, -1, TRUE )) != INVALID_HANDLE_VALUE)
{ {
struct load_registry_request *req = get_req_buffer(); struct load_registry_request *req = get_req_buffer();
req->hkey = hkey; req->hkey = hkey;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment