Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
0562539d
Commit
0562539d
authored
Jan 03, 1999
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented file sharing checks in the server.
Added set file time server request. Overall clean up of the file handling (DOS device handling is now broken, should be redone).
parent
74304fc3
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
635 additions
and
702 deletions
+635
-702
dos_fs.c
files/dos_fs.c
+11
-9
file.c
files/file.c
+227
-334
device.h
include/device.h
+1
-1
file.h
include/file.h
+5
-9
server.h
include/server.h
+14
-0
object.h
include/server/object.h
+10
-5
request.h
include/server/request.h
+3
-0
module.c
loader/ne/module.c
+2
-3
pe_image.c
loader/pe_image.c
+2
-2
crtdll.c
misc/crtdll.c
+56
-22
int21.c
msdos/int21.c
+12
-3
vxd.c
msdos/vxd.c
+1
-1
storage.c
ole/storage.c
+6
-3
process.c
scheduler/process.c
+8
-38
change.c
server/change.c
+3
-2
console.c
server/console.c
+12
-2
event.c
server/event.c
+4
-1
file.c
server/file.c
+180
-49
mapping.c
server/mapping.c
+4
-2
mutex.c
server/mutex.c
+3
-1
object.c
server/object.c
+13
-0
pipe.c
server/pipe.c
+12
-2
process.c
server/process.c
+1
-0
request.c
server/request.c
+19
-9
semaphore.c
server/semaphore.c
+3
-1
thread.c
server/thread.c
+3
-2
trace.c
server/trace.c
+18
-2
device.c
win32/device.c
+2
-14
file.c
win32/file.c
+0
-185
No files found.
files/dos_fs.c
View file @
0562539d
...
...
@@ -607,12 +607,10 @@ const DOS_DEVICE *DOSFS_GetDevice( const char *name )
*
* Open a DOS device. This might not map 1:1 into the UNIX device concept.
*/
HFILE32
DOSFS_OpenDevice
(
const
char
*
name
,
int
unixmode
)
HFILE32
DOSFS_OpenDevice
(
const
char
*
name
,
DWORD
access
)
{
int
i
;
const
char
*
p
;
FILE_OBJECT
*
file
;
HFILE32
handle
;
if
(
!
name
)
return
(
HFILE32
)
NULL
;
/* if FILE_DupUnixHandle was used */
if
(
name
[
0
]
&&
(
name
[
1
]
==
':'
))
name
+=
2
;
...
...
@@ -627,15 +625,17 @@ HFILE32 DOSFS_OpenDevice( const char *name, int unixmode )
if
(
!*
p
||
(
*
p
==
'.'
))
{
/* got it */
if
(
!
strcmp
(
DOSFS_Devices
[
i
].
name
,
"NUL"
))
return
FILE_OpenUnixFile
(
"/dev/null"
,
unixmode
);
return
FILE_CreateFile
(
"/dev/null"
,
access
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
0
,
-
1
);
if
(
!
strcmp
(
DOSFS_Devices
[
i
].
name
,
"CON"
))
{
HFILE32
to_dup
;
HFILE32
handle
;
switch
(
unixmode
)
{
case
O_RDONLY
:
switch
(
access
&
(
GENERIC_READ
|
GENERIC_WRITE
)
)
{
case
GENERIC_READ
:
to_dup
=
GetStdHandle
(
STD_INPUT_HANDLE
);
break
;
case
O_WRONLY
:
case
GENERIC_WRITE
:
to_dup
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
break
;
default:
...
...
@@ -651,8 +651,10 @@ HFILE32 DOSFS_OpenDevice( const char *name, int unixmode )
if
(
!
strcmp
(
DOSFS_Devices
[
i
].
name
,
"SCSIMGR$"
)
||
!
strcmp
(
DOSFS_Devices
[
i
].
name
,
"HPSCAN"
))
{
int
fd
=
open
(
"/dev/null"
,
unixmode
);
return
FILE_Alloc
(
&
file
,
fd
,
DOSFS_Devices
[
i
].
name
);
/* FIXME: should keep the name somewhere */
return
FILE_CreateFile
(
"/dev/null"
,
access
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
0
,
-
1
);
}
FIXME
(
dosfs
,
"device open %s not supported (yet)
\n
"
,
DOSFS_Devices
[
i
].
name
);
return
HFILE_ERROR32
;
...
...
files/file.c
View file @
0562539d
...
...
@@ -27,6 +27,7 @@
#include "windows.h"
#include "winerror.h"
#include "drive.h"
#include "device.h"
#include "file.h"
#include "global.h"
#include "heap.h"
...
...
@@ -66,43 +67,6 @@ typedef struct DOS_FILE_LOCK DOS_FILE_LOCK;
static
DOS_FILE_LOCK
*
locks
=
NULL
;
static
void
DOS_RemoveFileLocks
(
FILE_OBJECT
*
file
);
/***********************************************************************
* FILE_Alloc
*
* Allocate a file. The unix_handle is closed.
*/
HFILE32
FILE_Alloc
(
FILE_OBJECT
**
file
,
int
unix_handle
,
const
char
*
unix_name
)
{
HFILE32
handle
;
struct
create_file_request
req
;
struct
create_file_reply
reply
;
req
.
access
=
FILE_ALL_ACCESS
|
GENERIC_READ
|
GENERIC_WRITE
|
GENERIC_EXECUTE
;
/* FIXME */
req
.
inherit
=
1
;
/* FIXME */
CLIENT_SendRequest
(
REQ_CREATE_FILE
,
unix_handle
,
1
,
&
req
,
sizeof
(
req
)
);
CLIENT_WaitSimpleReply
(
&
reply
,
sizeof
(
reply
),
NULL
);
if
(
reply
.
handle
==
-
1
)
return
INVALID_HANDLE_VALUE32
;
*
file
=
HeapAlloc
(
SystemHeap
,
0
,
sizeof
(
FILE_OBJECT
)
);
if
(
!*
file
)
{
DOS_ERROR
(
ER_TooManyOpenFiles
,
EC_ProgramError
,
SA_Abort
,
EL_Disk
);
CLIENT_CloseHandle
(
reply
.
handle
);
return
(
HFILE32
)
NULL
;
}
(
*
file
)
->
header
.
type
=
K32OBJ_FILE
;
(
*
file
)
->
header
.
refcount
=
0
;
(
*
file
)
->
unix_name
=
unix_name
?
HEAP_strdupA
(
SystemHeap
,
0
,
unix_name
)
:
NULL
;
(
*
file
)
->
type
=
FILE_TYPE_DISK
;
(
*
file
)
->
mode
=
0
;
handle
=
HANDLE_Alloc
(
PROCESS_Current
(),
&
(
*
file
)
->
header
,
req
.
access
,
req
.
inherit
,
reply
.
handle
);
/* If the allocation failed, the object is already destroyed */
if
(
handle
==
INVALID_HANDLE_VALUE32
)
*
file
=
NULL
;
return
handle
;
}
/***********************************************************************
...
...
@@ -149,56 +113,32 @@ void FILE_ReleaseFile( FILE_OBJECT *file )
/***********************************************************************
* FILE_
UnixToDos
Mode
* FILE_
ConvertOF
Mode
*
* PARAMS
* unixmode[I]
* RETURNS
* dosmode
* Convert OF_* mode into flags for CreateFile.
*/
static
int
FILE_UnixToDosMode
(
int
unixMode
)
static
void
FILE_ConvertOFMode
(
INT32
mode
,
DWORD
*
access
,
DWORD
*
sharing
)
{
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
;
switch
(
mode
&
0x03
)
{
case
OF_READ
:
*
access
=
GENERIC_READ
;
break
;
case
OF_WRITE
:
*
access
=
GENERIC_WRITE
;
break
;
case
OF_READWRITE
:
*
access
=
GENERIC_READ
|
GENERIC_WRITE
;
break
;
default:
*
access
=
0
;
break
;
}
switch
(
mode
&
0x70
)
{
case
OF_SHARE_EXCLUSIVE
:
*
sharing
=
0
;
break
;
case
OF_SHARE_DENY_WRITE
:
*
sharing
=
FILE_SHARE_READ
;
break
;
case
OF_SHARE_DENY_READ
:
*
sharing
=
FILE_SHARE_WRITE
;
break
;
case
OF_SHARE_DENY_NONE
:
case
OF_SHARE_COMPAT
:
default:
*
sharing
=
FILE_SHARE_READ
|
FILE_SHARE_WRITE
;
break
;
}
}
/***********************************************************************
* 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
;
}
#if 0
/***********************************************************************
* FILE_ShareDeny
*
...
...
@@ -352,58 +292,8 @@ 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
);
#endif
if
(
!
pdb
)
return
0
;
for
(
i
=
0
;
i
<
pdb
->
nbFiles
;
i
++
)
{
file
=
FILE_GetFile
(
(
HFILE32
)
i
,
0
,
NULL
);
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
...
...
@@ -468,164 +358,213 @@ void FILE_SetDosError(void)
*
* Duplicate a Unix handle into a task handle.
*/
HFILE32
FILE_DupUnixHandle
(
int
fd
)
HFILE32
FILE_DupUnixHandle
(
int
fd
,
DWORD
access
)
{
int
unix_handle
;
FILE_OBJECT
*
file
;
int
unix_handle
;
struct
create_file_request
req
;
struct
create_file_reply
reply
;
if
((
unix_handle
=
dup
(
fd
))
==
-
1
)
{
FILE_SetDosError
();
return
INVALID_HANDLE_VALUE32
;
}
return
FILE_Alloc
(
&
file
,
unix_handle
,
NULL
);
req
.
access
=
access
;
req
.
inherit
=
1
;
req
.
sharing
=
FILE_SHARE_READ
|
FILE_SHARE_WRITE
;
req
.
create
=
0
;
req
.
attrs
=
0
;
CLIENT_SendRequest
(
REQ_CREATE_FILE
,
unix_handle
,
1
,
&
req
,
sizeof
(
req
)
);
CLIENT_WaitSimpleReply
(
&
reply
,
sizeof
(
reply
),
NULL
);
if
(
reply
.
handle
==
-
1
)
return
INVALID_HANDLE_VALUE32
;
if
(
!
(
file
=
HeapAlloc
(
SystemHeap
,
0
,
sizeof
(
FILE_OBJECT
)
)))
{
DOS_ERROR
(
ER_TooManyOpenFiles
,
EC_ProgramError
,
SA_Abort
,
EL_Disk
);
CLIENT_CloseHandle
(
reply
.
handle
);
return
(
HFILE32
)
NULL
;
}
file
->
header
.
type
=
K32OBJ_FILE
;
file
->
header
.
refcount
=
0
;
file
->
unix_name
=
NULL
;
return
HANDLE_Alloc
(
PROCESS_Current
(),
&
file
->
header
,
req
.
access
,
req
.
inherit
,
reply
.
handle
);
}
/***********************************************************************
* FILE_OpenUnixFile
* FILE_CreateFile
*
* Implementation of CreateFile. Takes a Unix path name.
*/
HFILE32
FILE_OpenUnixFile
(
const
char
*
name
,
int
mode
)
HFILE32
FILE_CreateFile
(
LPCSTR
filename
,
DWORD
access
,
DWORD
sharing
,
LPSECURITY_ATTRIBUTES
sa
,
DWORD
creation
,
DWORD
attributes
,
HANDLE32
template
)
{
int
unix_handle
;
FILE_OBJECT
*
file
;
struct
stat
st
;
struct
create_file_request
req
;
struct
create_file_reply
reply
;
if
((
unix_handle
=
open
(
name
,
mode
,
0666
))
==
-
1
)
{
if
(
!
Options
.
failReadOnly
&&
(
mode
==
O_RDWR
))
unix_handle
=
open
(
name
,
O_RDONLY
);
}
if
((
unix_handle
==
-
1
)
||
(
fstat
(
unix_handle
,
&
st
)
==
-
1
))
{
FILE_SetDosError
();
return
INVALID_HANDLE_VALUE32
;
}
if
(
S_ISDIR
(
st
.
st_mode
))
req
.
access
=
access
;
req
.
inherit
=
(
sa
&&
(
sa
->
nLength
>=
sizeof
(
*
sa
))
&&
sa
->
bInheritHandle
);
req
.
sharing
=
sharing
;
req
.
create
=
creation
;
req
.
attrs
=
attributes
;
CLIENT_SendRequest
(
REQ_CREATE_FILE
,
-
1
,
2
,
&
req
,
sizeof
(
req
),
filename
,
strlen
(
filename
)
+
1
);
CLIENT_WaitSimpleReply
(
&
reply
,
sizeof
(
reply
),
NULL
);
/* If write access failed, retry without GENERIC_WRITE */
if
((
reply
.
handle
==
-
1
)
&&
!
Options
.
failReadOnly
&&
(
access
&
GENERIC_WRITE
)
&&
(
GetLastError
()
==
ERROR_ACCESS_DENIED
))
{
DOS_ERROR
(
ER_AccessDenied
,
EC_AccessDenied
,
SA_Abort
,
EL_Disk
);
close
(
unix_handle
);
return
INVALID_HANDLE_VALUE32
;
req
.
access
&=
~
GENERIC_WRITE
;
CLIENT_SendRequest
(
REQ_CREATE_FILE
,
-
1
,
2
,
&
req
,
sizeof
(
req
),
filename
,
strlen
(
filename
)
+
1
);
CLIENT_WaitSimpleReply
(
&
reply
,
sizeof
(
reply
),
NULL
);
}
if
(
reply
.
handle
==
-
1
)
return
INVALID_HANDLE_VALUE32
;
/*
File opened OK, now allocate a handle
*/
/*
Now build the FILE_OBJECT
*/
return
FILE_Alloc
(
&
file
,
unix_handle
,
name
);
if
(
!
(
file
=
HeapAlloc
(
SystemHeap
,
0
,
sizeof
(
FILE_OBJECT
)
)))
{
SetLastError
(
ERROR_OUTOFMEMORY
);
CLIENT_CloseHandle
(
reply
.
handle
);
return
(
HFILE32
)
INVALID_HANDLE_VALUE32
;
}
file
->
header
.
type
=
K32OBJ_FILE
;
file
->
header
.
refcount
=
0
;
file
->
unix_name
=
HEAP_strdupA
(
SystemHeap
,
0
,
filename
);
return
HANDLE_Alloc
(
PROCESS_Current
(),
&
file
->
header
,
req
.
access
,
req
.
inherit
,
reply
.
handle
);
}
/***********************************************************************
* FILE_Open
/*************************************************************************
* CreateFile32A [KERNEL32.45] Creates or opens a file or other object
*
* Creates or opens an object, and returns a handle that can be used to
* access that object.
*
* PARAMS
*
* filename [I] pointer to filename to be accessed
* access [I] access mode requested
* sharing [I] share mode
* sa [I] pointer to security attributes
* creation [I] how to create the file
* attributes [I] attributes for newly created file
* template [I] handle to file with extended attributes to copy
*
* RETURNS
* Success: Open handle to specified file
* Failure: INVALID_HANDLE_VALUE
*
* NOTES
* Should call SetLastError() on failure.
*
* path[I] name of file to open
* mode[I] mode how to open, in unix notation
* shareMode[I] the sharing mode in the win OpenFile notation
* BUGS
*
* Doesn't support character devices, pipes, template files, or a
* lot of the 'attributes' flags yet.
*/
HFILE32
FILE_Open
(
LPCSTR
path
,
INT32
mode
,
INT32
shareMode
)
HFILE32
WINAPI
CreateFile32A
(
LPCSTR
filename
,
DWORD
access
,
DWORD
sharing
,
LPSECURITY_ATTRIBUTES
sa
,
DWORD
creation
,
DWORD
attributes
,
HANDLE32
template
)
{
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
;
HANDLE32
to_dup
=
HFILE_ERROR32
;
TRACE
(
file
,
"'%s' %04x
\n
"
,
path
,
mode
);
if
(
!
filename
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
HFILE_ERROR32
;
}
if
(
!
path
)
return
HFILE_ERROR32
;
/* If the name starts with '\\?\', ignore the first 4 chars. */
if
(
!
strncmp
(
filename
,
"
\\\\
?
\\
"
,
4
))
{
filename
+=
4
;
if
(
!
strncmp
(
filename
,
"UNC
\\
"
,
4
))
{
FIXME
(
file
,
"UNC name (%s) not supported.
\n
"
,
filename
);
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
HFILE_ERROR32
;
}
}
if
(
DOSFS_GetDevice
(
path
))
if
(
!
strncmp
(
filename
,
"
\\\\
.
\\
"
,
4
))
return
DEVICE_Open
(
filename
+
4
);
/* If the name still starts with '\\', it's a UNC name. */
if
(
!
strncmp
(
filename
,
"
\\\\
"
,
2
))
{
FIXME
(
file
,
"UNC name (%s) not supported.
\n
"
,
filename
);
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
HFILE_ERROR32
;
}
/* If the name is either CONIN$ or CONOUT$, give them duplicated stdin
* or stdout, respectively. The lower case version is also allowed. Most likely
* this should be a case ignore string compare.
*/
if
(
!
strcasecmp
(
filename
,
"CONIN$"
))
to_dup
=
GetStdHandle
(
STD_INPUT_HANDLE
);
else
if
(
!
strcasecmp
(
filename
,
"CONOUT$"
))
to_dup
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
if
(
to_dup
!=
HFILE_ERROR32
)
{
HFILE32
handle
;
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
to_dup
,
GetCurrentProcess
(),
&
handle
,
access
,
FALSE
,
0
))
handle
=
HFILE_ERROR32
;
return
handle
;
}
if
(
DOSFS_GetDevice
(
filename
))
{
HFILE32
ret
;
TRACE
(
file
,
"opening device '%s'
\n
"
,
path
);
TRACE
(
file
,
"opening device '%s'
\n
"
,
filename
);
if
(
HFILE_ERROR32
!=
(
ret
=
DOSFS_OpenDevice
(
path
,
mode
)))
if
(
HFILE_ERROR32
!=
(
ret
=
DOSFS_OpenDevice
(
filename
,
access
)))
return
ret
;
/* Do not silence this please. It is a critical error. -MM */
ERR
(
file
,
"Couldn't open device '%s'!
\n
"
,
path
);
ERR
(
file
,
"Couldn't open device '%s'!
\n
"
,
filename
);
DOS_ERROR
(
ER_FileNotFound
,
EC_NotFound
,
SA_Abort
,
EL_Disk
);
return
HFILE_ERROR32
;
}
else
/* check for filename, don't check for last entry if creating */
{
if
(
!
DOSFS_GetFullName
(
path
,
!
(
mode
&
O_CREAT
),
&
full_name
))
return
HFILE_ERROR32
;
unixName
=
full_name
.
long_name
;
}
dosMode
=
FILE_UnixToDosMode
(
mode
)
|
shareMode
;
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
,
0
,
NULL
))))
{
file
->
mode
=
dosMode
;
FILE_ReleaseFile
(
file
);
}
return
hFileRet
;
}
/***********************************************************************
* FILE_Create
*/
static
HFILE32
FILE_Create
(
LPCSTR
path
,
int
mode
,
int
unique
)
{
HFILE32
handle
;
int
unix_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
);
if
(
!
path
)
return
INVALID_HANDLE_VALUE32
;
/* check for filename, don't check for last entry if creating */
if
(
!
DOSFS_GetFullName
(
filename
,
(
creation
==
OPEN_EXISTING
)
||
(
creation
==
TRUNCATE_EXISTING
),
&
full_name
))
return
HFILE_ERROR32
;
if
(
DOSFS_GetDevice
(
path
))
{
WARN
(
file
,
"cannot create DOS device '%s'!
\n
"
,
path
);
DOS_ERROR
(
ER_AccessDenied
,
EC_NotFound
,
SA_Abort
,
EL_Disk
);
return
INVALID_HANDLE_VALUE32
;
}
return
FILE_CreateFile
(
full_name
.
long_name
,
access
,
sharing
,
sa
,
creation
,
attributes
,
template
);
}
if
(
!
DOSFS_GetFullName
(
path
,
FALSE
,
&
full_name
))
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
((
unix_handle
=
open
(
full_name
.
long_name
,
O_CREAT
|
O_TRUNC
|
O_RDWR
|
(
unique
?
O_EXCL
:
0
),
mode
))
==
-
1
)
{
FILE_SetDosError
();
return
INVALID_HANDLE_VALUE32
;
}
/* File created OK, now fill the FILE_OBJECT */
if
((
handle
=
FILE_Alloc
(
&
file
,
unix_handle
,
full_name
.
long_name
))
==
INVALID_HANDLE_VALUE32
)
return
INVALID_HANDLE_VALUE32
;
file
->
mode
=
dosMode
;
return
handle
;
/*************************************************************************
* CreateFile32W (KERNEL32.48)
*/
HFILE32
WINAPI
CreateFile32W
(
LPCWSTR
filename
,
DWORD
access
,
DWORD
sharing
,
LPSECURITY_ATTRIBUTES
sa
,
DWORD
creation
,
DWORD
attributes
,
HANDLE32
template
)
{
LPSTR
afn
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
filename
);
HFILE32
res
=
CreateFile32A
(
afn
,
access
,
sharing
,
sa
,
creation
,
attributes
,
template
);
HeapFree
(
GetProcessHeap
(),
0
,
afn
);
return
res
;
}
...
...
@@ -789,23 +728,6 @@ INT32 WINAPI CompareFileTime( LPFILETIME x, LPFILETIME y )
return
0
;
}
/***********************************************************************
* FILE_Dup
*
* dup() function for DOS handles.
*/
HFILE32
FILE_Dup
(
HFILE32
hFile
)
{
HFILE32
handle
;
TRACE
(
file
,
"FILE_Dup for handle %d
\n
"
,
hFile
);
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
hFile
,
GetCurrentProcess
(),
&
handle
,
FILE_ALL_ACCESS
/* FIXME */
,
FALSE
,
0
))
handle
=
HFILE_ERROR32
;
TRACE
(
file
,
"FILE_Dup return handle %d
\n
"
,
handle
);
return
handle
;
}
/***********************************************************************
* FILE_Dup2
...
...
@@ -886,7 +808,8 @@ UINT32 WINAPI GetTempFileName32A( LPCSTR path, LPCSTR prefix, UINT32 unique,
{
do
{
HFILE32
handle
=
FILE_Create
(
buffer
,
0666
,
TRUE
);
HFILE32
handle
=
CreateFile32A
(
buffer
,
GENERIC_WRITE
,
0
,
NULL
,
CREATE_NEW
,
FILE_ATTRIBUTE_NORMAL
,
-
1
);
if
(
handle
!=
INVALID_HANDLE_VALUE32
)
{
/* We created it */
TRACE
(
file
,
"created %s
\n
"
,
...
...
@@ -949,14 +872,11 @@ static HFILE32 FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT32 mode,
FILETIME
filetime
;
WORD
filedatetime
[
2
];
DOS_FULL_NAME
full_name
;
DWORD
access
,
sharing
;
char
*
p
;
int
unixMode
,
oldMode
;
FILE_OBJECT
*
file
;
BOOL32
fileInUse
=
FALSE
;
if
(
!
ofs
)
return
HFILE_ERROR32
;
ofs
->
cBytes
=
sizeof
(
OFSTRUCT
);
ofs
->
nErrCode
=
0
;
if
(
mode
&
OF_REOPEN
)
name
=
ofs
->
szPathName
;
...
...
@@ -973,6 +893,7 @@ static HFILE32 FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT32 mode,
Uwe Bonnes 1997 Apr 2 */
if
(
!
GetFullPathName32A
(
name
,
sizeof
(
ofs
->
szPathName
),
ofs
->
szPathName
,
NULL
))
goto
error
;
FILE_ConvertOFMode
(
mode
,
&
access
,
&
sharing
);
/* OF_PARSE simply fills the structure */
...
...
@@ -990,7 +911,9 @@ static HFILE32 FILE_DoOpenFile( LPCSTR name, OFSTRUCT *ofs, UINT32 mode,
if
(
mode
&
OF_CREATE
)
{
if
((
hFileRet
=
FILE_Create
(
name
,
0666
,
FALSE
))
==
INVALID_HANDLE_VALUE32
)
if
((
hFileRet
=
CreateFile32A
(
name
,
access
,
sharing
,
NULL
,
CREATE_ALWAYS
,
FILE_ATTRIBUTE_NORMAL
,
-
1
))
==
INVALID_HANDLE_VALUE32
)
goto
error
;
goto
success
;
}
...
...
@@ -1018,13 +941,6 @@ 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
...
...
@@ -1054,16 +970,9 @@ found:
return
1
;
}
unixMode
=
FILE_DOSToUnixMode
(
mode
);
hFileRet
=
FILE_OpenUnixFile
(
full_name
.
long_name
,
unixMode
);
hFileRet
=
FILE_CreateFile
(
full_name
.
long_name
,
access
,
sharing
,
NULL
,
OPEN_EXISTING
,
0
,
-
1
);
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
,
0
,
NULL
)))
{
file
->
mode
=
mode
;
FILE_ReleaseFile
(
file
);
}
GetFileTime
(
hFileRet
,
NULL
,
NULL
,
&
filetime
);
FileTimeToDosDateTime
(
&
filetime
,
&
filedatetime
[
0
],
&
filedatetime
[
1
]
);
...
...
@@ -1255,9 +1164,8 @@ UINT16 WINAPI _lread16( HFILE16 hFile, LPVOID buffer, UINT16 count )
*/
HFILE16
WINAPI
_lcreat16
(
LPCSTR
path
,
INT16
attr
)
{
int
mode
=
(
attr
&
1
)
?
0444
:
0666
;
TRACE
(
file
,
"%s %02x
\n
"
,
path
,
attr
);
return
(
HFILE16
)
HFILE32_TO_HFILE16
(
FILE_Create
(
path
,
mode
,
FALSE
));
return
(
HFILE16
)
HFILE32_TO_HFILE16
(
_lcreat32
(
path
,
attr
));
}
...
...
@@ -1266,9 +1174,10 @@ HFILE16 WINAPI _lcreat16( LPCSTR path, INT16 attr )
*/
HFILE32
WINAPI
_lcreat32
(
LPCSTR
path
,
INT32
attr
)
{
int
mode
=
(
attr
&
1
)
?
0444
:
0666
;
TRACE
(
file
,
"%s %02x
\n
"
,
path
,
attr
);
return
FILE_Create
(
path
,
mode
,
FALSE
);
return
CreateFile32A
(
path
,
GENERIC_READ
|
GENERIC_WRITE
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
CREATE_ALWAYS
,
attr
,
-
1
);
}
...
...
@@ -1277,9 +1186,10 @@ HFILE32 WINAPI _lcreat32( LPCSTR path, INT32 attr )
*/
HFILE32
_lcreat_uniq
(
LPCSTR
path
,
INT32
attr
)
{
int
mode
=
(
attr
&
1
)
?
0444
:
0666
;
TRACE
(
file
,
"%s %02x
\n
"
,
path
,
attr
);
return
FILE_Create
(
path
,
mode
,
TRUE
);
return
CreateFile32A
(
path
,
GENERIC_READ
|
GENERIC_WRITE
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
CREATE_NEW
,
attr
,
-
1
);
}
...
...
@@ -1353,12 +1263,11 @@ HFILE16 WINAPI _lopen16( LPCSTR path, INT16 mode )
*/
HFILE32
WINAPI
_lopen32
(
LPCSTR
path
,
INT32
mode
)
{
INT32
unixMode
;
DWORD
access
,
sharing
;
TRACE
(
file
,
"('%s',%04x)
\n
"
,
path
,
mode
);
unixMode
=
FILE_DOSToUnixMode
(
mode
);
return
FILE_Open
(
path
,
unixMode
,
(
mode
&
0x70
));
FILE_ConvertOFMode
(
mode
,
&
access
,
&
sharing
);
return
CreateFile32A
(
path
,
access
,
sharing
,
NULL
,
OPEN_EXISTING
,
0
,
-
1
);
}
...
...
@@ -1573,19 +1482,6 @@ BOOL32 WINAPI DeleteFile32W( LPCWSTR path )
/***********************************************************************
* FILE_SetFileType
*/
BOOL32
FILE_SetFileType
(
HFILE32
hFile
,
DWORD
type
)
{
FILE_OBJECT
*
file
=
FILE_GetFile
(
hFile
,
0
,
NULL
);
if
(
!
file
)
return
FALSE
;
file
->
type
=
type
;
FILE_ReleaseFile
(
file
);
return
TRUE
;
}
/***********************************************************************
* FILE_dommap
*/
LPVOID
FILE_dommap
(
int
unix_handle
,
LPVOID
start
,
...
...
@@ -1681,10 +1577,16 @@ int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low )
*/
DWORD
WINAPI
GetFileType
(
HFILE32
hFile
)
{
FILE_OBJECT
*
file
=
FILE_GetFile
(
hFile
,
0
,
NULL
);
if
(
!
file
)
return
FILE_TYPE_UNKNOWN
;
/* FIXME: correct? */
FILE_ReleaseFile
(
file
);
return
file
->
type
;
struct
get_file_info_request
req
;
struct
get_file_info_reply
reply
;
if
((
req
.
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
hFile
,
K32OBJ_FILE
,
0
))
==
-
1
)
return
FILE_TYPE_UNKNOWN
;
CLIENT_SendRequest
(
REQ_GET_FILE_INFO
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
if
(
CLIENT_WaitSimpleReply
(
&
reply
,
sizeof
(
reply
),
NULL
))
return
FILE_TYPE_UNKNOWN
;
return
reply
.
type
;
}
...
...
@@ -1859,7 +1761,9 @@ BOOL32 WINAPI CopyFile32A( LPCSTR source, LPCSTR dest, BOOL32 fail_if_exists )
return
FALSE
;
}
mode
=
(
info
.
dwFileAttributes
&
FILE_ATTRIBUTE_READONLY
)
?
0444
:
0666
;
if
((
h2
=
FILE_Create
(
dest
,
mode
,
fail_if_exists
))
==
HFILE_ERROR32
)
if
((
h2
=
CreateFile32A
(
dest
,
GENERIC_WRITE
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
fail_if_exists
?
CREATE_NEW
:
CREATE_ALWAYS
,
info
.
dwFileAttributes
,
h1
))
==
HFILE_ERROR32
)
{
CloseHandle
(
h1
);
return
FALSE
;
...
...
@@ -1959,33 +1863,22 @@ BOOL32 WINAPI SetFileTime( HFILE32 hFile,
const
FILETIME
*
lpLastAccessTime
,
const
FILETIME
*
lpLastWriteTime
)
{
FILE_OBJECT
*
file
=
FILE_GetFile
(
hFile
,
0
,
NULL
);
struct
utimbuf
utimbuf
;
if
(
!
file
)
return
FILE_TYPE_UNKNOWN
;
/* FIXME: correct? */
TRACE
(
file
,
"('%s',%p,%p,%p)
\n
"
,
file
->
unix_name
,
lpCreationTime
,
lpLastAccessTime
,
lpLastWriteTime
);
struct
set_file_time_request
req
;
if
((
req
.
handle
=
HANDLE_GetServerHandle
(
PROCESS_Current
(),
hFile
,
K32OBJ_FILE
,
GENERIC_WRITE
))
==
-
1
)
return
FALSE
;
if
(
lpLastAccessTime
)
utimbuf
.
actime
=
DOSFS_FileTimeToUnixTime
(
lpLastAccessTime
,
NULL
);
req
.
access_time
=
DOSFS_FileTimeToUnixTime
(
lpLastAccessTime
,
NULL
);
else
utimbuf
.
actime
=
0
;
/* FIXME */
req
.
access_time
=
0
;
/* FIXME */
if
(
lpLastWriteTime
)
utimbuf
.
modtime
=
DOSFS_FileTimeToUnixTime
(
lpLastWriteTime
,
NULL
);
req
.
write_time
=
DOSFS_FileTimeToUnixTime
(
lpLastWriteTime
,
NULL
);
else
utimbuf
.
modtime
=
0
;
/* FIXME */
if
(
-
1
==
utime
(
file
->
unix_name
,
&
utimbuf
))
{
MSG
(
"Couldn't set the time for file '%s'. Insufficient permissions !?
\n
"
,
file
->
unix_name
);
FILE_ReleaseFile
(
file
);
FILE_SetDosError
();
return
FALSE
;
}
FILE_ReleaseFile
(
file
);
return
TRUE
;
req
.
write_time
=
0
;
/* FIXME */
CLIENT_SendRequest
(
REQ_SET_FILE_TIME
,
-
1
,
1
,
&
req
,
sizeof
(
req
)
);
return
!
CLIENT_WaitReply
(
NULL
,
NULL
,
0
);
}
/* Locks need to be mirrored because unix file locking is based
...
...
include/device.h
View file @
0562539d
#ifndef __WINE_DEVICE_H
#define __WINE_DEVICE_H
extern
HANDLE32
DEVICE_Open
(
LPCSTR
name
,
DWORD
flags
);
extern
HANDLE32
DEVICE_Open
(
LPCSTR
name
);
#endif
include/file.h
View file @
0562539d
...
...
@@ -17,9 +17,7 @@
typedef
struct
{
K32OBJ
header
;
int
mode
;
char
*
unix_name
;
DWORD
type
;
/* Type for win32 apps */
}
FILE_OBJECT
;
/* Definition of a full DOS file name */
...
...
@@ -60,15 +58,13 @@ typedef struct
extern
FILE_OBJECT
*
FILE_GetFile
(
HFILE32
handle
,
DWORD
access
,
int
*
server_handle
);
extern
void
FILE_ReleaseFile
(
FILE_OBJECT
*
file
);
extern
HFILE32
FILE_Alloc
(
FILE_OBJECT
**
file
,
int
unix_handle
,
const
char
*
unix_name
);
extern
void
FILE_SetDosError
(
void
);
extern
HFILE32
FILE_DupUnixHandle
(
int
fd
);
extern
HFILE32
FILE_DupUnixHandle
(
int
fd
,
DWORD
access
);
extern
BOOL32
FILE_Stat
(
LPCSTR
unixName
,
BY_HANDLE_FILE_INFORMATION
*
info
);
extern
HFILE32
FILE_Dup
(
HFILE32
hFile
);
extern
HFILE32
FILE_Dup2
(
HFILE32
hFile1
,
HFILE32
hFile2
);
extern
HFILE32
FILE_
Open
(
LPCSTR
path
,
INT32
mode
,
INT32
sharemode
);
extern
HFILE32
FILE_OpenUnixFile
(
LPCSTR
path
,
INT32
mode
);
extern
BOOL32
FILE_SetFileType
(
HFILE32
hFile
,
DWORD
typ
e
);
extern
HFILE32
FILE_
CreateFile
(
LPCSTR
filename
,
DWORD
access
,
DWORD
sharing
,
LPSECURITY_ATTRIBUTES
sa
,
DWORD
creation
,
DWORD
attributes
,
HANDLE32
templat
e
);
extern
LPVOID
FILE_dommap
(
int
unix_handle
,
LPVOID
start
,
DWORD
size_high
,
DWORD
size_low
,
DWORD
offset_high
,
DWORD
offset_low
,
...
...
@@ -89,7 +85,7 @@ extern void DOSFS_UnixTimeToFileTime( time_t unixtime, LPFILETIME ft,
extern
time_t
DOSFS_FileTimeToUnixTime
(
const
FILETIME
*
ft
,
DWORD
*
remainder
);
extern
BOOL32
DOSFS_ToDosFCBFormat
(
LPCSTR
name
,
LPSTR
buffer
);
extern
const
DOS_DEVICE
*
DOSFS_GetDevice
(
const
char
*
name
);
extern
HFILE32
DOSFS_OpenDevice
(
const
char
*
name
,
INT32
mode
);
extern
HFILE32
DOSFS_OpenDevice
(
const
char
*
name
,
DWORD
access
);
extern
BOOL32
DOSFS_FindUnixName
(
LPCSTR
path
,
LPCSTR
name
,
LPSTR
long_buf
,
INT32
long_len
,
LPSTR
short_buf
,
BOOL32
ignore_case
);
...
...
include/server.h
View file @
0562539d
...
...
@@ -255,6 +255,10 @@ struct create_file_request
{
unsigned
int
access
;
/* wanted access rights */
int
inherit
;
/* inherit flag */
unsigned
int
sharing
;
/* sharing flags */
int
create
;
/* file create action */
unsigned
int
attrs
;
/* file attributes for creation */
char
name
[
0
];
/* file name */
};
struct
create_file_reply
{
...
...
@@ -298,6 +302,15 @@ struct truncate_file_request
};
/* Set a file access and modification times */
struct
set_file_time_request
{
int
handle
;
/* handle to the file */
time_t
access_time
;
/* last access time */
time_t
write_time
;
/* last write time */
};
/* Flush a file buffers */
struct
flush_file_request
{
...
...
@@ -312,6 +325,7 @@ struct get_file_info_request
};
struct
get_file_info_reply
{
int
type
;
/* file type */
int
attr
;
/* file attributes */
time_t
access_time
;
/* last access time */
time_t
write_time
;
/* last write time */
...
...
include/server/object.h
View file @
0562539d
...
...
@@ -23,6 +23,7 @@ struct thread;
struct
file
;
struct
wait_queue_entry
;
/* operations valid on all objects */
struct
object_ops
{
/* dump the object (for debugging) */
...
...
@@ -40,7 +41,9 @@ struct object_ops
/* return a Unix fd that can be used to write to the object */
int
(
*
get_write_fd
)(
struct
object
*
);
/* flush the object buffers */
int
(
*
flush
)(
struct
object
*
);
int
(
*
flush
)(
struct
object
*
);
/* get file information */
int
(
*
get_file_info
)(
struct
object
*
,
struct
get_file_info_reply
*
);
/* destroy on refcount == 0 */
void
(
*
destroy
)(
struct
object
*
);
};
...
...
@@ -57,8 +60,8 @@ struct object
extern
void
*
mem_alloc
(
size_t
size
);
/* malloc wrapper */
extern
struct
object
*
create_named_object
(
const
char
*
name
,
const
struct
object_ops
*
ops
,
size_t
size
);
extern
int
init_object
(
struct
object
*
obj
,
const
struct
object_ops
*
ops
,
const
char
*
name
);
extern
int
init_object
(
struct
object
*
obj
,
const
struct
object_ops
*
ops
,
const
char
*
name
);
extern
const
char
*
get_object_name
(
struct
object
*
obj
);
/* grab/release_object can take any pointer, but you better make sure */
/* that the thing pointed to starts with a struct object... */
extern
struct
object
*
grab_object
(
void
*
obj
);
...
...
@@ -69,6 +72,7 @@ extern int no_satisfied( struct object *obj, struct thread *thread );
extern
int
no_read_fd
(
struct
object
*
obj
);
extern
int
no_write_fd
(
struct
object
*
obj
);
extern
int
no_flush
(
struct
object
*
obj
);
extern
int
no_get_file_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
info
);
extern
void
default_select_event
(
int
fd
,
int
event
,
void
*
private
);
/* request handlers */
...
...
@@ -172,13 +176,14 @@ extern int release_semaphore( int handle, unsigned int count, unsigned int *prev
/* file functions */
extern
struct
object
*
create_file
(
int
fd
);
extern
struct
object
*
create_file
(
int
fd
,
const
char
*
name
,
unsigned
int
access
,
unsigned
int
sharing
,
int
create
,
unsigned
int
attrs
);
extern
struct
file
*
get_file_obj
(
struct
process
*
process
,
int
handle
,
unsigned
int
access
);
extern
int
file_get_mmap_fd
(
struct
file
*
file
);
extern
int
set_file_pointer
(
int
handle
,
int
*
low
,
int
*
high
,
int
whence
);
extern
int
truncate_file
(
int
handle
);
extern
int
get_file_info
(
int
handle
,
struct
get_file_info_reply
*
reply
);
extern
int
set_file_time
(
int
handle
,
time_t
access_time
,
time_t
write_time
);
extern
void
file_set_error
(
void
);
...
...
include/server/request.h
View file @
0562539d
...
...
@@ -28,6 +28,7 @@ enum request
REQ_GET_WRITE_FD
,
REQ_SET_FILE_POINTER
,
REQ_TRUNCATE_FILE
,
REQ_SET_FILE_TIME
,
REQ_FLUSH_FILE
,
REQ_GET_FILE_INFO
,
REQ_CREATE_PIPE
,
...
...
@@ -67,6 +68,7 @@ DECL_HANDLER(get_read_fd);
DECL_HANDLER
(
get_write_fd
);
DECL_HANDLER
(
set_file_pointer
);
DECL_HANDLER
(
truncate_file
);
DECL_HANDLER
(
set_file_time
);
DECL_HANDLER
(
flush_file
);
DECL_HANDLER
(
get_file_info
);
DECL_HANDLER
(
create_pipe
);
...
...
@@ -103,6 +105,7 @@ static const struct handler {
{
(
void
(
*
)())
req_get_write_fd
,
sizeof
(
struct
get_write_fd_request
)
},
{
(
void
(
*
)())
req_set_file_pointer
,
sizeof
(
struct
set_file_pointer_request
)
},
{
(
void
(
*
)())
req_truncate_file
,
sizeof
(
struct
truncate_file_request
)
},
{
(
void
(
*
)())
req_set_file_time
,
sizeof
(
struct
set_file_time_request
)
},
{
(
void
(
*
)())
req_flush_file
,
sizeof
(
struct
flush_file_request
)
},
{
(
void
(
*
)())
req_get_file_info
,
sizeof
(
struct
get_file_info_request
)
},
{
(
void
(
*
)())
req_create_pipe
,
sizeof
(
struct
create_pipe_request
)
},
...
...
loader/ne/module.c
View file @
0562539d
...
...
@@ -397,7 +397,6 @@ BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset )
*/
HANDLE32
NE_OpenFile
(
NE_MODULE
*
pModule
)
{
DOS_FULL_NAME
full_name
;
char
*
name
;
static
HANDLE32
cachedfd
=
-
1
;
...
...
@@ -408,8 +407,8 @@ HANDLE32 NE_OpenFile( NE_MODULE *pModule )
CloseHandle
(
cachedfd
);
pCachedModule
=
pModule
;
name
=
NE_MODULE_NAME
(
pModule
);
if
(
!
DOSFS_GetFullName
(
name
,
TRUE
,
&
full_name
)
||
(
cachedfd
=
FILE_OpenUnixFile
(
full_name
.
long_name
,
O_RDONLY
))
==
-
1
)
if
(
(
cachedfd
=
CreateFile32A
(
name
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
0
,
-
1
))
==
-
1
)
MSG
(
"Can't open file '%s' for module %04x
\n
"
,
name
,
pModule
->
self
);
else
/* FIXME: should not be necessary */
...
...
loader/pe_image.c
View file @
0562539d
...
...
@@ -475,7 +475,7 @@ static HMODULE32 PE_LoadImage( LPCSTR name, OFSTRUCT *ofs )
if
(
!
strchr
(
p
,
'.'
))
strcat
(
dllname
,
".DLL"
);
/* Open PE file */
hFile
=
OpenFile32
(
dllname
,
ofs
,
OF_READ
);
hFile
=
OpenFile32
(
dllname
,
ofs
,
OF_READ
|
OF_SHARE_DENY_WRITE
);
if
(
hFile
==
HFILE_ERROR32
)
{
WARN
(
win32
,
"OpenFile error %ld
\n
"
,
GetLastError
()
);
...
...
@@ -868,7 +868,7 @@ HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line,
if
((
hModule32
=
PE_LoadImage
(
name
,
&
ofs
))
<
32
)
return
hModule32
;
if
(
PE_HEADER
(
hModule32
)
->
FileHeader
.
Characteristics
&
IMAGE_FILE_DLL
)
return
11
;
return
20
;
/* FIXME: not the right error code */
/* Create 16-bit dummy module */
if
((
hModule16
=
MODULE_CreateDummyModule
(
&
ofs
))
<
32
)
return
hModule16
;
...
...
misc/crtdll.c
View file @
0562539d
...
...
@@ -296,23 +296,37 @@ CRTDLL_FILE * __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
file=fopen(full_name.long_name ,mode);
#endif
INT32
flagmode
=
0
;
DWORD
access
=
0
,
creation
=
0
;
if
((
strchr
(
mode
,
'r'
)
&&
strchr
(
mode
,
'a'
))
||
(
strchr
(
mode
,
'r'
)
&&
strchr
(
mode
,
'w'
))
||
(
strchr
(
mode
,
'w'
)
&&
strchr
(
mode
,
'a'
)))
return
NULL
;
if
(
strstr
(
mode
,
"r+"
))
flagmode
=
O_RDWR
;
else
if
(
strchr
(
mode
,
'r'
))
flagmode
=
O_RDONLY
;
else
if
(
strstr
(
mode
,
"w+"
))
flagmode
=
O_RDWR
|
O_TRUNC
|
O_CREAT
;
else
if
(
strchr
(
mode
,
'w'
))
flagmode
=
O_WRONLY
|
O_TRUNC
|
O_CREAT
;
else
if
(
strstr
(
mode
,
"a+"
))
flagmode
=
O_RDWR
|
O_CREAT
|
O_APPEND
;
else
if
(
strchr
(
mode
,
'w'
))
flagmode
=
O_RDWR
|
O_CREAT
|
O_APPEND
;
else
if
(
strchr
(
mode
,
'b'
))
TRACE
(
crtdll
,
"%s in BINARY mode
\n
"
,
path
);
if
((
handle
=
FILE_Open
(
path
,
flagmode
,
0
))
!=
INVALID_HANDLE_VALUE32
)
if
(
mode
[
0
]
==
'r'
)
{
access
=
GENERIC_READ
;
creation
=
OPEN_EXISTING
;
if
(
mode
[
1
]
==
'+'
)
access
|=
GENERIC_WRITE
;
}
else
if
(
mode
[
0
]
==
'w'
)
{
access
=
GENERIC_WRITE
;
creation
=
CREATE_ALWAYS
;
if
(
mode
[
1
]
==
'+'
)
access
|=
GENERIC_READ
;
}
else
if
(
mode
[
0
]
==
'a'
)
{
/* FIXME: there is no O_APPEND in CreateFile, should emulate it */
access
=
GENERIC_WRITE
;
creation
=
OPEN_ALWAYS
;
if
(
mode
[
1
]
==
'+'
)
access
|=
GENERIC_READ
;
}
/* FIXME: should handle text/binary mode */
if
((
handle
=
CreateFile32A
(
path
,
access
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
creation
,
FILE_ATTRIBUTE_NORMAL
,
-
1
))
!=
INVALID_HANDLE_VALUE32
)
{
file
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
file
)
);
file
->
handle
=
handle
;
...
...
@@ -1181,8 +1195,8 @@ int __cdecl CRTDLL__stat(const char * filename, struct win_stat * buf)
*/
HFILE32
__cdecl
CRTDLL__open
(
LPCSTR
path
,
INT32
flags
)
{
HFILE32
ret
=
0
;
int
wineflags
=
0
;
DWORD
access
=
0
,
creation
=
0
;
HFILE32
ret
;
/* FIXME:
the flags in lcc's header differ from the ones in Linux, e.g.
...
...
@@ -1191,18 +1205,38 @@ HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags)
so here a scheme to translate them
Probably lcc is wrong here, but at least a hack to get is going
*/
wineflags
=
(
flags
&
3
);
if
(
flags
&
0x0008
)
wineflags
|=
O_APPEND
;
if
(
flags
&
0x0100
)
wineflags
|=
O_CREAT
;
if
(
flags
&
0x0200
)
wineflags
|=
O_TRUNC
;
if
(
flags
&
0x0400
)
wineflags
|=
O_EXCL
;
if
(
flags
&
0xf0f4
)
switch
(
flags
&
3
)
{
case
O_RDONLY
:
access
|=
GENERIC_READ
;
break
;
case
O_WRONLY
:
access
|=
GENERIC_WRITE
;
break
;
case
O_RDWR
:
access
|=
GENERIC_WRITE
|
GENERIC_READ
;
break
;
}
if
(
flags
&
0x0100
)
/* O_CREAT */
{
if
(
flags
&
0x0400
)
/* O_EXCL */
creation
=
CREATE_NEW
;
else
if
(
flags
&
0x0200
)
/* O_TRUNC */
creation
=
CREATE_ALWAYS
;
else
creation
=
OPEN_ALWAYS
;
}
else
/* no O_CREAT */
{
if
(
flags
&
0x0200
)
/* O_TRUNC */
creation
=
TRUNCATE_EXISTING
;
else
creation
=
OPEN_EXISTING
;
}
if
(
flags
&
0x0008
)
/* O_APPEND */
FIXME
(
crtdll
,
"O_APPEND not supported
\n
"
);
if
(
flags
&
0xf0f4
)
TRACE
(
crtdll
,
"CRTDLL_open file unsupported flags 0x%04x
\n
"
,
flags
);
/* End Fixme */
ret
=
FILE_Open
(
path
,
wineflags
,
0
);
TRACE
(
crtdll
,
"CRTDLL_open file %s mode 0x%04x (lccmode 0x%04x) got dfh %d
\n
"
,
path
,
wineflags
,
flags
,
ret
);
ret
=
CreateFile32A
(
path
,
access
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
creation
,
FILE_ATTRIBUTE_NORMAL
,
-
1
);
TRACE
(
crtdll
,
"CRTDLL_open file %s mode 0x%04x got handle %d
\n
"
,
path
,
flags
,
ret
);
return
ret
;
}
...
...
msdos/int21.c
View file @
0562539d
...
...
@@ -1635,9 +1635,18 @@ void WINAPI DOS3Call( CONTEXT *context )
break
;
case
0x45
:
/* "DUP" - DUPLICATE FILE HANDLE */
TRACE
(
int21
,
"DUP - DUPLICATE FILE HANDLE %d
\n
"
,
BX_reg
(
context
));
bSetDOSExtendedError
=
((
AX_reg
(
context
)
=
HFILE32_TO_HFILE16
(
FILE_Dup
(
HFILE16_TO_HFILE32
(
BX_reg
(
context
)))))
==
(
WORD
)
HFILE_ERROR16
);
break
;
{
HANDLE32
handle
;
TRACE
(
int21
,
"DUP - DUPLICATE FILE HANDLE %d
\n
"
,
BX_reg
(
context
));
if
((
bSetDOSExtendedError
=
!
DuplicateHandle
(
GetCurrentProcess
(),
HFILE16_TO_HFILE32
(
BX_reg
(
context
)),
GetCurrentProcess
(),
&
handle
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
)))
AX_reg
(
context
)
=
HFILE_ERROR16
;
else
AX_reg
(
context
)
=
HFILE32_TO_HFILE16
(
handle
);
break
;
}
case
0x46
:
/* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
TRACE
(
int21
,
"FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d
\n
"
,
...
...
msdos/vxd.c
View file @
0562539d
...
...
@@ -687,7 +687,7 @@ void VXD_Win32s( CONTEXT *context )
IMAGE_NT_HEADERS
*
nt_header
=
PE_HEADER
(
module
->
baseAddr
);
IMAGE_SECTION_HEADER
*
pe_seg
=
PE_SECTIONS
(
module
->
baseAddr
);
HFILE32
image
=
FILE_Open
(
module
->
pathName
,
O_RDONLY
,
0
);
HFILE32
image
=
_lopen32
(
module
->
pathName
,
OF_READ
);
BOOL32
error
=
(
image
==
INVALID_HANDLE_VALUE32
);
UINT32
i
;
...
...
ole/storage.c
View file @
0562539d
...
...
@@ -1378,7 +1378,8 @@ HRESULT WINAPI IStorage16_fnCreateStream(
FIXME
(
ole
,
"We do not support transacted Compound Storage. Using direct mode.
\n
"
);
_create_istream16
(
ppstm
);
lpstr
=
(
_IStream16
*
)
PTR_SEG_TO_LIN
(
*
ppstm
);
lpstr
->
hf
=
FILE_Dup
(
this
->
hf
);
DuplicateHandle
(
GetCurrentProcess
(),
this
->
hf
,
GetCurrentProcess
(),
&
lpstr
->
hf
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
);
lpstr
->
offset
.
LowPart
=
0
;
lpstr
->
offset
.
HighPart
=
0
;
...
...
@@ -1430,7 +1431,8 @@ HRESULT WINAPI IStorage16_fnOpenStorage(
FIXME
(
ole
,
"We do not support transacted Compound Storage. Using direct mode.
\n
"
);
_create_istorage16
(
ppstg
);
lpstg
=
(
_IStream16
*
)
PTR_SEG_TO_LIN
(
*
ppstg
);
lpstg
->
hf
=
FILE_Dup
(
this
->
hf
);
DuplicateHandle
(
GetCurrentProcess
(),
this
->
hf
,
GetCurrentProcess
(),
&
lpstg
->
hf
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
);
lstrcpyAtoW
(
name
,
pwcsName
);
newpps
=
STORAGE_look_for_named_pps
(
lpstg
->
hf
,
this
->
stde
.
pps_dir
,
name
);
if
(
newpps
==-
1
)
{
...
...
@@ -1464,7 +1466,8 @@ HRESULT WINAPI IStorage16_fnOpenStream(
FIXME
(
ole
,
"We do not support transacted Compound Storage. Using direct mode.
\n
"
);
_create_istream16
(
ppstm
);
lpstr
=
(
_IStream16
*
)
PTR_SEG_TO_LIN
(
*
ppstm
);
lpstr
->
hf
=
FILE_Dup
(
this
->
hf
);
DuplicateHandle
(
GetCurrentProcess
(),
this
->
hf
,
GetCurrentProcess
(),
&
lpstr
->
hf
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
);
lstrcpyAtoW
(
name
,
pwcsName
);
newpps
=
STORAGE_look_for_named_pps
(
lpstr
->
hf
,
this
->
stde
.
pps_dir
,
name
);
if
(
newpps
==-
1
)
{
...
...
scheduler/process.c
View file @
0562539d
...
...
@@ -108,12 +108,9 @@ static BOOL32 PROCESS_BuildEnvDB( PDB32 *pdb )
/* Allocate the standard handles */
pdb
->
env_db
->
hStdin
=
FILE_DupUnixHandle
(
0
);
pdb
->
env_db
->
hStdout
=
FILE_DupUnixHandle
(
1
);
pdb
->
env_db
->
hStderr
=
FILE_DupUnixHandle
(
2
);
FILE_SetFileType
(
pdb
->
env_db
->
hStdin
,
FILE_TYPE_CHAR
);
FILE_SetFileType
(
pdb
->
env_db
->
hStdout
,
FILE_TYPE_CHAR
);
FILE_SetFileType
(
pdb
->
env_db
->
hStderr
,
FILE_TYPE_CHAR
);
pdb
->
env_db
->
hStdin
=
FILE_DupUnixHandle
(
0
,
GENERIC_READ
);
pdb
->
env_db
->
hStdout
=
FILE_DupUnixHandle
(
1
,
GENERIC_WRITE
);
pdb
->
env_db
->
hStderr
=
FILE_DupUnixHandle
(
2
,
GENERIC_WRITE
);
/* Build the command-line */
...
...
@@ -661,46 +658,19 @@ DWORD WINAPI GetPriorityClass(HANDLE32 hprocess)
/***********************************************************************
* GetStdHandle (KERNEL32.276)
*
* FIXME: These should be allocated when a console is created, or inherited
* from the parent.
*/
HANDLE32
WINAPI
GetStdHandle
(
DWORD
std_handle
)
{
HFILE32
hFile
;
int
fd
;
PDB32
*
pdb
=
PROCESS_Current
();
switch
(
std_handle
)
{
case
STD_INPUT_HANDLE
:
if
(
pdb
->
env_db
->
hStdin
)
return
pdb
->
env_db
->
hStdin
;
fd
=
0
;
break
;
case
STD_OUTPUT_HANDLE
:
if
(
pdb
->
env_db
->
hStdout
)
return
pdb
->
env_db
->
hStdout
;
fd
=
1
;
break
;
case
STD_ERROR_HANDLE
:
if
(
pdb
->
env_db
->
hStderr
)
return
pdb
->
env_db
->
hStderr
;
fd
=
2
;
break
;
default:
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
INVALID_HANDLE_VALUE32
;
}
hFile
=
FILE_DupUnixHandle
(
fd
);
if
(
hFile
!=
HFILE_ERROR32
)
{
FILE_SetFileType
(
hFile
,
FILE_TYPE_CHAR
);
switch
(
std_handle
)
{
case
STD_INPUT_HANDLE
:
pdb
->
env_db
->
hStdin
=
hFile
;
break
;
case
STD_OUTPUT_HANDLE
:
pdb
->
env_db
->
hStdout
=
hFile
;
break
;
case
STD_ERROR_HANDLE
:
pdb
->
env_db
->
hStderr
=
hFile
;
break
;
}
case
STD_INPUT_HANDLE
:
return
pdb
->
env_db
->
hStdin
;
case
STD_OUTPUT_HANDLE
:
return
pdb
->
env_db
->
hStdout
;
case
STD_ERROR_HANDLE
:
return
pdb
->
env_db
->
hStderr
;
}
return
hFile
;
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
INVALID_HANDLE_VALUE32
;
}
...
...
server/change.c
View file @
0562539d
...
...
@@ -33,6 +33,7 @@ static const struct object_ops change_ops =
no_read_fd
,
no_write_fd
,
no_flush
,
no_get_file_info
,
change_destroy
};
...
...
@@ -51,8 +52,8 @@ static void change_dump( struct object *obj, int verbose )
{
struct
change
*
change
=
(
struct
change
*
)
obj
;
assert
(
obj
->
ops
==
&
change_ops
);
printf
(
"Change notification sub=%d filter=%08x
\n
"
,
change
->
subtree
,
change
->
filter
);
fprintf
(
stderr
,
"Change notification sub=%d filter=%08x
\n
"
,
change
->
subtree
,
change
->
filter
);
}
static
int
change_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
)
...
...
server/console.c
View file @
0562539d
...
...
@@ -9,6 +9,7 @@
#include <assert.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/errno.h>
...
...
@@ -35,6 +36,7 @@ static void console_remove_queue( struct object *obj, struct wait_queue_entry *e
static
int
console_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
int
console_get_read_fd
(
struct
object
*
obj
);
static
int
console_get_write_fd
(
struct
object
*
obj
);
static
int
console_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
);
static
void
console_destroy
(
struct
object
*
obj
);
static
const
struct
object_ops
console_ops
=
...
...
@@ -47,6 +49,7 @@ static const struct object_ops console_ops =
console_get_read_fd
,
console_get_write_fd
,
no_flush
,
console_get_info
,
console_destroy
};
...
...
@@ -120,8 +123,8 @@ static void console_dump( struct object *obj, int verbose )
{
struct
console
*
console
=
(
struct
console
*
)
obj
;
assert
(
obj
->
ops
==
&
console_ops
);
printf
(
"Console %s fd=%d
\n
"
,
console
->
is_read
?
"input"
:
"output"
,
console
->
fd
);
fprintf
(
stderr
,
"Console %s fd=%d
\n
"
,
console
->
is_read
?
"input"
:
"output"
,
console
->
fd
);
}
static
int
console_add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
)
...
...
@@ -194,6 +197,13 @@ static int console_get_write_fd( struct object *obj )
return
dup
(
console
->
fd
);
}
static
int
console_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
)
{
memset
(
reply
,
0
,
sizeof
(
*
reply
)
);
reply
->
type
=
FILE_TYPE_CHAR
;
return
1
;
}
static
void
console_destroy
(
struct
object
*
obj
)
{
struct
console
*
console
=
(
struct
console
*
)
obj
;
...
...
server/event.c
View file @
0562539d
...
...
@@ -34,6 +34,7 @@ static const struct object_ops event_ops =
no_read_fd
,
no_write_fd
,
no_flush
,
no_get_file_info
,
event_destroy
};
...
...
@@ -103,7 +104,9 @@ static void event_dump( struct object *obj, int verbose )
{
struct
event
*
event
=
(
struct
event
*
)
obj
;
assert
(
obj
->
ops
==
&
event_ops
);
printf
(
"Event manual=%d signaled=%d
\n
"
,
event
->
manual_reset
,
event
->
signaled
);
fprintf
(
stderr
,
"Event manual=%d signaled=%d name='%s'
\n
"
,
event
->
manual_reset
,
event
->
signaled
,
get_object_name
(
&
event
->
obj
)
);
}
static
int
event_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
)
...
...
server/file.c
View file @
0562539d
...
...
@@ -15,6 +15,7 @@
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include "winerror.h"
#include "winnt.h"
...
...
@@ -23,10 +24,18 @@
struct
file
{
struct
object
obj
;
/* object header */
struct
file
*
next
;
/* next file in hashing list */
char
*
name
;
/* file name */
int
fd
;
/* Unix file descriptor */
int
event
;
/* possible events on this file */
unsigned
int
access
;
/* file access (GENERIC_READ/WRITE) */
unsigned
int
flags
;
/* flags (FILE_FLAG_*) */
unsigned
int
sharing
;
/* file sharing mode */
};
#define NAME_HASH_SIZE 37
static
struct
file
*
file_hash
[
NAME_HASH_SIZE
];
static
void
file_dump
(
struct
object
*
obj
,
int
verbose
);
static
int
file_add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
static
void
file_remove_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
...
...
@@ -34,6 +43,7 @@ static int file_signaled( struct object *obj, struct thread *thread );
static
int
file_get_read_fd
(
struct
object
*
obj
);
static
int
file_get_write_fd
(
struct
object
*
obj
);
static
int
file_flush
(
struct
object
*
obj
);
static
int
file_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
);
static
void
file_destroy
(
struct
object
*
obj
);
static
const
struct
object_ops
file_ops
=
...
...
@@ -46,6 +56,7 @@ static const struct object_ops file_ops =
file_get_read_fd
,
file_get_write_fd
,
file_flush
,
file_get_info
,
file_destroy
};
...
...
@@ -55,31 +66,134 @@ static const struct select_ops select_ops =
NULL
/* we never set a timeout on a file */
};
struct
object
*
create_file
(
int
fd
)
static
int
get_name_hash
(
const
char
*
name
)
{
int
hash
=
0
;
while
(
*
name
)
hash
^=
*
name
++
;
return
hash
%
NAME_HASH_SIZE
;
}
/* check if the desired access is possible without violating */
/* the sharing mode of other opens of the same file */
static
int
check_sharing
(
const
char
*
name
,
int
hash
,
unsigned
int
access
,
unsigned
int
sharing
)
{
struct
file
*
file
;
unsigned
int
existing_sharing
=
FILE_SHARE_READ
|
FILE_SHARE_WRITE
;
unsigned
int
existing_access
=
0
;
for
(
file
=
file_hash
[
hash
];
file
;
file
=
file
->
next
)
{
if
(
strcmp
(
file
->
name
,
name
))
continue
;
existing_sharing
&=
file
->
sharing
;
existing_access
|=
file
->
access
;
}
if
((
access
&
GENERIC_READ
)
&&
!
(
existing_sharing
&
FILE_SHARE_READ
))
return
0
;
if
((
access
&
GENERIC_WRITE
)
&&
!
(
existing_sharing
&
FILE_SHARE_WRITE
))
return
0
;
if
((
existing_access
&
GENERIC_READ
)
&&
!
(
sharing
&
FILE_SHARE_READ
))
return
0
;
if
((
existing_access
&
GENERIC_WRITE
)
&&
!
(
sharing
&
FILE_SHARE_WRITE
))
return
0
;
return
1
;
}
struct
object
*
create_file
(
int
fd
,
const
char
*
name
,
unsigned
int
access
,
unsigned
int
sharing
,
int
create
,
unsigned
int
attrs
)
{
struct
file
*
file
;
int
flags
;
int
hash
=
0
;
if
(
fd
==
-
1
)
{
int
flags
;
struct
stat
st
;
if
(
!
name
)
{
SET_ERROR
(
ERROR_INVALID_PARAMETER
);
return
NULL
;
}
/* check sharing mode */
hash
=
get_name_hash
(
name
);
if
(
!
check_sharing
(
name
,
hash
,
access
,
sharing
))
{
SET_ERROR
(
ERROR_SHARING_VIOLATION
);
return
NULL
;
}
switch
(
create
)
{
case
CREATE_NEW
:
flags
=
O_CREAT
|
O_EXCL
;
break
;
case
CREATE_ALWAYS
:
flags
=
O_CREAT
|
O_TRUNC
;
break
;
case
OPEN_ALWAYS
:
flags
=
O_CREAT
;
break
;
case
TRUNCATE_EXISTING
:
flags
=
O_TRUNC
;
break
;
case
OPEN_EXISTING
:
flags
=
0
;
break
;
default:
SET_ERROR
(
ERROR_INVALID_PARAMETER
);
return
NULL
;
}
switch
(
access
&
(
GENERIC_READ
|
GENERIC_WRITE
))
{
case
0
:
break
;
case
GENERIC_READ
:
flags
|=
O_RDONLY
;
break
;
case
GENERIC_WRITE
:
flags
|=
O_WRONLY
;
break
;
case
GENERIC_READ
|
GENERIC_WRITE
:
flags
|=
O_RDWR
;
break
;
}
if
((
fd
=
open
(
name
,
flags
|
O_NONBLOCK
,
(
attrs
&
FILE_ATTRIBUTE_READONLY
)
?
0444
:
0666
))
==
-
1
)
{
file_set_error
();
return
NULL
;
}
/* Refuse to open a directory */
if
(
fstat
(
fd
,
&
st
)
==
-
1
)
{
file_set_error
();
close
(
fd
);
return
NULL
;
}
if
(
S_ISDIR
(
st
.
st_mode
))
{
SET_ERROR
(
ERROR_ACCESS_DENIED
);
close
(
fd
);
return
NULL
;
}
}
else
{
if
((
fd
=
dup
(
fd
))
==
-
1
)
{
file_set_error
();
return
NULL
;
}
}
if
(
(
flags
=
fcntl
(
fd
,
F_GETFL
))
==
-
1
)
if
(
!
(
file
=
mem_alloc
(
sizeof
(
*
file
)
))
)
{
perror
(
"fcntl"
);
close
(
fd
);
return
NULL
;
}
if
(
!
(
file
=
mem_alloc
(
sizeof
(
*
file
)
)))
return
NULL
;
init_object
(
&
file
->
obj
,
&
file_ops
,
NULL
);
file
->
fd
=
fd
;
switch
(
flags
&
3
)
if
(
name
)
{
case
O_RDONLY
:
file
->
event
=
READ_EVENT
;
break
;
case
O_WRONLY
:
file
->
event
=
WRITE_EVENT
;
break
;
case
O_RDWR
:
file
->
event
=
READ_EVENT
|
WRITE_EVENT
;
break
;
if
(
!
(
file
->
name
=
mem_alloc
(
strlen
(
name
)
+
1
)))
{
close
(
fd
);
free
(
file
);
return
NULL
;
}
strcpy
(
file
->
name
,
name
);
file
->
next
=
file_hash
[
hash
];
file_hash
[
hash
]
=
file
;
}
else
{
file
->
name
=
NULL
;
file
->
next
=
NULL
;
}
init_object
(
&
file
->
obj
,
&
file_ops
,
NULL
);
file
->
fd
=
fd
;
file
->
access
=
access
;
file
->
flags
=
attrs
;
file
->
sharing
=
sharing
;
CLEAR_ERROR
();
return
&
file
->
obj
;
}
...
...
@@ -88,7 +202,8 @@ static void file_dump( struct object *obj, int verbose )
{
struct
file
*
file
=
(
struct
file
*
)
obj
;
assert
(
obj
->
ops
==
&
file_ops
);
printf
(
"File fd=%d
\n
"
,
file
->
fd
);
printf
(
"File fd=%d flags=%08x name='%s'
\n
"
,
file
->
fd
,
file
->
flags
,
file
->
name
);
}
static
int
file_add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
)
...
...
@@ -128,8 +243,8 @@ static int file_signaled( struct object *obj, struct thread *thread )
FD_ZERO
(
&
read_fds
);
FD_ZERO
(
&
write_fds
);
if
(
file
->
event
&
READ_EVENT
)
FD_SET
(
file
->
fd
,
&
read_fds
);
if
(
file
->
event
&
WRITE_EVENT
)
FD_SET
(
file
->
fd
,
&
write_fds
);
if
(
file
->
access
&
GENERIC_READ
)
FD_SET
(
file
->
fd
,
&
read_fds
);
if
(
file
->
access
&
GENERIC_WRITE
)
FD_SET
(
file
->
fd
,
&
write_fds
);
return
select
(
file
->
fd
+
1
,
&
read_fds
,
&
write_fds
,
NULL
,
&
tv
)
>
0
;
}
...
...
@@ -137,12 +252,6 @@ static int file_get_read_fd( struct object *obj )
{
struct
file
*
file
=
(
struct
file
*
)
obj
;
assert
(
obj
->
ops
==
&
file_ops
);
if
(
!
(
file
->
event
&
READ_EVENT
))
/* FIXME: should not be necessary */
{
SET_ERROR
(
ERROR_ACCESS_DENIED
);
return
-
1
;
}
return
dup
(
file
->
fd
);
}
...
...
@@ -150,12 +259,6 @@ static int file_get_write_fd( struct object *obj )
{
struct
file
*
file
=
(
struct
file
*
)
obj
;
assert
(
obj
->
ops
==
&
file_ops
);
if
(
!
(
file
->
event
&
WRITE_EVENT
))
/* FIXME: should not be necessary */
{
SET_ERROR
(
ERROR_ACCESS_DENIED
);
return
-
1
;
}
return
dup
(
file
->
fd
);
}
...
...
@@ -171,11 +274,48 @@ static int file_flush( struct object *obj )
return
ret
;
}
static
int
file_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
)
{
struct
stat
st
;
struct
file
*
file
=
(
struct
file
*
)
obj
;
assert
(
obj
->
ops
==
&
file_ops
);
if
(
fstat
(
file
->
fd
,
&
st
)
==
-
1
)
{
file_set_error
();
return
0
;
}
if
(
S_ISCHR
(
st
.
st_mode
)
||
S_ISFIFO
(
st
.
st_mode
)
||
S_ISSOCK
(
st
.
st_mode
)
||
isatty
(
file
->
fd
))
reply
->
type
=
FILE_TYPE_CHAR
;
else
reply
->
type
=
FILE_TYPE_DISK
;
if
(
S_ISDIR
(
st
.
st_mode
))
reply
->
attr
=
FILE_ATTRIBUTE_DIRECTORY
;
else
reply
->
attr
=
FILE_ATTRIBUTE_ARCHIVE
;
if
(
!
(
st
.
st_mode
&
S_IWUSR
))
reply
->
attr
|=
FILE_ATTRIBUTE_READONLY
;
reply
->
access_time
=
st
.
st_atime
;
reply
->
write_time
=
st
.
st_mtime
;
reply
->
size_high
=
0
;
reply
->
size_low
=
S_ISDIR
(
st
.
st_mode
)
?
0
:
st
.
st_size
;
reply
->
links
=
st
.
st_nlink
;
reply
->
index_high
=
st
.
st_dev
;
reply
->
index_low
=
st
.
st_ino
;
reply
->
serial
=
0
;
/* FIXME */
return
1
;
}
static
void
file_destroy
(
struct
object
*
obj
)
{
struct
file
**
pptr
;
struct
file
*
file
=
(
struct
file
*
)
obj
;
assert
(
obj
->
ops
==
&
file_ops
);
/* remove it from the hashing list */
pptr
=
&
file_hash
[
get_name_hash
(
file
->
name
)];
while
(
*
pptr
&&
*
pptr
!=
file
)
pptr
=
&
(
*
pptr
)
->
next
;
assert
(
*
pptr
);
*
pptr
=
(
*
pptr
)
->
next
;
close
(
file
->
fd
);
free
(
file
->
name
);
free
(
file
);
}
...
...
@@ -263,31 +403,22 @@ int truncate_file( int handle )
}
int
get_file_info
(
int
handle
,
struct
get_file_info_reply
*
reply
)
int
set_file_time
(
int
handle
,
time_t
access_time
,
time_t
write_time
)
{
struct
file
*
file
;
struct
stat
st
;
struct
utimbuf
utimbuf
;
if
(
!
(
file
=
get_file_obj
(
current
->
process
,
handle
,
0
)))
if
(
!
(
file
=
get_file_obj
(
current
->
process
,
handle
,
GENERIC_WRITE
)))
return
0
;
if
(
fstat
(
file
->
fd
,
&
st
)
==
-
1
)
utimbuf
.
actime
=
access_time
;
utimbuf
.
modtime
=
write_time
;
if
(
utime
(
file
->
name
,
&
utimbuf
)
==
-
1
)
{
file_set_error
();
release_object
(
file
);
return
0
;
}
if
(
S_ISDIR
(
st
.
st_mode
))
reply
->
attr
=
FILE_ATTRIBUTE_DIRECTORY
;
else
reply
->
attr
=
FILE_ATTRIBUTE_ARCHIVE
;
if
(
!
(
st
.
st_mode
&
S_IWUSR
))
reply
->
attr
|=
FILE_ATTRIBUTE_READONLY
;
reply
->
access_time
=
st
.
st_atime
;
reply
->
write_time
=
st
.
st_mtime
;
reply
->
size_high
=
0
;
reply
->
size_low
=
S_ISDIR
(
st
.
st_mode
)
?
0
:
st
.
st_size
;
reply
->
links
=
st
.
st_nlink
;
reply
->
index_high
=
st
.
st_dev
;
reply
->
index_low
=
st
.
st_ino
;
reply
->
serial
=
0
;
/* FIXME */
release_object
(
file
);
return
1
;
}
server/mapping.c
View file @
0562539d
...
...
@@ -35,6 +35,7 @@ static const struct object_ops mapping_ops =
no_read_fd
,
no_write_fd
,
no_flush
,
no_get_file_info
,
mapping_destroy
};
...
...
@@ -93,8 +94,9 @@ static void mapping_dump( struct object *obj, int verbose )
{
struct
mapping
*
mapping
=
(
struct
mapping
*
)
obj
;
assert
(
obj
->
ops
==
&
mapping_ops
);
fprintf
(
stderr
,
"Mapping size=%08x%08x prot=%08x file=%p
\n
"
,
mapping
->
size_high
,
mapping
->
size_low
,
mapping
->
protect
,
mapping
->
file
);
fprintf
(
stderr
,
"Mapping size=%08x%08x prot=%08x file=%p name='%s'
\n
"
,
mapping
->
size_high
,
mapping
->
size_low
,
mapping
->
protect
,
mapping
->
file
,
get_object_name
(
&
mapping
->
obj
)
);
}
static
void
mapping_destroy
(
struct
object
*
obj
)
...
...
server/mutex.c
View file @
0562539d
...
...
@@ -37,6 +37,7 @@ static const struct object_ops mutex_ops =
no_read_fd
,
no_write_fd
,
no_flush
,
no_get_file_info
,
mutex_destroy
};
...
...
@@ -110,7 +111,8 @@ static void mutex_dump( struct object *obj, int verbose )
{
struct
mutex
*
mutex
=
(
struct
mutex
*
)
obj
;
assert
(
obj
->
ops
==
&
mutex_ops
);
printf
(
"Mutex count=%u owner=%p
\n
"
,
mutex
->
count
,
mutex
->
owner
);
printf
(
"Mutex count=%u owner=%p name='%s'
\n
"
,
mutex
->
count
,
mutex
->
owner
,
get_object_name
(
&
mutex
->
obj
)
);
}
static
int
mutex_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
)
...
...
server/object.c
View file @
0562539d
...
...
@@ -110,6 +110,13 @@ struct object *create_named_object( const char *name, const struct object_ops *o
return
obj
;
}
/* return a pointer to the object name, or to an empty string */
const
char
*
get_object_name
(
struct
object
*
obj
)
{
if
(
!
obj
->
name
)
return
""
;
return
obj
->
name
->
name
;
}
/* grab an object (i.e. increment its refcount) and return the object */
struct
object
*
grab_object
(
void
*
ptr
)
{
...
...
@@ -176,6 +183,12 @@ int no_flush( struct object *obj )
return
0
;
}
int
no_get_file_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
info
)
{
SET_ERROR
(
ERROR_INVALID_HANDLE
);
return
0
;
}
void
default_select_event
(
int
fd
,
int
event
,
void
*
private
)
{
struct
object
*
obj
=
(
struct
object
*
)
private
;
...
...
server/pipe.c
View file @
0562539d
...
...
@@ -6,6 +6,7 @@
#include <assert.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/errno.h>
...
...
@@ -35,6 +36,7 @@ static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entr
static
int
pipe_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
int
pipe_get_read_fd
(
struct
object
*
obj
);
static
int
pipe_get_write_fd
(
struct
object
*
obj
);
static
int
pipe_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
);
static
void
pipe_destroy
(
struct
object
*
obj
);
static
const
struct
object_ops
pipe_ops
=
...
...
@@ -47,6 +49,7 @@ static const struct object_ops pipe_ops =
pipe_get_read_fd
,
pipe_get_write_fd
,
no_flush
,
pipe_get_info
,
pipe_destroy
};
...
...
@@ -97,8 +100,8 @@ static void pipe_dump( struct object *obj, int verbose )
{
struct
pipe
*
pipe
=
(
struct
pipe
*
)
obj
;
assert
(
obj
->
ops
==
&
pipe_ops
);
printf
(
"Pipe %s-side fd=%d
\n
"
,
(
pipe
->
side
==
READ_SIDE
)
?
"read"
:
"write"
,
pipe
->
fd
);
fprintf
(
stderr
,
"Pipe %s-side fd=%d
\n
"
,
(
pipe
->
side
==
READ_SIDE
)
?
"read"
:
"write"
,
pipe
->
fd
);
}
static
int
pipe_add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
)
...
...
@@ -181,6 +184,13 @@ static int pipe_get_write_fd( struct object *obj )
return
dup
(
pipe
->
fd
);
}
static
int
pipe_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
)
{
memset
(
reply
,
0
,
sizeof
(
*
reply
)
);
reply
->
type
=
FILE_TYPE_PIPE
;
return
1
;
}
static
void
pipe_destroy
(
struct
object
*
obj
)
{
struct
pipe
*
pipe
=
(
struct
pipe
*
)
obj
;
...
...
server/process.c
View file @
0562539d
...
...
@@ -77,6 +77,7 @@ static const struct object_ops process_ops =
no_read_fd
,
no_write_fd
,
no_flush
,
no_get_file_info
,
process_destroy
};
...
...
server/request.c
View file @
0562539d
...
...
@@ -396,19 +396,16 @@ DECL_HANDLER(create_file)
{
struct
create_file_reply
reply
=
{
-
1
};
struct
object
*
obj
;
int
new_fd
;
char
*
name
=
(
char
*
)
data
;
if
(
!
len
)
name
=
NULL
;
else
CHECK_STRING
(
"create_file"
,
name
,
len
);
if
((
new_fd
=
dup
(
fd
))
==
-
1
)
{
SET_ERROR
(
ERROR_TOO_MANY_OPEN_FILES
);
goto
done
;
}
if
((
obj
=
create_file
(
new_fd
))
!=
NULL
)
if
((
obj
=
create_file
(
fd
,
name
,
req
->
access
,
req
->
sharing
,
req
->
create
,
req
->
attrs
))
!=
NULL
)
{
reply
.
handle
=
alloc_handle
(
current
->
process
,
obj
,
req
->
access
,
req
->
inherit
);
release_object
(
obj
);
}
done
:
send_reply
(
current
,
-
1
,
1
,
&
reply
,
sizeof
(
reply
)
);
}
...
...
@@ -470,11 +467,24 @@ DECL_HANDLER(flush_file)
send_reply
(
current
,
-
1
,
0
);
}
/* set a file access and modification times */
DECL_HANDLER
(
set_file_time
)
{
set_file_time
(
req
->
handle
,
req
->
access_time
,
req
->
write_time
);
send_reply
(
current
,
-
1
,
0
);
}
/* get a file information */
DECL_HANDLER
(
get_file_info
)
{
struct
object
*
obj
;
struct
get_file_info_reply
reply
;
get_file_info
(
req
->
handle
,
&
reply
);
if
((
obj
=
get_handle_obj
(
current
->
process
,
req
->
handle
,
0
,
NULL
)))
{
obj
->
ops
->
get_file_info
(
obj
,
&
reply
);
release_object
(
obj
);
}
send_reply
(
current
,
-
1
,
1
,
&
reply
,
sizeof
(
reply
)
);
}
...
...
server/semaphore.c
View file @
0562539d
...
...
@@ -34,6 +34,7 @@ static const struct object_ops semaphore_ops =
no_read_fd
,
no_write_fd
,
no_flush
,
no_get_file_info
,
semaphore_destroy
};
...
...
@@ -96,7 +97,8 @@ static void semaphore_dump( struct object *obj, int verbose )
{
struct
semaphore
*
sem
=
(
struct
semaphore
*
)
obj
;
assert
(
obj
->
ops
==
&
semaphore_ops
);
printf
(
"Semaphore count=%d max=%d
\n
"
,
sem
->
count
,
sem
->
max
);
fprintf
(
stderr
,
"Semaphore count=%d max=%d name='%s'
\n
"
,
sem
->
count
,
sem
->
max
,
get_object_name
(
&
sem
->
obj
)
);
}
static
int
semaphore_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
)
...
...
server/thread.c
View file @
0562539d
...
...
@@ -55,6 +55,7 @@ static const struct object_ops thread_ops =
no_read_fd
,
no_write_fd
,
no_flush
,
no_get_file_info
,
destroy_thread
};
...
...
@@ -145,8 +146,8 @@ static void dump_thread( struct object *obj, int verbose )
struct
thread
*
thread
=
(
struct
thread
*
)
obj
;
assert
(
obj
->
ops
==
&
thread_ops
);
printf
(
"Thread pid=%d fd=%d name='%s'
\n
"
,
thread
->
unix_pid
,
thread
->
client_fd
,
thread
->
name
);
fprintf
(
stderr
,
"Thread pid=%d fd=%d name='%s'
\n
"
,
thread
->
unix_pid
,
thread
->
client_fd
,
thread
->
name
);
}
static
int
thread_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
)
...
...
server/trace.c
View file @
0562539d
...
...
@@ -214,8 +214,12 @@ static int dump_open_named_obj_reply( struct open_named_obj_reply *req, int len
static
int
dump_create_file_request
(
struct
create_file_request
*
req
,
int
len
)
{
fprintf
(
stderr
,
" access=%08x,"
,
req
->
access
);
fprintf
(
stderr
,
" inherit=%d"
,
req
->
inherit
);
return
(
int
)
sizeof
(
*
req
);
fprintf
(
stderr
,
" inherit=%d,"
,
req
->
inherit
);
fprintf
(
stderr
,
" sharing=%08x,"
,
req
->
sharing
);
fprintf
(
stderr
,
" create=%d,"
,
req
->
create
);
fprintf
(
stderr
,
" attrs=%08x,"
,
req
->
attrs
);
fprintf
(
stderr
,
" name=
\"
%.*s
\"
"
,
len
-
(
int
)
sizeof
(
*
req
),
(
char
*
)(
req
+
1
)
);
return
len
;
}
static
int
dump_create_file_reply
(
struct
create_file_reply
*
req
,
int
len
)
...
...
@@ -258,6 +262,14 @@ static int dump_truncate_file_request( struct truncate_file_request *req, int le
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_set_file_time_request
(
struct
set_file_time_request
*
req
,
int
len
)
{
fprintf
(
stderr
,
" handle=%d,"
,
req
->
handle
);
fprintf
(
stderr
,
" access_time=%ld,"
,
req
->
access_time
);
fprintf
(
stderr
,
" write_time=%ld"
,
req
->
write_time
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_flush_file_request
(
struct
flush_file_request
*
req
,
int
len
)
{
fprintf
(
stderr
,
" handle=%d"
,
req
->
handle
);
...
...
@@ -272,6 +284,7 @@ static int dump_get_file_info_request( struct get_file_info_request *req, int le
static
int
dump_get_file_info_reply
(
struct
get_file_info_reply
*
req
,
int
len
)
{
fprintf
(
stderr
,
" type=%d,"
,
req
->
type
);
fprintf
(
stderr
,
" attr=%d,"
,
req
->
attr
);
fprintf
(
stderr
,
" access_time=%ld,"
,
req
->
access_time
);
fprintf
(
stderr
,
" write_time=%ld,"
,
req
->
write_time
);
...
...
@@ -413,6 +426,8 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
(
void
(
*
)())
dump_set_file_pointer_reply
},
{
(
int
(
*
)(
void
*
,
int
))
dump_truncate_file_request
,
(
void
(
*
)())
0
},
{
(
int
(
*
)(
void
*
,
int
))
dump_set_file_time_request
,
(
void
(
*
)())
0
},
{
(
int
(
*
)(
void
*
,
int
))
dump_flush_file_request
,
(
void
(
*
)())
0
},
{
(
int
(
*
)(
void
*
,
int
))
dump_get_file_info_request
,
...
...
@@ -456,6 +471,7 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"get_write_fd"
,
"set_file_pointer"
,
"truncate_file"
,
"set_file_time"
,
"flush_file"
,
"get_file_info"
,
"create_pipe"
,
...
...
win32/device.c
View file @
0562539d
...
...
@@ -42,11 +42,7 @@ const K32OBJ_OPS DEVICE_Ops =
typedef
struct
{
K32OBJ
header
;
struct
VxDInfo
*
info
;
char
*
devname
;
int
mode
;
}
DEVICE_OBJECT
;
...
...
@@ -270,7 +266,7 @@ LPCSTR VMM_Service_Name[N_VMM_SERVICE] =
"<KERNEL32.101>"
/* 0x0028 -- What does this do??? */
};
HANDLE32
DEVICE_Open
(
LPCSTR
filename
,
DWORD
access
)
HANDLE32
DEVICE_Open
(
LPCSTR
filename
)
{
DEVICE_OBJECT
*
dev
;
HANDLE32
handle
;
...
...
@@ -281,8 +277,6 @@ HANDLE32 DEVICE_Open(LPCSTR filename, DWORD access)
dev
->
header
.
type
=
K32OBJ_DEVICE_IOCTL
;
dev
->
header
.
refcount
=
1
;
dev
->
mode
=
access
;
dev
->
devname
=
HEAP_strdupA
(
SystemHeap
,
0
,
filename
);
dev
->
info
=
NULL
;
for
(
i
=
0
;
VxDList
[
i
].
name
;
i
++
)
...
...
@@ -307,12 +301,6 @@ static void DEVICE_Destroy(K32OBJ *obj)
DEVICE_OBJECT
*
dev
=
(
DEVICE_OBJECT
*
)
obj
;
assert
(
obj
->
type
==
K32OBJ_DEVICE_IOCTL
);
if
(
dev
->
devname
)
{
HeapFree
(
SystemHeap
,
0
,
dev
->
devname
);
dev
->
devname
=
NULL
;
}
obj
->
type
=
K32OBJ_UNKNOWN
;
HeapFree
(
SystemHeap
,
0
,
dev
);
}
...
...
@@ -360,7 +348,7 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode,
{
/* FIXME: Set appropriate error */
FIXME
(
win32
,
"Unimplemented control %ld for VxD device %s
\n
"
,
dwIoControlCode
,
dev
->
dev
name
);
dwIoControlCode
,
dev
->
info
->
name
);
}
}
else
...
...
win32/file.c
View file @
0562539d
...
...
@@ -25,10 +25,6 @@
DWORD
ErrnoToLastError
(
int
errno_num
);
static
int
TranslateCreationFlags
(
DWORD
create_flags
);
static
int
TranslateAccessFlags
(
DWORD
access_flags
);
static
int
TranslateShareFlags
(
DWORD
share_flags
);
/***********************************************************************
* ReadFileEx (KERNEL32.)
*/
...
...
@@ -51,187 +47,6 @@ BOOL32 WINAPI ReadFileEx(HFILE32 hFile, LPVOID lpBuffer, DWORD numtoread,
return
0
;
}
/*************************************************************************
* CreateFile32A [KERNEL32.45] Creates or opens a file or other object
*
* Creates or opens an object, and returns a handle that can be used to
* access that object.
*
* PARAMS
*
* filename [I] pointer to filename to be accessed
* access [I] access mode requested
* sharing [I] share mode
* security [I] pointer to security attributes
* creation [I] ?
* attributes [I] ?
* template [I] handle to file with attributes to copy
*
* RETURNS
* Success: Open handle to specified file
* Failure: INVALID_HANDLE_VALUE
*
* NOTES
* Should call SetLastError() on failure.
*
* BUGS
*
* Doesn't support character devices, pipes, template files, or a
* lot of the 'attributes' flags yet.
*/
HFILE32
WINAPI
CreateFile32A
(
LPCSTR
filename
,
DWORD
access
,
DWORD
sharing
,
LPSECURITY_ATTRIBUTES
security
,
DWORD
creation
,
DWORD
attributes
,
HANDLE32
template
)
{
int
access_flags
,
create_flags
,
share_flags
;
HFILE32
to_dup
=
HFILE_ERROR32
;
/* handle to dup */
/* Translate the various flags to Unix-style.
*/
access_flags
=
TranslateAccessFlags
(
access
);
create_flags
=
TranslateCreationFlags
(
creation
);
share_flags
=
TranslateShareFlags
(
sharing
);
if
(
template
)
FIXME
(
file
,
"template handles not supported.
\n
"
);
if
(
!
filename
)
return
HFILE_ERROR32
;
/* If the name starts with '\\?\' or '\\.\', ignore the first 4 chars.
*/
if
(
!
strncmp
(
filename
,
"
\\\\
?
\\
"
,
4
)
||
!
strncmp
(
filename
,
"
\\\\
.
\\
"
,
4
))
{
if
(
filename
[
2
]
==
'.'
)
return
DEVICE_Open
(
filename
+
4
,
access_flags
|
create_flags
);
filename
+=
4
;
if
(
!
strncmp
(
filename
,
"UNC"
,
3
))
{
FIXME
(
file
,
"UNC name (%s) not supported.
\n
"
,
filename
);
SetLastError
(
ERROR_CALL_NOT_IMPLEMENTED
);
return
HFILE_ERROR32
;
}
}
/* If the name still starts with '\\', it's a UNC name.
*/
if
(
!
strncmp
(
filename
,
"
\\\\
"
,
2
))
{
FIXME
(
file
,
"UNC names not supported.
\n
"
);
SetLastError
(
ERROR_CALL_NOT_IMPLEMENTED
);
return
HFILE_ERROR32
;
}
/* If the name is either CONIN$ or CONOUT$, give them duplicated stdin
* or stdout, respectively. The lower case version is also allowed. Most likely
* this should be a case ignore string compare.
*/
if
(
!
strcasecmp
(
filename
,
"CONIN$"
))
to_dup
=
GetStdHandle
(
STD_INPUT_HANDLE
);
else
if
(
!
strcasecmp
(
filename
,
"CONOUT$"
))
to_dup
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
if
(
to_dup
!=
HFILE_ERROR32
)
{
HFILE32
handle
;
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
to_dup
,
GetCurrentProcess
(),
&
handle
,
access
,
FALSE
,
0
))
handle
=
HFILE_ERROR32
;
return
handle
;
}
return
FILE_Open
(
filename
,
access_flags
|
create_flags
,
share_flags
);
}
/*************************************************************************
* CreateFile32W (KERNEL32.48)
*/
HFILE32
WINAPI
CreateFile32W
(
LPCWSTR
filename
,
DWORD
access
,
DWORD
sharing
,
LPSECURITY_ATTRIBUTES
security
,
DWORD
creation
,
DWORD
attributes
,
HANDLE32
template
)
{
LPSTR
afn
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
filename
);
HFILE32
res
=
CreateFile32A
(
afn
,
access
,
sharing
,
security
,
creation
,
attributes
,
template
);
HeapFree
(
GetProcessHeap
(),
0
,
afn
);
return
res
;
}
static
int
TranslateAccessFlags
(
DWORD
access_flags
)
{
int
rc
=
0
;
switch
(
access_flags
)
{
case
GENERIC_READ
:
rc
=
O_RDONLY
;
break
;
case
GENERIC_WRITE
:
rc
=
O_WRONLY
;
break
;
case
(
GENERIC_READ
|
GENERIC_WRITE
):
rc
=
O_RDWR
;
break
;
}
return
rc
;
}
static
int
TranslateCreationFlags
(
DWORD
create_flags
)
{
int
rc
=
0
;
switch
(
create_flags
)
{
case
CREATE_NEW
:
rc
=
O_CREAT
|
O_EXCL
;
break
;
case
CREATE_ALWAYS
:
rc
=
O_CREAT
|
O_TRUNC
;
break
;
case
OPEN_EXISTING
:
rc
=
0
;
break
;
case
OPEN_ALWAYS
:
rc
=
O_CREAT
;
break
;
case
TRUNCATE_EXISTING
:
rc
=
O_TRUNC
;
break
;
}
return
rc
;
}
static
int
TranslateShareFlags
(
DWORD
share_flags
)
/*
OPEN_SHARE_DENYNONE FILE_SHARE_READ | FILE_SHARE_WRITE
OPEN_SHARE_DENYREAD FILE_SHARE_WRITE
OPEN_SHARE_DENYREADWRITE 0
OPEN_SHARE_DENYWRITE FILE_SHARE_READ
*/
{
switch
(
share_flags
)
{
case
FILE_SHARE_READ
|
FILE_SHARE_WRITE
:
return
OF_SHARE_DENY_NONE
;
case
FILE_SHARE_WRITE
:
return
OF_SHARE_DENY_READ
;
case
FILE_SHARE_READ
:
return
OF_SHARE_DENY_WRITE
;
case
0
:
return
OF_SHARE_EXCLUSIVE
;
default:
}
FIXME
(
file
,
"unknown sharing flags 0x%04lx
\n
"
,
share_flags
);
return
OF_SHARE_EXCLUSIVE
;
}
/**************************************************************************
* SetFileAttributes16 (KERNEL.421)
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment