Added a per-drive FailReadOnly flag, and removed the global
--failreadonly option.
This commit is contained in:
parent
8a971bfec0
commit
fbace6eefe
|
@ -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
|
||||||
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 )
|
||||||
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 )
|
||||||
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
|
||||||
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)
|
||||||
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 )
|
||||||
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];
|
||||||
|
|
||||||
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 )
|
||||||
|
|
||||||
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;
|
||||||
|
|
30
files/file.c
30
files/file.c
|
@ -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 )
|
||||||
* 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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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:
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
#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 );
|
||||||
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
|
||||||
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 =
|
||||||
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[] =
|
||||||
"--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 )
|
||||||
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 )
|
||||||
{
|
{
|
||||||
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 )
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue