Create a branch for header work.

svn path=/branches/header-work/; revision=45691
This commit is contained in:
Timo Kreuzer 2010-02-26 22:57:55 +00:00
parent 14fe274b1c
commit 9ea495ba33
19538 changed files with 0 additions and 1063950 deletions

View file

@ -0,0 +1,19 @@
/*
* Copyright 2008 Robert Shearman
*
* 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 "wine/epm.idl"

284
base/services/rpcss/epmp.c Normal file
View file

@ -0,0 +1,284 @@
/*
* Endpoint Mapper
*
* Copyright (C) 2007 Robert Shearman for CodeWeavers
*
* 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 "epm_s.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
struct registered_ept_entry
{
struct list entry;
GUID object;
RPC_SYNTAX_IDENTIFIER iface;
RPC_SYNTAX_IDENTIFIER syntax;
char *protseq;
char *endpoint;
char *address;
char annotation[ept_max_annotation_size];
};
static struct list registered_ept_entry_list = LIST_INIT(registered_ept_entry_list);
static CRITICAL_SECTION csEpm;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &csEpm,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": csEpm") }
};
static CRITICAL_SECTION csEpm = { &critsect_debug, -1, 0, 0, 0, 0 };
static const UUID nil_object;
/* must be called inside csEpm */
static void delete_registered_ept_entry(struct registered_ept_entry *entry)
{
I_RpcFree(entry->protseq);
I_RpcFree(entry->endpoint);
I_RpcFree(entry->address);
list_remove(&entry->entry);
HeapFree(GetProcessHeap(), 0, entry);
}
static struct registered_ept_entry *find_ept_entry(
const RPC_SYNTAX_IDENTIFIER *iface, const RPC_SYNTAX_IDENTIFIER *syntax,
const char *protseq, const char *endpoint, const char *address,
const UUID *object)
{
struct registered_ept_entry *entry;
LIST_FOR_EACH_ENTRY(entry, &registered_ept_entry_list, struct registered_ept_entry, entry)
{
if (memcmp(&entry->iface, iface, sizeof(RPC_SYNTAX_IDENTIFIER))) continue;
if (memcmp(&entry->syntax, syntax, sizeof(RPC_SYNTAX_IDENTIFIER))) continue;
if (strcmp(entry->protseq, protseq)) continue;
if (memcmp(&entry->object, object, sizeof(UUID))) continue;
WINE_TRACE("found entry with iface %d.%d %s, syntax %d.%d %s, protseq %s, object %s\n",
entry->iface.SyntaxVersion.MajorVersion, entry->iface.SyntaxVersion.MinorVersion,
wine_dbgstr_guid(&entry->iface.SyntaxGUID),
entry->syntax.SyntaxVersion.MajorVersion, entry->syntax.SyntaxVersion.MinorVersion,
wine_dbgstr_guid(&entry->syntax.SyntaxGUID), protseq,
wine_dbgstr_guid(&entry->object));
return entry;
}
WINE_TRACE("not found\n");
return NULL;
}
void __RPC_USER ept_lookup_handle_t_rundown(ept_lookup_handle_t entry_handle)
{
WINE_FIXME("%p\n", entry_handle);
}
void ept_insert(handle_t h,
unsigned32 num_ents,
ept_entry_t entries[],
boolean32 replace,
error_status_t *status)
{
unsigned32 i;
RPC_STATUS rpc_status;
WINE_TRACE("(%p, %lu, %p, %lu, %p)\n", h, num_ents, entries, replace, status);
*status = RPC_S_OK;
EnterCriticalSection(&csEpm);
for (i = 0; i < num_ents; i++)
{
struct registered_ept_entry *entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
if (!entry)
{
/* FIXME: cleanup code to delete added entries */
*status = EPT_S_CANT_PERFORM_OP;
break;
}
list_init(&entry->entry);
memcpy(entry->annotation, entries[i].annotation, sizeof(entries[i].annotation));
rpc_status = TowerExplode(entries[i].tower, &entry->iface, &entry->syntax,
&entry->protseq, &entry->endpoint,
&entry->address);
if (rpc_status != RPC_S_OK)
{
WINE_WARN("TowerExplode failed %lu\n", rpc_status);
*status = rpc_status;
break; /* FIXME: more cleanup? */
}
entry->object = entries[i].object;
if (replace)
{
/* FIXME: correct find algorithm */
struct registered_ept_entry *old_entry = find_ept_entry(&entry->iface, &entry->syntax, entry->protseq, entry->endpoint, entry->address, &entry->object);
if (old_entry) delete_registered_ept_entry(old_entry);
}
list_add_tail(&registered_ept_entry_list, &entry->entry);
}
LeaveCriticalSection(&csEpm);
}
void ept_delete(handle_t h,
unsigned32 num_ents,
ept_entry_t entries[],
error_status_t *status)
{
unsigned32 i;
RPC_STATUS rpc_status;
*status = RPC_S_OK;
WINE_TRACE("(%p, %lu, %p, %p)\n", h, num_ents, entries, status);
EnterCriticalSection(&csEpm);
for (i = 0; i < num_ents; i++)
{
struct registered_ept_entry *entry;
RPC_SYNTAX_IDENTIFIER iface, syntax;
char *protseq;
char *endpoint;
char *address;
rpc_status = TowerExplode(entries[i].tower, &iface, &syntax, &protseq,
&endpoint, &address);
if (rpc_status != RPC_S_OK)
break;
entry = find_ept_entry(&iface, &syntax, protseq, endpoint, address, &entries[i].object);
if (entry)
delete_registered_ept_entry(entry);
else
{
*status = EPT_S_NOT_REGISTERED;
break;
}
I_RpcFree(protseq);
I_RpcFree(endpoint);
I_RpcFree(address);
}
LeaveCriticalSection(&csEpm);
}
void ept_lookup(handle_t h,
unsigned32 inquiry_type,
uuid_p_t object,
rpc_if_id_p_t interface_id,
unsigned32 vers_option,
ept_lookup_handle_t *entry_handle,
unsigned32 max_ents,
unsigned32 *num_ents,
ept_entry_t entries[],
error_status_t *status)
{
WINE_FIXME("(%p, %p, %p): stub\n", h, entry_handle, status);
*status = EPT_S_CANT_PERFORM_OP;
}
void ept_map(handle_t h,
uuid_p_t object,
twr_p_t map_tower,
ept_lookup_handle_t *entry_handle,
unsigned32 max_towers,
unsigned32 *num_towers,
twr_p_t *towers,
error_status_t *status)
{
RPC_STATUS rpc_status;
RPC_SYNTAX_IDENTIFIER iface, syntax;
char *protseq;
struct registered_ept_entry *entry;
*status = RPC_S_OK;
*num_towers = 0;
WINE_TRACE("(%p, %p, %p, %p, %lu, %p, %p, %p)\n", h, object, map_tower,
entry_handle, max_towers, num_towers, towers, status);
rpc_status = TowerExplode(map_tower, &iface, &syntax, &protseq,
NULL, NULL);
if (rpc_status != RPC_S_OK)
{
*status = rpc_status;
return;
}
EnterCriticalSection(&csEpm);
LIST_FOR_EACH_ENTRY(entry, &registered_ept_entry_list, struct registered_ept_entry, entry)
{
if (IsEqualGUID(&entry->iface.SyntaxGUID, &iface.SyntaxGUID) &&
(entry->iface.SyntaxVersion.MajorVersion == iface.SyntaxVersion.MajorVersion) &&
(entry->iface.SyntaxVersion.MinorVersion >= iface.SyntaxVersion.MinorVersion) &&
!memcmp(&entry->syntax, &syntax, sizeof(syntax)) &&
!strcmp(entry->protseq, protseq) &&
((!object && IsEqualGUID(&entry->object, &nil_object)) || IsEqualGUID(object, &entry->object)))
{
if (*num_towers < max_towers)
{
rpc_status = TowerConstruct(&entry->iface, &entry->syntax,
entry->protseq, entry->endpoint,
entry->address,
&towers[*num_towers]);
if (rpc_status != RPC_S_OK)
{
*status = rpc_status;
break; /* FIXME: more cleanup? */
}
}
(*num_towers)++;
}
}
LeaveCriticalSection(&csEpm);
}
void ept_lookup_handle_free(handle_t h,
ept_lookup_handle_t *entry_handle,
error_status_t *status)
{
WINE_FIXME("(%p, %p, %p): stub\n", h, entry_handle, status);
*status = EPT_S_CANT_PERFORM_OP;
}
void ept_inq_object(handle_t h,
GUID *ept_object,
error_status_t *status)
{
WINE_FIXME("(%p, %p, %p): stub\n", h, ept_object, status);
*status = EPT_S_CANT_PERFORM_OP;
}
void ept_mgmt_delete(handle_t h,
boolean32 object_speced,
uuid_p_t object,
twr_p_t tower,
error_status_t *status)
{
WINE_FIXME("(%p, %ld, %p, %p, %p): stub\n", h, object_speced, object, tower, status);
*status = EPT_S_CANT_PERFORM_OP;
}

View file

@ -0,0 +1,19 @@
/*
* Copyright 2007 Robert Shearman for CodeWeavers
*
* 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 "wine/irot.idl"

379
base/services/rpcss/irotp.c Normal file
View file

@ -0,0 +1,379 @@
/*
* Running Object Table
*
* Copyright 2007 Robert Shearman
*
* 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 <stdarg.h>
#include <string.h>
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "irot_s.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(rpcss);
/* define the structure of the running object table elements */
struct rot_entry
{
struct list entry;
InterfaceData *object; /* marshaled running object*/
InterfaceData *moniker; /* marshaled moniker that identifies this object */
MonikerComparisonData *moniker_data; /* moniker comparison data that identifies this object */
DWORD cookie; /* cookie identifying this object */
FILETIME last_modified;
LONG refs;
};
static struct list RunningObjectTable = LIST_INIT(RunningObjectTable);
static CRITICAL_SECTION csRunningObjectTable;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &csRunningObjectTable,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": csRunningObjectTable") }
};
static CRITICAL_SECTION csRunningObjectTable = { &critsect_debug, -1, 0, 0, 0, 0 };
static LONG last_cookie = 1;
static inline void rot_entry_release(struct rot_entry *rot_entry)
{
if (!InterlockedDecrement(&rot_entry->refs))
{
HeapFree(GetProcessHeap(), 0, rot_entry->object);
HeapFree(GetProcessHeap(), 0, rot_entry->moniker);
HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data);
HeapFree(GetProcessHeap(), 0, rot_entry);
}
}
HRESULT IrotRegister(
IrotHandle h,
const MonikerComparisonData *data,
const InterfaceData *obj,
const InterfaceData *mk,
const FILETIME *time,
DWORD grfFlags,
IrotCookie *cookie,
IrotContextHandle *ctxt_handle)
{
struct rot_entry *rot_entry;
struct rot_entry *existing_rot_entry;
HRESULT hr;
if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT))
{
WINE_ERR("Invalid grfFlags: 0x%08x\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT));
return E_INVALIDARG;
}
rot_entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rot_entry));
if (!rot_entry)
return E_OUTOFMEMORY;
rot_entry->refs = 1;
rot_entry->object = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[obj->ulCntData]));
if (!rot_entry->object)
{
rot_entry_release(rot_entry);
return E_OUTOFMEMORY;
}
rot_entry->object->ulCntData = obj->ulCntData;
memcpy(&rot_entry->object->abData, obj->abData, obj->ulCntData);
rot_entry->last_modified = *time;
rot_entry->moniker = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[mk->ulCntData]));
if (!rot_entry->moniker)
{
rot_entry_release(rot_entry);
return E_OUTOFMEMORY;
}
rot_entry->moniker->ulCntData = mk->ulCntData;
memcpy(&rot_entry->moniker->abData, mk->abData, mk->ulCntData);
rot_entry->moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MonikerComparisonData, abData[data->ulCntData]));
if (!rot_entry->moniker_data)
{
rot_entry_release(rot_entry);
return E_OUTOFMEMORY;
}
rot_entry->moniker_data->ulCntData = data->ulCntData;
memcpy(&rot_entry->moniker_data->abData, data->abData, data->ulCntData);
EnterCriticalSection(&csRunningObjectTable);
hr = S_OK;
LIST_FOR_EACH_ENTRY(existing_rot_entry, &RunningObjectTable, struct rot_entry, entry)
{
if ((existing_rot_entry->moniker_data->ulCntData == data->ulCntData) &&
!memcmp(&data->abData, &existing_rot_entry->moniker_data->abData, data->ulCntData))
{
hr = MK_S_MONIKERALREADYREGISTERED;
WINE_TRACE("moniker already registered with cookie %d\n", existing_rot_entry->cookie);
break;
}
}
list_add_tail(&RunningObjectTable, &rot_entry->entry);
LeaveCriticalSection(&csRunningObjectTable);
/* gives a registration identifier to the registered object*/
*cookie = rot_entry->cookie = InterlockedIncrement(&last_cookie);
*ctxt_handle = rot_entry;
return hr;
}
HRESULT IrotRevoke(
IrotHandle h,
IrotCookie cookie,
IrotContextHandle *ctxt_handle,
PInterfaceData *obj,
PInterfaceData *mk)
{
struct rot_entry *rot_entry;
WINE_TRACE("%d\n", cookie);
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
{
if (rot_entry->cookie == cookie)
{
HRESULT hr = S_OK;
list_remove(&rot_entry->entry);
LeaveCriticalSection(&csRunningObjectTable);
*obj = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->object->ulCntData]));
*mk = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->moniker->ulCntData]));
if (*obj && *mk)
{
(*obj)->ulCntData = rot_entry->object->ulCntData;
memcpy((*obj)->abData, rot_entry->object->abData, (*obj)->ulCntData);
(*mk)->ulCntData = rot_entry->moniker->ulCntData;
memcpy((*mk)->abData, rot_entry->moniker->abData, (*mk)->ulCntData);
}
else
{
MIDL_user_free(*obj);
MIDL_user_free(*mk);
hr = E_OUTOFMEMORY;
}
rot_entry_release(rot_entry);
*ctxt_handle = NULL;
return hr;
}
}
LeaveCriticalSection(&csRunningObjectTable);
return E_INVALIDARG;
}
HRESULT IrotIsRunning(
IrotHandle h,
const MonikerComparisonData *data)
{
const struct rot_entry *rot_entry;
HRESULT hr = S_FALSE;
WINE_TRACE("\n");
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
{
if ((rot_entry->moniker_data->ulCntData == data->ulCntData) &&
!memcmp(&data->abData, &rot_entry->moniker_data->abData, data->ulCntData))
{
hr = S_OK;
break;
}
}
LeaveCriticalSection(&csRunningObjectTable);
return hr;
}
HRESULT IrotGetObject(
IrotHandle h,
const MonikerComparisonData *moniker_data,
PInterfaceData *obj,
IrotCookie *cookie)
{
const struct rot_entry *rot_entry;
WINE_TRACE("%p\n", moniker_data);
*cookie = 0;
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
{
HRESULT hr = S_OK;
if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
!memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
{
*obj = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->object->ulCntData]));
if (*obj)
{
(*obj)->ulCntData = rot_entry->object->ulCntData;
memcpy((*obj)->abData, rot_entry->object->abData, (*obj)->ulCntData);
*cookie = rot_entry->cookie;
}
else
hr = E_OUTOFMEMORY;
LeaveCriticalSection(&csRunningObjectTable);
return hr;
}
}
LeaveCriticalSection(&csRunningObjectTable);
return MK_E_UNAVAILABLE;
}
HRESULT IrotNoteChangeTime(
IrotHandle h,
IrotCookie cookie,
const FILETIME *last_modified_time)
{
struct rot_entry *rot_entry;
WINE_TRACE("%d %p\n", cookie, last_modified_time);
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
{
if (rot_entry->cookie == cookie)
{
rot_entry->last_modified = *last_modified_time;
LeaveCriticalSection(&csRunningObjectTable);
return S_OK;
}
}
LeaveCriticalSection(&csRunningObjectTable);
return E_INVALIDARG;
}
HRESULT IrotGetTimeOfLastChange(
IrotHandle h,
const MonikerComparisonData *moniker_data,
FILETIME *time)
{
const struct rot_entry *rot_entry;
HRESULT hr = MK_E_UNAVAILABLE;
WINE_TRACE("%p\n", moniker_data);
memset(time, 0, sizeof(*time));
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
{
if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
!memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
{
*time = rot_entry->last_modified;
hr = S_OK;
break;
}
}
LeaveCriticalSection(&csRunningObjectTable);
return hr;
}
HRESULT IrotEnumRunning(
IrotHandle h,
PInterfaceList *list)
{
const struct rot_entry *rot_entry;
HRESULT hr = S_OK;
ULONG moniker_count = 0;
ULONG i = 0;
WINE_TRACE("\n");
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry )
moniker_count++;
*list = MIDL_user_allocate(FIELD_OFFSET(InterfaceList, interfaces[moniker_count]));
if (*list)
{
(*list)->size = moniker_count;
LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry )
{
(*list)->interfaces[i] = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->moniker->ulCntData]));
if (!(*list)->interfaces[i])
{
ULONG end = i - 1;
for (i = 0; i < end; i++)
MIDL_user_free((*list)->interfaces[i]);
MIDL_user_free(*list);
hr = E_OUTOFMEMORY;
break;
}
(*list)->interfaces[i]->ulCntData = rot_entry->moniker->ulCntData;
memcpy((*list)->interfaces[i]->abData, rot_entry->moniker->abData, rot_entry->moniker->ulCntData);
i++;
}
}
else
hr = E_OUTOFMEMORY;
LeaveCriticalSection(&csRunningObjectTable);
return hr;
}
void __RPC_USER IrotContextHandle_rundown(IrotContextHandle ctxt_handle)
{
struct rot_entry *rot_entry = ctxt_handle;
EnterCriticalSection(&csRunningObjectTable);
list_remove(&rot_entry->entry);
LeaveCriticalSection(&csRunningObjectTable);
rot_entry_release(rot_entry);
}
void * __RPC_USER MIDL_user_allocate(SIZE_T size)
{
return HeapAlloc(GetProcessHeap(), 0, size);
}
void __RPC_USER MIDL_user_free(void * p)
{
HeapFree(GetProcessHeap(), 0, p);
}

View file

@ -0,0 +1,26 @@
/*
* RPCSS definitions
*
* 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_H
#define __WINE_RPCSS_H
#include "windows.h"
#endif /* __WINE_RPCSS_H */

View file

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<group>
<module name="rpcss" type="win32cui" installbase="system32" installname="rpcss.exe" unicode="yes">
<include base="rpcss">.</include>
<include base="rpcss" root="intermediate">.</include>
<library>wine</library>
<library>rpcss_epm_server</library>
<library>rpcss_irot_server</library>
<library>rpcrt4</library>
<library>advapi32</library>
<library>pseh</library>
<file>epmp.c</file>
<file>irotp.c</file>
<file>rpcss_main.c</file>
<file>service_main.c</file>
<file>epm.idl</file>
<file>irot.idl</file>
<file>rpcss.rc</file>
</module>
<module name="rpcss_epm_server" type="rpcserver">
<file>epm.idl</file>
</module>
<module name="rpcss_irot_server" type="rpcserver">
<file>irot.idl</file>
</module>
</group>

View file

@ -0,0 +1,6 @@
/* $Id$ */
#define REACTOS_STR_FILE_DESCRIPTION "RPC subsystem\0"
#define REACTOS_STR_INTERNAL_NAME "RpcSs\0"
#define REACTOS_STR_ORIGINAL_FILENAME "RpcSs.exe\0"
#include <reactos/version.rc>

View file

@ -0,0 +1,146 @@
/*
* Copyright 2001, Ove Kåven, TransGaming Technologies Inc.
* Copyright 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
*
* ---- rpcss_main.c:
* Initialize and start serving requests. Bail if rpcss already is
* running.
*
* ---- RPCSS.EXE:
*
* Wine needs a server whose role is somewhat like that
* of rpcss.exe in windows. This is not a clone of
* windows rpcss at all. It has been given the same name, however,
* to provide for the possibility that at some point in the future,
* it may become interface compatible with the "real" rpcss.exe on
* Windows.
*
* ---- KNOWN BUGS / TODO:
*
* o Service hooks are unimplemented (if you bother to implement
* these, also implement net.exe, at least for "net start" and
* "net stop" (should be pretty easy I guess, assuming the rest
* of the services API infrastructure works.
*
* o There is a looming problem regarding listening on privileged
* ports. We will need to be able to coexist with SAMBA, and be able
* to function without running winelib code as root. This may
* take some doing, including significant reconceptualization of the
* role of rpcss.exe in wine.
*/
#include <stdio.h>
#include <limits.h>
#include <assert.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "rpcss.h"
#include "winnt.h"
#include "irot.h"
#include "epm.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
HANDLE exit_event;
//extern HANDLE __wine_make_process_system(void);
BOOL RPCSS_Initialize(void)
{
static unsigned short irot_protseq[] = IROT_PROTSEQ;
static unsigned short irot_endpoint[] = IROT_ENDPOINT;
static unsigned short epm_protseq[] = {'n','c','a','c','n','_','n','p',0};
static unsigned short epm_endpoint[] = {'\\','p','i','p','e','\\','e','p','m','a','p','p','e','r',0};
static unsigned short epm_protseq_lrpc[] = {'n','c','a','l','r','p','c',0};
static unsigned short epm_endpoint_lrpc[] = {'e','p','m','a','p','p','e','r',0};
RPC_STATUS status;
WINE_TRACE("\n");
status = RpcServerRegisterIf(epm_v3_0_s_ifspec, NULL, NULL);
if (status != RPC_S_OK)
return status;
status = RpcServerRegisterIf(Irot_v0_2_s_ifspec, NULL, NULL);
if (status != RPC_S_OK)
{
RpcServerUnregisterIf(epm_v3_0_s_ifspec, NULL, FALSE);
return FALSE;
}
status = RpcServerUseProtseqEpW(epm_protseq, RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
epm_endpoint, NULL);
if (status != RPC_S_OK)
goto fail;
status = RpcServerUseProtseqEpW(epm_protseq_lrpc, RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
epm_endpoint_lrpc, NULL);
if (status != RPC_S_OK)
goto fail;
status = RpcServerUseProtseqEpW(irot_protseq, RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
irot_endpoint, NULL);
if (status != RPC_S_OK)
goto fail;
status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE);
if (status != RPC_S_OK)
goto fail;
//exit_event = __wine_make_process_system();
exit_event = CreateEventW(NULL, FALSE, FALSE, NULL); // never fires
return TRUE;
fail:
RpcServerUnregisterIf(epm_v3_0_s_ifspec, NULL, FALSE);
RpcServerUnregisterIf(Irot_v0_2_s_ifspec, NULL, FALSE);
return FALSE;
}
/* returns false if we discover at the last moment that we
aren't ready to terminate */
BOOL RPCSS_Shutdown(void)
{
RpcMgmtStopServerListening(NULL);
RpcServerUnregisterIf(epm_v3_0_s_ifspec, NULL, TRUE);
RpcServerUnregisterIf(Irot_v0_2_s_ifspec, NULL, TRUE);
CloseHandle(exit_event);
return TRUE;
}
#if 0
int main( int argc, char **argv )
{
/*
* We are invoked as a standard executable; we act in a
* "lazy" manner. We register our interfaces and endpoints, and hang around
* until we all user processes exit, and then silently terminate.
*/
if (RPCSS_Initialize()) {
WaitForSingleObject(exit_event, INFINITE);
RPCSS_Shutdown();
}
return 0;
}
#endif

View file

@ -0,0 +1,40 @@
Index: rpcss_main.c
===================================================================
--- rpcss_main.c
+++ rpcss_main.c
@@ -58,11 +58,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-static HANDLE exit_event;
+HANDLE exit_event;
//extern HANDLE __wine_make_process_system(void);
-static BOOL RPCSS_Initialize(void)
+BOOL RPCSS_Initialize(void)
{
static unsigned short irot_protseq[] = IROT_PROTSEQ;
static unsigned short irot_endpoint[] = IROT_ENDPOINT;
@@ -116,7 +116,7 @@
/* returns false if we discover at the last moment that we
aren't ready to terminate */
-static BOOL RPCSS_Shutdown(void)
+BOOL RPCSS_Shutdown(void)
{
RpcMgmtStopServerListening(NULL);
RpcServerUnregisterIf(epm_v3_0_s_ifspec, NULL, TRUE);
@@ -127,6 +127,7 @@
return TRUE;
}
+#if 0
int main( int argc, char **argv )
{
/*
@@ -142,3 +143,4 @@
return 0;
}
+#endif

View file

@ -0,0 +1,98 @@
/*
* PROJECT: ReactOS Remote Procedure Call service
* LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/rpcss/service_main.c
* PURPOSE: Service control code
* COPYRIGHT: Copyright 2008 Ged Murphy <gedmurphy@reactos.org>
*
*/
#include "rpcss.h"
#define NDEBUG
#include <debug.h>
extern BOOL RPCSS_Initialize(void);
extern BOOL RPCSS_Shutdown(void);
extern HANDLE exit_event;
static VOID WINAPI ServiceMain(DWORD, LPWSTR *);
static WCHAR ServiceName[] = L"RpcSs";
SERVICE_TABLE_ENTRYW ServiceTable[] =
{
{ ServiceName, ServiceMain },
{ NULL, NULL }
};
static SERVICE_STATUS ServiceStatus;
static SERVICE_STATUS_HANDLE ServiceStatusHandle;
DWORD WINAPI
ServiceControlHandler(DWORD dwControl,
DWORD dwEventType,
LPVOID lpEventData,
LPVOID lpContext)
{
switch (dwControl)
{
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
SetEvent(exit_event);
return NO_ERROR;
case SERVICE_CONTROL_INTERROGATE:
return NO_ERROR;
default:
return ERROR_CALL_NOT_IMPLEMENTED;
}
}
VOID WINAPI
ServiceMain(DWORD argc, LPWSTR argv[])
{
DWORD dwError;
ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
ServiceControlHandler,
NULL);
if (!ServiceStatusHandle)
{
dwError = GetLastError();
DPRINT1("RegisterServiceCtrlHandlerW() failed! (Error %lu)\n", dwError);
return;
}
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwWin32ExitCode = NO_ERROR;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 1000;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
if (RPCSS_Initialize())
{
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
WaitForSingleObject(exit_event, INFINITE);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
RPCSS_Shutdown();
}
}
int wmain(int argc, LPWSTR argv[])
{
if (!StartServiceCtrlDispatcherW(ServiceTable))
{
DPRINT1("StartServiceCtrlDispatcherW() failed\n");
return 1;
}
return 0;
}