#ifndef _METERPRETER_LIB_CHANNEL_H #define _METERPRETER_LIB_CHANNEL_H #include "linkage.h" #include "remote.h" struct _Channel; struct _ChannelBuffer; // Direct I/O operation modes (read/write/close) typedef enum { CHANNEL_DIO_MODE_OPEN = 0, CHANNEL_DIO_MODE_READ = 1, CHANNEL_DIO_MODE_WRITE = 2, CHANNEL_DIO_MODE_CLOSE = 3, CHANNEL_DIO_MODE_INTERACT = 3, } ChannelDioMode; // Direct I/O handler -- used in place of internal buffering for channels // that can do event based forwarding of buffers. typedef DWORD (*DirectIoHandler)(struct _Channel *channel, struct _ChannelBuffer *buffer, LPVOID context, ChannelDioMode mode, PUCHAR chunk, ULONG length, PULONG bytesXfered); // Asynchronous completion routines -- used with channel_open, channel_read, // etc. typedef DWORD (*ChannelOpenCompletionRoutine)(Remote *remote, struct _Channel *channel, LPVOID context, DWORD result); typedef DWORD (*ChannelReadCompletionRoutine)(Remote *remote, struct _Channel *channel, LPVOID context, DWORD result, PUCHAR buffer, ULONG bytesRead); typedef DWORD (*ChannelWriteCompletionRoutine)(Remote *remote, struct _Channel *channel, LPVOID context, DWORD result, ULONG bytesWritten); typedef DWORD (*ChannelCloseCompletionRoutine)(Remote *remote, struct _Channel *channel, LPVOID context, DWORD result); typedef DWORD (*ChannelInteractCompletionRoutine)(Remote *remote, struct _Channel *channel, LPVOID context, DWORD result); // Completion routine wrapper context typedef struct _ChannelCompletionRoutine { LPVOID context; struct { ChannelOpenCompletionRoutine open; ChannelReadCompletionRoutine read; ChannelWriteCompletionRoutine write; ChannelCloseCompletionRoutine close; ChannelInteractCompletionRoutine interact; } routine; } ChannelCompletionRoutine; // Logical channel buffer used to queue or for event based updating typedef struct _ChannelBuffer { PUCHAR buffer; ULONG currentSize; ULONG totalSize; // IO handler -- default is internal queuing DirectIoHandler dio; LPVOID dioContext; } ChannelBuffer; // Channel operations that are used by any channel typedef struct _NativeChannelOps { LPVOID context; DWORD (*write)(struct _Channel *channel, Packet *request, LPVOID context, LPVOID buffer, DWORD bufferSize, LPDWORD bytesWritten); DWORD (*close)(struct _Channel *channel, Packet *request, LPVOID context); DWORD (*interact)(struct _Channel *channel, Packet *request, LPVOID context, BOOLEAN interact); } NativeChannelOps; // Channel operations for a stream-based channel typedef struct _StreamChannelOps { NativeChannelOps native; } StreamChannelOps; // Channel operations for a datagram-based channel typedef struct _DatagramChannelOps { NativeChannelOps native; } DatagramChannelOps; // Channel operations for a pool-based channel typedef struct _PoolChannelOps { NativeChannelOps native; DWORD (*read)(struct _Channel *channel, Packet *request, LPVOID context, LPVOID buffer, DWORD bufferSize, LPDWORD bytesRead); DWORD (*eof)(struct _Channel *channel, Packet *request, LPVOID context, LPBOOL isEof); DWORD (*seek)(struct _Channel *channel, Packet *request, LPVOID context, LONG offset, DWORD whence); DWORD (*tell)(struct _Channel *channel, Packet *request, LPVOID context, LPLONG offset); } PoolChannelOps; /* * Values for the 'cls' attribute */ #define CHANNEL_CLASS_BUFFERED 0 #define CHANNEL_CLASS_STREAM 1 #define CHANNEL_CLASS_DATAGRAM 2 #define CHANNEL_CLASS_POOL 3 typedef struct _Channel { // The channel's identifier DWORD identifier; // The channel's class DWORD cls; // The type of channel, NULL for default. PCHAR type; // Flag for whether or not the channel is currently interactive BOOL interactive; // Operational flags ULONG flags; // Lock for synchronizing communication to a channel LOCK * lock; // The buffered output buffer (as in being outputted bufferedly) union { ChannelBuffer buffered; StreamChannelOps stream; DatagramChannelOps datagram; PoolChannelOps pool; } ops; // Internal attributes for list struct _Channel *prev; struct _Channel *next; } Channel; #define CHANNEL_CHUNK_SIZE 4096 /* * Channel manipulation */ LINKAGE Channel *channel_create(DWORD identifier, DWORD flags); LINKAGE Channel *channel_create_stream(DWORD identifier, DWORD flags, StreamChannelOps *ops); LINKAGE Channel *channel_create_datagram(DWORD identifier, DWORD flags, DatagramChannelOps *ops); LINKAGE Channel *channel_create_pool(DWORD identifier, DWORD flags, PoolChannelOps *ops); LINKAGE VOID channel_destroy(Channel *channel, Packet *request); LINKAGE DWORD channel_get_id(Channel *channel); LINKAGE VOID channel_set_type(Channel *channel, PCHAR type); LINKAGE PCHAR channel_get_type(Channel *channel); LINKAGE DWORD channel_get_class(Channel *channel); LINKAGE VOID channel_set_flags(Channel *channel, ULONG flags); LINKAGE BOOLEAN channel_is_flag(Channel *channel, ULONG flag); LINKAGE ULONG channel_get_flags(Channel *channel); LINKAGE VOID channel_set_interactive(Channel *channel, BOOL interactive); LINKAGE BOOL channel_is_interactive(Channel *channel); LINKAGE DWORD channel_write_to_remote(Remote *remote, Channel *channel, PUCHAR chunk, ULONG chunkLength, PULONG bytesWritten); LINKAGE DWORD channel_write_to_buffered(Channel *channel, PUCHAR chunk, ULONG chunkLength, PULONG bytesWritten); LINKAGE DWORD channel_read_from_buffered(Channel *channel, PUCHAR chunk, ULONG chunkLength, PULONG bytesRead); LINKAGE VOID channel_set_buffered_io_handler(Channel *channel, LPVOID dioContext, DirectIoHandler dio); LINKAGE PVOID channel_get_buffered_io_context(Channel *channel); LINKAGE VOID channel_set_native_io_context(Channel *channel, LPVOID context); LINKAGE LPVOID channel_get_native_io_context(Channel *channel); LINKAGE DWORD channel_default_io_handler(Channel *channel, ChannelBuffer *buffer, LPVOID context, ChannelDioMode mode, PUCHAR chunk, ULONG length, PULONG bytesXfered); /* * Remote channel API, used for communication with remotes * * Each of these routines accepts a completion routine that allows for custom * handling of the response. */ LINKAGE DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength, ChannelCompletionRoutine *completionRoutine); LINKAGE DWORD channel_read(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, ULONG length, ChannelCompletionRoutine *completionRoutine); LINKAGE DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, PUCHAR buffer, ULONG length, ChannelCompletionRoutine *completionRoutine); LINKAGE DWORD channel_close(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, ChannelCompletionRoutine *completionRoutine); LINKAGE DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, BOOL enable, ChannelCompletionRoutine *completionRoutine); /* * Channel searching */ LINKAGE Channel *channel_find_by_id(DWORD id); LINKAGE BOOL channel_exists(Channel *channel); #endif