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
bf55457f
Commit
bf55457f
authored
Aug 23, 2001
by
Mike McCormack
Committed by
Alexandre Julliard
Aug 23, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement WaitNamedPipe and DisconnectNamedPipe.
Add a state for each pipe handle in the server. Create a socket on when the pipe is opened, not before.
parent
c86517fc
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
290 additions
and
76 deletions
+290
-76
sync.c
dlls/kernel/sync.c
+75
-26
server_protocol.h
include/wine/server_protocol.h
+23
-1
named_pipe.c
server/named_pipe.c
+155
-49
protocol.def
server/protocol.def
+14
-0
request.h
server/request.h
+4
-0
trace.c
server/trace.c
+19
-0
No files found.
dlls/kernel/sync.c
View file @
bf55457f
...
...
@@ -605,24 +605,73 @@ BOOL WINAPI PeekNamedPipe( HANDLE hPipe, LPVOID lpvBuffer, DWORD cbBuffer,
/***********************************************************************
* WaitNamedPipeA (KERNEL32.@)
*/
BOOL
WINAPI
WaitNamedPipeA
(
LPCSTR
lpNamedPipeN
ame
,
DWORD
nTimeOut
)
BOOL
WINAPI
WaitNamedPipeA
(
LPCSTR
n
ame
,
DWORD
nTimeOut
)
{
FIXME
(
"%s 0x%08lx
\n
"
,
lpNamedPipeName
,
nTimeOut
);
SetLastError
(
ERROR_PIPE_NOT_CONNECTED
);
return
FALSE
;
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
;
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
);
CloseHandle
(
event
);
return
ret
;
}
/***********************************************************************
* WaitNamedPipeW (KERNEL32.@)
*/
BOOL
WINAPI
WaitNamedPipeW
(
LPCWSTR
lpNamedPipeN
ame
,
DWORD
nTimeOut
)
BOOL
WINAPI
WaitNamedPipeW
(
LPCWSTR
n
ame
,
DWORD
nTimeOut
)
{
FIXME
(
"%s 0x%08lx
\n
"
,
debugstr_w
(
lpNamedPipeName
),
nTimeOut
);
SetLastError
(
ERROR_PIPE_NOT_CONNECTED
);
return
FALSE
;
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
;
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.@)
*/
...
...
@@ -631,7 +680,7 @@ BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
BOOL
ret
;
HANDLE
event
;
TRACE
(
"(%d,%p)
:stub
\n
"
,
hPipe
,
overlapped
);
TRACE
(
"(%d,%p)
\n
"
,
hPipe
,
overlapped
);
if
(
overlapped
)
{
...
...
@@ -640,29 +689,20 @@ BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
return
FALSE
;
}
event
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
);
if
(
event
==
INVALID_HANDLE_VALUE
)
{
ERR
(
"create event failed!
\n
"
);
return
FALSE
;
}
if
(
!
(
event
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
)))
return
FALSE
;
SERVER_START_REQ
(
connect_named_pipe
)
{
req
->
handle
=
hPipe
;
req
->
event
=
event
;
ret
=
SERVER_CALL_ERR
();
ret
=
!
SERVER_CALL_ERR
();
}
SERVER_END_REQ
;
if
(
ret
)
{
ERR
(
"server returned status %08lx
\n
"
,
GetLastError
());
return
FALSE
;
}
if
(
ret
)
WaitForSingleObject
(
event
,
INFINITE
);
WaitForSingleObject
(
event
,
INFINITE
);
return
TRUE
;
CloseHandle
(
event
);
return
ret
;
}
/***********************************************************************
...
...
@@ -670,8 +710,17 @@ BOOL WINAPI ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped)
*/
BOOL
WINAPI
DisconnectNamedPipe
(
HANDLE
hPipe
)
{
FIXME
(
"(%d):stub
\n
"
,
hPipe
);
SetLastError
(
ERROR_CALL_NOT_IMPLEMENTED
);
return
FALSE
;
BOOL
ret
;
TRACE
(
"(%d)
\n
"
,
hPipe
);
SERVER_START_REQ
(
disconnect_named_pipe
)
{
req
->
handle
=
hPipe
;
ret
=
!
SERVER_CALL_ERR
();
}
SERVER_END_REQ
;
return
ret
;
}
include/wine/server_protocol.h
View file @
bf55457f
...
...
@@ -1532,6 +1532,24 @@ struct connect_named_pipe_request
};
struct
wait_named_pipe_request
{
struct
request_header
__header
;
unsigned
int
timeout
;
handle_t
event
;
/* VARARG(filename,string); */
};
struct
disconnect_named_pipe_request
{
struct
request_header
__header
;
handle_t
handle
;
};
enum
request
{
REQ_new_process
,
...
...
@@ -1654,6 +1672,8 @@ enum request
REQ_create_named_pipe
,
REQ_open_named_pipe
,
REQ_connect_named_pipe
,
REQ_wait_named_pipe
,
REQ_disconnect_named_pipe
,
REQ_NB_REQUESTS
};
...
...
@@ -1781,8 +1801,10 @@ union generic_request
struct
create_named_pipe_request
create_named_pipe
;
struct
open_named_pipe_request
open_named_pipe
;
struct
connect_named_pipe_request
connect_named_pipe
;
struct
wait_named_pipe_request
wait_named_pipe
;
struct
disconnect_named_pipe_request
disconnect_named_pipe
;
};
#define SERVER_PROTOCOL_VERSION
49
#define SERVER_PROTOCOL_VERSION
50
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/named_pipe.c
View file @
bf55457f
...
...
@@ -2,6 +2,10 @@
* Server-side pipe management
*
* Copyright (C) 1998 Alexandre Julliard
* Copyright (C) 2001 Mike McCormack
*
* TODO:
* improve error handling
*/
#include "config.h"
...
...
@@ -23,12 +27,24 @@
#include "thread.h"
#include "request.h"
enum
pipe_state
{
ps_none
,
ps_idle_server
,
ps_wait_open
,
ps_wait_connect
,
ps_connected_server
,
ps_connected_client
,
ps_disconnected
};
struct
named_pipe
;
struct
pipe_user
{
struct
object
obj
;
int
other_fd
;
enum
pipe_state
state
;
struct
pipe_user
*
other
;
struct
named_pipe
*
pipe
;
struct
pipe_user
*
next
;
struct
pipe_user
*
prev
;
...
...
@@ -96,8 +112,7 @@ static void pipe_user_dump( struct object *obj, int verbose )
{
struct
pipe_user
*
user
=
(
struct
pipe_user
*
)
obj
;
assert
(
obj
->
ops
==
&
pipe_user_ops
);
fprintf
(
stderr
,
"named pipe user %p (%s)
\n
"
,
user
,
(
user
->
other_fd
!=
-
1
)
?
"server"
:
"client"
);
fprintf
(
stderr
,
"named pipe user %p (state %d)
\n
"
,
user
,
user
->
state
);
}
static
void
named_pipe_destroy
(
struct
object
*
obj
)
...
...
@@ -118,6 +133,25 @@ static void pipe_user_destroy( struct object *obj)
release_object
(
user
->
event
);
user
->
event
=
NULL
;
}
if
(
user
->
other
)
{
close
(
user
->
other
->
obj
.
fd
);
user
->
other
->
obj
.
fd
=
-
1
;
switch
(
user
->
other
->
state
)
{
case
ps_connected_server
:
user
->
other
->
state
=
ps_idle_server
;
break
;
case
ps_connected_client
:
user
->
other
->
state
=
ps_disconnected
;
break
;
default:
fprintf
(
stderr
,
"connected pipe has strange state %d!
\n
"
,
user
->
other
->
state
);
}
user
->
other
->
other
=
NULL
;
user
->
other
=
NULL
;
}
/* remove user from pipe's user list */
if
(
user
->
next
)
user
->
next
->
prev
=
user
->
prev
;
...
...
@@ -157,29 +191,15 @@ static struct pipe_user *get_pipe_user_obj( struct process *process, handle_t ha
static
struct
pipe_user
*
create_pipe_user
(
struct
named_pipe
*
pipe
,
int
fd
)
{
struct
pipe_user
*
user
;
int
fds
[
2
];
if
(
fd
==
-
1
)
{
/* FIXME: what about messages? */
if
(
0
>
socketpair
(
PF_UNIX
,
SOCK_STREAM
,
0
,
fds
))
goto
error
;
}
else
{
if
((
fds
[
0
]
=
dup
(
fd
))
==
-
1
)
goto
error
;
fds
[
1
]
=
-
1
;
}
user
=
alloc_object
(
&
pipe_user_ops
,
fds
[
0
]
);
user
=
alloc_object
(
&
pipe_user_ops
,
fd
);
if
(
!
user
)
{
if
(
fds
[
1
]
!=
-
1
)
close
(
fds
[
1
]
);
return
NULL
;
}
user
->
pipe
=
pipe
;
user
->
other_fd
=
fds
[
1
]
;
user
->
state
=
ps_none
;
user
->
event
=
NULL
;
/* thread wait on this pipe */
user
->
other
=
NULL
;
/* add to list of pipe users */
if
((
user
->
next
=
pipe
->
users
))
user
->
next
->
prev
=
user
;
...
...
@@ -189,29 +209,21 @@ static struct pipe_user *create_pipe_user( struct named_pipe *pipe, int fd )
grab_object
(
pipe
);
return
user
;
error:
file_set_error
();
return
NULL
;
}
static
struct
pipe_user
*
find_partner
(
struct
named_pipe
*
pipe
)
static
struct
pipe_user
*
find_partner
(
struct
named_pipe
*
pipe
,
enum
pipe_state
state
)
{
struct
pipe_user
*
x
;
for
(
x
=
pipe
->
users
;
x
;
x
=
x
->
next
)
{
/* only pair threads that are waiting */
if
(
!
x
->
event
)
continue
;
/* only pair with pipes that haven't been connected */
if
(
x
->
other_fd
==
-
1
)
continue
;
if
(
x
->
state
==
state
)
break
;
}
if
(
!
x
)
return
NULL
;
return
(
struct
pipe_user
*
)
grab_object
(
x
);
}
...
...
@@ -229,6 +241,7 @@ DECL_HANDLER(create_named_pipe)
if
(
user
)
{
user
->
state
=
ps_idle_server
;
req
->
handle
=
alloc_handle
(
current
->
process
,
user
,
GENERIC_READ
|
GENERIC_WRITE
,
0
);
release_object
(
user
);
}
...
...
@@ -239,7 +252,6 @@ DECL_HANDLER(create_named_pipe)
DECL_HANDLER
(
open_named_pipe
)
{
struct
named_pipe
*
pipe
;
struct
pipe_user
*
user
,
*
partner
;
req
->
handle
=
0
;
pipe
=
create_named_pipe
(
get_req_data
(
req
),
get_req_data_size
(
req
)
);
...
...
@@ -248,26 +260,43 @@ DECL_HANDLER(open_named_pipe)
if
(
get_error
()
==
STATUS_OBJECT_NAME_COLLISION
)
{
if
((
partner
=
find_partner
(
pipe
)))
struct
pipe_user
*
partner
;
if
((
partner
=
find_partner
(
pipe
,
ps_wait_open
)))
{
user
=
create_pipe_user
(
pipe
,
partner
->
other_fd
);
if
(
user
)
int
fds
[
2
];
if
(
!
socketpair
(
PF_UNIX
,
SOCK_STREAM
,
0
,
fds
))
{
set_event
(
partner
->
event
);
release_object
(
partner
->
event
);
partner
->
event
=
NULL
;
close
(
partner
->
other_fd
);
partner
->
other_fd
=
-
1
;
req
->
handle
=
alloc_handle
(
current
->
process
,
user
,
req
->
access
,
0
);
release_object
(
user
);
struct
pipe_user
*
user
;
if
(
(
user
=
create_pipe_user
(
pipe
,
fds
[
1
]))
)
{
partner
->
obj
.
fd
=
fds
[
0
];
set_event
(
partner
->
event
);
release_object
(
partner
->
event
);
partner
->
event
=
NULL
;
partner
->
state
=
ps_connected_server
;
partner
->
other
=
user
;
user
->
state
=
ps_connected_client
;
user
->
other
=
partner
;
req
->
handle
=
alloc_handle
(
current
->
process
,
user
,
req
->
access
,
0
);
release_object
(
user
);
}
else
{
close
(
fds
[
0
]);
}
}
release_object
(
partner
);
}
else
{
else
{
set_error
(
STATUS_PIPE_NOT_AVAILABLE
);
}
}
else
{
else
{
set_error
(
STATUS_NO_SUCH_FILE
);
}
...
...
@@ -276,24 +305,101 @@ DECL_HANDLER(open_named_pipe)
DECL_HANDLER
(
connect_named_pipe
)
{
struct
pipe_user
*
user
;
struct
pipe_user
*
user
,
*
partner
;
struct
event
*
event
;
user
=
get_pipe_user_obj
(
current
->
process
,
req
->
handle
,
0
);
if
(
!
user
)
return
;
if
(
user
->
event
||
user
->
other_fd
==
-
1
)
if
(
user
->
state
!=
ps_idle_server
)
{
/* fprintf(stderr,"fd = %x event = %p\n",user->obj.fd,user->event);*/
set_error
(
STATUS_PORT_ALREADY_SET
);
}
else
{
user
->
state
=
ps_wait_open
;
event
=
get_event_obj
(
current
->
process
,
req
->
event
,
0
);
if
(
event
)
user
->
event
=
event
;
/* 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
;
release_object
(
partner
);
release_object
(
partner
);
}
}
release_object
(
user
);
}
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
)
{
/* only wait if the pipe already exists */
if
(
get_error
()
==
STATUS_OBJECT_NAME_COLLISION
)
{
struct
pipe_user
*
partner
;
set_error
(
STATUS_SUCCESS
);
if
(
(
partner
=
find_partner
(
pipe
,
ps_wait_open
))
)
{
set_event
(
event
);
release_object
(
partner
);
}
else
{
struct
pipe_user
*
user
;
if
(
(
user
=
create_pipe_user
(
pipe
,
-
1
))
)
{
user
->
event
=
(
struct
event
*
)
grab_object
(
event
);
user
->
state
=
ps_wait_connect
;
/* don't release it */
}
}
}
else
{
set_error
(
STATUS_PIPE_NOT_AVAILABLE
);
}
release_object
(
pipe
);
}
release_object
(
event
);
}
DECL_HANDLER
(
disconnect_named_pipe
)
{
struct
pipe_user
*
user
;
user
=
get_pipe_user_obj
(
current
->
process
,
req
->
handle
,
0
);
if
(
!
user
)
return
;
if
(
(
user
->
state
==
ps_connected_server
)
&&
(
user
->
other
->
state
==
ps_connected_client
)
)
{
close
(
user
->
other
->
obj
.
fd
);
user
->
other
->
obj
.
fd
=
-
1
;
user
->
other
->
state
=
ps_disconnected
;
user
->
other
->
other
=
NULL
;
close
(
user
->
obj
.
fd
);
user
->
obj
.
fd
=
-
1
;
user
->
state
=
ps_idle_server
;
user
->
other
=
NULL
;
}
release_object
(
user
);
}
server/protocol.def
View file @
bf55457f
...
...
@@ -1368,3 +1368,17 @@ enum message_type
handle_t handle;
handle_t event; /* set this event when it's ready */
@END
/* Wait for a named pipe */
@REQ(wait_named_pipe)
unsigned int timeout;
handle_t event; /* set this event when it's ready */
VARARG(filename,string); /* pipe name */
@END
/* Disconnect a named pipe */
@REQ(disconnect_named_pipe)
handle_t handle;
@END
server/request.h
View file @
bf55457f
...
...
@@ -185,6 +185,8 @@ DECL_HANDLER(create_async);
DECL_HANDLER
(
create_named_pipe
);
DECL_HANDLER
(
open_named_pipe
);
DECL_HANDLER
(
connect_named_pipe
);
DECL_HANDLER
(
wait_named_pipe
);
DECL_HANDLER
(
disconnect_named_pipe
);
#ifdef WANT_REQUEST_HANDLERS
...
...
@@ -311,6 +313,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_create_named_pipe
,
(
req_handler
)
req_open_named_pipe
,
(
req_handler
)
req_connect_named_pipe
,
(
req_handler
)
req_wait_named_pipe
,
(
req_handler
)
req_disconnect_named_pipe
,
};
#endif
/* WANT_REQUEST_HANDLERS */
...
...
server/trace.c
View file @
bf55457f
...
...
@@ -1626,6 +1626,19 @@ static void dump_connect_named_pipe_request( const struct connect_named_pipe_req
fprintf
(
stderr
,
" event=%d"
,
req
->
event
);
}
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
,
" filename="
);
cur_pos
+=
dump_varargs_string
(
req
);
}
static
void
dump_disconnect_named_pipe_request
(
const
struct
disconnect_named_pipe_request
*
req
)
{
fprintf
(
stderr
,
" handle=%d"
,
req
->
handle
);
}
static
const
dump_func
req_dumpers
[
REQ_NB_REQUESTS
]
=
{
(
dump_func
)
dump_new_process_request
,
(
dump_func
)
dump_get_new_process_info_request
,
...
...
@@ -1747,6 +1760,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_create_named_pipe_request
,
(
dump_func
)
dump_open_named_pipe_request
,
(
dump_func
)
dump_connect_named_pipe_request
,
(
dump_func
)
dump_wait_named_pipe_request
,
(
dump_func
)
dump_disconnect_named_pipe_request
,
};
static
const
dump_func
reply_dumpers
[
REQ_NB_REQUESTS
]
=
{
...
...
@@ -1870,6 +1885,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_create_named_pipe_reply
,
(
dump_func
)
dump_open_named_pipe_reply
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
0
,
};
static
const
char
*
const
req_names
[
REQ_NB_REQUESTS
]
=
{
...
...
@@ -1993,6 +2010,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_named_pipe"
,
"open_named_pipe"
,
"connect_named_pipe"
,
"wait_named_pipe"
,
"disconnect_named_pipe"
,
};
/* ### make_requests end ### */
...
...
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