117 строки
3.0 KiB
C++
117 строки
3.0 KiB
C++
// Copyright (c) Microsoft Corporation
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// Windows.h needs to be included before other headers.
|
|
// It has a #define for WINAPI_FAMILY_PARTITION among others that control
|
|
// the behavior of other Windows headers.
|
|
#include <winsock2.h>
|
|
#include <windows.h>
|
|
|
|
#include <malloc.h>
|
|
#include <sddl.h>
|
|
#include "rpc_interface_s.c"
|
|
#include "svc_common.h"
|
|
|
|
#pragma comment(lib, "Rpcrt4.lib")
|
|
|
|
#define ANNOTATION L"ebpfsvc rpc server"
|
|
#define EBPF_SERVICE_INTERFACE_HANDLE ebpf_server_ebpf_service_interface_v1_0_s_ifspec
|
|
#define MAX_RPC_CALL_SIZE 1024 * 1024
|
|
|
|
static const WCHAR* _protocol_sequence = L"ncalrpc";
|
|
static bool _rpc_server_initialized = false;
|
|
|
|
DWORD
|
|
initialize_rpc_server()
|
|
{
|
|
RPC_STATUS status;
|
|
bool registered = false;
|
|
RPC_BINDING_VECTOR* binding_vector = nullptr;
|
|
void* security_descriptor = nullptr;
|
|
|
|
// Only permit access from SDDL_BUILTIN_ADMINISTRATORS.
|
|
if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(
|
|
"D:(A;;FA;;;BA)", SDDL_REVISION_1, &security_descriptor, nullptr)) {
|
|
status = GetLastError();
|
|
goto Exit;
|
|
}
|
|
|
|
status = RpcServerUseProtseq((RPC_WSTR)_protocol_sequence, RPC_C_PROTSEQ_MAX_REQS_DEFAULT, nullptr);
|
|
if (status != RPC_S_OK) {
|
|
goto Exit;
|
|
}
|
|
|
|
status = RpcServerRegisterIf3(
|
|
EBPF_SERVICE_INTERFACE_HANDLE,
|
|
nullptr,
|
|
nullptr,
|
|
RPC_IF_AUTOLISTEN,
|
|
RPC_C_LISTEN_MAX_CALLS_DEFAULT,
|
|
MAX_RPC_CALL_SIZE,
|
|
nullptr,
|
|
security_descriptor);
|
|
LocalFree(security_descriptor);
|
|
if (status != RPC_S_OK) {
|
|
goto Exit;
|
|
}
|
|
registered = true;
|
|
|
|
status = RpcServerInqBindings(&binding_vector);
|
|
if (status != RPC_S_OK) {
|
|
goto Exit;
|
|
}
|
|
|
|
status = RpcEpRegister(EBPF_SERVICE_INTERFACE_HANDLE, binding_vector, NULL, (RPC_WSTR)ANNOTATION);
|
|
|
|
if (status == RPC_S_OK) {
|
|
_rpc_server_initialized = true;
|
|
}
|
|
|
|
Exit:
|
|
if (binding_vector != nullptr) {
|
|
RpcBindingVectorFree(&binding_vector);
|
|
}
|
|
if (status != RPC_S_OK) {
|
|
if (registered) {
|
|
RPC_STATUS unregister_status = RpcServerUnregisterIf(nullptr, nullptr, true);
|
|
if (unregister_status != RPC_S_OK) {
|
|
// TODO: Add a trace that something happened.
|
|
}
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
void
|
|
shutdown_rpc_server()
|
|
{
|
|
RPC_STATUS status;
|
|
RPC_BINDING_VECTOR* binding_vector = nullptr;
|
|
|
|
if (!_rpc_server_initialized) {
|
|
return;
|
|
}
|
|
|
|
status = RpcServerInqBindings(&binding_vector);
|
|
if (status != RPC_S_OK) {
|
|
goto Exit;
|
|
}
|
|
|
|
status = RpcEpUnregister(EBPF_SERVICE_INTERFACE_HANDLE, binding_vector, nullptr);
|
|
if (status != RPC_S_OK) {
|
|
goto Exit;
|
|
}
|
|
|
|
status = RpcServerUnregisterIf(EBPF_SERVICE_INTERFACE_HANDLE, nullptr, true);
|
|
if (status != RPC_S_OK) {
|
|
// TODO: Add a trace that something happened.
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
if (binding_vector != nullptr) {
|
|
RpcBindingVectorFree(&binding_vector);
|
|
}
|
|
return;
|
|
}
|