#include "stdafx.h" #include "MraSendQueue.h" struct MRA_SEND_QUEUE : public LIST_MT { DWORD dwSendTimeOutInterval; }; struct MRA_SEND_QUEUE_ITEM : public LIST_MT_ITEM { // internal FILETIME ftSendTime; // external DWORD dwCMDNum; DWORD dwFlags; MCONTACT hContact; DWORD dwAckType; LPBYTE lpbData; size_t dwDataSize; }; #define FILETIME_SECOND ((DWORDLONG)10000000) DWORD MraSendQueueInitialize(DWORD dwSendTimeOutInterval, HANDLE *phSendQueueHandle) { if (!phSendQueueHandle) return ERROR_INVALID_HANDLE; MRA_SEND_QUEUE *pmrasqSendQueue = new MRA_SEND_QUEUE(); pmrasqSendQueue->dwSendTimeOutInterval = dwSendTimeOutInterval; *phSendQueueHandle = (HANDLE)pmrasqSendQueue; return NO_ERROR; } void MraSendQueueDestroy(HANDLE hSendQueueHandle) { if (!hSendQueueHandle) return; MRA_SEND_QUEUE *pmrasqSendQueue = (MRA_SEND_QUEUE*)hSendQueueHandle; MRA_SEND_QUEUE_ITEM *pmrasqiSendQueueItem; { mir_cslock l(pmrasqSendQueue->cs); while ( !ListMTItemGetFirst(pmrasqSendQueue, nullptr, (LPVOID*)&pmrasqiSendQueueItem)) { ListMTItemDelete(pmrasqSendQueue, pmrasqiSendQueueItem); mir_free(pmrasqiSendQueueItem); } } delete pmrasqSendQueue; } DWORD MraSendQueueAdd(HANDLE hSendQueueHandle, DWORD dwCMDNum, DWORD dwFlags, MCONTACT hContact, DWORD dwAckType, LPBYTE lpbData, size_t dwDataSize) { if (!hSendQueueHandle || !dwCMDNum) return ERROR_INVALID_HANDLE; MRA_SEND_QUEUE *pmrasqSendQueue = (MRA_SEND_QUEUE*)hSendQueueHandle; MRA_SEND_QUEUE_ITEM *pmrasqiSendQueueItem; pmrasqiSendQueueItem = (MRA_SEND_QUEUE_ITEM*)mir_calloc(sizeof(MRA_SEND_QUEUE_ITEM)); if (!pmrasqiSendQueueItem) return GetLastError(); GetSystemTimeAsFileTime(&pmrasqiSendQueueItem->ftSendTime); pmrasqiSendQueueItem->dwCMDNum = dwCMDNum; pmrasqiSendQueueItem->dwFlags = dwFlags; pmrasqiSendQueueItem->hContact = hContact; pmrasqiSendQueueItem->dwAckType = dwAckType; pmrasqiSendQueueItem->lpbData = lpbData; pmrasqiSendQueueItem->dwDataSize = dwDataSize; mir_cslock l(pmrasqSendQueue->cs); ListMTItemAdd(pmrasqSendQueue, pmrasqiSendQueueItem, pmrasqiSendQueueItem); return 0; } DWORD MraSendQueueFree(HANDLE hSendQueueHandle, DWORD dwCMDNum) { if (!hSendQueueHandle) return ERROR_INVALID_HANDLE; MRA_SEND_QUEUE *pmrasqSendQueue = (MRA_SEND_QUEUE*)hSendQueueHandle; MRA_SEND_QUEUE_ITEM *pmrasqiSendQueueItem; LIST_MT_ITERATOR lmtiIterator; mir_cslock l(pmrasqSendQueue->cs); ListMTIteratorMoveFirst(pmrasqSendQueue, &lmtiIterator); do { if ( !ListMTIteratorGet(&lmtiIterator, nullptr, (LPVOID*)&pmrasqiSendQueueItem)) if (pmrasqiSendQueueItem->dwCMDNum == dwCMDNum) { ListMTItemDelete(pmrasqSendQueue, pmrasqiSendQueueItem); mir_free(pmrasqiSendQueueItem); return 0; } } while (ListMTIteratorMoveNext(&lmtiIterator)); return ERROR_NOT_FOUND; } DWORD MraSendQueueFind(HANDLE hSendQueueHandle, DWORD dwCMDNum, DWORD *pdwFlags, MCONTACT *phContact, DWORD *pdwAckType, LPBYTE *plpbData, size_t *pdwDataSize) { if (!hSendQueueHandle) return ERROR_INVALID_HANDLE; MRA_SEND_QUEUE *pmrasqSendQueue = (MRA_SEND_QUEUE*)hSendQueueHandle; MRA_SEND_QUEUE_ITEM *pmrasqiSendQueueItem; LIST_MT_ITERATOR lmtiIterator; mir_cslock l(pmrasqSendQueue->cs); ListMTIteratorMoveFirst(pmrasqSendQueue, &lmtiIterator); do { if ( !ListMTIteratorGet(&lmtiIterator, nullptr, (LPVOID*)&pmrasqiSendQueueItem)) if (pmrasqiSendQueueItem->dwCMDNum == dwCMDNum) { if (pdwFlags) (*pdwFlags) = pmrasqiSendQueueItem->dwFlags; if (phContact) (*phContact) = pmrasqiSendQueueItem->hContact; if (pdwAckType) (*pdwAckType) = pmrasqiSendQueueItem->dwAckType; if (plpbData) (*plpbData) = pmrasqiSendQueueItem->lpbData; if (pdwDataSize) (*pdwDataSize) = pmrasqiSendQueueItem->dwDataSize; return 0; } } while (ListMTIteratorMoveNext(&lmtiIterator)); return ERROR_NOT_FOUND; } DWORD MraSendQueueFindOlderThan(HANDLE hSendQueueHandle, DWORD dwTime, DWORD *pdwCMDNum, DWORD *pdwFlags, MCONTACT *phContact, DWORD *pdwAckType, LPBYTE *plpbData, size_t *pdwDataSize) { if (!hSendQueueHandle) return ERROR_INVALID_HANDLE; FILETIME ftExpireTime; GetSystemTimeAsFileTime(&ftExpireTime); (*((DWORDLONG*)&ftExpireTime))-=((DWORDLONG)dwTime*FILETIME_SECOND); MRA_SEND_QUEUE *pmrasqSendQueue = (MRA_SEND_QUEUE*)hSendQueueHandle; mir_cslock l(pmrasqSendQueue->cs); LIST_MT_ITERATOR lmtiIterator; ListMTIteratorMoveFirst(pmrasqSendQueue, &lmtiIterator); do { MRA_SEND_QUEUE_ITEM *pmrasqiSendQueueItem; if ( !ListMTIteratorGet(&lmtiIterator, nullptr, (LPVOID*)&pmrasqiSendQueueItem)) if ((*((DWORDLONG*)&ftExpireTime))>(*((DWORDLONG*)&pmrasqiSendQueueItem->ftSendTime))) { if (pdwCMDNum) *pdwCMDNum = pmrasqiSendQueueItem->dwCMDNum; if (pdwFlags) *pdwFlags = pmrasqiSendQueueItem->dwFlags; if (phContact) *phContact = pmrasqiSendQueueItem->hContact; if (pdwAckType) *pdwAckType = pmrasqiSendQueueItem->dwAckType; if (plpbData) *plpbData = pmrasqiSendQueueItem->lpbData; if (pdwDataSize) *pdwDataSize = pmrasqiSendQueueItem->dwDataSize; return 0; } } while (ListMTIteratorMoveNext(&lmtiIterator)); return ERROR_NOT_FOUND; }