Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Johnny Cai
wine
Commits
e6b5e38b
Commit
e6b5e38b
authored
26 years ago
by
Uwe Bonnes
Committed by
Alexandre Julliard
26 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Try to implement the OF_SHARE_XXX options.
Move the mode translations to functions.
parent
75175345
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
files/file.c
+320
-29
320 additions, 29 deletions
files/file.c
with
320 additions
and
29 deletions
files/file.c
+
320
−
29
View file @
e6b5e38b
...
...
@@ -88,6 +88,7 @@ HFILE32 FILE_Alloc( FILE_OBJECT **file )
(
*
file
)
->
unix_name
=
NULL
;
(
*
file
)
->
type
=
FILE_TYPE_DISK
;
(
*
file
)
->
pos
=
0
;
(
*
file
)
->
mode
=
0
;
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
&
(
*
file
)
->
header
,
FILE_ALL_ACCESS
|
GENERIC_READ
|
...
...
@@ -228,6 +229,259 @@ int FILE_GetUnixHandle( HFILE32 hFile )
return
ret
;
}
/***********************************************************************
* FILE_UnixToDosMode
*
* PARAMS
* unixmode[I]
* RETURNS
* dosmode
*/
static
int
FILE_UnixToDosMode
(
int
unixMode
)
{
int
dosMode
;
switch
(
unixMode
&
3
)
{
case
O_WRONLY
:
dosMode
=
OF_WRITE
;
break
;
case
O_RDWR
:
dosMode
=
OF_READWRITE
;
break
;
case
O_RDONLY
:
default:
dosMode
=
OF_READ
;
break
;
}
return
dosMode
;
}
/***********************************************************************
* FILE_DOSToUnixMode
*
* PARAMS
* dosMode[I]
* RETURNS
* unixmode
*/
static
int
FILE_DOSToUnixMode
(
int
dosMode
)
{
int
unixMode
;
switch
(
dosMode
&
3
)
{
case
OF_WRITE
:
unixMode
=
O_WRONLY
;
break
;
case
OF_READWRITE
:
unixMode
=
O_RDWR
;
break
;
case
OF_READ
:
default:
unixMode
=
O_RDONLY
;
break
;
}
return
unixMode
;
}
/***********************************************************************
* FILE_ShareDeny
*
* PARAMS
* oldmode[I] mode how file was first opened
* mode[I] mode how the file should get opened
* RETURNS
* TRUE: deny open
* FALSE: allow open
*
* Look what we have to do with the given SHARE modes
*
* Ralph Brown's interrupt list gives following explication, I guess
* the same holds for Windows, DENY ALL should be OF_SHARE_COMPAT
*
* FIXME: Validate this function
========from Ralph Brown's list =========
(Table 0750)
Values of DOS file sharing behavior:
| Second and subsequent Opens
First |Compat Deny Deny Deny Deny
Open | All Write Read None
|R W RW R W RW R W RW R W RW R W RW
- - - - -| - - - - - - - - - - - - - - - - -
Compat R |Y Y Y N N N 1 N N N N N 1 N N
W |Y Y Y N N N N N N N N N N N N
RW|Y Y Y N N N N N N N N N N N N
- - - - -|
Deny R |C C C N N N N N N N N N N N N
All W |C C C N N N N N N N N N N N N
RW|C C C N N N N N N N N N N N N
- - - - -|
Deny R |2 C C N N N Y N N N N N Y N N
Write W |C C C N N N N N N Y N N Y N N
RW|C C C N N N N N N N N N Y N N
- - - - -|
Deny R |C C C N N N N Y N N N N N Y N
Read W |C C C N N N N N N N Y N N Y N
RW|C C C N N N N N N N N N N Y N
- - - - -|
Deny R |2 C C N N N Y Y Y N N N Y Y Y
None W |C C C N N N N N N Y Y Y Y Y Y
RW|C C C N N N N N N N N N Y Y Y
Legend: Y = open succeeds, N = open fails with error code 05h
C = open fails, INT 24 generated
1 = open succeeds if file read-only, else fails with error code
2 = open succeeds if file read-only, else fails with INT 24
========end of description from Ralph Brown's List =====
For every "Y" in the table we return FALSE
For every "N" we set the DOS_ERROR and return TRUE
For all other cases we barf,set the DOS_ERROR and return TRUE
*/
static
BOOL32
FILE_ShareDeny
(
int
mode
,
int
oldmode
)
{
int
oldsharemode
=
oldmode
&
0x70
;
int
sharemode
=
mode
&
0x70
;
int
oldopenmode
=
oldmode
&
3
;
int
openmode
=
mode
&
3
;
switch
(
oldsharemode
)
{
case
OF_SHARE_COMPAT
:
if
(
sharemode
==
OF_SHARE_COMPAT
)
return
FALSE
;
if
(
openmode
==
OF_READ
)
goto
test_ro_err05
;
goto
fail_error05
;
case
OF_SHARE_EXCLUSIVE
:
if
(
sharemode
==
OF_SHARE_COMPAT
)
goto
fail_int24
;
goto
fail_error05
;
case
OF_SHARE_DENY_WRITE
:
if
(
openmode
!=
OF_READ
)
{
if
(
sharemode
==
OF_SHARE_COMPAT
)
goto
fail_int24
;
goto
fail_error05
;
}
switch
(
sharemode
)
{
case
OF_SHARE_COMPAT
:
if
(
oldopenmode
==
OF_READ
)
goto
test_ro_int24
;
goto
fail_int24
;
case
OF_SHARE_DENY_NONE
:
return
FALSE
;
case
OF_SHARE_DENY_WRITE
:
if
(
oldopenmode
==
OF_READ
)
return
FALSE
;
case
OF_SHARE_DENY_READ
:
if
(
oldopenmode
==
OF_WRITE
)
return
FALSE
;
case
OF_SHARE_EXCLUSIVE
:
default:
goto
fail_error05
;
}
break
;
case
OF_SHARE_DENY_READ
:
if
(
openmode
!=
OF_WRITE
)
{
if
(
sharemode
==
OF_SHARE_COMPAT
)
goto
fail_int24
;
goto
fail_error05
;
}
switch
(
sharemode
)
{
case
OF_SHARE_COMPAT
:
goto
fail_int24
;
case
OF_SHARE_DENY_NONE
:
return
FALSE
;
case
OF_SHARE_DENY_WRITE
:
if
(
oldopenmode
==
OF_READ
)
return
FALSE
;
case
OF_SHARE_DENY_READ
:
if
(
oldopenmode
==
OF_WRITE
)
return
FALSE
;
case
OF_SHARE_EXCLUSIVE
:
default:
goto
fail_error05
;
}
break
;
case
OF_SHARE_DENY_NONE
:
switch
(
sharemode
)
{
case
OF_SHARE_COMPAT
:
goto
fail_int24
;
case
OF_SHARE_DENY_NONE
:
return
FALSE
;
case
OF_SHARE_DENY_WRITE
:
if
(
oldopenmode
==
OF_READ
)
return
FALSE
;
case
OF_SHARE_DENY_READ
:
if
(
oldopenmode
==
OF_WRITE
)
return
FALSE
;
case
OF_SHARE_EXCLUSIVE
:
default:
goto
fail_error05
;
}
default:
ERR
(
file
,
"unknown mode
\n
"
);
}
ERR
(
file
,
"shouldn't happen
\n
"
);
ERR
(
file
,
"Please report to bon@elektron.ikp.physik.tu-darmstadt.de
\n
"
);
return
TRUE
;
test_ro_int24:
FIXME
(
file
,
"test if file is RO missing
\n
"
);
/* Fall through */
fail_int24:
FIXME
(
file
,
"generate INT24 missing
\n
"
);
/* Is this the right error? */
DOS_ERROR
(
ER_AccessDenied
,
EC_AccessDenied
,
SA_Abort
,
EL_Disk
);
return
TRUE
;
test_ro_err05:
FIXME
(
file
,
"test if file is RO missing
\n
"
);
/* fall through */
fail_error05:
DOS_ERROR
(
ER_AccessDenied
,
EC_AccessDenied
,
SA_Abort
,
EL_Disk
);
return
TRUE
;
}
/***********************************************************************
*
*
* Look if the File is in Use For the OF_SHARE_XXX options
*
* PARAMS
* name [I]: full unix name of the file that should be opened
* mode [O]: mode how the file was first opened
* RETURNS
* TRUE if the file was opened before
* FALSE if we open the file exclusive for this process
*
* Scope of the files we look for is only the current pdb
* Could we use /proc/self/? on Linux for this?
* Should we use flock? Should we create another structure?
* Searching through all files seem quite expensive for me, but
* I don't see any other way.
*
* FIXME: Extend scope to the whole Wine process
*
*/
static
BOOL32
FILE_InUse
(
char
*
name
,
int
*
mode
)
{
FILE_OBJECT
*
file
;
int
i
;
HGLOBAL16
hPDB
=
GetCurrentPDB
();
PDB
*
pdb
=
(
PDB
*
)
GlobalLock16
(
hPDB
);
if
(
!
pdb
)
return
0
;
for
(
i
=
0
;
i
<
pdb
->
nbFiles
;
i
++
)
{
file
=
FILE_GetFile
(
(
HFILE32
)
i
);
if
(
file
)
{
if
(
file
->
unix_name
)
{
TRACE
(
file
,
"got %s at %d
\n
"
,
file
->
unix_name
,
i
);
if
(
!
lstrcmp32A
(
file
->
unix_name
,
name
))
{
*
mode
=
file
->
mode
;
FILE_ReleaseFile
(
file
);
return
TRUE
;
}
FILE_ReleaseFile
(
file
);
}
}
}
return
FALSE
;
}
/***********************************************************************
* FILE_SetDosError
...
...
@@ -354,6 +608,11 @@ HFILE32 FILE_Open( LPCSTR path, INT32 mode )
{
DOS_FULL_NAME
full_name
;
const
char
*
unixName
;
int
oldMode
,
dosMode
;
/* FIXME: Do we really need unixmode as argument for
FILE_Open */
FILE_OBJECT
*
file
;
HFILE32
hFileRet
;
BOOL32
fileInUse
=
FALSE
;
TRACE
(
file
,
"'%s' %04x
\n
"
,
path
,
mode
);
...
...
@@ -380,7 +639,23 @@ HFILE32 FILE_Open( LPCSTR path, INT32 mode )
return
HFILE_ERROR32
;
unixName
=
full_name
.
long_name
;
}
return
FILE_OpenUnixFile
(
unixName
,
mode
);
dosMode
=
FILE_UnixToDosMode
(
mode
);
fileInUse
=
FILE_InUse
(
full_name
.
long_name
,
&
oldMode
);
if
(
fileInUse
)
{
TRACE
(
file
,
"found another instance with mode 0x%02x
\n
"
,
oldMode
&
0x70
);
if
(
FILE_ShareDeny
(
dosMode
,
oldMode
))
return
HFILE_ERROR32
;
}
hFileRet
=
FILE_OpenUnixFile
(
unixName
,
mode
);
/* we need to save the mode, but only if it is not in use yet*/
if
((
hFileRet
)
&&
(
!
fileInUse
)
&&
((
file
=
FILE_GetFile
(
hFileRet
))))
{
file
->
mode
=
dosMode
;
FILE_ReleaseFile
(
file
);
}
return
hFileRet
;
}
...
...
@@ -392,6 +667,9 @@ static HFILE32 FILE_Create( LPCSTR path, int mode, int unique )
HFILE32
handle
;
FILE_OBJECT
*
file
;
DOS_FULL_NAME
full_name
;
BOOL32
fileInUse
=
FALSE
;
int
oldMode
,
dosMode
;
/* FIXME: Do we really need unixmode as argument for
FILE_Create */
;
TRACE
(
file
,
"'%s' %04x %d
\n
"
,
path
,
mode
,
unique
);
...
...
@@ -412,6 +690,15 @@ static HFILE32 FILE_Create( LPCSTR path, int mode, int unique )
CloseHandle
(
handle
);
return
INVALID_HANDLE_VALUE32
;
}
dosMode
=
FILE_UnixToDosMode
(
mode
);
fileInUse
=
FILE_InUse
(
full_name
.
long_name
,
&
oldMode
);
if
(
fileInUse
)
{
TRACE
(
file
,
"found another instance with mode 0x%02x
\n
"
,
oldMode
&
0x70
);
if
(
FILE_ShareDeny
(
dosMode
,
oldMode
))
return
INVALID_HANDLE_VALUE32
;
}
if
((
file
->
unix_handle
=
open
(
full_name
.
long_name
,
O_CREAT
|
O_TRUNC
|
O_RDWR
|
(
unique
?
O_EXCL
:
0
),
mode
))
==
-
1
)
...
...
@@ -424,6 +711,7 @@ static HFILE32 FILE_Create( LPCSTR path, int mode, int unique )
/* File created OK, now fill the FILE_OBJECT */
file
->
unix_name
=
HEAP_strdupA
(
SystemHeap
,
0
,
full_name
.
long_name
);
file
->
mode
=
dosMode
;
return
handle
;
}
...
...
@@ -739,7 +1027,9 @@ static HFILE32 FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT32 mode,
WORD
filedatetime
[
2
];
DOS_FULL_NAME
full_name
;
char
*
p
;
int
unixMode
;
int
unixMode
,
oldMode
;
FILE_OBJECT
*
file
;
BOOL32
fileInUse
=
FALSE
;
if
(
!
ofs
)
return
HFILE_ERROR32
;
...
...
@@ -805,20 +1095,33 @@ found:
lstrcpyn32A
(
ofs
->
szPathName
,
full_name
.
short_name
,
sizeof
(
ofs
->
szPathName
)
);
fileInUse
=
FILE_InUse
(
full_name
.
long_name
,
&
oldMode
);
if
(
fileInUse
)
{
TRACE
(
file
,
"found another instance with mode 0x%02x
\n
"
,
oldMode
&
0x70
);
if
(
FILE_ShareDeny
(
mode
,
oldMode
))
return
HFILE_ERROR32
;
}
if
(
mode
&
OF_SHARE_EXCLUSIVE
)
/* Some InstallShield version uses OF_SHARE_EXCLUSIVE
on the file <tempdir>/_ins0432._mp to determine how
far installation has proceeded.
_ins0432._mp is an executable and while running the
application expects the open with OF_SHARE_ to fail*/
/* Probable FIXME:
As our loader closes the files after loading the executable,
we can't find the running executable with FILE_InUse.
Perhaps the loader should keep the file open.
Recheck against how Win handles that case */
{
char
*
last
=
strrchr
(
full_name
.
long_name
,
'/'
);
if
(
!
last
)
last
=
full_name
.
long_name
-
1
;
/* Some InstallShield version uses OF_SHARE_EXCLUSIVE
on the file <tempdir>/_ins0432._mp to determine how
far installation has proceeded*/
if
(
GetModuleHandle16
(
last
+
1
))
{
TRACE
(
file
,
"Denying shared open for %s
\n
"
,
full_name
.
long_name
);
return
HFILE_ERROR32
;
}
FIXME
(
file
,
"OF_SHARE_EXCLUSIVE only partial implemented
\n
"
);
}
if
(
mode
&
OF_DELETE
)
...
...
@@ -828,19 +1131,17 @@ found:
return
1
;
}
switch
(
mode
&
3
)
{
case
OF_WRITE
:
unixMode
=
O_WRONLY
;
break
;
case
OF_READWRITE
:
unixMode
=
O_RDWR
;
break
;
case
OF_READ
:
default:
unixMode
=
O_RDONLY
;
break
;
}
unixMode
=
FILE_DOSToUnixMode
(
mode
);
hFileRet
=
FILE_OpenUnixFile
(
full_name
.
long_name
,
unixMode
);
if
(
hFileRet
==
HFILE_ERROR32
)
goto
not_found
;
/* we need to save the mode, but only if it is not in use yet*/
if
(
(
!
fileInUse
)
&&
(
file
=
FILE_GetFile
(
hFileRet
)))
{
file
->
mode
=
mode
;
FILE_ReleaseFile
(
file
);
}
GetFileTime
(
hFileRet
,
NULL
,
NULL
,
&
filetime
);
FileTimeToDosDateTime
(
&
filetime
,
&
filedatetime
[
0
],
&
filedatetime
[
1
]
);
if
((
mode
&
OF_VERIFY
)
&&
(
mode
&
OF_REOPEN
))
...
...
@@ -1107,19 +1408,9 @@ HFILE32 WINAPI _lopen32( LPCSTR path, INT32 mode )
TRACE
(
file
,
"('%s',%04x)
\n
"
,
path
,
mode
);
switch
(
mode
&
3
)
{
case
OF_WRITE
:
unixMode
=
O_WRONLY
;
break
;
case
OF_READWRITE
:
unixMode
=
O_RDWR
;
break
;
case
OF_READ
:
default:
unixMode
=
O_RDONLY
;
break
;
}
unixMode
=
FILE_DOSToUnixMode
(
mode
);
unixMode
|=
(
mode
&
0x70
);
/* transfer the OF_SHARE options to handle
them in FILE_Open*/
return
FILE_Open
(
path
,
unixMode
);
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment