From fbace6eefee927dca6768c3ef6d6e2d2b9eaa1c5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 4 Apr 2000 20:35:45 +0000 Subject: [PATCH] Added a per-drive FailReadOnly flag, and removed the global --failreadonly option. --- documentation/wine.conf.man.in | 6 ++++++ documentation/wine.man.in | 5 ----- files/dos_fs.c | 4 ++-- files/drive.c | 17 +++++++++-------- files/file.c | 30 +++++++++++++++--------------- include/drive.h | 2 ++ include/file.h | 4 ++-- include/options.h | 2 -- misc/main.c | 1 - misc/options.c | 7 ------- misc/registry.c | 4 ++-- 11 files changed, 38 insertions(+), 44 deletions(-) diff --git a/documentation/wine.conf.man.in b/documentation/wine.conf.man.in index 7c827ce41e5..05877885aff 100644 --- a/documentation/wine.conf.man.in +++ b/documentation/wine.conf.man.in @@ -97,6 +97,12 @@ You definitely don't want to use "unix" unless you intend to port programs using .br Always try to avoid using FAT16. Use VFAT/FAT32 OS file system driver instead ! .PP +.I format: FailReadOnly= +.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] .br .I format: windows = diff --git a/documentation/wine.man.in b/documentation/wine.man.in index 8481353f419..a7b2e560e02 100644 --- a/documentation/wine.man.in +++ b/documentation/wine.man.in @@ -215,11 +215,6 @@ Specify the DOS version should imitate (e.g. 6.22) This option is only valid when used in conjunction with --winver win31. .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 Set the language to .I xx diff --git a/files/dos_fs.c b/files/dos_fs.c index 81025f1baee..0355f608073 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -660,7 +660,7 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access ) 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 @@ HFILE DOSFS_OpenDevice( const char *name, DWORD access ) 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 14d12d02e72..eda5db4a1a7 100644 --- a/files/drive.c +++ b/files/drive.c @@ -60,7 +60,6 @@ typedef struct 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 @@ int DRIVE_Init(void) 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 @@ const char * DRIVE_GetLabel( int drive ) 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 @@ char buff[DRIVE_SUPER]; 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 @@ int DRIVE_SetSerialNumber( int drive, DWORD serial ) 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 f10a9bdd79c..206667fd0bf 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 @@ HFILE FILE_DupUnixHandle( int fd, DWORD access ) * 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 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, 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 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD 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: } 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 ); diff --git a/include/drive.h b/include/drive.h index 9328af8c85b..631fdd6474f 100644 --- a/include/drive.h +++ b/include/drive.h @@ -26,6 +26,8 @@ typedef enum #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_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_IsValid( int drive ); diff --git a/include/file.h b/include/file.h index 6e9ebc3f741..4250243a44d 100644 --- a/include/file.h +++ b/include/file.h @@ -36,8 +36,8 @@ extern HFILE FILE_DupUnixHandle( int fd, DWORD access ); extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info ); extern HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 ); extern 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 ); extern HFILE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa ); extern LPVOID FILE_dommap( int unix_handle, LPVOID start, diff --git a/include/options.h b/include/options.h index 8bd15f8b507..d05fde39172 100644 --- a/include/options.h +++ b/include/options.h @@ -62,8 +62,6 @@ struct options char *dllFlags; /* -dll flags (hack for Winelib support) */ int synchronous; /* X synchronous mode */ int debug; - int failReadOnly; /* Opening a read only file will fail - if write access is requested */ WINE_LANGUAGE language; /* Current language */ int managed; /* Managed windows */ char * configFileName; /* Command line config file */ diff --git a/misc/main.c b/misc/main.c index 69152a2885b..9214206b245 100644 --- a/misc/main.c +++ b/misc/main.c @@ -90,7 +90,6 @@ struct options Options = NULL, /* dllFlags */ FALSE, /* synchronous */ FALSE, /* debug */ - FALSE, /* failReadOnly */ 0, /* language */ FALSE, /* Managed windows */ NULL /* Alternate config file name */ diff --git a/misc/options.c b/misc/options.c index c86e7d4f41c..b2c613d5348 100644 --- a/misc/options.c +++ b/misc/options.c @@ -49,8 +49,6 @@ static const struct option option_table[] = "--dll name Enable or disable built-in DLLs" }, { "dosver", 0, 1, VERSION_ParseDosVersion, "--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 Show this help message" }, { "language", 0, 1, MAIN_ParseLanguageOption, @@ -89,11 +87,6 @@ static void do_debug( const char *arg ) Options.debug = TRUE; } -static void do_failreadonly( const char *arg ) -{ - Options.failReadOnly = TRUE; -} - static void do_desktop( const char *arg ) { Options.desktopGeometry = strdup( arg ); diff --git a/misc/registry.c b/misc/registry.c index 76c71b9880f..66754d21fa1 100644 --- a/misc/registry.c +++ b/misc/registry.c @@ -203,7 +203,7 @@ static void save_key( HKEY hkey, const char *filename ) { sprintf( p, "reg%04x.tmp", count++ ); 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 ((ret = GetLastError()) != ERROR_ALREADY_EXISTS) break; } @@ -628,7 +628,7 @@ static int _wine_loadsubreg( FILE *F, HKEY hkey, const char *fn ) { HANDLE file; 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(); req->hkey = hkey;