Commit 45a3462c authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

rpcrt4/rpcss: Remove old named pipe code for communicating with RPCSS process.

parent 9e1c7a30
......@@ -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
......
......@@ -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)
{
......
......@@ -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
/******************************************************************************
......
/*
* 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;
}
/*
* 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 */
......@@ -7,10 +7,8 @@ APPMODE = -mconsole
IMPORTS = rpcrt4 kernel32 ntdll
C_SRCS = \
epmap_server.c \
epmp.c \
irotp.c \
np_server.c \
rpcss_main.c
IDL_S_SRCS = \
......
/*
* 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);
}
......@@ -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 */
......@@ -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
* until we all user processes exit, and then silently terminate.
*/
if (RPCSS_Initialize()) {
RPCSS_MainLoop();
WaitForSingleObject(exit_event, INFINITE);
RPCSS_Shutdown();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment