#ifndef DALIST_H #define DALIST_H #include "dalist_api.h" #ifdef __cplusplus extern "C" { #endif /* dalist node types */ enum dalist_node_types { DALIST_NODE, DALIST_NODE_EX, }; /* dalist caller-provided memory allocation methods */ enum dalist_memfn { DALIST_MEMFN_CUSTOM, DALIST_MEMFN_MMAP, DALIST_MEMFN_MALLOC, DALIST_MEMFN_NT_ALLOCATE_VIRTUAL_MEMORY, }; /* dalist debug environments */ enum dalist_dbgenv { DALIST_DEBUG_ENV_POSIX, DALIST_DEBUG_ENV_NT, }; /* dalist return values */ #define DALIST_OK (0x0) #define DALIST_EINTERNAL (0xD0000000) /* internal error */ #define DALIST_EMEMFN (0xD0000001) /* memory allocation error */ #define DALIST_EMEMBLOCK (0xD0000002) /* invalid memory block */ #define DALIST_ELIST (0xD0000003) /* invalid list */ #define DALIST_ENODE (0xD0000004) /* invalid node */ #define DALIST_EPARAMMIX (0xD0000005) /* invalid parameter mix */ #define DALIST_EKEYEXISTS (0xD0000006) /* key already exists */ #define DALIST_ELISTNOTEMPTY (0xD0000007) /* null insertion point with non-empty list */ /* dalist debug return values */ #define DALIST_EDEBUGSTRUCT (0xD0001000) /* invalid debug structure */ #define DALIST_EDEBUGENV (0xD0001001) /* invalid debug environment */ #define DALIST_EDEBUGSPRINTF (0xD0001002) /* invalid debug pointer to sprintf */ #define DALIST_EDEBUGWRITE (0xD0001003) /* invalid debug pointer to write (posix) */ #define DALIST_EDEBUGWRITEFILE (0xD0001004) /* invalid debug pointer to zw_write_file (nt) */ /* dalist node flag bits */ #define DALIST_NODE_TYPE_NONE (0x00u) #define DALIST_NODE_TYPE_EXISTING (0x01u) #define DALIST_NODE_TYPE_NEW (0x02u) #define DALIST_NODE_TYPE_DELETED (0x04u) #define DALIST_NODE_MEM_BLOCK_BASE (0x80u) struct dalist_node { struct dalist_node * prev; struct dalist_node * next; uintptr_t any; }; struct dalist { struct dalist_node * head; struct dalist_node * tail; }; struct dalist_node_ex { struct dalist_node_ex * prev; struct dalist_node_ex * next; uintptr_t key; uintptr_t flags; uintptr_t dblock; }; struct dalist_debug; struct dalist_ex { void * head; /************************************/ void * tail; /* head, tail, free: */ void * free; /* dalist_node when dblock_size is */ uintptr_t * bookmarks; /* zero, dalist_node_ex otherwise. */ size_t dblock_size; /* */ size_t lblock_size; /* lblock_size: */ void * memfn_ptr; /* used when memfn_method is mmap */ enum dalist_memfn memfn_method; /* or nt_allocate_virtual_memory */ int memfn_status; /* as the system call's alloc_size */ int mmap_prot; /* argument. */ int mmap_flags; /* */ int mmap_fildes; /* */ intptr_t mmap_offset; /************************************/ struct dalist_debug * debug; struct dalist_info { uintptr_t list_nodes; uintptr_t free_nodes; uintptr_t bookmark_from; uintptr_t bookmark_to; uintptr_t bookmark_key_min; uintptr_t bookmark_key_max; uintptr_t nodes_below_first_bookmark; uintptr_t nodes_above_last_bookmark; } info; }; /* signatures for caller-provided debug output functions */ typedef int __cdecl dalist_sprintf(char * buffer, const char * format, ...); typedef ssize_t __cdecl dalist_write(int fildes, const void *buf, size_t nbyte); typedef int32_t __stdcall dalist_write_file( void * hfile, void * hevent, void * apc_routine, void * apc_context, void * io_status_block, void * buffer, uint32_t bytes_sent, int64_t * byte_offset, uint32_t * key); /* debug */ struct dalist_debug { enum dalist_dbgenv dbgenv; dalist_sprintf * sprintf; /* required (all) */ dalist_write * write; /* required (posix only) */ dalist_write_file * zw_write_file; /* required (nt only) */ }; /* signatures for caller-provided memory allocation functions */ typedef void * __cdecl dalist_memfn_mmap( void * addr, size_t alloc_size, int prot, int flags, int fildes, intptr_t offset); typedef void * __cdecl dalist_memfn_malloc( size_t alloc_size); typedef int32_t __stdcall dalist_memfn_nt_allocvm( void * hprocess, void ** base_address, uint32_t zero_bits, size_t * alloc_size, uint32_t alloc_type, uint32_t protect); /** * dalist_memfn_custom: * must return either DALIST_OK or DALIST_EMEMFN; * may update the list's memfn_status member **/ typedef int __cdecl dalist_memfn_custom( struct dalist_ex * dlist, void ** addr, size_t * alloc_size); dalist_api int dalist_init(struct dalist * dlist); dalist_api int dalist_init_ex( struct dalist_ex * dlist, size_t dblock_size, size_t lblock_size, void * memfn_ptr, enum dalist_memfn memfn_method); dalist_api int dalist_insert_before( struct dalist * dlist, struct dalist_node * lnode, struct dalist_node * nnode); dalist_api int dalist_insert_after( struct dalist * dlist, struct dalist_node * lnode, struct dalist_node * nnode); dalist_api int dalist_get_free_node( struct dalist_ex * dlist, void ** fnode); dalist_api int dalist_deposit_free_node( struct dalist_ex * dlist, void * fnode); dalist_api int dalist_deposit_memory_block( struct dalist_ex * dlist, void * addr, size_t alloc_size); dalist_api int dalist_unlink_node( struct dalist * dlist, struct dalist_node * node); dalist_api int dalist_unlink_node_ex( struct dalist_ex * dlist, struct dalist_node_ex * node); dalist_api int dalist_discard_node( struct dalist_ex * dlist, struct dalist_node_ex * node); dalist_api int dalist_get_node_by_key( struct dalist_ex * dlist, struct dalist_node_ex **node, uintptr_t key, uintptr_t get_flags, uintptr_t * node_flags); dalist_api int dalist_insert_node_by_key( struct dalist_ex * dlist, struct dalist_node_ex * node); /* debug routines */ dalist_api int dalist_debug_setup( struct dalist_ex * dlist, struct dalist_debug * dlist_debug, enum dalist_dbgenv dbgenv, dalist_sprintf * pfn_sprintf, dalist_write * pfn_write, dalist_write_file * pfn_write_file); dalist_api int dalist_debug_print( struct dalist_ex * dlist, intptr_t fildes_or_hfile); #ifdef __cplusplus } #endif #endif