bool ChatClient::queueCompletionStatus() { TRACE_IF(LOG_IOCP, "try to queue completion status\n"); DWORD bytes; ULONG_PTR key; ChatOverlappedData* ol; if (!GetQueuedCompletionStatus(hComp_, &bytes, &key, (LPOVERLAPPED*)&ol, 0)) { TRACE_IF(LOG_IOCP, "no queued completion status\n"); return false; } if (key == kTimerKey) { msgMan_.checkRequests(); } else if (key == kServerKey) { int type = ol->getNetType(); TRACE_IF(LOG_IOCP, "get queued completion status type = %d\n", type); if (type == net::kAction_Recv) { TRACE("recved bytes count %d\n", bytes); onRecv(ol, bytes, key); } else if (type == net::kAction_Send) { } else if (type == net::kAction_SendMessage) { cmdCenter_.sendImageMessage(sock_, (ImageMessageForSend*)(ol->getProp())); } } else if (key == kPeerListenKey) { } else if (key == kPeerConnKey) { } return true; }
/* * Touches (reads/writes) the first word in every page of memory pointed to by * buf of len bytes. If buf is not on the page boundary, the word at buf is * touched instead. Note that the page is only touched if it's reserved (i.e. * neither committed, nor free). * * This function is used to work around a bug in DosRead that causes it to fail * when interrupted by the exception handler, see * https://github.com/bitwiseworks/libcx/issues/21. */ void touch_pages(void *buf, size_t len) { APIRET arc; ULONG dos_len; ULONG dos_flags; volatile ULONG buf_addr = (ULONG)buf; ULONG buf_end = buf_addr + len; /* * Note: we need to at least perform the write operation when toucing so that * in case if it's our memory mapped region then it's marked dirty and with * PAG_WRITE is set (on read PAG_WRITE would have been removed whcih would * cause DosRead to fail too). And, to make sure that the touched region is * not corrupted by touching, we first read the target word and then simply * write it back. */ if (!PAGE_ALIGNED(buf_addr)) { dos_len = PAGE_SIZE; arc = DosQueryMem((PVOID)PAGE_ALIGN(buf_addr), &dos_len, &dos_flags); TRACE_IF(arc, "DosQueryMem = %lu\n", arc); if (!arc && !(dos_flags & (PAG_FREE | PAG_COMMIT))) *(int *)buf_addr = *(int *)buf_addr; buf_addr = PAGE_ALIGN(buf_addr) + PAGE_SIZE; } while (buf_addr < buf_end) { dos_len = ~0U; arc = DosQueryMem((PVOID)PAGE_ALIGN(buf_addr), &dos_len, &dos_flags); TRACE_IF(arc, "DosQueryMem = %lu\n", arc); if (!arc && !(dos_flags & (PAG_FREE | PAG_COMMIT))) { /* touch all pages within the reported range */ dos_len += buf_addr; while (buf_addr < dos_len) { *(int *)buf_addr = *(int *)buf_addr; buf_addr += PAGE_SIZE; } } else { buf_addr += dos_len; } } }
char *get_module_name(char *buf, size_t len) { HMODULE hmod; ULONG obj, offset; APIRET arc; arc = DosQueryModFromEIP(&hmod, &obj, len, buf, &offset, (ULONG)get_module_name); TRACE_IF(arc, "DosQueryModFromEIP %ld\n", arc); ASSERT_MSG(!arc || arc == ERROR_BAD_LENGTH, "%ld %d", arc, len); if (arc) return NULL; arc = DosQueryModuleName(hmod, len, buf); TRACE_IF(arc, "DosQueryModuleName %ld\n", arc); ASSERT_MSG(!arc || arc == ERROR_BAD_LENGTH, "%ld %d", arc, len); if (arc) return NULL; return buf; }