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
e57749d5
Commit
e57749d5
authored
Apr 05, 2007
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Avoid setting status in IO_STATUS_BLOCK until the I/O operation is done.
parent
0ce39d58
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
125 additions
and
133 deletions
+125
-133
file.c
dlls/ntdll/file.c
+125
-133
No files found.
dlls/ntdll/file.c
View file @
e57749d5
...
...
@@ -250,13 +250,13 @@ typedef struct async_fileio
HANDLE
event
;
}
async_fileio
;
static
void
fileio_terminate
(
async_fileio
*
fileio
,
IO_STATUS_BLOCK
*
iosb
)
static
void
fileio_terminate
(
async_fileio
*
fileio
,
IO_STATUS_BLOCK
*
iosb
,
NTSTATUS
status
)
{
TRACE
(
"data: %p
\n
"
,
fileio
);
i
f
(
fileio
->
apc
&&
(
iosb
->
u
.
S
tatus
==
STATUS_SUCCESS
||
fileio
->
queue_apc_on_error
))
fileio
->
apc
(
fileio
->
apc_user
,
iosb
,
iosb
->
Information
);
i
osb
->
u
.
Status
=
status
;
if
(
fileio
->
apc
&&
(
s
tatus
==
STATUS_SUCCESS
||
fileio
->
queue_apc_on_error
))
fileio
->
apc
(
fileio
->
apc_user
,
iosb
,
0
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
fileio
);
}
...
...
@@ -283,11 +283,9 @@ static ULONG fileio_queue_async(async_fileio* fileio, IO_STATUS_BLOCK* iosb,
SERVER_END_REQ
;
if
(
status
!=
STATUS_PENDING
)
{
iosb
->
u
.
Status
=
status
;
(
apc
)(
fileio
,
iosb
,
iosb
->
u
.
Status
);
}
else
NtCurrentTeb
()
->
num_async_io
++
;
fileio_terminate
(
fileio
,
iosb
,
status
);
else
NtCurrentTeb
()
->
num_async_io
++
;
return
status
;
}
...
...
@@ -351,12 +349,11 @@ static void WINAPI FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, ULON
switch
(
status
)
{
case
STATUS_ALERTED
:
/* got some new data */
if
(
iosb
->
u
.
Status
!=
STATUS_PENDING
)
FIXME
(
"unexpected status %08x
\n
"
,
iosb
->
u
.
Status
);
/* check to see if the data is ready (non-blocking) */
if
((
iosb
->
u
.
S
tatus
=
server_get_unix_fd
(
fileio
->
handle
,
FILE_READ_DATA
,
&
fd
,
&
needs_close
,
NULL
,
NULL
)))
if
((
s
tatus
=
server_get_unix_fd
(
fileio
->
handle
,
FILE_READ_DATA
,
&
fd
,
&
needs_close
,
NULL
,
NULL
)))
{
fileio_terminate
(
fileio
,
iosb
);
fileio_terminate
(
fileio
,
iosb
,
status
);
break
;
}
result
=
read
(
fd
,
&
fileio
->
buffer
[
already
],
fileio
->
count
-
already
);
...
...
@@ -367,42 +364,41 @@ static void WINAPI FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, ULON
if
(
errno
==
EAGAIN
||
errno
==
EINTR
)
{
TRACE
(
"Deferred read %d
\n
"
,
errno
);
iosb
->
u
.
S
tatus
=
STATUS_PENDING
;
s
tatus
=
STATUS_PENDING
;
}
else
/* check to see if the transfer is complete */
iosb
->
u
.
S
tatus
=
FILE_GetNtStatus
();
s
tatus
=
FILE_GetNtStatus
();
}
else
if
(
result
==
0
)
{
iosb
->
u
.
S
tatus
=
iosb
->
Information
?
STATUS_SUCCESS
:
STATUS_END_OF_FILE
;
s
tatus
=
iosb
->
Information
?
STATUS_SUCCESS
:
STATUS_END_OF_FILE
;
}
else
{
iosb
->
Information
+=
result
;
if
(
iosb
->
Information
>=
fileio
->
count
||
fileio
->
avail_mode
)
iosb
->
u
.
S
tatus
=
STATUS_SUCCESS
;
s
tatus
=
STATUS_SUCCESS
;
else
{
/* if we only have to read the available data, and none is available,
* simply cancel the request. If data was available, it has been read
* while in by previous call (NtDelayExecution)
*/
iosb
->
u
.
S
tatus
=
(
fileio
->
avail_mode
)
?
STATUS_SUCCESS
:
STATUS_PENDING
;
s
tatus
=
(
fileio
->
avail_mode
)
?
STATUS_SUCCESS
:
STATUS_PENDING
;
}
TRACE
(
"read %d more bytes %ld/%d so far (%s)
\n
"
,
result
,
iosb
->
Information
,
fileio
->
count
,
(
iosb
->
u
.
S
tatus
==
STATUS_SUCCESS
)
?
"success"
:
"pending"
);
result
,
iosb
->
Information
,
fileio
->
count
,
(
s
tatus
==
STATUS_SUCCESS
)
?
"success"
:
"pending"
);
}
/* queue another async operation ? */
if
(
iosb
->
u
.
S
tatus
==
STATUS_PENDING
)
if
(
s
tatus
==
STATUS_PENDING
)
fileio_queue_async
(
fileio
,
iosb
,
TRUE
);
else
fileio_terminate
(
fileio
,
iosb
);
fileio_terminate
(
fileio
,
iosb
,
status
);
break
;
default:
iosb
->
u
.
Status
=
status
;
fileio_terminate
(
fileio
,
iosb
);
fileio_terminate
(
fileio
,
iosb
,
status
);
break
;
}
}
...
...
@@ -436,6 +432,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
PLARGE_INTEGER
offset
,
PULONG
key
)
{
int
result
,
unix_handle
,
needs_close
,
flags
;
NTSTATUS
status
;
enum
server_fd_type
type
;
TRACE
(
"(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p),partial stub!
\n
"
,
...
...
@@ -444,9 +441,13 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
if
(
!
io_status
)
return
STATUS_ACCESS_VIOLATION
;
io_status
->
Information
=
0
;
io_status
->
u
.
Status
=
server_get_unix_fd
(
hFile
,
FILE_READ_DATA
,
&
unix_handle
,
&
needs_close
,
&
type
,
&
flags
);
if
(
io_status
->
u
.
Status
)
return
io_status
->
u
.
Status
;
status
=
server_get_unix_fd
(
hFile
,
FILE_READ_DATA
,
&
unix_handle
,
&
needs_close
,
&
type
,
&
flags
);
if
(
status
)
{
io_status
->
u
.
Status
=
status
;
return
status
;
}
if
(
type
==
FD_TYPE_FILE
&&
offset
)
{
...
...
@@ -458,19 +459,18 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
if
(
errno
==
EINTR
)
continue
;
if
(
errno
==
EAGAIN
||
errno
==
ESPIPE
)
{
io_status
->
u
.
S
tatus
=
STATUS_PENDING
;
s
tatus
=
STATUS_PENDING
;
break
;
}
result
=
0
;
io_status
->
u
.
S
tatus
=
FILE_GetNtStatus
();
s
tatus
=
FILE_GetNtStatus
();
goto
done
;
}
if
(
result
>=
0
)
{
io_status
->
Information
=
result
;
io_status
->
u
.
S
tatus
=
result
?
STATUS_SUCCESS
:
STATUS_END_OF_FILE
;
s
tatus
=
result
?
STATUS_SUCCESS
:
STATUS_END_OF_FILE
;
if
(
hEvent
)
NtSetEvent
(
hEvent
,
NULL
);
if
(
apc
&&
!
io_status
->
u
.
Status
)
apc
(
apc_user
,
io_status
,
io_status
->
Information
);
goto
done
;
}
}
...
...
@@ -478,7 +478,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
{
if
(
lseek
(
unix_handle
,
offset
->
QuadPart
,
SEEK_SET
)
==
(
off_t
)
-
1
)
{
io_status
->
u
.
S
tatus
=
FILE_GetNtStatus
();
s
tatus
=
FILE_GetNtStatus
();
goto
done
;
}
}
...
...
@@ -486,8 +486,8 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
if
(
flags
&
FD_FLAG_RECV_SHUTDOWN
)
{
if
(
needs_close
)
close
(
unix_handle
)
;
return
STATUS_PIPE_DISCONNECTED
;
status
=
STATUS_PIPE_DISCONNECTED
;
goto
done
;
}
if
(
flags
&
FD_FLAG_TIMEOUT
)
...
...
@@ -496,27 +496,22 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
{
/* this shouldn't happen, but check it */
FIXME
(
"NIY-hEvent
\n
"
);
if
(
needs_close
)
close
(
unix_handle
);
return
STATUS_NOT_IMPLEMENTED
;
}
io_status
->
u
.
Status
=
NtCreateEvent
(
&
hEvent
,
EVENT_ALL_ACCESS
,
NULL
,
0
,
0
);
if
(
io_status
->
u
.
Status
)
{
if
(
needs_close
)
close
(
unix_handle
);
return
io_status
->
u
.
Status
;
status
=
STATUS_NOT_IMPLEMENTED
;
goto
done
;
}
status
=
NtCreateEvent
(
&
hEvent
,
EVENT_ALL_ACCESS
,
NULL
,
0
,
0
);
if
(
status
)
goto
done
;
}
if
(
flags
&
(
FD_FLAG_OVERLAPPED
|
FD_FLAG_TIMEOUT
))
{
async_fileio
*
fileio
;
NTSTATUS
ret
;
if
(
!
(
fileio
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
async_fileio
))))
{
if
(
needs_close
)
close
(
unix_handle
);
if
(
flags
&
FD_FLAG_TIMEOUT
)
NtClose
(
hEvent
);
return
STATUS_NO_MEMORY
;
status
=
STATUS_NO_MEMORY
;
goto
done
;
}
fileio
->
handle
=
hFile
;
fileio
->
count
=
length
;
...
...
@@ -526,25 +521,19 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
fileio
->
queue_apc_on_error
=
0
;
fileio
->
avail_mode
=
(
flags
&
FD_FLAG_AVAILABLE
);
fileio
->
event
=
hEvent
;
if
(
needs_close
)
close
(
unix_handle
);
io_status
->
u
.
Status
=
STATUS_PENDING
;
ret
=
fileio_queue_async
(
fileio
,
io_status
,
TRUE
);
if
(
ret
!=
STATUS_PENDING
)
status
=
fileio_queue_async
(
fileio
,
io_status
,
TRUE
);
if
(
status
!=
STATUS_PENDING
)
{
if
(
flags
&
FD_FLAG_TIMEOUT
)
NtClose
(
hEvent
);
return
ret
;
goto
done
;
}
if
(
needs_close
)
close
(
unix_handle
);
if
(
flags
&
FD_FLAG_TIMEOUT
)
{
do
{
ret
=
NtWaitForSingleObject
(
hEvent
,
TRUE
,
NULL
);
}
while
(
ret
==
STATUS_USER_APC
&&
io_status
->
u
.
Status
==
STATUS_PENDING
);
while
(
NtWaitForSingleObject
(
hEvent
,
TRUE
,
NULL
)
==
STATUS_USER_APC
)
/* nothing */
;
NtClose
(
hEvent
);
if
(
ret
!=
STATUS_USER_APC
)
fileio
->
queue_apc_on_error
=
1
;
}
else
{
...
...
@@ -552,13 +541,13 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
/* let some APC be run, this will read some already pending data */
timeout
.
u
.
LowPart
=
timeout
.
u
.
HighPart
=
0
;
ret
=
NtDelayExecution
(
TRUE
,
&
timeout
);
status
=
NtDelayExecution
(
TRUE
,
&
timeout
);
/* the apc didn't run and therefore the completion routine now
* needs to be sent errors.
* Note that there is no race between setting this flag and
* returning errors because apc's are run only during alertable
* waits */
if
(
ret
!=
STATUS_USER_APC
)
if
(
status
!=
STATUS_USER_APC
)
fileio
->
queue_apc_on_error
=
1
;
}
TRACE
(
"= 0x%08x
\n
"
,
io_status
->
u
.
Status
);
...
...
@@ -566,26 +555,29 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
}
/* code for synchronous reads */
status
=
STATUS_SUCCESS
;
while
((
result
=
read
(
unix_handle
,
buffer
,
length
))
==
-
1
)
{
if
((
errno
==
EAGAIN
)
||
(
errno
==
EINTR
))
continue
;
io_status
->
u
.
S
tatus
=
FILE_GetNtStatus
();
s
tatus
=
FILE_GetNtStatus
();
result
=
0
;
break
;
}
io_status
->
Information
=
result
;
if
(
io_status
->
u
.
S
tatus
==
STATUS_SUCCESS
&&
io_status
->
Information
==
0
)
if
(
s
tatus
==
STATUS_SUCCESS
&&
io_status
->
Information
==
0
)
{
struct
stat
st
;
if
(
fstat
(
unix_handle
,
&
st
)
!=
-
1
&&
S_ISSOCK
(
st
.
st_mode
))
io_status
->
u
.
S
tatus
=
STATUS_PIPE_BROKEN
;
s
tatus
=
STATUS_PIPE_BROKEN
;
else
io_status
->
u
.
S
tatus
=
STATUS_END_OF_FILE
;
s
tatus
=
STATUS_END_OF_FILE
;
}
done:
if
(
needs_close
)
close
(
unix_handle
);
TRACE
(
"= 0x%08x (%lu)
\n
"
,
io_status
->
u
.
Status
,
io_status
->
Information
);
return
io_status
->
u
.
Status
;
TRACE
(
"= 0x%08x (%lu)
\n
"
,
status
,
io_status
->
Information
);
if
(
status
!=
STATUS_PENDING
)
io_status
->
u
.
Status
=
status
;
if
(
apc
&&
!
status
)
apc
(
apc_user
,
io_status
,
0
);
return
status
;
}
/***********************************************************************
...
...
@@ -603,10 +595,10 @@ static void WINAPI FILE_AsyncWriteService(void *ovp, IO_STATUS_BLOCK *iosb, ULON
{
case
STATUS_ALERTED
:
/* write some data (non-blocking) */
if
((
iosb
->
u
.
S
tatus
=
server_get_unix_fd
(
fileio
->
handle
,
FILE_WRITE_DATA
,
&
fd
,
&
needs_close
,
NULL
,
NULL
)))
if
((
s
tatus
=
server_get_unix_fd
(
fileio
->
handle
,
FILE_WRITE_DATA
,
&
fd
,
&
needs_close
,
NULL
,
NULL
)))
{
fileio_terminate
(
fileio
,
iosb
);
fileio_terminate
(
fileio
,
iosb
,
status
);
break
;
}
result
=
write
(
fd
,
&
fileio
->
buffer
[
already
],
fileio
->
count
-
already
);
...
...
@@ -614,24 +606,23 @@ static void WINAPI FILE_AsyncWriteService(void *ovp, IO_STATUS_BLOCK *iosb, ULON
if
(
result
<
0
)
{
if
(
errno
==
EAGAIN
||
errno
==
EINTR
)
iosb
->
u
.
S
tatus
=
STATUS_PENDING
;
else
iosb
->
u
.
S
tatus
=
FILE_GetNtStatus
();
if
(
errno
==
EAGAIN
||
errno
==
EINTR
)
s
tatus
=
STATUS_PENDING
;
else
s
tatus
=
FILE_GetNtStatus
();
}
else
{
iosb
->
Information
+=
result
;
iosb
->
u
.
S
tatus
=
(
iosb
->
Information
<
fileio
->
count
)
?
STATUS_PENDING
:
STATUS_SUCCESS
;
s
tatus
=
(
iosb
->
Information
<
fileio
->
count
)
?
STATUS_PENDING
:
STATUS_SUCCESS
;
TRACE
(
"wrote %d more bytes %ld/%d so far
\n
"
,
result
,
iosb
->
Information
,
fileio
->
count
);
}
if
(
iosb
->
u
.
S
tatus
==
STATUS_PENDING
)
if
(
s
tatus
==
STATUS_PENDING
)
fileio_queue_async
(
fileio
,
iosb
,
FALSE
);
else
fileio_terminate
(
fileio
,
iosb
);
fileio_terminate
(
fileio
,
iosb
,
status
);
break
;
default:
iosb
->
u
.
Status
=
status
;
fileio_terminate
(
fileio
,
iosb
);
fileio_terminate
(
fileio
,
iosb
,
status
);
break
;
}
}
...
...
@@ -665,6 +656,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
PLARGE_INTEGER
offset
,
PULONG
key
)
{
int
result
,
unix_handle
,
needs_close
,
flags
;
NTSTATUS
status
;
enum
server_fd_type
type
;
TRACE
(
"(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p)!
\n
"
,
...
...
@@ -673,9 +665,13 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
if
(
!
io_status
)
return
STATUS_ACCESS_VIOLATION
;
io_status
->
Information
=
0
;
io_status
->
u
.
Status
=
server_get_unix_fd
(
hFile
,
FILE_WRITE_DATA
,
&
unix_handle
,
&
needs_close
,
&
type
,
&
flags
);
if
(
io_status
->
u
.
Status
)
return
io_status
->
u
.
Status
;
status
=
server_get_unix_fd
(
hFile
,
FILE_WRITE_DATA
,
&
unix_handle
,
&
needs_close
,
&
type
,
&
flags
);
if
(
status
)
{
io_status
->
u
.
Status
=
status
;
return
status
;
}
if
(
type
==
FD_TYPE_FILE
&&
offset
)
{
...
...
@@ -687,20 +683,19 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
if
(
errno
==
EINTR
)
continue
;
if
(
errno
==
EAGAIN
||
errno
==
ESPIPE
)
{
io_status
->
u
.
S
tatus
=
STATUS_PENDING
;
s
tatus
=
STATUS_PENDING
;
break
;
}
result
=
0
;
if
(
errno
==
EFAULT
)
io_status
->
u
.
S
tatus
=
STATUS_INVALID_USER_BUFFER
;
else
io_status
->
u
.
S
tatus
=
FILE_GetNtStatus
();
if
(
errno
==
EFAULT
)
s
tatus
=
STATUS_INVALID_USER_BUFFER
;
else
s
tatus
=
FILE_GetNtStatus
();
goto
done
;
}
if
(
result
>=
0
)
{
io_status
->
Information
=
result
;
io_status
->
u
.
S
tatus
=
STATUS_SUCCESS
;
s
tatus
=
STATUS_SUCCESS
;
if
(
hEvent
)
NtSetEvent
(
hEvent
,
NULL
);
if
(
apc
)
apc
(
apc_user
,
io_status
,
io_status
->
Information
);
goto
done
;
}
}
...
...
@@ -708,7 +703,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
{
if
(
lseek
(
unix_handle
,
offset
->
QuadPart
,
SEEK_SET
)
==
(
off_t
)
-
1
)
{
io_status
->
u
.
S
tatus
=
FILE_GetNtStatus
();
s
tatus
=
FILE_GetNtStatus
();
goto
done
;
}
}
...
...
@@ -716,8 +711,8 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
if
(
flags
&
FD_FLAG_SEND_SHUTDOWN
)
{
if
(
needs_close
)
close
(
unix_handle
)
;
return
STATUS_PIPE_DISCONNECTED
;
status
=
STATUS_PIPE_DISCONNECTED
;
goto
done
;
}
if
(
flags
&
FD_FLAG_TIMEOUT
)
...
...
@@ -726,27 +721,22 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
{
/* this shouldn't happen, but check it */
FIXME
(
"NIY-hEvent
\n
"
);
if
(
needs_close
)
close
(
unix_handle
);
return
STATUS_NOT_IMPLEMENTED
;
}
io_status
->
u
.
Status
=
NtCreateEvent
(
&
hEvent
,
EVENT_ALL_ACCESS
,
NULL
,
0
,
0
);
if
(
io_status
->
u
.
Status
)
{
if
(
needs_close
)
close
(
unix_handle
);
return
io_status
->
u
.
Status
;
status
=
STATUS_NOT_IMPLEMENTED
;
goto
done
;
}
status
=
NtCreateEvent
(
&
hEvent
,
EVENT_ALL_ACCESS
,
NULL
,
0
,
0
);
if
(
status
)
goto
done
;
}
if
(
flags
&
(
FD_FLAG_OVERLAPPED
|
FD_FLAG_TIMEOUT
))
{
async_fileio
*
fileio
;
NTSTATUS
ret
;
if
(
!
(
fileio
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
async_fileio
))))
{
if
(
needs_close
)
close
(
unix_handle
);
if
(
flags
&
FD_FLAG_TIMEOUT
)
NtClose
(
hEvent
);
return
STATUS_NO_MEMORY
;
status
=
STATUS_NO_MEMORY
;
goto
done
;
}
fileio
->
handle
=
hFile
;
fileio
->
count
=
length
;
...
...
@@ -756,26 +746,20 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
fileio
->
queue_apc_on_error
=
0
;
fileio
->
avail_mode
=
(
flags
&
FD_FLAG_AVAILABLE
);
fileio
->
event
=
hEvent
;
if
(
needs_close
)
close
(
unix_handle
);
io_status
->
Information
=
0
;
io_status
->
u
.
Status
=
STATUS_PENDING
;
ret
=
fileio_queue_async
(
fileio
,
io_status
,
FALSE
);
if
(
ret
!=
STATUS_PENDING
)
status
=
fileio_queue_async
(
fileio
,
io_status
,
FALSE
);
if
(
status
!=
STATUS_PENDING
)
{
if
(
flags
&
FD_FLAG_TIMEOUT
)
NtClose
(
hEvent
);
return
ret
;
goto
done
;
}
if
(
needs_close
)
close
(
unix_handle
);
if
(
flags
&
FD_FLAG_TIMEOUT
)
{
do
{
ret
=
NtWaitForSingleObject
(
hEvent
,
TRUE
,
NULL
);
}
while
(
ret
==
STATUS_USER_APC
&&
io_status
->
u
.
Status
==
STATUS_PENDING
);
while
(
NtWaitForSingleObject
(
hEvent
,
TRUE
,
NULL
)
==
STATUS_USER_APC
)
/* nothing */
;
NtClose
(
hEvent
);
if
(
ret
!=
STATUS_USER_APC
)
fileio
->
queue_apc_on_error
=
1
;
}
else
{
...
...
@@ -783,31 +767,34 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
/* let some APC be run, this will write as much data as possible */
timeout
.
u
.
LowPart
=
timeout
.
u
.
HighPart
=
0
;
ret
=
NtDelayExecution
(
TRUE
,
&
timeout
);
status
=
NtDelayExecution
(
TRUE
,
&
timeout
);
/* the apc didn't run and therefore the completion routine now
* needs to be sent errors.
* Note that there is no race between setting this flag and
* returning errors because apc's are run only during alertable
* waits */
if
(
ret
!=
STATUS_USER_APC
)
if
(
status
!=
STATUS_USER_APC
)
fileio
->
queue_apc_on_error
=
1
;
}
return
io_status
->
u
.
Status
;
}
/* synchronous file write */
status
=
STATUS_SUCCESS
;
while
((
result
=
write
(
unix_handle
,
buffer
,
length
))
==
-
1
)
{
if
((
errno
==
EAGAIN
)
||
(
errno
==
EINTR
))
continue
;
result
=
0
;
if
(
errno
==
EFAULT
)
io_status
->
u
.
S
tatus
=
STATUS_INVALID_USER_BUFFER
;
else
io_status
->
u
.
S
tatus
=
FILE_GetNtStatus
();
if
(
errno
==
EFAULT
)
s
tatus
=
STATUS_INVALID_USER_BUFFER
;
else
s
tatus
=
FILE_GetNtStatus
();
break
;
}
io_status
->
Information
=
result
;
done:
if
(
needs_close
)
close
(
unix_handle
);
return
io_status
->
u
.
Status
;
if
(
status
!=
STATUS_PENDING
)
io_status
->
u
.
Status
=
status
;
if
(
apc
&&
!
status
)
apc
(
apc_user
,
io_status
,
0
);
return
status
;
}
/**************************************************************************
...
...
@@ -906,6 +893,8 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
PVOID
apc_context
,
PIO_STATUS_BLOCK
io
,
ULONG
code
,
PVOID
in_buffer
,
ULONG
in_size
,
PVOID
out_buffer
,
ULONG
out_size
)
{
NTSTATUS
status
;
TRACE
(
"(%p,%p,%p,%p,%p,0x%08x,%p,0x%08x,%p,0x%08x)
\n
"
,
handle
,
event
,
apc
,
apc_context
,
io
,
code
,
in_buffer
,
in_size
,
out_buffer
,
out_size
);
...
...
@@ -915,7 +904,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
switch
(
code
)
{
case
FSCTL_DISMOUNT_VOLUME
:
io
->
u
.
S
tatus
=
DIR_unmount_device
(
handle
);
s
tatus
=
DIR_unmount_device
(
handle
);
break
;
case
FSCTL_PIPE_LISTEN
:
...
...
@@ -924,8 +913,8 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
if
(
!
event
&&
!
apc
)
{
io
->
u
.
S
tatus
=
NtCreateEvent
(
&
internal_event
,
EVENT_ALL_ACCESS
,
NULL
,
FALSE
,
FALSE
);
if
(
io
->
u
.
Status
!=
STATUS_SUCCESS
)
return
io
->
u
.
Status
;
s
tatus
=
NtCreateEvent
(
&
internal_event
,
EVENT_ALL_ACCESS
,
NULL
,
FALSE
,
FALSE
);
if
(
status
!=
STATUS_SUCCESS
)
break
;
}
SERVER_START_REQ
(
connect_named_pipe
)
{
...
...
@@ -936,13 +925,14 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
req
->
async
.
apc
=
apc
;
req
->
async
.
apc_arg
=
apc_context
;
req
->
async
.
event
=
event
?
event
:
internal_event
;
io
->
u
.
S
tatus
=
wine_server_call
(
req
);
s
tatus
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
internal_event
&&
io
->
u
.
S
tatus
==
STATUS_PENDING
)
if
(
internal_event
&&
s
tatus
==
STATUS_PENDING
)
{
while
(
NtWaitForSingleObject
(
internal_event
,
TRUE
,
NULL
)
==
STATUS_USER_APC
)
/*nothing*/
;
status
=
io
->
u
.
Status
;
}
if
(
internal_event
)
NtClose
(
internal_event
);
}
...
...
@@ -955,8 +945,8 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
if
(
!
event
&&
!
apc
)
{
io
->
u
.
S
tatus
=
NtCreateEvent
(
&
internal_event
,
EVENT_ALL_ACCESS
,
NULL
,
FALSE
,
FALSE
);
if
(
io
->
u
.
Status
!=
STATUS_SUCCESS
)
return
io
->
u
.
Status
;
s
tatus
=
NtCreateEvent
(
&
internal_event
,
EVENT_ALL_ACCESS
,
NULL
,
FALSE
,
FALSE
);
if
(
status
!=
STATUS_SUCCESS
)
break
;
}
SERVER_START_REQ
(
wait_named_pipe
)
{
...
...
@@ -970,13 +960,14 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
req
->
async
.
apc_arg
=
apc_context
;
req
->
async
.
event
=
event
?
event
:
internal_event
;
wine_server_add_data
(
req
,
buff
->
Name
,
buff
->
NameLength
);
io
->
u
.
S
tatus
=
wine_server_call
(
req
);
s
tatus
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
internal_event
&&
io
->
u
.
S
tatus
==
STATUS_PENDING
)
if
(
internal_event
&&
s
tatus
==
STATUS_PENDING
)
{
while
(
NtWaitForSingleObject
(
internal_event
,
TRUE
,
NULL
)
==
STATUS_USER_APC
)
/*nothing*/
;
status
=
io
->
u
.
Status
;
}
if
(
internal_event
)
NtClose
(
internal_event
);
}
...
...
@@ -989,18 +980,17 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
if
(
out_size
<
FIELD_OFFSET
(
FILE_PIPE_PEEK_BUFFER
,
Data
))
{
io
->
u
.
S
tatus
=
STATUS_INFO_LENGTH_MISMATCH
;
s
tatus
=
STATUS_INFO_LENGTH_MISMATCH
;
break
;
}
if
((
io
->
u
.
Status
=
server_get_unix_fd
(
handle
,
FILE_READ_DATA
,
&
fd
,
&
needs_close
,
NULL
,
&
flags
)))
if
((
status
=
server_get_unix_fd
(
handle
,
FILE_READ_DATA
,
&
fd
,
&
needs_close
,
NULL
,
&
flags
)))
break
;
if
(
flags
&
FD_FLAG_RECV_SHUTDOWN
)
{
if
(
needs_close
)
close
(
fd
);
io
->
u
.
S
tatus
=
STATUS_PIPE_DISCONNECTED
;
s
tatus
=
STATUS_PIPE_DISCONNECTED
;
break
;
}
...
...
@@ -1009,7 +999,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
{
TRACE
(
"FIONREAD failed reason: %s
\n
"
,
strerror
(
errno
));
if
(
needs_close
)
close
(
fd
);
io
->
u
.
S
tatus
=
FILE_GetNtStatus
();
s
tatus
=
FILE_GetNtStatus
();
break
;
}
#endif
...
...
@@ -1025,7 +1015,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
if
(
ret
==
-
1
||
(
ret
==
1
&&
(
pollfd
.
revents
&
(
POLLHUP
|
POLLERR
))))
{
if
(
needs_close
)
close
(
fd
);
io
->
u
.
S
tatus
=
STATUS_PIPE_BROKEN
;
s
tatus
=
STATUS_PIPE_BROKEN
;
break
;
}
}
...
...
@@ -1034,7 +1024,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
buffer
->
NumberOfMessages
=
0
;
/* FIXME */
buffer
->
MessageLength
=
0
;
/* FIXME */
io
->
Information
=
FIELD_OFFSET
(
FILE_PIPE_PEEK_BUFFER
,
Data
);
io
->
u
.
S
tatus
=
STATUS_SUCCESS
;
s
tatus
=
STATUS_SUCCESS
;
if
(
avail
)
{
ULONG
data_size
=
out_size
-
FIELD_OFFSET
(
FILE_PIPE_PEEK_BUFFER
,
Data
);
...
...
@@ -1052,8 +1042,8 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
SERVER_START_REQ
(
disconnect_named_pipe
)
{
req
->
handle
=
handle
;
io
->
u
.
S
tatus
=
wine_server_call
(
req
);
if
(
!
io
->
u
.
S
tatus
)
s
tatus
=
wine_server_call
(
req
);
if
(
!
s
tatus
)
{
int
fd
=
server_remove_fd_from_cache
(
handle
);
if
(
fd
!=
-
1
)
close
(
fd
);
...
...
@@ -1066,16 +1056,18 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
case
FSCTL_UNLOCK_VOLUME
:
FIXME
(
"stub! return success - Unsupported fsctl %x (device=%x access=%x func=%x method=%x)
\n
"
,
code
,
code
>>
16
,
(
code
>>
14
)
&
3
,
(
code
>>
2
)
&
0xfff
,
code
&
3
);
io
->
u
.
S
tatus
=
STATUS_SUCCESS
;
s
tatus
=
STATUS_SUCCESS
;
break
;
default:
FIXME
(
"Unsupported fsctl %x (device=%x access=%x func=%x method=%x)
\n
"
,
code
,
code
>>
16
,
(
code
>>
14
)
&
3
,
(
code
>>
2
)
&
0xfff
,
code
&
3
);
io
->
u
.
S
tatus
=
STATUS_NOT_SUPPORTED
;
s
tatus
=
STATUS_NOT_SUPPORTED
;
break
;
}
return
io
->
u
.
Status
;
if
(
status
!=
STATUS_PENDING
)
io
->
u
.
Status
=
status
;
return
status
;
}
/******************************************************************************
...
...
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