예제 #1
0
EXTERN_C void LogIrpShutdownHandler() {
  PAGED_CODE();

  LOG_DEBUG("Flushing... (Max log usage = %08x bytes)",
            g_LogpLogBufferInfo.LogMaximumUsage);
  LOG_INFO("Bye!");
  g_LogpDebugFlag = LOG_PUT_LEVEL_DISABLE;

  // Wait until the log buffer is emptied.
  auto &info = g_LogpLogBufferInfo;
  while (info.LogBufferHead[0]) {
    LogpSleep(LOGP_AUTO_FLUSH_INTERVAL_MSEC);
  }
}
예제 #2
0
// Terminates the log functions without releasing resources.
_Use_decl_annotations_ void LogIrpShutdownHandler() {
  PAGED_CODE();

  HYPERPLATFORM_LOG_DEBUG("Flushing... (Max log usage = %08x bytes)",
                          g_logp_log_buffer_info.log_max_usage);
  HYPERPLATFORM_LOG_INFO("Bye!");
  g_logp_debug_flag = kLogPutLevelDisable;

  // Wait until the log buffer is emptied.
  auto &info = g_logp_log_buffer_info;
  while (info.log_buffer_head[0]) {
    LogpSleep(kLogpLogFlushIntervalMsec);
  }
}
예제 #3
0
// Initializes a log file and startes a log buffer thread.
_Use_decl_annotations_ static NTSTATUS LogpInitializeLogFile(
    LogBufferInfo *info) {
  PAGED_CODE();

  if (info->log_file_handle) {
    return STATUS_SUCCESS;
  }

  // Initialize a log file
  UNICODE_STRING log_file_path_u = {};
  RtlInitUnicodeString(&log_file_path_u, info->log_file_path);

  OBJECT_ATTRIBUTES oa = {};
  InitializeObjectAttributes(&oa, &log_file_path_u,
                             OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, nullptr,
                             nullptr);

  IO_STATUS_BLOCK io_status = {};
  auto status = ZwCreateFile(
      &info->log_file_handle, FILE_APPEND_DATA | SYNCHRONIZE, &oa, &io_status,
      nullptr, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF,
      FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, nullptr, 0);
  if (!NT_SUCCESS(status)) {
    return status;
  }

  // Initialize a log buffer flush thread.
  info->buffer_flush_thread_should_be_alive = true;
  status = PsCreateSystemThread(&info->buffer_flush_thread_handle, GENERIC_ALL,
                                nullptr, nullptr, nullptr,
                                LogpBufferFlushThreadRoutine, info);
  if (!NT_SUCCESS(status)) {
    ZwClose(info->log_file_handle);
    info->log_file_handle = nullptr;
    info->buffer_flush_thread_should_be_alive = false;
    return status;
  }

  // Wait until the thead has started
  while (!info->buffer_flush_thread_started) {
    LogpSleep(100);
  }
  return status;
}
예제 #4
0
EXTERN_C static VOID LogpBufferFlushThreadRoutine(_In_ void *StartContext) {
  PAGED_CODE();
  auto status = STATUS_SUCCESS;
  auto info = reinterpret_cast<LogBufferInfo *>(StartContext);
  LOG_DEBUG("Log thread started.");
  NT_ASSERT(LogpIsLogFileEnabled(*info));

  while (info->BufferFlushThreadShouldBeAlive) {
    LogpSleep(LOGP_AUTO_FLUSH_INTERVAL_MSEC);
    if (info->LogBufferHead[0]) {
      NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
      NT_ASSERT(!KeAreAllApcsDisabled());
      status = LogpWriteLogBufferToFile(info);
      // Do not flush the file for overall performance. Even a case of
      // bug check, we should be able to recover logs by looking at both
      // log buffers.
    }
  }
  LOG_DEBUG("Log thread is ending.");
  PsTerminateSystemThread(status);
}
예제 #5
0
// A thread runs as long as info.buffer_flush_thread_should_be_alive is true and
// flushes a log buffer to a log file every kLogpLogFlushIntervalMsec msec.
_Use_decl_annotations_ static VOID LogpBufferFlushThreadRoutine(
    void *start_context) {
  PAGED_CODE();
  auto status = STATUS_SUCCESS;
  auto info = reinterpret_cast<LogBufferInfo *>(start_context);
  info->buffer_flush_thread_started = true;
  HYPERPLATFORM_LOG_DEBUG("Log thread started (TID= %p).",
                          PsGetCurrentThreadId());

  while (info->buffer_flush_thread_should_be_alive) {
    NT_ASSERT(LogpIsLogFileActivated(*info));
    if (info->log_buffer_head[0]) {
      NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
      NT_ASSERT(!KeAreAllApcsDisabled());
      status = LogpFlushLogBuffer(info);
      // Do not flush the file for overall performance. Even a case of
      // bug check, we should be able to recover logs by looking at both
      // log buffers.
    }
    LogpSleep(kLogpLogFlushIntervalMsec);
  }
  PsTerminateSystemThread(status);
}