#include "datadll.h" #include static inline void _far *operator new(unsigned size, void _far *p) { return p; } static const struct RTLData initData = { //put whatever you want here 1, 3 }; class _far RTLDataInstance { long magic; public: RTLData rtlData; RTLDataInstance(); int check() const; }; #define MAGIC 0x1234BEEFL RTLDataInstance::RTLDataInstance() { rtlData = initData; magic = MAGIC; } inline int RTLDataInstance::check() const { return magic==MAGIC; } // task data database -------------------------------------------------------- class TaskDataDatabase { struct TaskData { HTASK theTask; HGLOBAL hglbRTLDataInstance; RTLDataInstance far *lpRTLDataInstance; int IsValid() const; }; static HLOCAL hlocalTaskDataTable; static TaskData near *npTaskDataTable; static int entriesAllocated; static int entriesUsed; static int expandTable(); public: static int init(); static RTLData far *FindRTLData(HTASK whatTask); static RTLData far *CreateRTLData(HTASK whatTask); static void RemoveAllBadData(); }; HLOCAL TaskDataDatabase::hlocalTaskDataTable=NULL; TaskDataDatabase::TaskData near *TaskDataDatabase::npTaskDataTable=0; int TaskDataDatabase::entriesAllocated=0; int TaskDataDatabase::entriesUsed=0; int TaskDataDatabase::init() { //allocate the maximum size table (from the local heap) unsigned tryAlloc=65526U/sizeof(TaskData); while((hlocalTaskDataTable=LocalAlloc(LMEM_FIXED,sizeof(TaskData)*tryAlloc))==NULL) { //reduce the number of entries tryAlloc= (tryAlloc*2)/3; if(tryAlloc==0) return 0; //fail to initialize } npTaskDataTable=(TaskData near *)hlocalTaskDataTable; entriesAllocated=tryAlloc; return 1; } int TaskDataDatabase::TaskData::IsValid() const { if(IsTask(theTask) && //does task still exist? //!IsBadReadPtr(lpRTLDataInstance,sizeof(RTLDataInstance)) && //is memory readable? !IsBadWritePtr(lpRTLDataInstance,sizeof(RTLDataInstance)) && //is memory writeable lpRTLDataInstance->check()) //magic cookie still there? return 1; else return 0; } RTLData far *TaskDataDatabase::FindRTLData(HTASK whatTask) { for(int i=0; irtlData; } return 0; } RTLData far *TaskDataDatabase::CreateRTLData(HTASK whatTask) { //try to delete invalid entries RemoveAllBadData(); if(entriesUsed==entriesAllocated) { //no room in table return 0; } HGLOBAL hglobRTLDataInstance; RTLDataInstance far* lpRTLDataInstance; hglobRTLDataInstance = GlobalAlloc(GMEM_MOVEABLE, sizeof(RTLDataInstance)); if(hglobRTLDataInstance==NULL) { return 0; } lpRTLDataInstance = (RTLDataInstance far*)GlobalLock(hglobRTLDataInstance); if(lpRTLDataInstance==NULL) { GlobalFree(hglobRTLDataInstance); return 0; } //from here, nothing can fail //set up the task data entry TaskData near *pTaskData = npTaskDataTable+entriesUsed; entriesUsed++; pTaskData->theTask = whatTask; pTaskData->hglbRTLDataInstance = hglobRTLDataInstance; pTaskData->lpRTLDataInstance = lpRTLDataInstance; //set up the RTLDataInstance new(lpRTLDataInstance) RTLDataInstance(); return &lpRTLDataInstance->rtlData; } void TaskDataDatabase::RemoveAllBadData(void) { for(int i=0; i