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
45a3462c
Commit
45a3462c
authored
Jun 25, 2008
by
Rob Shearman
Committed by
Alexandre Julliard
Jun 26, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rpcrt4/rpcss: Remove old named pipe code for communicating with RPCSS process.
parent
9e1c7a30
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
6 additions
and
1099 deletions
+6
-1099
Makefile.in
dlls/rpcrt4/Makefile.in
+1
-2
rpc_binding.h
dlls/rpcrt4/rpc_binding.h
+0
-3
rpcrt4_main.c
dlls/rpcrt4/rpcrt4_main.c
+0
-108
rpcss_np_client.c
dlls/rpcrt4/rpcss_np_client.c
+0
-152
rpcss_np_client.h
dlls/rpcrt4/rpcss_np_client.h
+0
-26
Makefile.in
programs/rpcss/Makefile.in
+2
-4
epmap_server.c
programs/rpcss/epmap_server.c
+0
-210
np_server.c
programs/rpcss/np_server.c
+0
-527
rpcss.h
programs/rpcss/rpcss.h
+0
-22
rpcss_main.c
programs/rpcss/rpcss_main.c
+3
-45
No files found.
dlls/rpcrt4/Makefile.in
View file @
45a3462c
...
...
@@ -25,8 +25,7 @@ C_SRCS = \
rpc_message.c
\
rpc_server.c
\
rpc_transport.c
\
rpcrt4_main.c
\
rpcss_np_client.c
rpcrt4_main.c
RC_SRCS
=
version.rc
...
...
dlls/rpcrt4/rpc_binding.h
View file @
45a3462c
...
...
@@ -150,9 +150,6 @@ RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding);
RPC_STATUS
RPCRT4_OpenBinding
(
RpcBinding
*
Binding
,
RpcConnection
**
Connection
,
const
RPC_SYNTAX_IDENTIFIER
*
TransferSyntax
,
const
RPC_SYNTAX_IDENTIFIER
*
InterfaceId
);
RPC_STATUS
RPCRT4_CloseBinding
(
RpcBinding
*
Binding
,
RpcConnection
*
Connection
);
BOOL
RPCRT4_RPCSSOnDemandCall
(
PRPCSS_NP_MESSAGE
msg
,
char
*
vardata_payload
,
PRPCSS_NP_REPLY
reply
);
HANDLE
RPCRT4_GetMasterMutex
(
void
);
HANDLE
RPCRT4_RpcssNPConnect
(
void
);
static
inline
const
char
*
rpcrt4_conn_get_name
(
const
RpcConnection
*
Connection
)
{
...
...
dlls/rpcrt4/rpcrt4_main.c
View file @
45a3462c
...
...
@@ -53,19 +53,12 @@
#include "rpcproxy.h"
#include "rpc_binding.h"
#include "rpcss_np_client.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
rpc
);
static
UUID
uuid_nil
;
static
HANDLE
master_mutex
;
HANDLE
RPCRT4_GetMasterMutex
(
void
)
{
return
master_mutex
;
}
static
CRITICAL_SECTION
uuid_cs
;
static
CRITICAL_SECTION_DEBUG
critsect_debug
=
...
...
@@ -122,9 +115,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
switch
(
fdwReason
)
{
case
DLL_PROCESS_ATTACH
:
master_mutex
=
CreateMutexA
(
NULL
,
FALSE
,
RPCSS_MASTER_MUTEX_NAME
);
if
(
!
master_mutex
)
ERR
(
"Failed to create master mutex
\n
"
);
break
;
case
DLL_THREAD_DETACH
:
...
...
@@ -145,8 +135,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
break
;
case
DLL_PROCESS_DETACH
:
CloseHandle
(
master_mutex
);
master_mutex
=
NULL
;
break
;
}
...
...
@@ -645,102 +633,6 @@ HRESULT WINAPI DllRegisterServer( void )
return
S_OK
;
}
static
BOOL
RPCRT4_StartRPCSS
(
void
)
{
PROCESS_INFORMATION
pi
;
STARTUPINFOA
si
;
static
char
cmd
[
6
];
BOOL
rslt
;
ZeroMemory
(
&
pi
,
sizeof
(
PROCESS_INFORMATION
));
ZeroMemory
(
&
si
,
sizeof
(
STARTUPINFOA
));
si
.
cb
=
sizeof
(
STARTUPINFOA
);
/* apparently it's not OK to use a constant string below */
CopyMemory
(
cmd
,
"rpcss"
,
6
);
/* FIXME: will this do the right thing when run as a test? */
rslt
=
CreateProcessA
(
NULL
,
/* executable */
cmd
,
/* command line */
NULL
,
/* process security attributes */
NULL
,
/* primary thread security attributes */
FALSE
,
/* inherit handles */
0
,
/* creation flags */
NULL
,
/* use parent's environment */
NULL
,
/* use parent's current directory */
&
si
,
/* STARTUPINFO pointer */
&
pi
/* PROCESS_INFORMATION */
);
if
(
rslt
)
{
CloseHandle
(
pi
.
hProcess
);
CloseHandle
(
pi
.
hThread
);
}
return
rslt
;
}
/***********************************************************************
* RPCRT4_RPCSSOnDemandCall (internal)
*
* Attempts to send a message to the RPCSS process
* on the local machine, invoking it if necessary.
* For remote RPCSS calls, use.... your imagination.
*
* PARAMS
* msg [I] pointer to the RPCSS message
* vardata_payload [I] pointer vardata portion of the RPCSS message
* reply [O] pointer to reply structure
*
* RETURNS
* TRUE if successful
* FALSE otherwise
*/
BOOL
RPCRT4_RPCSSOnDemandCall
(
PRPCSS_NP_MESSAGE
msg
,
char
*
vardata_payload
,
PRPCSS_NP_REPLY
reply
)
{
HANDLE
client_handle
;
BOOL
ret
;
int
i
,
j
=
0
;
TRACE
(
"(msg == %p, vardata_payload == %p, reply == %p)
\n
"
,
msg
,
vardata_payload
,
reply
);
client_handle
=
RPCRT4_RpcssNPConnect
();
while
(
INVALID_HANDLE_VALUE
==
client_handle
)
{
/* start the RPCSS process */
if
(
!
RPCRT4_StartRPCSS
())
{
ERR
(
"Unable to start RPCSS process.
\n
"
);
return
FALSE
;
}
/* wait for a connection (w/ periodic polling) */
for
(
i
=
0
;
i
<
60
;
i
++
)
{
Sleep
(
200
);
client_handle
=
RPCRT4_RpcssNPConnect
();
if
(
INVALID_HANDLE_VALUE
!=
client_handle
)
break
;
}
/* we are only willing to try twice */
if
(
j
++
>=
1
)
break
;
}
if
(
INVALID_HANDLE_VALUE
==
client_handle
)
{
/* no dice! */
ERR
(
"Unable to connect to RPCSS process!
\n
"
);
SetLastError
(
RPC_E_SERVER_DIED_DNE
);
return
FALSE
;
}
/* great, we're connected. now send the message */
ret
=
TRUE
;
if
(
!
RPCRT4_SendReceiveNPMsg
(
client_handle
,
msg
,
vardata_payload
,
reply
))
{
ERR
(
"Something is amiss: RPC_SendReceive failed.
\n
"
);
ret
=
FALSE
;
}
CloseHandle
(
client_handle
);
return
ret
;
}
#define MAX_RPC_ERROR_TEXT 256
/******************************************************************************
...
...
dlls/rpcrt4/rpcss_np_client.c
deleted
100644 → 0
View file @
9e1c7a30
/*
* RPCSS named pipe client implementation
*
* Copyright (C) 2002 Greg Turner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wine/rpcss_shared.h"
#include "wine/debug.h"
#include "rpc_binding.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
ole
);
HANDLE
RPCRT4_RpcssNPConnect
(
void
)
{
HANDLE
the_pipe
;
DWORD
dwmode
,
wait_result
;
HANDLE
master_mutex
=
RPCRT4_GetMasterMutex
();
TRACE
(
"
\n
"
);
while
(
TRUE
)
{
wait_result
=
WaitForSingleObject
(
master_mutex
,
MASTER_MUTEX_TIMEOUT
);
switch
(
wait_result
)
{
case
WAIT_ABANDONED
:
case
WAIT_OBJECT_0
:
break
;
case
WAIT_FAILED
:
case
WAIT_TIMEOUT
:
default:
ERR
(
"This should never happen: couldn't enter mutex.
\n
"
);
return
NULL
;
}
/* try to open the client side of the named pipe. */
the_pipe
=
CreateFileA
(
NAME_RPCSS_NAMED_PIPE
,
/* pipe name */
GENERIC_READ
|
GENERIC_WRITE
,
/* r/w access */
0
,
/* no sharing */
NULL
,
/* no security attributes */
OPEN_EXISTING
,
/* open an existing pipe */
0
,
/* default attributes */
NULL
/* no template file */
);
if
(
the_pipe
!=
INVALID_HANDLE_VALUE
)
break
;
if
(
GetLastError
()
!=
ERROR_PIPE_BUSY
)
{
WARN
(
"Unable to open named pipe %s (assuming unavailable).
\n
"
,
debugstr_a
(
NAME_RPCSS_NAMED_PIPE
));
break
;
}
WARN
(
"Named pipe busy (will wait)
\n
"
);
if
(
!
ReleaseMutex
(
master_mutex
))
ERR
(
"Failed to release master mutex. Expect deadlock.
\n
"
);
/* wait for the named pipe. We are only willing to wait for 5 seconds.
It should be available /very/ soon. */
if
(
!
WaitNamedPipeA
(
NAME_RPCSS_NAMED_PIPE
,
MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT
))
{
ERR
(
"Named pipe unavailable after waiting. Something is probably wrong.
\n
"
);
break
;
}
}
if
(
the_pipe
!=
INVALID_HANDLE_VALUE
)
{
dwmode
=
PIPE_READMODE_MESSAGE
;
/* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */
if
(
!
SetNamedPipeHandleState
(
the_pipe
,
&
dwmode
,
NULL
,
NULL
))
WARN
(
"Failed to set pipe handle state
\n
"
);
}
if
(
!
ReleaseMutex
(
master_mutex
))
ERR
(
"Uh oh, failed to leave the RPC Master Mutex!
\n
"
);
return
the_pipe
;
}
BOOL
RPCRT4_SendReceiveNPMsg
(
HANDLE
np
,
PRPCSS_NP_MESSAGE
msg
,
char
*
vardata
,
PRPCSS_NP_REPLY
reply
)
{
DWORD
count
;
UINT32
payload_offset
;
RPCSS_NP_MESSAGE
vardata_payload_msg
;
TRACE
(
"(np == %p, msg == %p, vardata == %p, reply == %p)
\n
"
,
np
,
msg
,
vardata
,
reply
);
if
(
!
WriteFile
(
np
,
msg
,
sizeof
(
RPCSS_NP_MESSAGE
),
&
count
,
NULL
))
{
ERR
(
"write failed.
\n
"
);
return
FALSE
;
}
if
(
count
!=
sizeof
(
RPCSS_NP_MESSAGE
))
{
ERR
(
"write count mismatch.
\n
"
);
return
FALSE
;
}
/* process the vardata payload if necessary */
vardata_payload_msg
.
message_type
=
RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG
;
vardata_payload_msg
.
vardata_payload_size
=
0
;
/* meaningless */
for
(
payload_offset
=
0
;
payload_offset
<
msg
->
vardata_payload_size
;
payload_offset
+=
VARDATA_PAYLOAD_BYTES
)
{
TRACE
(
"sending vardata payload. vd=%p, po=%d, ps=%d
\n
"
,
vardata
,
payload_offset
,
msg
->
vardata_payload_size
);
ZeroMemory
(
vardata_payload_msg
.
message
.
vardatapayloadmsg
.
payload
,
VARDATA_PAYLOAD_BYTES
);
CopyMemory
(
vardata_payload_msg
.
message
.
vardatapayloadmsg
.
payload
,
vardata
,
min
(
VARDATA_PAYLOAD_BYTES
,
msg
->
vardata_payload_size
-
payload_offset
));
vardata
+=
VARDATA_PAYLOAD_BYTES
;
if
(
!
WriteFile
(
np
,
&
vardata_payload_msg
,
sizeof
(
RPCSS_NP_MESSAGE
),
&
count
,
NULL
))
{
ERR
(
"vardata write failed at %u bytes.
\n
"
,
payload_offset
);
return
FALSE
;
}
}
if
(
!
ReadFile
(
np
,
reply
,
sizeof
(
RPCSS_NP_REPLY
),
&
count
,
NULL
))
{
ERR
(
"read failed.
\n
"
);
return
FALSE
;
}
if
(
count
!=
sizeof
(
RPCSS_NP_REPLY
))
{
ERR
(
"read count mismatch. got %d.
\n
"
,
count
);
return
FALSE
;
}
/* message execution was successful */
return
TRUE
;
}
dlls/rpcrt4/rpcss_np_client.h
deleted
100644 → 0
View file @
9e1c7a30
/*
* Copyright (C) 2002 Greg Turner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_RPCSS_NP_CLIENT_H
#define __WINE_RPCSS_NP_CLIENT_H
/* rpcss_np_client.c */
HANDLE
RPC_RpcssNPConnect
(
void
);
BOOL
RPCRT4_SendReceiveNPMsg
(
HANDLE
,
PRPCSS_NP_MESSAGE
,
char
*
,
PRPCSS_NP_REPLY
);
#endif
/* __RPCSS_NP_CLIENT_H */
programs/rpcss/Makefile.in
View file @
45a3462c
...
...
@@ -7,11 +7,9 @@ APPMODE = -mconsole
IMPORTS
=
rpcrt4 kernel32 ntdll
C_SRCS
=
\
epmap_server.c
\
epmp.c
\
irotp.c
\
np_server.c
\
rpcss_main.c
irotp.c
\
rpcss_main.c
IDL_S_SRCS
=
\
epm.idl
\
...
...
programs/rpcss/epmap_server.c
deleted
100644 → 0
View file @
9e1c7a30
/*
* RPC endpoint mapper server
*
* Copyright (C) 2001 Ove Kven, TransGaming Technologies Inc,
* Copyright (C) 2002 Greg Turner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <string.h>
#include "rpcss.h"
#include "rpc.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
ole
);
struct
epmap_entry
{
struct
epmap_entry
*
next
;
RPC_SYNTAX_IDENTIFIER
iface
;
UUID
object
;
char
*
protseq
;
char
*
endpoint
;
};
static
struct
epmap_entry
*
epmap
;
static
const
UUID
nil_object
;
static
char
*
mystrdup
(
const
char
*
str
)
{
char
*
rval
;
rval
=
LocalAlloc
(
LPTR
,
strlen
(
str
)
+
1
);
CopyMemory
(
rval
,
str
,
strlen
(
str
)
+
1
);
return
rval
;
}
static
struct
epmap_entry
*
find_endpoint
(
const
RPC_SYNTAX_IDENTIFIER
*
iface
,
const
char
*
protseq
,
const
UUID
*
object
)
{
struct
epmap_entry
*
map
;
for
(
map
=
epmap
;
map
;
map
=
map
->
next
)
{
if
(
memcmp
(
&
map
->
iface
,
iface
,
sizeof
(
RPC_SYNTAX_IDENTIFIER
)))
continue
;
if
(
memcmp
(
&
map
->
object
,
object
,
sizeof
(
UUID
)))
continue
;
if
(
strcmp
(
map
->
protseq
,
protseq
))
continue
;
WINE_TRACE
(
"found.
\n
"
);
return
map
;
}
WINE_TRACE
(
"not found.
\n
"
);
return
NULL
;
}
static
void
register_endpoint
(
const
RPC_SYNTAX_IDENTIFIER
*
iface
,
const
char
*
protseq
,
const
char
*
endpoint
,
const
UUID
*
objects
,
int
objcount
,
int
no_replace
)
{
int
c
;
WINE_TRACE
(
"(protseq == %s, endpoint == %s, objcount == %i, no_replace == %i)
\n
"
,
wine_dbgstr_a
(
protseq
),
wine_dbgstr_a
(
endpoint
),
objcount
,
no_replace
);
if
(
!
objcount
)
{
objects
=
&
nil_object
;
objcount
=
1
;
}
for
(
c
=
0
;
c
<
objcount
;
c
++
)
{
struct
epmap_entry
*
map
=
NULL
;
if
(
!
no_replace
)
map
=
find_endpoint
(
iface
,
protseq
,
&
objects
[
c
]);
if
(
map
)
{
LocalFree
(
map
->
endpoint
);
}
else
{
map
=
LocalAlloc
(
LPTR
,
sizeof
(
struct
epmap_entry
));
memcpy
(
&
map
->
iface
,
iface
,
sizeof
(
RPC_SYNTAX_IDENTIFIER
));
memcpy
(
&
map
->
object
,
&
objects
[
c
],
sizeof
(
UUID
));
map
->
protseq
=
mystrdup
(
protseq
);
map
->
next
=
epmap
;
epmap
=
map
;
}
WINE_TRACE
(
" mapping endpoint (protseq == %s, endpoint == %s, uuid == %s)
\n
"
,
wine_dbgstr_a
(
protseq
),
wine_dbgstr_a
(
endpoint
),
wine_dbgstr_guid
(
&
objects
[
c
]));
map
->
endpoint
=
mystrdup
(
endpoint
);
}
}
static
void
unregister_endpoint
(
const
RPC_SYNTAX_IDENTIFIER
*
iface
,
const
char
*
protseq
,
const
char
*
endpoint
,
const
UUID
*
objects
,
int
objcount
)
{
struct
epmap_entry
*
map
,
*
prev
,
*
nprev
,
*
next
;
int
c
;
WINE_TRACE
(
"(protseq == %s, endpoint == %s, objcount == %i)
\n
"
,
wine_dbgstr_a
(
protseq
),
wine_dbgstr_a
(
endpoint
),
objcount
);
if
(
!
objcount
)
{
objects
=
&
nil_object
;
objcount
=
1
;
}
prev
=
NULL
;
nprev
=
NULL
;
map
=
epmap
;
while
(
map
)
{
next
=
map
->
next
;
nprev
=
map
;
if
(
memcmp
(
&
map
->
iface
,
iface
,
sizeof
(
RPC_SYNTAX_IDENTIFIER
)))
goto
cont
;
for
(
c
=
0
;
c
<
objcount
;
c
++
)
if
(
!
memcmp
(
&
map
->
object
,
&
objects
[
c
],
sizeof
(
UUID
)))
break
;
if
(
c
==
objcount
)
goto
cont
;
if
(
strcmp
(
map
->
protseq
,
protseq
))
goto
cont
;
WINE_TRACE
(
" unmapping: (protseq == %s, endpoint == %s, uuid == %s)
\n
"
,
wine_dbgstr_a
(
map
->
protseq
),
wine_dbgstr_a
(
map
->
endpoint
),
wine_dbgstr_guid
(
&
map
->
object
));
if
(
prev
)
prev
->
next
=
map
->
next
;
else
epmap
=
map
->
next
;
nprev
=
prev
;
LocalFree
(
map
->
protseq
);
LocalFree
(
map
->
endpoint
);
LocalFree
(
map
);
cont:
prev
=
nprev
;
map
=
next
;
}
}
static
void
resolve_endpoint
(
const
RPC_SYNTAX_IDENTIFIER
*
iface
,
const
char
*
protseq
,
const
UUID
*
object
,
char
*
rslt_ep
)
{
size_t
len
;
struct
epmap_entry
*
map
;
if
(
!
(
map
=
find_endpoint
(
iface
,
protseq
,
object
)))
return
;
len
=
min
(
MAX_RPCSS_NP_REPLY_STRING_LEN
,
strlen
(
map
->
endpoint
)
+
1
);
if
(
len
)
memcpy
(
rslt_ep
,
map
->
endpoint
,
len
);
}
static
const
char
*
get_string
(
const
char
**
ptr
,
const
char
*
end
)
{
const
char
*
str
=
*
ptr
,
*
nptr
=
str
;
while
(
nptr
<
end
&&
*
nptr
)
nptr
++
;
if
(
nptr
==
end
)
return
NULL
;
*
ptr
=
nptr
+
1
;
return
str
;
}
BOOL
RPCSS_EpmapEmpty
(
void
)
{
return
(
!
epmap
);
}
void
RPCSS_RegisterRpcEndpoints
(
RPC_SYNTAX_IDENTIFIER
iface
,
int
object_count
,
int
binding_count
,
int
no_replace
,
char
*
vardata
,
long
vardata_size
)
{
const
char
*
data
=
vardata
;
const
char
*
end
=
data
+
vardata_size
;
const
UUID
*
objects
=
(
const
UUID
*
)
data
;
int
c
;
data
+=
object_count
*
sizeof
(
UUID
);
for
(
c
=
0
;
c
<
binding_count
;
c
++
)
{
const
char
*
protseq
=
get_string
(
&
data
,
end
);
const
char
*
endpoint
=
get_string
(
&
data
,
end
);
if
(
protseq
&&
endpoint
)
register_endpoint
(
&
iface
,
protseq
,
endpoint
,
objects
,
object_count
,
no_replace
);
}
}
void
RPCSS_UnregisterRpcEndpoints
(
RPC_SYNTAX_IDENTIFIER
iface
,
int
object_count
,
int
binding_count
,
char
*
vardata
,
long
vardata_size
)
{
const
char
*
data
=
vardata
;
const
char
*
end
=
data
+
vardata_size
;
const
UUID
*
objects
=
(
const
UUID
*
)
data
;
int
c
;
data
+=
object_count
*
sizeof
(
UUID
);
for
(
c
=
0
;
c
<
binding_count
;
c
++
)
{
const
char
*
protseq
=
get_string
(
&
data
,
end
);
const
char
*
endpoint
=
get_string
(
&
data
,
end
);
if
(
protseq
&&
endpoint
)
unregister_endpoint
(
&
iface
,
protseq
,
endpoint
,
objects
,
object_count
);
}
}
void
RPCSS_ResolveRpcEndpoints
(
RPC_SYNTAX_IDENTIFIER
iface
,
UUID
object
,
char
*
protseq
,
char
*
rslt_ep
)
{
resolve_endpoint
(
&
iface
,
protseq
,
&
object
,
rslt_ep
);
}
programs/rpcss/np_server.c
deleted
100644 → 0
View file @
9e1c7a30
/*
* RPCSS named pipe server
*
* Copyright (C) 2002 Greg Turner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include "rpcss.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
ole
);
static
HANDLE
np_server_end
;
static
HANDLE
np_server_work_event
;
static
CRITICAL_SECTION
np_server_cs
;
static
LONG
srv_thread_count
;
static
BOOL
server_live
;
LONG
RPCSS_SrvThreadCount
(
void
)
{
return
srv_thread_count
;
}
BOOL
RPCSS_UnBecomePipeServer
(
void
)
{
WINE_TRACE
(
"
\n
"
);
WINE_TRACE
(
"shutting down pipe.
\n
"
);
server_live
=
FALSE
;
if
(
!
CloseHandle
(
np_server_end
))
WINE_WARN
(
"Failed to close named pipe.
\n
"
);
if
(
!
CloseHandle
(
np_server_work_event
))
WINE_WARN
(
"Failed to close the event handle.
\n
"
);
DeleteCriticalSection
(
&
np_server_cs
);
return
TRUE
;
}
static
void
RPCSS_ServerProcessRANMessage
(
PRPCSS_NP_MESSAGE
pMsg
,
PRPCSS_NP_REPLY
pReply
)
{
WINE_TRACE
(
"
\n
"
);
pReply
->
as_uint
=
0
;
}
static
void
RPCSS_ServerProcessREGISTEREPMessage
(
PRPCSS_NP_MESSAGE
pMsg
,
PRPCSS_NP_REPLY
pReply
,
char
*
vardata
)
{
WINE_TRACE
(
"
\n
"
);
RPCSS_RegisterRpcEndpoints
(
pMsg
->
message
.
registerepmsg
.
iface
,
pMsg
->
message
.
registerepmsg
.
object_count
,
pMsg
->
message
.
registerepmsg
.
binding_count
,
pMsg
->
message
.
registerepmsg
.
no_replace
,
vardata
,
pMsg
->
vardata_payload_size
);
/* no reply */
pReply
->
as_uint
=
0
;
}
static
void
RPCSS_ServerProcessUNREGISTEREPMessage
(
PRPCSS_NP_MESSAGE
pMsg
,
PRPCSS_NP_REPLY
pReply
,
char
*
vardata
)
{
WINE_TRACE
(
"
\n
"
);
RPCSS_UnregisterRpcEndpoints
(
pMsg
->
message
.
unregisterepmsg
.
iface
,
pMsg
->
message
.
unregisterepmsg
.
object_count
,
pMsg
->
message
.
unregisterepmsg
.
binding_count
,
vardata
,
pMsg
->
vardata_payload_size
);
/* no reply */
pReply
->
as_uint
=
0
;
}
static
void
RPCSS_ServerProcessRESOLVEEPMessage
(
PRPCSS_NP_MESSAGE
pMsg
,
PRPCSS_NP_REPLY
pReply
,
char
*
vardata
)
{
WINE_TRACE
(
"
\n
"
);
/* for now, reply is placed into *pReply.as_string, on success, by RPCSS_ResolveRpcEndpoints */
ZeroMemory
(
pReply
->
as_string
,
MAX_RPCSS_NP_REPLY_STRING_LEN
);
RPCSS_ResolveRpcEndpoints
(
pMsg
->
message
.
resolveepmsg
.
iface
,
pMsg
->
message
.
resolveepmsg
.
object
,
vardata
,
pReply
->
as_string
);
}
static
void
RPCSS_ServerProcessMessage
(
PRPCSS_NP_MESSAGE
pMsg
,
PRPCSS_NP_REPLY
pReply
,
char
*
vardata
)
{
WINE_TRACE
(
"
\n
"
);
ZeroMemory
(
pReply
,
sizeof
(
*
pReply
));
switch
(
pMsg
->
message_type
)
{
case
RPCSS_NP_MESSAGE_TYPEID_RANMSG
:
RPCSS_ServerProcessRANMessage
(
pMsg
,
pReply
);
break
;
case
RPCSS_NP_MESSAGE_TYPEID_REGISTEREPMSG
:
RPCSS_ServerProcessREGISTEREPMessage
(
pMsg
,
pReply
,
vardata
);
break
;
case
RPCSS_NP_MESSAGE_TYPEID_UNREGISTEREPMSG
:
RPCSS_ServerProcessUNREGISTEREPMessage
(
pMsg
,
pReply
,
vardata
);
break
;
case
RPCSS_NP_MESSAGE_TYPEID_RESOLVEEPMSG
:
RPCSS_ServerProcessRESOLVEEPMessage
(
pMsg
,
pReply
,
vardata
);
break
;
default:
WINE_ERR
(
"Message type unknown!! No action taken.
\n
"
);
}
}
/* each message gets its own thread. this is it. */
static
DWORD
WINAPI
HandlerThread
(
LPVOID
lpvPipeHandle
)
{
RPCSS_NP_MESSAGE
msg
,
vardata_payload_msg
;
char
*
c
,
*
vardata
=
NULL
;
RPCSS_NP_REPLY
reply
;
DWORD
bytesread
,
written
;
BOOL
success
,
had_payload
=
FALSE
;
HANDLE
mypipe
;
mypipe
=
(
HANDLE
)
lpvPipeHandle
;
WINE_TRACE
(
"mypipe: %p
\n
"
,
mypipe
);
success
=
ReadFile
(
mypipe
,
/* pipe handle */
(
char
*
)
&
msg
,
/* message buffer */
sizeof
(
RPCSS_NP_MESSAGE
),
/* message buffer size */
&
bytesread
,
/* receives number of bytes read */
NULL
/* not overlapped */
);
if
(
msg
.
vardata_payload_size
)
{
had_payload
=
TRUE
;
/* this fudge space allows us not to worry about exceeding the buffer space
on the last read */
vardata
=
LocalAlloc
(
LPTR
,
(
msg
.
vardata_payload_size
)
+
VARDATA_PAYLOAD_BYTES
);
if
(
!
vardata
)
{
WINE_ERR
(
"vardata memory allocation failure.
\n
"
);
success
=
FALSE
;
}
else
{
for
(
c
=
vardata
;
(
c
-
vardata
)
<
msg
.
vardata_payload_size
;
c
+=
VARDATA_PAYLOAD_BYTES
)
{
success
=
ReadFile
(
mypipe
,
(
char
*
)
&
vardata_payload_msg
,
sizeof
(
RPCSS_NP_MESSAGE
),
&
bytesread
,
NULL
);
if
(
(
!
success
)
||
(
bytesread
!=
sizeof
(
RPCSS_NP_MESSAGE
))
||
(
vardata_payload_msg
.
message_type
!=
RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG
)
)
{
WINE_ERR
(
"vardata payload read failure! (s=%s,br=%d,mt=%u,mt_exp=%u
\n
"
,
success
?
"TRUE"
:
"FALSE"
,
bytesread
,
vardata_payload_msg
.
message_type
,
RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG
);
success
=
FALSE
;
break
;
}
CopyMemory
(
c
,
vardata_payload_msg
.
message
.
vardatapayloadmsg
.
payload
,
VARDATA_PAYLOAD_BYTES
);
WINE_TRACE
(
"payload read.
\n
"
);
}
}
}
if
(
success
&&
(
bytesread
==
sizeof
(
RPCSS_NP_MESSAGE
)))
{
WINE_TRACE
(
"read success.
\n
"
);
/* process the message and send a reply, serializing requests. */
EnterCriticalSection
(
&
np_server_cs
);
WINE_TRACE
(
"processing message.
\n
"
);
RPCSS_ServerProcessMessage
(
&
msg
,
&
reply
,
vardata
);
LeaveCriticalSection
(
&
np_server_cs
);
if
(
had_payload
)
LocalFree
(
vardata
);
WINE_TRACE
(
"message processed, sending reply....
\n
"
);
success
=
WriteFile
(
mypipe
,
/* pipe handle */
(
char
*
)
&
reply
,
/* reply buffer */
sizeof
(
RPCSS_NP_REPLY
),
/* reply buffer size */
&
written
,
/* receives number of bytes written */
NULL
/* not overlapped */
);
if
(
(
!
success
)
||
(
written
!=
sizeof
(
RPCSS_NP_REPLY
))
)
WINE_WARN
(
"Message reply failed. (success=%d, br=%d)
\n
"
,
success
,
written
);
else
WINE_TRACE
(
"Reply sent successfully.
\n
"
);
}
else
WINE_WARN
(
"Message receipt failed.
\n
"
);
FlushFileBuffers
(
mypipe
);
DisconnectNamedPipe
(
mypipe
);
CloseHandle
(
mypipe
);
InterlockedDecrement
(
&
srv_thread_count
);
return
0
;
}
static
DWORD
WINAPI
NPMainWorkThread
(
LPVOID
ignored
)
{
BOOL
connected
;
HANDLE
hthread
,
master_mutex
=
RPCSS_GetMasterMutex
();
DWORD
threadid
,
wait_result
;
WINE_TRACE
(
"
\n
"
);
while
(
server_live
)
{
connected
=
ConnectNamedPipe
(
np_server_end
,
NULL
)
?
TRUE
:
(
GetLastError
()
==
ERROR_PIPE_CONNECTED
);
if
(
connected
)
{
/* is "work" the act of connecting pipes, or the act of serving
requests successfully? for now I will make it the former. */
if
(
!
SetEvent
(
np_server_work_event
))
WINE_WARN
(
"failed to signal np_server_work_event.
\n
"
);
/* Create a thread for this client. */
InterlockedIncrement
(
&
srv_thread_count
);
hthread
=
CreateThread
(
NULL
,
/* no security attribute */
0
,
/* default stack size */
HandlerThread
,
(
LPVOID
)
np_server_end
,
/* thread parameter */
0
,
/* not suspended */
&
threadid
/* returns thread ID (not used) */
);
if
(
hthread
)
{
WINE_TRACE
(
"Spawned handler thread: %p
\n
"
,
hthread
);
CloseHandle
(
hthread
);
/* for safety's sake, hold the mutex while we switch the pipe */
wait_result
=
WaitForSingleObject
(
master_mutex
,
MASTER_MUTEX_TIMEOUT
);
switch
(
wait_result
)
{
case
WAIT_ABANDONED
:
/* ? */
case
WAIT_OBJECT_0
:
/* we have ownership */
break
;
case
WAIT_FAILED
:
case
WAIT_TIMEOUT
:
default:
/* huh? */
wait_result
=
WAIT_FAILED
;
}
if
(
wait_result
==
WAIT_FAILED
)
{
WINE_ERR
(
"Couldn't enter master mutex. Expect problems.
\n
"
);
}
else
{
/* now create a new named pipe instance to listen on */
np_server_end
=
CreateNamedPipe
(
NAME_RPCSS_NAMED_PIPE
,
/* pipe name */
PIPE_ACCESS_DUPLEX
,
/* pipe open mode */
PIPE_TYPE_MESSAGE
|
PIPE_READMODE_MESSAGE
|
PIPE_WAIT
,
/* pipe-specific modes */
PIPE_UNLIMITED_INSTANCES
,
/* maximum instances */
sizeof
(
RPCSS_NP_REPLY
),
/* output buffer size */
sizeof
(
RPCSS_NP_MESSAGE
),
/* input buffer size */
2000
,
/* time-out interval */
NULL
/* SD */
);
if
(
np_server_end
==
INVALID_HANDLE_VALUE
)
{
WINE_ERR
(
"Failed to recreate named pipe!
\n
"
);
/* not sure what to do? */
assert
(
FALSE
);
}
if
(
!
ReleaseMutex
(
master_mutex
))
WINE_ERR
(
"Uh oh. Couldn't leave master mutex. Expect deadlock.
\n
"
);
}
}
else
{
WINE_ERR
(
"Failed to spawn handler thread!
\n
"
);
DisconnectNamedPipe
(
np_server_end
);
InterlockedDecrement
(
&
srv_thread_count
);
}
}
}
WINE_TRACE
(
"Server thread shutdown.
\n
"
);
return
0
;
}
static
HANDLE
RPCSS_NPConnect
(
void
)
{
HANDLE
the_pipe
;
DWORD
dwmode
,
wait_result
;
HANDLE
master_mutex
=
RPCSS_GetMasterMutex
();
WINE_TRACE
(
"
\n
"
);
while
(
TRUE
)
{
wait_result
=
WaitForSingleObject
(
master_mutex
,
MASTER_MUTEX_TIMEOUT
);
switch
(
wait_result
)
{
case
WAIT_ABANDONED
:
case
WAIT_OBJECT_0
:
break
;
case
WAIT_FAILED
:
case
WAIT_TIMEOUT
:
default:
WINE_ERR
(
"This should never happen: couldn't enter mutex.
\n
"
);
return
NULL
;
}
/* try to open the client side of the named pipe. */
the_pipe
=
CreateFileA
(
NAME_RPCSS_NAMED_PIPE
,
/* pipe name */
GENERIC_READ
|
GENERIC_WRITE
,
/* r/w access */
0
,
/* no sharing */
NULL
,
/* no security attributes */
OPEN_EXISTING
,
/* open an existing pipe */
0
,
/* default attributes */
NULL
/* no template file */
);
if
(
the_pipe
!=
INVALID_HANDLE_VALUE
)
break
;
if
(
GetLastError
()
!=
ERROR_PIPE_BUSY
)
{
WINE_WARN
(
"Unable to open named pipe %s (assuming unavailable).
\n
"
,
wine_dbgstr_a
(
NAME_RPCSS_NAMED_PIPE
));
break
;
}
WINE_WARN
(
"Named pipe busy (will wait)
\n
"
);
if
(
!
ReleaseMutex
(
master_mutex
))
WINE_ERR
(
"Failed to release master mutex. Expect deadlock.
\n
"
);
/* wait for the named pipe. We are only
willing to wait only 5 seconds. It should be available /very/ soon. */
if
(
!
WaitNamedPipeA
(
NAME_RPCSS_NAMED_PIPE
,
MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT
))
{
WINE_ERR
(
"Named pipe unavailable after waiting. Something is probably wrong.
\n
"
);
return
NULL
;
}
}
if
(
the_pipe
!=
INVALID_HANDLE_VALUE
)
{
dwmode
=
PIPE_READMODE_MESSAGE
;
/* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */
if
(
!
SetNamedPipeHandleState
(
the_pipe
,
&
dwmode
,
NULL
,
NULL
))
WINE_WARN
(
"Failed to set pipe handle state
\n
"
);
}
if
(
!
ReleaseMutex
(
master_mutex
))
WINE_ERR
(
"Uh oh, failed to leave the RPC Master Mutex!
\n
"
);
return
the_pipe
;
}
static
BOOL
RPCSS_SendReceiveNPMsg
(
HANDLE
np
,
PRPCSS_NP_MESSAGE
msg
,
PRPCSS_NP_REPLY
reply
)
{
DWORD
count
;
WINE_TRACE
(
"(np == %p, msg == %p, reply == %p)
\n
"
,
np
,
msg
,
reply
);
if
(
!
WriteFile
(
np
,
msg
,
sizeof
(
RPCSS_NP_MESSAGE
),
&
count
,
NULL
))
{
WINE_ERR
(
"write failed.
\n
"
);
return
FALSE
;
}
if
(
count
!=
sizeof
(
RPCSS_NP_MESSAGE
))
{
WINE_ERR
(
"write count mismatch.
\n
"
);
return
FALSE
;
}
if
(
!
ReadFile
(
np
,
reply
,
sizeof
(
RPCSS_NP_REPLY
),
&
count
,
NULL
))
{
WINE_ERR
(
"read failed.
\n
"
);
return
FALSE
;
}
if
(
count
!=
sizeof
(
RPCSS_NP_REPLY
))
{
WINE_ERR
(
"read count mismatch, got %d.
\n
"
,
count
);
return
FALSE
;
}
/* message execution was successful */
return
TRUE
;
}
BOOL
RPCSS_BecomePipeServer
(
void
)
{
RPCSS_NP_MESSAGE
msg
;
RPCSS_NP_REPLY
reply
;
BOOL
rslt
=
TRUE
;
HANDLE
client_handle
,
hthread
,
master_mutex
=
RPCSS_GetMasterMutex
();
DWORD
threadid
,
wait_result
;
WINE_TRACE
(
"
\n
"
);
wait_result
=
WaitForSingleObject
(
master_mutex
,
MASTER_MUTEX_TIMEOUT
);
switch
(
wait_result
)
{
case
WAIT_ABANDONED
:
/* ? */
case
WAIT_OBJECT_0
:
/* we have ownership */
break
;
case
WAIT_FAILED
:
case
WAIT_TIMEOUT
:
default:
WINE_ERR
(
"Couldn't enter master mutex.
\n
"
);
return
FALSE
;
}
/* now we have the master mutex. during this time we will
*
* o check if an rpcss already listens on the pipe. If so,
* we will tell it we were invoked, which will cause the
* other end to update its timeouts. After, we just return
* false.
*
* o otherwise, we establish the pipe for ourselves and get
* ready to listen on it
*/
if
((
client_handle
=
RPCSS_NPConnect
())
!=
INVALID_HANDLE_VALUE
)
{
ZeroMemory
(
&
msg
,
sizeof
(
msg
));
msg
.
message_type
=
RPCSS_NP_MESSAGE_TYPEID_RANMSG
;
msg
.
message
.
ranmsg
.
timeout
=
1000
;
msg
.
vardata_payload_size
=
0
;
if
(
!
RPCSS_SendReceiveNPMsg
(
client_handle
,
&
msg
,
&
reply
))
WINE_ERR
(
"Something is amiss: RPC_SendReceive failed.
\n
"
);
CloseHandle
(
client_handle
);
rslt
=
FALSE
;
}
if
(
rslt
)
{
np_server_work_event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
"RpcNpServerWorkEvent"
);
if
(
np_server_work_event
==
NULL
)
{
/* dunno what we can do then */
WINE_ERR
(
"Unable to create the np_server_work_event
\n
"
);
assert
(
FALSE
);
}
InitializeCriticalSection
(
&
np_server_cs
);
np_server_end
=
CreateNamedPipe
(
NAME_RPCSS_NAMED_PIPE
,
/* pipe name */
PIPE_ACCESS_DUPLEX
,
/* pipe open mode */
PIPE_TYPE_MESSAGE
|
PIPE_READMODE_MESSAGE
|
PIPE_WAIT
,
/* pipe-specific modes */
PIPE_UNLIMITED_INSTANCES
,
/* maximum number of instances */
sizeof
(
RPCSS_NP_REPLY
),
/* output buffer size */
sizeof
(
RPCSS_NP_MESSAGE
),
/* input buffer size */
2000
,
/* time-out interval */
NULL
/* SD */
);
if
(
np_server_end
==
INVALID_HANDLE_VALUE
)
{
WINE_ERR
(
"Failed to create named pipe!
\n
"
);
DeleteCriticalSection
(
&
np_server_cs
);
if
(
!
CloseHandle
(
np_server_work_event
))
/* we will leak the handle... */
WINE_WARN
(
"Failed to close np_server_work_event handle!
\n
"
);
np_server_work_event
=
NULL
;
np_server_end
=
NULL
;
rslt
=
FALSE
;
}
}
server_live
=
rslt
;
if
(
rslt
)
{
/* OK, now spawn the (single) server thread */
hthread
=
CreateThread
(
NULL
,
/* no security attribute */
0
,
/* default stack size */
NPMainWorkThread
,
NULL
,
/* thread parameter */
0
,
/* not suspended */
&
threadid
/* returns thread ID (not used) */
);
if
(
hthread
)
{
WINE_TRACE
(
"Created server thread.
\n
"
);
CloseHandle
(
hthread
);
}
else
{
WINE_ERR
(
"Serious error: unable to create server thread!
\n
"
);
if
(
!
CloseHandle
(
np_server_work_event
))
/* we will leak the handle... */
WINE_WARN
(
"Failed to close np_server_work_event handle!
\n
"
);
if
(
!
CloseHandle
(
np_server_end
))
/* we will leak the handle... */
WINE_WARN
(
"Unable to close named pipe handle!
\n
"
);
DeleteCriticalSection
(
&
np_server_cs
);
np_server_end
=
NULL
;
np_server_work_event
=
NULL
;
rslt
=
FALSE
;
server_live
=
FALSE
;
}
}
if
(
!
ReleaseMutex
(
master_mutex
))
WINE_ERR
(
"Unable to leave master mutex!??
\n
"
);
return
rslt
;
}
BOOL
RPCSS_NPDoWork
(
HANDLE
exit_handle
)
{
HANDLE
handles
[
2
];
DWORD
waitresult
;
handles
[
0
]
=
np_server_work_event
;
handles
[
1
]
=
exit_handle
;
waitresult
=
WaitForMultipleObjects
(
2
,
handles
,
FALSE
,
INFINITE
);
if
(
waitresult
==
WAIT_OBJECT_0
)
return
TRUE
;
return
FALSE
;
}
programs/rpcss/rpcss.h
View file @
45a3462c
...
...
@@ -21,28 +21,6 @@
#ifndef __WINE_RPCSS_H
#define __WINE_RPCSS_H
#include "wine/rpcss_shared.h"
#include "windows.h"
/* in seconds */
#define RPCSS_DEFAULT_MAX_LAZY_TIMEOUT 30
/* rpcss_main.c */
HANDLE
RPCSS_GetMasterMutex
(
void
);
/* epmap_server.c */
BOOL
RPCSS_EpmapEmpty
(
void
);
BOOL
RPCSS_NPDoWork
(
HANDLE
exit_event
);
void
RPCSS_RegisterRpcEndpoints
(
RPC_SYNTAX_IDENTIFIER
iface
,
int
object_count
,
int
binding_count
,
int
no_replace
,
char
*
vardata
,
long
vardata_size
);
void
RPCSS_UnregisterRpcEndpoints
(
RPC_SYNTAX_IDENTIFIER
iface
,
int
object_count
,
int
binding_count
,
char
*
vardata
,
long
vardata_size
);
void
RPCSS_ResolveRpcEndpoints
(
RPC_SYNTAX_IDENTIFIER
iface
,
UUID
object
,
char
*
protseq
,
char
*
rslt_ep
);
/* named_pipe_kludge.c */
BOOL
RPCSS_BecomePipeServer
(
void
);
BOOL
RPCSS_UnBecomePipeServer
(
void
);
LONG
RPCSS_SrvThreadCount
(
void
);
#endif
/* __WINE_RPCSS_H */
programs/rpcss/rpcss_main.c
View file @
45a3462c
...
...
@@ -58,21 +58,10 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
ole
);
static
HANDLE
master_mutex
;
static
HANDLE
exit_event
;
extern
HANDLE
__wine_make_process_system
(
void
);
HANDLE
RPCSS_GetMasterMutex
(
void
)
{
return
master_mutex
;
}
static
BOOL
RPCSS_work
(
HANDLE
exit_event
)
{
return
RPCSS_NPDoWork
(
exit_event
);
}
static
BOOL
RPCSS_Initialize
(
void
)
{
static
unsigned
short
irot_protseq
[]
=
IROT_PROTSEQ
;
...
...
@@ -83,21 +72,6 @@ static BOOL RPCSS_Initialize(void)
WINE_TRACE
(
"
\n
"
);
master_mutex
=
CreateMutexA
(
NULL
,
FALSE
,
RPCSS_MASTER_MUTEX_NAME
);
if
(
!
master_mutex
)
{
WINE_ERR
(
"Failed to create master mutex
\n
"
);
return
FALSE
;
}
if
(
!
RPCSS_BecomePipeServer
())
{
WINE_WARN
(
"Server already running: exiting.
\n
"
);
CloseHandle
(
master_mutex
);
master_mutex
=
NULL
;
return
FALSE
;
}
status
=
RpcServerRegisterIf
(
epm_v3_0_s_ifspec
,
NULL
,
NULL
);
if
(
status
!=
RPC_S_OK
)
return
status
;
...
...
@@ -136,14 +110,6 @@ fail:
aren't ready to terminate */
static
BOOL
RPCSS_Shutdown
(
void
)
{
if
(
!
RPCSS_UnBecomePipeServer
())
return
FALSE
;
if
(
!
CloseHandle
(
master_mutex
))
WINE_WARN
(
"Failed to release master mutex
\n
"
);
master_mutex
=
NULL
;
RpcMgmtStopServerListening
(
NULL
);
RpcServerUnregisterIf
(
epm_v3_0_s_ifspec
,
NULL
,
TRUE
);
RpcServerUnregisterIf
(
Irot_v0_2_s_ifspec
,
NULL
,
TRUE
);
...
...
@@ -153,24 +119,16 @@ static BOOL RPCSS_Shutdown(void)
return
TRUE
;
}
static
void
RPCSS_MainLoop
(
void
)
{
WINE_TRACE
(
"
\n
"
);
while
(
RPCSS_work
(
exit_event
)
)
;
}
int
main
(
int
argc
,
char
**
argv
)
{
/*
* We are invoked as a standard executable; we act in a
* "lazy" manner. We
open up our pipe, and hang around until we all
* user processes exit, and then silently terminate.
* "lazy" manner. We
register our interfaces and endpoints, and hang around
* u
ntil we all u
ser processes exit, and then silently terminate.
*/
if
(
RPCSS_Initialize
())
{
RPCSS_MainLoop
(
);
WaitForSingleObject
(
exit_event
,
INFINITE
);
RPCSS_Shutdown
();
}
...
...
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