size_t HandleStream::write(const void *buffer, size_t length) { if (m_cancelWrite) MORDOR_THROW_EXCEPTION(OperationAbortedException()); SchedulerSwitcher switcher(m_ioManager ? NULL : m_scheduler); DWORD written; OVERLAPPED *overlapped = NULL; if (m_ioManager) { MORDOR_ASSERT(Scheduler::getThis()); m_ioManager->registerEvent(&m_writeEvent); overlapped = &m_writeEvent.overlapped; if (supportsSeek()) { overlapped->Offset = (DWORD)m_pos; overlapped->OffsetHigh = (DWORD)(m_pos >> 32); } } length = (std::min)(length, m_maxOpSize); BOOL ret = WriteFile(m_hFile, buffer, (DWORD)length, &written, overlapped); Log::Level level = Log::DEBUG; if (!ret) { if (m_ioManager && GetLastError() == ERROR_IO_PENDING) level = Log::TRACE; else level = Log::ERROR; } DWORD error = GetLastError(); MORDOR_LOG_LEVEL(g_log, level) << this << " WriteFile(" << m_hFile << ", " << length << "): " << ret << " - " << written << " (" << error << ")"; if (m_ioManager) { if (!ret && error != ERROR_IO_PENDING) { m_ioManager->unregisterEvent(&m_writeEvent); MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("WriteFile"); } if (m_skipCompletionPortOnSuccess && ret) m_ioManager->unregisterEvent(&m_writeEvent); else Scheduler::yieldTo(); DWORD error = pRtlNtStatusToDosError((NTSTATUS)m_writeEvent.overlapped.Internal); MORDOR_LOG_LEVEL(g_log, error ? Log::ERROR : Log::VERBOSE) << this << " WriteFile(" << m_hFile << ", " << length << "): " << m_writeEvent.overlapped.InternalHigh << " (" << error << ")"; if (error) MORDOR_THROW_EXCEPTION_FROM_ERROR_API(error, "WriteFile"); if (supportsSeek()) { m_pos = ((long long)overlapped->Offset | ((long long)overlapped->OffsetHigh << 32)) + m_writeEvent.overlapped.InternalHigh; } return m_writeEvent.overlapped.InternalHigh; } if (!ret) MORDOR_THROW_EXCEPTION_FROM_ERROR_API(error, "WriteFile"); return written; }
BOOL He4HookDriverHide::SendCommand(USER_COMMAND *lpUserCommand) { if (IsBadReadPtr(lpUserCommand, sizeof(USER_COMMAND))) return FALSE; if ( lpUserCommand->m_dwInBufferSize != 0 && IsBadReadPtr(lpUserCommand->m_lpInBuffer, lpUserCommand->m_dwInBufferSize) ) return FALSE; if ( lpUserCommand->m_dwOutBufferSize != 0 && IsBadWritePtr(lpUserCommand->m_lpOutBuffer, lpUserCommand->m_dwOutBufferSize) ) return FALSE; __try { DWORD NtStatus = ZwDispatchFunction(0, 0, lpUserCommand->m_dwCommand, lpUserCommand->m_lpInBuffer, lpUserCommand->m_dwInBufferSize, lpUserCommand->m_lpOutBuffer, lpUserCommand->m_dwOutBufferSize, &lpUserCommand->m_dwBytesReturned); if (GetNtProcAddresses()) { SetLastError(pRtlNtStatusToDosError(NtStatus)); } if (NtStatus) { DriverErrorMessage(); return FALSE; } } __except(EXCEPTION_EXECUTE_HANDLER) { _DebugMessage("BOOL He4HookDriverHide::SendCommand(USER_COMMAND *lpUserCommand)"); return FALSE; } return TRUE; }
static void uv_poll_ex(int block) { BOOL success; DWORD timeout; uv_req_t* req; OVERLAPPED_ENTRY overlappeds[64]; ULONG count; ULONG i; if (block) { timeout = uv_get_poll_timeout(); } else { timeout = 0; } assert(pGetQueuedCompletionStatusEx); success = pGetQueuedCompletionStatusEx(LOOP->iocp, overlappeds, COUNTOF(overlappeds), &count, timeout, FALSE); if (success) { for (i = 0; i < count; i++) { /* Package was dequeued */ req = uv_overlapped_to_req(overlappeds[i].lpOverlapped); if (overlappeds[i].lpOverlapped->Internal != STATUS_SUCCESS) { req->error = uv_new_sys_error(pRtlNtStatusToDosError( overlappeds[i].lpOverlapped->Internal)); } uv_insert_pending_req(req); } } else if (GetLastError() != WAIT_TIMEOUT) { /* Serious error */ uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx"); } }
int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { uv_cpu_info_t* cpu_infos; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; DWORD sppi_size; SYSTEM_INFO system_info; DWORD cpu_count, r, i; NTSTATUS status; ULONG result_size; int err; uv_cpu_info_t* cpu_info; cpu_infos = NULL; cpu_count = 0; sppi = NULL; uv__once_init(); GetSystemInfo(&system_info); cpu_count = system_info.dwNumberOfProcessors; cpu_infos = calloc(cpu_count, sizeof *cpu_infos); if (cpu_infos == NULL) { err = ERROR_OUTOFMEMORY; goto error; } sppi_size = cpu_count * sizeof(*sppi); sppi = malloc(sppi_size); if (sppi == NULL) { err = ERROR_OUTOFMEMORY; goto error; } status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, sppi_size, &result_size); if (!NT_SUCCESS(status)) { err = pRtlNtStatusToDosError(status); goto error; } assert(result_size == sppi_size); for (i = 0; i < cpu_count; i++) { WCHAR key_name[128]; HKEY processor_key; DWORD cpu_speed; DWORD cpu_speed_size = sizeof(cpu_speed); WCHAR cpu_brand[256]; DWORD cpu_brand_size = sizeof(cpu_brand); size_t len; len = _snwprintf(key_name, ARRAY_SIZE(key_name), L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", i); assert(len > 0 && len < ARRAY_SIZE(key_name)); r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_name, 0, KEY_QUERY_VALUE, &processor_key); if (r != ERROR_SUCCESS) { err = GetLastError(); goto error; } if (RegQueryValueExW(processor_key, L"~MHz", NULL, NULL, (BYTE*) &cpu_speed, &cpu_speed_size) != ERROR_SUCCESS) { err = GetLastError(); RegCloseKey(processor_key); goto error; } if (RegQueryValueExW(processor_key, L"ProcessorNameString", NULL, NULL, (BYTE*) &cpu_brand, &cpu_brand_size) != ERROR_SUCCESS) { err = GetLastError(); RegCloseKey(processor_key); goto error; } RegCloseKey(processor_key); cpu_info = &cpu_infos[i]; cpu_info->speed = cpu_speed; cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - sppi[i].IdleTime.QuadPart) / 10000; cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; cpu_info->cpu_times.nice = 0; len = WideCharToMultiByte(CP_UTF8, 0, cpu_brand, cpu_brand_size / sizeof(WCHAR), NULL, 0, NULL, NULL); if (len == 0) { err = GetLastError(); goto error; } assert(len > 0); /* Allocate 1 extra byte for the null terminator. */ cpu_info->model = malloc(len + 1); if (cpu_info->model == NULL) { err = ERROR_OUTOFMEMORY; goto error; } if (WideCharToMultiByte(CP_UTF8, 0, cpu_brand, cpu_brand_size / sizeof(WCHAR), cpu_info->model, len, NULL, NULL) == 0) { err = GetLastError(); goto error; } /* Ensure that cpu_info->model is null terminated. */ cpu_info->model[len] = '\0'; } free(sppi); *cpu_count_ptr = cpu_count; *cpu_infos_ptr = cpu_infos; return 0; error: /* This is safe because the cpu_infos array is zeroed on allocation. */ for (i = 0; i < cpu_count; i++) free(cpu_infos[i].model); free(cpu_infos); free(sppi); return uv_translate_sys_error(err); }
void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { DWORD result; uv_shutdown_t* req; NTSTATUS nt_status; IO_STATUS_BLOCK io_status; FILE_PIPE_LOCAL_INFORMATION pipe_info; if ((handle->flags & UV_HANDLE_CONNECTION) && handle->shutdown_req != NULL && handle->write_reqs_pending == 0) { req = handle->shutdown_req; /* Clear the shutdown_req field so we don't go here again. */ handle->shutdown_req = NULL; if (handle->flags & UV__HANDLE_CLOSING) { UNREGISTER_HANDLE_REQ(loop, handle, req); /* Already closing. Cancel the shutdown. */ if (req->cb) { uv__set_artificial_error(loop, UV_ECANCELED); req->cb(req, -1); } DECREASE_PENDING_REQ_COUNT(handle); return; } /* Try to avoid flushing the pipe buffer in the thread pool. */ nt_status = pNtQueryInformationFile(handle->handle, &io_status, &pipe_info, sizeof pipe_info, FilePipeLocalInformation); if (nt_status != STATUS_SUCCESS) { /* Failure */ UNREGISTER_HANDLE_REQ(loop, handle, req); handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ if (req->cb) { uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status)); req->cb(req, -1); } DECREASE_PENDING_REQ_COUNT(handle); return; } if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) { /* Short-circuit, no need to call FlushFileBuffers. */ uv_insert_pending_req(loop, (uv_req_t*) req); return; } /* Run FlushFileBuffers in the thread pool. */ result = QueueUserWorkItem(pipe_shutdown_thread_proc, req, WT_EXECUTELONGFUNCTION); if (result) { return; } else { /* Failure. */ UNREGISTER_HANDLE_REQ(loop, handle, req); handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ if (req->cb) { uv__set_sys_error(loop, GetLastError()); req->cb(req, -1); } DECREASE_PENDING_REQ_COUNT(handle); return; } } if (handle->flags & UV__HANDLE_CLOSING && handle->reqs_pending == 0) { assert(!(handle->flags & UV_HANDLE_CLOSED)); if (handle->flags & UV_HANDLE_CONNECTION) { if (handle->pending_ipc_info.socket_info) { free(handle->pending_ipc_info.socket_info); handle->pending_ipc_info.socket_info = NULL; } if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { UnregisterWait(handle->read_req.wait_handle); handle->read_req.wait_handle = INVALID_HANDLE_VALUE; } if (handle->read_req.event_handle) { CloseHandle(handle->read_req.event_handle); handle->read_req.event_handle = NULL; } } } if (handle->flags & UV_HANDLE_PIPESERVER) { assert(handle->accept_reqs); free(handle->accept_reqs); handle->accept_reqs = NULL; } uv__handle_close(handle); } }
void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { unsigned int uv_alloced; DWORD result; uv_shutdown_t* req; NTSTATUS nt_status; IO_STATUS_BLOCK io_status; FILE_PIPE_LOCAL_INFORMATION pipe_info; if (handle->flags & UV_HANDLE_SHUTTING && !(handle->flags & UV_HANDLE_SHUT) && handle->write_reqs_pending == 0) { req = handle->shutdown_req; /* Try to avoid flushing the pipe buffer in the thread pool. */ nt_status = pNtQueryInformationFile(handle->handle, &io_status, &pipe_info, sizeof pipe_info, FilePipeLocalInformation); if (nt_status != STATUS_SUCCESS) { /* Failure */ handle->flags &= ~UV_HANDLE_SHUTTING; if (req->cb) { uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status)); req->cb(req, -1); } DECREASE_PENDING_REQ_COUNT(handle); return; } if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) { handle->flags |= UV_HANDLE_SHUT; /* Short-circuit, no need to call FlushFileBuffers. */ uv_insert_pending_req(loop, (uv_req_t*) req); return; } /* Run FlushFileBuffers in the thread pool. */ result = QueueUserWorkItem(pipe_shutdown_thread_proc, req, WT_EXECUTELONGFUNCTION); if (result) { /* Mark the handle as shut now to avoid going through this again. */ handle->flags |= UV_HANDLE_SHUT; return; } else { /* Failure. */ handle->flags &= ~UV_HANDLE_SHUTTING; if (req->cb) { uv__set_sys_error(loop, GetLastError()); req->cb(req, -1); } DECREASE_PENDING_REQ_COUNT(handle); return; } } if (handle->flags & UV_HANDLE_CLOSING && handle->reqs_pending == 0) { assert(!(handle->flags & UV_HANDLE_CLOSED)); handle->flags |= UV_HANDLE_CLOSED; if (handle->flags & UV_HANDLE_CONNECTION) { if (handle->pending_socket_info) { free(handle->pending_socket_info); handle->pending_socket_info = NULL; } if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { UnregisterWait(handle->read_req.wait_handle); handle->read_req.wait_handle = INVALID_HANDLE_VALUE; } if (handle->read_req.event_handle) { CloseHandle(handle->read_req.event_handle); handle->read_req.event_handle = NULL; } } } if (handle->flags & UV_HANDLE_PIPESERVER) { assert(handle->accept_reqs); free(handle->accept_reqs); handle->accept_reqs = NULL; } /* Remember the state of this flag because the close callback is */ /* allowed to clobber or free the handle's memory */ uv_alloced = handle->flags & UV_HANDLE_UV_ALLOCED; if (handle->close_cb) { handle->close_cb((uv_handle_t*)handle); } if (uv_alloced) { free(handle); } uv_unref(loop); } }