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
309ed4e1
Commit
309ed4e1
authored
Nov 07, 2001
by
Mike McCormack
Committed by
Alexandre Julliard
Nov 07, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make ConnectNamedPipe work in overlapped mode.
parent
37f61c45
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
161 additions
and
65 deletions
+161
-65
sync.c
dlls/kernel/sync.c
+113
-32
server_protocol.h
include/wine/server_protocol.h
+5
-3
synchro.c
scheduler/synchro.c
+1
-0
named_pipe.c
server/named_pipe.c
+34
-26
protocol.def
server/protocol.def
+4
-2
trace.c
server/trace.c
+4
-2
No files found.
dlls/kernel/sync.c
View file @
309ed4e1
...
...
@@ -601,38 +601,72 @@ BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
return
FALSE
;
}
/***********************************************************************
* SYNC_CompletePipeOverlapped (Internal)
*/
static
void
SYNC_CompletePipeOverlapped
(
LPOVERLAPPED
overlapped
,
DWORD
result
)
{
TRACE
(
"for %p result %08lx
\n
"
,
overlapped
,
result
);
if
(
!
overlapped
)
return
;
overlapped
->
Internal
=
result
;
SetEvent
(
overlapped
->
hEvent
);
}
/***********************************************************************
* WaitNamedPipeA (KERNEL32.@)
*/
BOOL
WINAPI
WaitNamedPipeA
(
LPCSTR
name
,
DWORD
nTimeOut
)
static
BOOL
SYNC_WaitNamedPipeA
(
LPCSTR
name
,
DWORD
nTimeOut
,
LPOVERLAPPED
overlapped
)
{
DWORD
len
=
name
?
MultiByteToWideChar
(
CP_ACP
,
0
,
name
,
strlen
(
name
),
NULL
,
0
)
:
0
;
HANDLE
event
;
BOOL
ret
;
TRACE
(
"%s 0x%08lx
\n
"
,
debugstr_a
(
name
),
nTimeOut
);
if
(
len
>=
MAX_PATH
)
{
SetLastError
(
ERROR_FILENAME_EXCED_RANGE
);
return
FALSE
;
}
if
(
!
(
event
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
)))
return
FALSE
;
SERVER_START_VAR_REQ
(
wait_named_pipe
,
len
*
sizeof
(
WCHAR
)
)
{
req
->
timeout
=
nTimeOut
;
req
->
event
=
event
;
req
->
overlapped
=
overlapped
;
req
->
func
=
SYNC_CompletePipeOverlapped
;
if
(
len
)
MultiByteToWideChar
(
CP_ACP
,
0
,
name
,
strlen
(
name
),
server_data_ptr
(
req
),
len
);
ret
=
!
SERVER_CALL_ERR
();
}
SERVER_END_REQ
;
if
(
ret
)
WaitForSingleObject
(
event
,
INFINITE
);
return
ret
;
}
/***********************************************************************
* WaitNamedPipeA (KERNEL32.@)
*/
BOOL
WINAPI
WaitNamedPipeA
(
LPCSTR
name
,
DWORD
nTimeOut
)
{
BOOL
ret
;
OVERLAPPED
ov
;
TRACE
(
"%s 0x%08lx
\n
"
,
debugstr_a
(
name
),
nTimeOut
);
memset
(
&
ov
,
0
,
sizeof
ov
);
ov
.
hEvent
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
);
if
(
!
ov
.
hEvent
)
return
FALSE
;
CloseHandle
(
event
);
/* expect to fail with STATUS_PENDING */
ret
=
SYNC_WaitNamedPipeA
(
name
,
nTimeOut
,
&
ov
);
if
(
ret
)
{
if
(
WAIT_OBJECT_0
==
WaitForSingleObject
(
ov
.
hEvent
,
INFINITE
))
{
SetLastError
(
ov
.
Internal
);
ret
=
(
ov
.
Internal
==
STATUS_SUCCESS
);
}
}
CloseHandle
(
ov
.
hEvent
);
return
ret
;
}
...
...
@@ -640,68 +674,115 @@ BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut)
/***********************************************************************
* WaitNamedPipeW (KERNEL32.@)
*/
BOOL
WINAPI
WaitNamedPipeW
(
LPCWSTR
name
,
DWORD
nTimeOut
)
static
BOOL
SYNC_WaitNamedPipeW
(
LPCWSTR
name
,
DWORD
nTimeOut
,
LPOVERLAPPED
overlapped
)
{
DWORD
len
=
name
?
strlenW
(
name
)
:
0
;
HANDLE
event
;
BOOL
ret
;
TRACE
(
"%s 0x%08lx
\n
"
,
debugstr_w
(
name
),
nTimeOut
);
if
(
len
>=
MAX_PATH
)
{
SetLastError
(
ERROR_FILENAME_EXCED_RANGE
);
return
FALSE
;
}
if
(
!
(
event
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
)))
return
FALSE
;
SERVER_START_VAR_REQ
(
wait_named_pipe
,
len
*
sizeof
(
WCHAR
)
)
{
req
->
timeout
=
nTimeOut
;
req
->
event
=
event
;
req
->
overlapped
=
overlapped
;
req
->
func
=
SYNC_CompletePipeOverlapped
;
memcpy
(
server_data_ptr
(
req
),
name
,
len
*
sizeof
(
WCHAR
)
);
ret
=
!
SERVER_CALL_ERR
();
}
SERVER_END_REQ
;
if
(
ret
)
WaitForSingleObject
(
event
,
INFINITE
);
CloseHandle
(
event
);
return
ret
;
}
/***********************************************************************
*
ConnectNamedPipe
(KERNEL32.@)
*
WaitNamedPipeW
(KERNEL32.@)
*/
BOOL
WINAPI
ConnectNamedPipe
(
HANDLE
hPipe
,
LPOVERLAPPED
overlapped
)
BOOL
WINAPI
WaitNamedPipeW
(
LPCWSTR
name
,
DWORD
nTimeOut
)
{
BOOL
ret
;
HANDLE
event
;
OVERLAPPED
ov
;
TRACE
(
"
(%d,%p)
\n
"
,
hPipe
,
overlapped
);
TRACE
(
"
%s 0x%08lx
\n
"
,
debugstr_w
(
name
),
nTimeOut
);
if
(
overlapped
)
{
FIXME
(
"overlapped operation not supported
\n
"
);
SetLastError
(
ERROR_CALL_NOT_IMPLEMENTED
);
memset
(
&
ov
,
0
,
sizeof
ov
);
ov
.
hEvent
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
);
if
(
!
ov
.
hEvent
)
return
FALSE
;
ret
=
SYNC_WaitNamedPipeW
(
name
,
nTimeOut
,
&
ov
);
if
(
ret
)
{
if
(
WAIT_OBJECT_0
==
WaitForSingleObject
(
ov
.
hEvent
,
INFINITE
))
{
SetLastError
(
ov
.
Internal
);
ret
=
(
ov
.
Internal
==
STATUS_SUCCESS
);
}
}
if
(
!
(
event
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
)))
return
FALSE
;
CloseHandle
(
ov
.
hEvent
);
return
ret
;
}
/***********************************************************************
* SYNC_ConnectNamedPipe (Internal)
*/
static
BOOL
SYNC_ConnectNamedPipe
(
HANDLE
hPipe
,
LPOVERLAPPED
overlapped
)
{
BOOL
ret
;
if
(
!
overlapped
)
return
FALSE
;
overlapped
->
Internal
=
STATUS_PENDING
;
SERVER_START_REQ
(
connect_named_pipe
)
{
req
->
handle
=
hPipe
;
req
->
event
=
event
;
req
->
overlapped
=
overlapped
;
req
->
func
=
SYNC_CompletePipeOverlapped
;
ret
=
!
SERVER_CALL_ERR
();
}
SERVER_END_REQ
;
if
(
ret
)
WaitForSingleObject
(
event
,
INFINITE
);
return
ret
;
}
/***********************************************************************
* ConnectNamedPipe (KERNEL32.@)
*/
BOOL
WINAPI
ConnectNamedPipe
(
HANDLE
hPipe
,
LPOVERLAPPED
overlapped
)
{
OVERLAPPED
ov
;
BOOL
ret
;
TRACE
(
"(%d,%p)
\n
"
,
hPipe
,
overlapped
);
if
(
overlapped
)
return
SYNC_ConnectNamedPipe
(
hPipe
,
overlapped
);
memset
(
&
ov
,
0
,
sizeof
ov
);
ov
.
hEvent
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
);
if
(
!
ov
.
hEvent
)
return
FALSE
;
ret
=
SYNC_ConnectNamedPipe
(
hPipe
,
&
ov
);
if
(
ret
)
{
if
(
WAIT_OBJECT_0
==
WaitForSingleObject
(
ov
.
hEvent
,
INFINITE
))
{
SetLastError
(
ov
.
Internal
);
ret
=
(
ov
.
Internal
==
STATUS_SUCCESS
);
}
}
CloseHandle
(
ov
.
hEvent
);
CloseHandle
(
event
);
return
ret
;
}
...
...
include/wine/server_protocol.h
View file @
309ed4e1
...
...
@@ -1552,7 +1552,8 @@ struct connect_named_pipe_request
{
struct
request_header
__header
;
handle_t
handle
;
handle_t
event
;
void
*
overlapped
;
void
*
func
;
};
...
...
@@ -1561,7 +1562,8 @@ struct wait_named_pipe_request
{
struct
request_header
__header
;
unsigned
int
timeout
;
handle_t
event
;
void
*
overlapped
;
void
*
func
;
/* VARARG(filename,string); */
};
...
...
@@ -2056,6 +2058,6 @@ union generic_request
struct
get_window_properties_request
get_window_properties
;
};
#define SERVER_PROTOCOL_VERSION 6
2
#define SERVER_PROTOCOL_VERSION 6
3
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
scheduler/synchro.c
View file @
309ed4e1
...
...
@@ -243,6 +243,7 @@ static void call_apcs( BOOL alertable )
case
APC_NONE
:
return
;
/* no more APCs */
case
APC_ASYNC
:
proc
(
args
[
0
],
args
[
1
]);
break
;
case
APC_USER
:
proc
(
args
[
0
]
);
...
...
server/named_pipe.c
View file @
309ed4e1
...
...
@@ -48,7 +48,9 @@ struct pipe_user
struct
named_pipe
*
pipe
;
struct
pipe_user
*
next
;
struct
pipe_user
*
prev
;
struct
event
*
event
;
void
*
thread
;
void
*
func
;
void
*
overlapped
;
};
struct
named_pipe
...
...
@@ -122,18 +124,28 @@ static void named_pipe_destroy( struct object *obj)
assert
(
!
pipe
->
users
);
}
static
void
notify_waiter
(
struct
pipe_user
*
user
,
unsigned
int
status
)
{
if
(
user
->
thread
&&
user
->
func
&&
user
->
overlapped
)
{
/* queue a system APC, to notify a waiting thread */
thread_queue_apc
(
user
->
thread
,
NULL
,
user
->
func
,
APC_ASYNC
,
1
,
2
,
user
->
overlapped
,
status
);
}
user
->
thread
=
NULL
;
user
->
func
=
NULL
;
user
->
overlapped
=
NULL
;
}
static
void
pipe_user_destroy
(
struct
object
*
obj
)
{
struct
pipe_user
*
user
=
(
struct
pipe_user
*
)
obj
;
assert
(
obj
->
ops
==
&
pipe_user_ops
);
if
(
user
->
event
)
{
/* FIXME: signal waiter of failure */
release_object
(
user
->
event
);
user
->
event
=
NULL
;
}
if
(
user
->
overlapped
)
notify_waiter
(
user
,
STATUS_HANDLES_CLOSED
);
if
(
user
->
other
)
{
close
(
user
->
other
->
obj
.
fd
);
...
...
@@ -217,8 +229,10 @@ static struct pipe_user *create_pipe_user( struct named_pipe *pipe, int fd )
user
->
pipe
=
pipe
;
user
->
state
=
ps_none
;
user
->
event
=
NULL
;
/* thread wait on this pipe */
user
->
other
=
NULL
;
user
->
thread
=
NULL
;
user
->
func
=
NULL
;
user
->
overlapped
=
NULL
;
/* add to list of pipe users */
if
((
user
->
next
=
pipe
->
users
))
user
->
next
->
prev
=
user
;
...
...
@@ -301,9 +315,7 @@ DECL_HANDLER(open_named_pipe)
if
(
(
user
=
create_pipe_user
(
pipe
,
fds
[
1
]))
)
{
partner
->
obj
.
fd
=
fds
[
0
];
set_event
(
partner
->
event
);
release_object
(
partner
->
event
);
partner
->
event
=
NULL
;
notify_waiter
(
partner
,
STATUS_SUCCESS
);
partner
->
state
=
ps_connected_server
;
partner
->
other
=
user
;
user
->
state
=
ps_connected_client
;
...
...
@@ -334,7 +346,6 @@ DECL_HANDLER(open_named_pipe)
DECL_HANDLER
(
connect_named_pipe
)
{
struct
pipe_user
*
user
,
*
partner
;
struct
event
*
event
;
user
=
get_pipe_user_obj
(
current
->
process
,
req
->
handle
,
0
);
if
(
!
user
)
...
...
@@ -347,16 +358,14 @@ DECL_HANDLER(connect_named_pipe)
else
{
user
->
state
=
ps_wait_open
;
event
=
get_event_obj
(
current
->
process
,
req
->
event
,
0
)
;
if
(
event
)
user
->
event
=
event
;
user
->
thread
=
current
;
user
->
func
=
req
->
func
;
user
->
overlapped
=
req
->
overlapped
;
/* notify all waiters that a pipe just became available */
while
(
(
partner
=
find_partner
(
user
->
pipe
,
ps_wait_connect
))
)
{
set_event
(
partner
->
event
);
release_object
(
partner
->
event
);
partner
->
event
=
NULL
;
notify_waiter
(
partner
,
STATUS_SUCCESS
);
release_object
(
partner
);
release_object
(
partner
);
}
...
...
@@ -367,13 +376,8 @@ DECL_HANDLER(connect_named_pipe)
DECL_HANDLER
(
wait_named_pipe
)
{
struct
event
*
event
;
struct
named_pipe
*
pipe
;
event
=
get_event_obj
(
current
->
process
,
req
->
event
,
0
);
if
(
!
event
)
return
;
pipe
=
create_named_pipe
(
get_req_data
(
req
),
get_req_data_size
(
req
)
);
if
(
pipe
)
{
...
...
@@ -385,7 +389,10 @@ DECL_HANDLER(wait_named_pipe)
set_error
(
STATUS_SUCCESS
);
if
(
(
partner
=
find_partner
(
pipe
,
ps_wait_open
))
)
{
set_event
(
event
);
/* this should use notify_waiter,
but no pipe_user object exists now... */
thread_queue_apc
(
current
,
NULL
,
req
->
func
,
APC_ASYNC
,
1
,
2
,
req
->
overlapped
,
STATUS_SUCCESS
);
release_object
(
partner
);
}
else
...
...
@@ -394,8 +401,10 @@ DECL_HANDLER(wait_named_pipe)
if
(
(
user
=
create_pipe_user
(
pipe
,
-
1
))
)
{
user
->
event
=
(
struct
event
*
)
grab_object
(
event
);
user
->
state
=
ps_wait_connect
;
user
->
thread
=
current
;
user
->
func
=
req
->
func
;
user
->
overlapped
=
req
->
overlapped
;
/* don't release it */
}
}
...
...
@@ -406,7 +415,6 @@ DECL_HANDLER(wait_named_pipe)
}
release_object
(
pipe
);
}
release_object
(
event
);
}
DECL_HANDLER
(
disconnect_named_pipe
)
...
...
server/protocol.def
View file @
309ed4e1
...
...
@@ -1392,14 +1392,16 @@ enum message_type
/* Connect to a named pipe */
@REQ(connect_named_pipe)
handle_t handle;
handle_t event; /* set this event when it's ready */
void* overlapped;
void* func;
@END
/* Wait for a named pipe */
@REQ(wait_named_pipe)
unsigned int timeout;
handle_t event; /* set this event when it's ready */
void* overlapped;
void* func;
VARARG(filename,string); /* pipe name */
@END
...
...
server/trace.c
View file @
309ed4e1
...
...
@@ -1661,13 +1661,15 @@ static void dump_open_named_pipe_reply( const struct open_named_pipe_request *re
static
void
dump_connect_named_pipe_request
(
const
struct
connect_named_pipe_request
*
req
)
{
fprintf
(
stderr
,
" handle=%d,"
,
req
->
handle
);
fprintf
(
stderr
,
" event=%d"
,
req
->
event
);
fprintf
(
stderr
,
" overlapped=%p,"
,
req
->
overlapped
);
fprintf
(
stderr
,
" func=%p"
,
req
->
func
);
}
static
void
dump_wait_named_pipe_request
(
const
struct
wait_named_pipe_request
*
req
)
{
fprintf
(
stderr
,
" timeout=%08x,"
,
req
->
timeout
);
fprintf
(
stderr
,
" event=%d,"
,
req
->
event
);
fprintf
(
stderr
,
" overlapped=%p,"
,
req
->
overlapped
);
fprintf
(
stderr
,
" func=%p,"
,
req
->
func
);
fprintf
(
stderr
,
" filename="
);
cur_pos
+=
dump_varargs_string
(
req
);
}
...
...
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