[RPCSS] Sync to wine-10.0

This commit is contained in:
Mikhail Tyukin
2025-11-15 11:14:33 -05:00
committed by Timo Kreuzer
parent 5f6b295cb9
commit 20312ce0b1
9 changed files with 227 additions and 79 deletions

View File

@@ -1,7 +1,8 @@
add_rpc_files(server
${REACTOS_SOURCE_DIR}/sdk/include/wine/epm.idl
${REACTOS_SOURCE_DIR}/sdk/include/wine/irot.idl)
${REACTOS_SOURCE_DIR}/sdk/include/wine/irot.idl
${REACTOS_SOURCE_DIR}/sdk/include/wine/irpcss.idl)
list(APPEND SOURCE
@@ -11,9 +12,10 @@ list(APPEND SOURCE
setup.c
precomp.h
${CMAKE_CURRENT_BINARY_DIR}/epm_s.c
${CMAKE_CURRENT_BINARY_DIR}/irot_s.c)
${CMAKE_CURRENT_BINARY_DIR}/irot_s.c
${CMAKE_CURRENT_BINARY_DIR}/irpcss_s.c)
include_directories(${REACTOS_BINARY_DIR}/sdk/include/reactos/wine)
include_directories(${REACTOS_BINARY_DIR}/sdk/include/wine)
add_executable(rpcss ${SOURCE} rpcss.rc)
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")

View File

@@ -0,0 +1 @@
#include "epm_s.h"

View File

@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "epm_s.h"
#include "epm.h"
#include "wine/debug.h"
#include "wine/list.h"
@@ -57,7 +57,7 @@ static void delete_registered_ept_entry(struct registered_ept_entry *entry)
I_RpcFree(entry->endpoint);
I_RpcFree(entry->address);
list_remove(&entry->entry);
HeapFree(GetProcessHeap(), 0, entry);
free(entry);
}
static struct registered_ept_entry *find_ept_entry(
@@ -98,7 +98,7 @@ void __cdecl ept_insert(handle_t h,
unsigned32 i;
RPC_STATUS rpc_status;
WINE_TRACE("(%p, %u, %p, %u, %p)\n", h, num_ents, entries, replace, status);
WINE_TRACE("(%p, %lu, %p, %lu, %p)\n", h, num_ents, entries, replace, status);
*status = RPC_S_OK;
@@ -106,7 +106,7 @@ void __cdecl ept_insert(handle_t h,
for (i = 0; i < num_ents; i++)
{
struct registered_ept_entry *entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
struct registered_ept_entry *entry = malloc(sizeof(*entry));
if (!entry)
{
/* FIXME: cleanup code to delete added entries */
@@ -119,9 +119,9 @@ void __cdecl ept_insert(handle_t h,
&entry->address);
if (rpc_status != RPC_S_OK)
{
WINE_WARN("TowerExplode failed %u\n", rpc_status);
WINE_WARN("TowerExplode failed %lu\n", rpc_status);
*status = rpc_status;
HeapFree(GetProcessHeap(), 0, entry);
free(entry);
break; /* FIXME: more cleanup? */
}
@@ -149,7 +149,7 @@ void __cdecl ept_delete(handle_t h,
*status = RPC_S_OK;
WINE_TRACE("(%p, %u, %p, %p)\n", h, num_ents, entries, status);
WINE_TRACE("(%p, %lu, %p, %p)\n", h, num_ents, entries, status);
EnterCriticalSection(&csEpm);
@@ -215,7 +215,7 @@ void __cdecl ept_map(handle_t h,
*status = RPC_S_OK;
*num_towers = 0;
WINE_TRACE("(%p, %p, %p, %p, %u, %p, %p, %p)\n", h, object, map_tower,
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,
@@ -282,7 +282,7 @@ void __cdecl ept_mgmt_delete(handle_t h,
twr_p_t tower,
error_status_t *status)
{
WINE_FIXME("(%p, %d, %p, %p, %p): stub\n", h, object_speced, object, tower, 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 @@
#include "irot_s.h"

View File

@@ -25,7 +25,7 @@
#include "windef.h"
#include "winbase.h"
#include "irot_s.h"
#include "irot.h"
#include "wine/list.h"
#include "wine/debug.h"
@@ -61,10 +61,10 @@ 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);
free(rot_entry->object);
free(rot_entry->moniker);
free(rot_entry->moniker_data);
free(rot_entry);
}
}
@@ -84,16 +84,15 @@ HRESULT __cdecl IrotRegister(
if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT))
{
WINE_ERR("Invalid grfFlags: 0x%08x\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT));
WINE_ERR("Invalid grfFlags: 0x%08lx\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT));
return E_INVALIDARG;
}
rot_entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rot_entry));
if (!rot_entry)
if (!(rot_entry = calloc(1, sizeof(*rot_entry))))
return E_OUTOFMEMORY;
rot_entry->refs = 1;
rot_entry->object = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[obj->ulCntData]));
rot_entry->object = malloc(FIELD_OFFSET(InterfaceData, abData[obj->ulCntData]));
if (!rot_entry->object)
{
rot_entry_release(rot_entry);
@@ -104,7 +103,7 @@ HRESULT __cdecl IrotRegister(
rot_entry->last_modified = *time;
rot_entry->moniker = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[mk->ulCntData]));
rot_entry->moniker = malloc(FIELD_OFFSET(InterfaceData, abData[mk->ulCntData]));
if (!rot_entry->moniker)
{
rot_entry_release(rot_entry);
@@ -113,8 +112,7 @@ HRESULT __cdecl IrotRegister(
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)
if (!(rot_entry->moniker_data = malloc(FIELD_OFFSET(MonikerComparisonData, abData[data->ulCntData]))))
{
rot_entry_release(rot_entry);
return E_OUTOFMEMORY;
@@ -132,7 +130,7 @@ HRESULT __cdecl IrotRegister(
!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);
WINE_TRACE("moniker already registered with cookie %ld\n", existing_rot_entry->cookie);
break;
}
}
@@ -157,7 +155,7 @@ HRESULT __cdecl IrotRevoke(
{
struct rot_entry *rot_entry;
WINE_TRACE("%d\n", cookie);
WINE_TRACE("%ld\n", cookie);
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
@@ -269,7 +267,7 @@ HRESULT __cdecl IrotNoteChangeTime(
{
struct rot_entry *rot_entry;
WINE_TRACE("%d %p\n", cookie, last_modified_time);
WINE_TRACE("%ld %p\n", cookie, last_modified_time);
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
@@ -370,10 +368,10 @@ void __RPC_USER IrotContextHandle_rundown(IrotContextHandle ctxt_handle)
void * __RPC_USER MIDL_user_allocate(SIZE_T size)
{
return HeapAlloc(GetProcessHeap(), 0, size);
return I_RpcAllocate(size);
}
void __RPC_USER MIDL_user_free(void * p)
{
HeapFree(GetProcessHeap(), 0, p);
I_RpcFree(p);
}

View File

@@ -0,0 +1 @@
#include "irpcss_s.h"

View File

@@ -0,0 +1,21 @@
/*
* Copyright 2019 Nikolay Sivov 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
*/
#pragma makedep server
#include "wine/irpcss.idl"

View File

@@ -5,17 +5,14 @@
#include <stdarg.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define COBJMACROS
#include <windef.h>
#include <winbase.h>
#include <irot_s.h>
#include <epm_s.h>
#include <irpcss_s.h>
#include <wine/list.h>

View File

@@ -21,69 +21,191 @@
#include <stdarg.h>
#include <limits.h>
#include <assert.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winnt.h"
#include "winsvc.h"
#include "irot_s.h"
#include "epm_s.h"
#include "irot.h"
#include "epm.h"
#include "irpcss.h"
#ifdef __REACTOS__
#include <objbase.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
static WCHAR rpcssW[] = {'R','p','c','S','s',0};
static WCHAR rpcssW[] = L"RpcSs";
static HANDLE exit_event;
static SERVICE_STATUS_HANDLE service_handle;
static BOOL RPCSS_Initialize(void)
struct registered_class
{
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;
struct list entry;
GUID clsid;
unsigned int cookie;
PMInterfacePointer object;
unsigned int single_use : 1;
};
WINE_TRACE("\n");
static CRITICAL_SECTION registered_classes_cs = { NULL, -1, 0, 0, 0, 0 };
static struct list registered_classes = LIST_INIT(registered_classes);
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;
}
HRESULT __cdecl irpcss_server_register(handle_t h, const GUID *clsid, unsigned int flags,
PMInterfacePointer object, unsigned int *cookie)
{
struct registered_class *entry;
static LONG next_cookie;
status = RpcServerUseProtseqEpW(epm_protseq, RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
epm_endpoint, NULL);
if (status != RPC_S_OK)
goto fail;
if (!(entry = calloc(1, sizeof(*entry))))
return E_OUTOFMEMORY;
status = RpcServerUseProtseqEpW(epm_protseq_lrpc, RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
epm_endpoint_lrpc, NULL);
if (status != RPC_S_OK)
goto fail;
entry->clsid = *clsid;
entry->single_use = !(flags & (REGCLS_MULTIPLEUSE | REGCLS_MULTI_SEPARATE));
if (!(entry->object = malloc(FIELD_OFFSET(MInterfacePointer, abData[object->ulCntData]))))
{
free(entry);
return E_OUTOFMEMORY;
}
entry->object->ulCntData = object->ulCntData;
memcpy(&entry->object->abData, object->abData, object->ulCntData);
*cookie = entry->cookie = InterlockedIncrement(&next_cookie);
status = RpcServerUseProtseqEpW(irot_protseq, RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
irot_endpoint, NULL);
if (status != RPC_S_OK)
goto fail;
EnterCriticalSection(&registered_classes_cs);
list_add_tail(&registered_classes, &entry->entry);
LeaveCriticalSection(&registered_classes_cs);
status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE);
if (status != RPC_S_OK)
goto fail;
return S_OK;
}
return TRUE;
static void scm_revoke_class(struct registered_class *_class)
{
list_remove(&_class->entry);
free(_class->object);
free(_class);
}
HRESULT __cdecl irpcss_server_revoke(handle_t h, unsigned int cookie)
{
struct registered_class *cur;
EnterCriticalSection(&registered_classes_cs);
LIST_FOR_EACH_ENTRY(cur, &registered_classes, struct registered_class, entry)
{
if (cur->cookie == cookie)
{
scm_revoke_class(cur);
break;
}
}
LeaveCriticalSection(&registered_classes_cs);
return S_OK;
}
HRESULT __cdecl irpcss_get_class_object(handle_t h, const GUID *clsid,
PMInterfacePointer *object)
{
struct registered_class *cur;
*object = NULL;
EnterCriticalSection(&registered_classes_cs);
LIST_FOR_EACH_ENTRY(cur, &registered_classes, struct registered_class, entry)
{
if (!memcmp(clsid, &cur->clsid, sizeof(*clsid)))
{
*object = MIDL_user_allocate(FIELD_OFFSET(MInterfacePointer, abData[cur->object->ulCntData]));
if (*object)
{
(*object)->ulCntData = cur->object->ulCntData;
memcpy((*object)->abData, cur->object->abData, cur->object->ulCntData);
}
if (cur->single_use)
scm_revoke_class(cur);
break;
}
}
LeaveCriticalSection(&registered_classes_cs);
return *object ? S_OK : E_NOINTERFACE;
}
HRESULT __cdecl irpcss_get_thread_seq_id(handle_t h, DWORD *id)
{
static LONG thread_seq_id;
*id = InterlockedIncrement(&thread_seq_id);
return S_OK;
}
static RPC_STATUS RPCSS_Initialize(void)
{
static unsigned short irot_protseq[] = IROT_PROTSEQ;
static unsigned short irot_endpoint[] = IROT_ENDPOINT;
static unsigned short epm_protseq[] = L"ncacn_np";
static unsigned short epm_endpoint[] = L"\\pipe\\epmapper";
static unsigned short epm_protseq_lrpc[] = L"ncalrpc";
static unsigned short epm_endpoint_lrpc[] = L"epmapper";
static unsigned short irpcss_protseq[] = IRPCSS_PROTSEQ;
static unsigned short irpcss_endpoint[] = IRPCSS_ENDPOINT;
static const struct protseq_map
{
unsigned short *protseq;
unsigned short *endpoint;
} protseqs[] =
{
{ epm_protseq, epm_endpoint },
{ epm_protseq_lrpc, epm_endpoint_lrpc },
{ irot_protseq, irot_endpoint },
{ irpcss_protseq, irpcss_endpoint },
};
RPC_IF_HANDLE ifspecs[] =
{
epm_v3_0_s_ifspec,
Irot_v0_2_s_ifspec,
Irpcss_v0_0_s_ifspec,
};
RPC_STATUS status;
int i, j;
WINE_TRACE("\n");
for (i = 0, j = 0; i < ARRAY_SIZE(ifspecs); ++i, j = i)
{
status = RpcServerRegisterIf(ifspecs[i], NULL, NULL);
if (status != RPC_S_OK)
goto fail;
}
for (i = 0; i < ARRAY_SIZE(protseqs); ++i)
{
status = RpcServerUseProtseqEpW(protseqs[i].protseq, RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
protseqs[i].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;
return RPC_S_OK;
fail:
RpcServerUnregisterIf(epm_v3_0_s_ifspec, NULL, FALSE);
RpcServerUnregisterIf(Irot_v0_2_s_ifspec, NULL, FALSE);
return FALSE;
for (i = 0; i < j; ++i)
RpcServerUnregisterIf(ifspecs[i], NULL, FALSE);
return status;
}
static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
@@ -115,7 +237,7 @@ static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_
SetEvent( exit_event );
return NO_ERROR;
default:
FIXME( "got service ctrl %x\n", ctrl );
FIXME( "got service ctrl %lx\n", ctrl );
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus( service_handle, &status );
return NO_ERROR;
@@ -129,10 +251,15 @@ extern VOID DoRpcSsSetupConfiguration(VOID);
static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
{
SERVICE_STATUS status;
RPC_STATUS ret;
TRACE( "starting service\n" );
if (!RPCSS_Initialize()) return;
if ((ret = RPCSS_Initialize()))
{
WARN("Failed to initialize rpc interfaces, status %ld.\n", ret);
return;
}
exit_event = CreateEventW( NULL, TRUE, FALSE, NULL );
@@ -144,7 +271,7 @@ static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
#ifdef __REACTOS__
status.dwControlsAccepted = 0;
#else
status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
#endif
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
@@ -168,7 +295,7 @@ static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
TRACE( "service stopped\n" );
}
int wmain( int argc, WCHAR *argv[] )
int __cdecl wmain( int argc, WCHAR *argv[] )
{
static const SERVICE_TABLE_ENTRYW service_table[] =
{