128 строки
4.0 KiB
C
128 строки
4.0 KiB
C
// Copyright (c) eBPF for Windows contributors
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#define EBPF_FILE_ID EBPF_FILE_ID_HANDLE
|
|
#include "ebpf_handle.h"
|
|
#include "ebpf_tracelog.h"
|
|
|
|
typedef ebpf_base_object_t* ebpf_handle_entry_t;
|
|
|
|
// Simplified handle table implementation.
|
|
// TODO: Replace this with the real Windows object manager handle table code.
|
|
|
|
static ebpf_lock_t _ebpf_handle_table_lock = {0};
|
|
static _Guarded_by_(_ebpf_handle_table_lock) ebpf_handle_entry_t _ebpf_handle_table[1024];
|
|
|
|
static bool _ebpf_handle_table_initiated = false;
|
|
|
|
_Must_inspect_result_ ebpf_result_t
|
|
ebpf_handle_table_initiate()
|
|
{
|
|
EBPF_LOG_ENTRY();
|
|
ebpf_lock_create(&_ebpf_handle_table_lock);
|
|
memset(_ebpf_handle_table, 0, sizeof(_ebpf_handle_table));
|
|
_ebpf_handle_table_initiated = true;
|
|
EBPF_RETURN_RESULT(EBPF_SUCCESS);
|
|
}
|
|
|
|
void
|
|
ebpf_handle_table_terminate()
|
|
{
|
|
EBPF_LOG_ENTRY();
|
|
ebpf_handle_t handle;
|
|
if (!_ebpf_handle_table_initiated) {
|
|
EBPF_RETURN_VOID();
|
|
}
|
|
|
|
ebpf_lock_state_t state;
|
|
state = ebpf_lock_lock(&_ebpf_handle_table_lock);
|
|
for (handle = 0; handle < EBPF_COUNT_OF(_ebpf_handle_table); handle++) {
|
|
if (_ebpf_handle_table[handle] != NULL) {
|
|
EBPF_OBJECT_RELEASE_REFERENCE_INDIRECT(_ebpf_handle_table[handle]);
|
|
_ebpf_handle_table[handle] = NULL;
|
|
}
|
|
}
|
|
ebpf_lock_unlock(&_ebpf_handle_table_lock, state);
|
|
_ebpf_handle_table_initiated = false;
|
|
EBPF_RETURN_VOID();
|
|
}
|
|
|
|
_Must_inspect_result_ ebpf_result_t
|
|
ebpf_handle_create(_Out_ ebpf_handle_t* handle, _Inout_ ebpf_base_object_t* object)
|
|
{
|
|
EBPF_LOG_ENTRY();
|
|
ebpf_handle_t new_handle;
|
|
ebpf_result_t return_value;
|
|
ebpf_lock_state_t state;
|
|
state = ebpf_lock_lock(&_ebpf_handle_table_lock);
|
|
for (new_handle = 1; new_handle < EBPF_COUNT_OF(_ebpf_handle_table); new_handle++) {
|
|
if (_ebpf_handle_table[new_handle] == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
if (new_handle == EBPF_COUNT_OF(_ebpf_handle_table)) {
|
|
return_value = EBPF_NO_MEMORY;
|
|
goto Done;
|
|
}
|
|
|
|
*handle = new_handle;
|
|
_ebpf_handle_table[new_handle] = object;
|
|
EBPF_OBJECT_ACQUIRE_REFERENCE_INDIRECT(object);
|
|
|
|
return_value = EBPF_SUCCESS;
|
|
|
|
Done:
|
|
ebpf_lock_unlock(&_ebpf_handle_table_lock, state);
|
|
|
|
EBPF_RETURN_RESULT(return_value);
|
|
}
|
|
|
|
_Must_inspect_result_ ebpf_result_t
|
|
ebpf_handle_close(ebpf_handle_t handle)
|
|
{
|
|
// High volume call - Skip entry/exit logging.
|
|
ebpf_lock_state_t state;
|
|
ebpf_result_t return_value;
|
|
|
|
state = ebpf_lock_lock(&_ebpf_handle_table_lock);
|
|
if (((size_t)handle < EBPF_COUNT_OF(_ebpf_handle_table)) && _ebpf_handle_table[handle] != NULL) {
|
|
EBPF_OBJECT_RELEASE_REFERENCE_INDIRECT(_ebpf_handle_table[handle]);
|
|
_ebpf_handle_table[handle] = NULL;
|
|
return_value = EBPF_SUCCESS;
|
|
} else {
|
|
return_value = EBPF_INVALID_OBJECT;
|
|
}
|
|
ebpf_lock_unlock(&_ebpf_handle_table_lock, state);
|
|
return return_value;
|
|
}
|
|
|
|
_IRQL_requires_max_(PASSIVE_LEVEL) ebpf_result_t ebpf_reference_base_object_by_handle(
|
|
ebpf_handle_t handle,
|
|
_In_opt_ ebpf_compare_object_t compare_function,
|
|
_In_opt_ const void* context,
|
|
_Outptr_ struct _ebpf_base_object** object,
|
|
uint32_t file_id,
|
|
uint32_t line)
|
|
{
|
|
ebpf_result_t return_value;
|
|
ebpf_lock_state_t state;
|
|
|
|
if (handle >= EBPF_COUNT_OF(_ebpf_handle_table)) {
|
|
EBPF_LOG_MESSAGE_UINT64(EBPF_TRACELOG_LEVEL_CRITICAL, EBPF_TRACELOG_KEYWORD_BASE, "Invalid handle", handle);
|
|
return EBPF_INVALID_OBJECT;
|
|
}
|
|
|
|
state = ebpf_lock_lock(&_ebpf_handle_table_lock);
|
|
if (_ebpf_handle_table[handle] != NULL &&
|
|
(compare_function == NULL || compare_function(_ebpf_handle_table[handle], context))) {
|
|
_ebpf_handle_table[handle]->acquire_reference(_ebpf_handle_table[handle], file_id, line);
|
|
*object = _ebpf_handle_table[handle];
|
|
return_value = EBPF_SUCCESS;
|
|
} else {
|
|
return_value = EBPF_INVALID_OBJECT;
|
|
}
|
|
|
|
ebpf_lock_unlock(&_ebpf_handle_table_lock, state);
|
|
return return_value;
|
|
}
|