mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 05:25:48 +00:00
Create a branch for header work.
svn path=/branches/header-work/; revision=45691
This commit is contained in:
parent
14fe274b1c
commit
9ea495ba33
19538 changed files with 0 additions and 1063950 deletions
19
base/services/rpcss/epm.idl
Normal file
19
base/services/rpcss/epm.idl
Normal 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
284
base/services/rpcss/epmp.c
Normal 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, ®istered_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(®istered_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, ®istered_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;
|
||||
}
|
19
base/services/rpcss/irot.idl
Normal file
19
base/services/rpcss/irot.idl
Normal 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
379
base/services/rpcss/irotp.c
Normal 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);
|
||||
}
|
26
base/services/rpcss/rpcss.h
Normal file
26
base/services/rpcss/rpcss.h
Normal 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 */
|
27
base/services/rpcss/rpcss.rbuild
Normal file
27
base/services/rpcss/rpcss.rbuild
Normal 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>
|
6
base/services/rpcss/rpcss.rc
Normal file
6
base/services/rpcss/rpcss.rc
Normal 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>
|
146
base/services/rpcss/rpcss_main.c
Normal file
146
base/services/rpcss/rpcss_main.c
Normal 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
|
40
base/services/rpcss/rpcss_ros.diff
Normal file
40
base/services/rpcss/rpcss_ros.diff
Normal 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
|
98
base/services/rpcss/service_main.c
Normal file
98
base/services/rpcss/service_main.c
Normal 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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue