#include #include "Common.h" #include "IPC.h" // Ritorna l'indirizzo di memoria della configurazione di un dato wrapper // Torna NULL se fallisce BYTE * __stdcall IPCClientRead(DWORD wrapper_tag, IPCClientRead_data_struct *pData) { if (!pData->mem_addr) return NULL; return (pData->mem_addr + wrapper_tag); } void IPCClientRead_setup(IPCClientRead_data_struct *data) { HANDLE h_file = OpenFileMapping(FILE_MAP_READ, FALSE, SHARE_MEMORY_READ_NAME); data->mem_addr = 0; // Se non riesce ad aprire l'oggetto setta mem_addr a NULL e la funzione ritornera' sempre NULL // Chi la richiama dovra' controllare che il valore di ritorno sia diverso da NULL prima di leggere // dalla memoria if (h_file) data->mem_addr = (BYTE *)MapViewOfFile(h_file, FILE_MAP_READ, 0, 0, SHARE_MEMORY_READ_SIZE); } // Torna TRUE se ha scritto, FALSE se fallisce BOOL __stdcall IPCClientWrite(DWORD wrapper_tag, IPCClientWrite_data_struct *pData, BYTE *message, DWORD msg_len, DWORD flags, DWORD priority) { unsigned int i, j; message_struct *pMessage; FILETIME time_stamp; // Fallisce se la memoria non e' presente o se il messaggio e' troppo grosso // per essere scritto if (!pData->mem_addr || msg_len > MAX_MSG_LEN || !message) return FALSE; // La prima volta cerca una posizione libera. // Se non la trova, cerca una posizione occupata da una // priorita' minore for (j=0; j<2; j++) { for (i=0, pMessage=pData->mem_addr; istatus == STATUS_FREE || (j && pMessage->status == STATUS_WRIT && pMessage->priority < priority)) { // XXX Possibilita' di remota race condition sulla lettura dello status pMessage->status = STATUS_BUSY; pMessage->message_len = msg_len; pMessage->priority = priority; pMessage->wrapper_tag = wrapper_tag; pMessage->flags = flags; // Setta il time stamp if (pData->pGetSystemTimeAsFileTime) { pData->pGetSystemTimeAsFileTime(&time_stamp); // Gestisce il caso di due log dello stesso tipo con timestamp uguali if (time_stamp.dwLowDateTime != pData->old_low_part || time_stamp.dwHighDateTime != pData->old_hi_part) { pData->old_low_part = time_stamp.dwLowDateTime; pData->old_hi_part = time_stamp.dwHighDateTime; pData->increment = 0; pMessage->time_stamp.dwHighDateTime = time_stamp.dwHighDateTime; pMessage->time_stamp.dwLowDateTime = time_stamp.dwLowDateTime; } else { pData->increment++; pMessage->time_stamp.dwHighDateTime = time_stamp.dwHighDateTime; pMessage->time_stamp.dwLowDateTime = time_stamp.dwLowDateTime + pData->increment; // se c'e' riporto if (pMessage->time_stamp.dwLowDateTime < time_stamp.dwLowDateTime) pMessage->time_stamp.dwHighDateTime++; } } else { pMessage->time_stamp.dwHighDateTime = 0; pMessage->time_stamp.dwLowDateTime = 0; } __try { MMCPY(pMessage->message, message, msg_len); } __except(EXCEPTION_EXECUTE_HANDLER) { pMessage->status = STATUS_FREE; } if (pMessage->status == STATUS_BUSY) pMessage->status = STATUS_WRIT; return TRUE; } } } // Se arriva qui, la coda e' DAVVERO piena e il messaggio viene droppato return FALSE; } void IPCClientWrite_setup(IPCClientWrite_data_struct *data) { HMODULE h_krn; HANDLE h_file; h_krn = GetModuleHandle("kernel32.dll"); data->pGetSystemTimeAsFileTime = (GetSystemTimeAsFileTime_t)GetProcAddress(h_krn, "GetSystemTimeAsFileTime"); h_file = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHARE_MEMORY_WRITE_NAME); data->mem_addr = NULL; data->old_low_part = 0; data->old_hi_part = 0; data->increment = 0; // Se non riesce ad aprire l'oggetto setta mem_addr a NULL e la funzione ritornera' sempre NULL // Chi la richiama dovra' controllare che il valore di ritorno sia diverso da NULL prima di leggere // dalla memoria if (h_file) data->mem_addr = (message_struct *)MapViewOfFile(h_file, FILE_MAP_ALL_ACCESS, 0, 0, SHARE_MEMORY_WRITE_SIZE); } .