#ifndef _METERPRETER_CORE_H #define _METERPRETER_CORE_H #include "linkage.h" #include "remote.h" /* * Enumerations for TLVs and packets */ #define MAKE_TLV(name, meta, actual) TLV_TYPE_ ## name = actual | meta #define MAKE_CUSTOM_TLV(meta, base, actual) (TlvType)((base + actual) | meta) typedef enum { PACKET_TLV_TYPE_REQUEST = 0, PACKET_TLV_TYPE_RESPONSE = 1, PACKET_TLV_TYPE_PLAIN_REQUEST = 10, PACKET_TLV_TYPE_PLAIN_RESPONSE = 11, } PacketTlvType; // Meta argument types, used for validation #define TLV_META_TYPE_NONE (0 << 0) #define TLV_META_TYPE_STRING (1 << 16) #define TLV_META_TYPE_UINT (1 << 17) #define TLV_META_TYPE_RAW (1 << 18) #define TLV_META_TYPE_BOOL (1 << 19) #define TLV_META_TYPE_GROUP (1 << 30) #define TLV_META_TYPE_COMPLEX (1 << 31) #define TLV_META_TYPE_MASK(x) ((x) & 0xffff0000) #define TLV_RESERVED 0 #define TLV_EXTENSIONS 20000 #define TLV_USER 40000 #define TLV_TEMP 60000 #define LOAD_LIBRARY_FLAG_ON_DISK (1 << 0) #define LOAD_LIBRARY_FLAG_EXTENSION (1 << 1) #define LOAD_LIBRARY_FLAG_LOCAL (1 << 2) #define CHANNEL_FLAG_SYNCHRONOUS (1 << 0) typedef DWORD TlvMetaType; typedef enum { MAKE_TLV(ANY, TLV_META_TYPE_NONE, 0), MAKE_TLV(METHOD, TLV_META_TYPE_STRING, 1), MAKE_TLV(REQUEST_ID, TLV_META_TYPE_STRING, 2), MAKE_TLV(EXCEPTION, TLV_META_TYPE_GROUP, 3), MAKE_TLV(RESULT, TLV_META_TYPE_UINT, 4), // Argument basic types MAKE_TLV(STRING, TLV_META_TYPE_STRING, 10), MAKE_TLV(UINT, TLV_META_TYPE_UINT, 11), MAKE_TLV(BOOL, TLV_META_TYPE_BOOL, 12), // Extended types MAKE_TLV(LENGTH, TLV_META_TYPE_UINT, 25), MAKE_TLV(DATA, TLV_META_TYPE_RAW, 26), MAKE_TLV(FLAGS, TLV_META_TYPE_UINT, 27), // Channel types MAKE_TLV(CHANNEL_ID, TLV_META_TYPE_UINT, 50), MAKE_TLV(CHANNEL_TYPE, TLV_META_TYPE_STRING, 51), MAKE_TLV(CHANNEL_DATA, TLV_META_TYPE_RAW, 52), MAKE_TLV(CHANNEL_DATA_GROUP, TLV_META_TYPE_GROUP, 53), MAKE_TLV(CHANNEL_CLASS, TLV_META_TYPE_UINT, 54), // Channel extended types MAKE_TLV(SEEK_WHENCE, TLV_META_TYPE_UINT, 70), MAKE_TLV(SEEK_OFFSET, TLV_META_TYPE_UINT, 71), MAKE_TLV(SEEK_POS, TLV_META_TYPE_UINT, 72), // Grouped identifiers MAKE_TLV(EXCEPTION_CODE, TLV_META_TYPE_UINT, 300), MAKE_TLV(EXCEPTION_STRING, TLV_META_TYPE_STRING, 301), // Library loading MAKE_TLV(LIBRARY_PATH, TLV_META_TYPE_STRING, 400), MAKE_TLV(TARGET_PATH, TLV_META_TYPE_STRING, 401), MAKE_TLV(MIGRATE_PID, TLV_META_TYPE_UINT, 402), MAKE_TLV(MIGRATE_LEN, TLV_META_TYPE_UINT, 403), MAKE_TLV(MIGRATE_PAYLOAD, TLV_META_TYPE_STRING, 404), // Cryptography MAKE_TLV(CIPHER_NAME, TLV_META_TYPE_STRING, 500), MAKE_TLV(CIPHER_PARAMETERS, TLV_META_TYPE_GROUP, 501), MAKE_TLV(EXTENSIONS, TLV_META_TYPE_COMPLEX, 20000), MAKE_TLV(USER, TLV_META_TYPE_COMPLEX, 40000), MAKE_TLV(TEMP, TLV_META_TYPE_COMPLEX, 60000), } TlvType; typedef struct { DWORD length; DWORD type; } TlvHeader; typedef struct { TlvHeader header; PUCHAR buffer; } Tlv; typedef struct _Packet { TlvHeader header; PUCHAR payload; ULONG payloadLength; } Packet; /* * Packet request completion notification handler */ typedef DWORD (*PacketRequestCompletionRoutine)(Remote *remote, Packet *response, LPVOID context, LPCSTR method, DWORD result); typedef struct { LPVOID context; PacketRequestCompletionRoutine routine; DWORD timeout; } PacketRequestCompletion; /* * Packet manipulation */ LINKAGE Packet *packet_create(PacketTlvType type, LPCSTR method); LINKAGE Packet *packet_create_response(Packet *packet); LINKAGE Packet *packet_duplicate(Packet *packet); LINKAGE VOID packet_destroy(Packet *packet); LINKAGE DWORD packet_add_tlv_string(Packet *packet, TlvType type, LPCSTR str); LINKAGE DWORD packet_add_tlv_uint(Packet *packet, TlvType type, UINT val); LINKAGE DWORD packet_add_tlv_bool(Packet *packet, TlvType type, BOOL val); LINKAGE DWORD packet_add_tlv_group(Packet *packet, TlvType type, Tlv *entries, DWORD numEntries); LINKAGE DWORD packet_add_tlvs(Packet *packet, Tlv *entries, DWORD numEntries); LINKAGE DWORD packet_add_tlv_raw(Packet *packet, TlvType type, LPVOID buf, DWORD length); LINKAGE DWORD packet_is_tlv_null_terminated(Packet *packet, Tlv *tlv); LINKAGE PacketTlvType packet_get_type(Packet *packet); LINKAGE TlvMetaType packet_get_tlv_meta(Packet *packet, Tlv *tlv); LINKAGE DWORD packet_get_tlv(Packet *packet, TlvType type, Tlv *tlv); LINKAGE DWORD packet_get_tlv_string(Packet *packet, TlvType type, Tlv *tlv); LINKAGE DWORD packet_get_tlv_group_entry(Packet *packet, Tlv *group, TlvType type, Tlv *entry); LINKAGE DWORD packet_enum_tlv(Packet *packet, DWORD index, TlvType type, Tlv *tlv); LINKAGE PCHAR packet_get_tlv_value_string(Packet *packet, TlvType type); LINKAGE UINT packet_get_tlv_value_uint(Packet *packet, TlvType type); LINKAGE BOOL packet_get_tlv_value_bool(Packet *packet, TlvType type); LINKAGE DWORD packet_add_exception(Packet *packet, DWORD code, PCHAR string, ...); LINKAGE DWORD packet_get_result(Packet *packet); /* * Packet transmission */ LINKAGE DWORD packet_transmit(Remote *remote, Packet *packet, PacketRequestCompletion *completion); LINKAGE DWORD packet_transmit_empty_response(Remote *remote, Packet *packet, DWORD res); LINKAGE DWORD packet_receive(Remote *remote, Packet **packet); #define packet_transmit_response(result, remote, response) \ if (response) { \ packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); \ packet_transmit(remote, response, NULL); \ } /* * Packet completion notification */ LINKAGE DWORD packet_add_completion_handler(LPCSTR requestId, PacketRequestCompletion *completion); LINKAGE DWORD packet_call_completion_handlers(Remote *remote, Packet *response, LPCSTR requestId); LINKAGE DWORD packet_remove_completion_handler(LPCSTR requestId); /* * Core API */ LINKAGE DWORD send_core_console_write(Remote *remote, LPCSTR fmt, ...); LINKAGE HANDLE core_update_thread_token(Remote *remote, HANDLE token); #endif