Esempio n. 1
0
BOOLEAN LastUpdateCheckExpired(
    VOID
    )
{
    ULONG64 lastUpdateTimeTicks = 0;
    LARGE_INTEGER currentUpdateTimeTicks;
    PPH_STRING lastUpdateTimeString;

    PhQuerySystemTime(&currentUpdateTimeTicks);

    lastUpdateTimeString = PhGetStringSetting(SETTING_NAME_LAST_CHECK);
    PhStringToInteger64(&lastUpdateTimeString->sr, 0, &lastUpdateTimeTicks);

    if (currentUpdateTimeTicks.QuadPart - lastUpdateTimeTicks >= 7 * PH_TICKS_PER_DAY)
    {
        PPH_STRING currentUpdateTimeString;
        
        currentUpdateTimeString = PhFormatUInt64(currentUpdateTimeTicks.QuadPart, FALSE);
        PhSetStringSetting2(SETTING_NAME_LAST_CHECK, &currentUpdateTimeString->sr);

        PhDereferenceObject(currentUpdateTimeString);
        PhDereferenceObject(lastUpdateTimeString);
        return TRUE;
    }

    PhDereferenceObject(lastUpdateTimeString);
    return FALSE;
}
Esempio n. 2
0
static BOOLEAN LastUpdateCheckExpired(
    VOID
    )
{
    ULONG64 lastUpdateTimeTicks = 0;
    LARGE_INTEGER currentUpdateTimeTicks;
    PPH_STRING lastUpdateTimeString;

    // Get the last update check time 
    lastUpdateTimeString = PhGetStringSetting(SETTING_NAME_LAST_CHECK);
    PhStringToInteger64(&lastUpdateTimeString->sr, 0, &lastUpdateTimeTicks);

    // Query the current time
    PhQuerySystemTime(&currentUpdateTimeTicks);

    // Check if the last update check was more than 7 days ago
    if (currentUpdateTimeTicks.QuadPart - lastUpdateTimeTicks >= 7 * PH_TICKS_PER_DAY)
    {
        PPH_STRING currentUpdateTimeString = PhFormatUInt64(currentUpdateTimeTicks.QuadPart, FALSE);

        // Save the current time
        PhSetStringSetting2(SETTING_NAME_LAST_CHECK, &currentUpdateTimeString->sr);

        // Cleanup
        PhDereferenceObject(currentUpdateTimeString);
        PhDereferenceObject(lastUpdateTimeString);
        return TRUE;
    }

    // Cleanup
    PhDereferenceObject(lastUpdateTimeString);
    return FALSE;
}
Esempio n. 3
0
PPH_LOG_ENTRY PhpCreateLogEntry(
    _In_ UCHAR Type
    )
{
    PPH_LOG_ENTRY entry;

    entry = PhAllocate(sizeof(PH_LOG_ENTRY));
    memset(entry, 0, sizeof(PH_LOG_ENTRY));

    entry->Type = Type;
    PhQuerySystemTime(&entry->Time);

    return entry;
}
Esempio n. 4
0
PPH_STRING PhapGetRelativeTimeString(
    __in PLARGE_INTEGER Time
    )
{
    LARGE_INTEGER time;
    LARGE_INTEGER currentTime;
    SYSTEMTIME timeFields;
    PPH_STRING timeRelativeString;
    PPH_STRING timeString;

    time = *Time;
    PhQuerySystemTime(&currentTime);
    timeRelativeString = PHA_DEREFERENCE(PhFormatTimeSpanRelative(currentTime.QuadPart - time.QuadPart));

    PhLargeIntegerToLocalSystemTime(&timeFields, &time);
    timeString = PhaFormatDateTime(&timeFields);

    return PhaFormatString(L"%s (%s)", timeRelativeString->Buffer, timeString->Buffer);
}
Esempio n. 5
0
VOID PhWritePhTextHeader(
    __inout PPH_FILE_STREAM FileStream
    )
{
    PPH_STRING version;
    LARGE_INTEGER time;
    SYSTEMTIME systemTime;
    PPH_STRING dateString;
    PPH_STRING timeString;

    PhWriteStringAsAnsiFileStream2(FileStream, L"Process Hacker ");

    if (version = PhGetPhVersion())
    {
        PhWriteStringAsAnsiFileStream(FileStream, &version->sr);
        PhDereferenceObject(version);
    }

    PhWriteStringFormatFileStream(FileStream, L"\r\nWindows NT %u.%u", PhOsVersion.dwMajorVersion, PhOsVersion.dwMinorVersion);

    if (PhOsVersion.szCSDVersion[0] != 0)
        PhWriteStringFormatFileStream(FileStream, L" %s", PhOsVersion.szCSDVersion);

#ifdef _M_IX86
    PhWriteStringAsAnsiFileStream2(FileStream, L" (32-bit)");
#else
    PhWriteStringAsAnsiFileStream2(FileStream, L" (64-bit)");
#endif

    PhQuerySystemTime(&time);
    PhLargeIntegerToLocalSystemTime(&systemTime, &time);

    dateString = PhFormatDate(&systemTime, NULL);
    timeString = PhFormatTime(&systemTime, NULL);
    PhWriteStringFormatFileStream(FileStream, L"\r\n%s %s\r\n\r\n", dateString->Buffer, timeString->Buffer);
    PhDereferenceObject(dateString);
    PhDereferenceObject(timeString);
}
Esempio n. 6
0
VOID StatusBarUpdate(
    _In_ BOOLEAN ResetMaxWidths
    )
{
    static ULONG64 lastTickCount = 0;

    ULONG count;
    ULONG i;
    HDC hdc;
    BOOLEAN resetMaxWidths = FALSE;
    PPH_STRING text[MAX_STATUSBAR_ITEMS];
    ULONG widths[MAX_STATUSBAR_ITEMS];

    if (ProcessesUpdatedCount < 2)
        return;

    if (ResetMaxWidths)
        resetMaxWidths = TRUE;

    if (!StatusBarItemList || StatusBarItemList->Count == 0)
    {
        // The status bar doesn't cope well with 0 parts.
        widths[0] = -1;
        SendMessage(StatusBarHandle, SB_SETPARTS, 1, (LPARAM)widths);
        SendMessage(StatusBarHandle, SB_SETTEXT, 0, (LPARAM)L"");
        return;
    }

    hdc = GetDC(StatusBarHandle);
    SelectObject(hdc, (HFONT)SendMessage(StatusBarHandle, WM_GETFONT, 0, 0));

    // Reset max. widths for Max. CPU Process and Max. I/O Process parts once in a while.
    {
        LARGE_INTEGER tickCount;

        PhQuerySystemTime(&tickCount);

        if (tickCount.QuadPart - lastTickCount >= 10 * PH_TICKS_PER_SEC)
        {
            resetMaxWidths = TRUE;
            lastTickCount = tickCount.QuadPart;
        }
    }

    count = 0;

    for (i = 0; i < StatusBarItemList->Count; i++)
    {
        SIZE size;
        ULONG width;
        PSTATUSBAR_ITEM statusItem;

        statusItem = StatusBarItemList->Items[i];

        switch (statusItem->Id)
        {
        case ID_STATUS_CPUUSAGE:
            {
                text[count] = PhFormatString(
                    L"CPU Usage: %.2f%%",
                    (SystemStatistics.CpuKernelUsage + SystemStatistics.CpuUserUsage) * 100
                    );
            }
            break;
        case ID_STATUS_COMMITCHARGE:
            {
                ULONG commitUsage = SystemStatistics.Performance->CommittedPages;
                FLOAT commitFraction = (FLOAT)commitUsage / SystemStatistics.Performance->CommitLimit * 100;

                text[count] = PhFormatString(
                    L"Commit Charge: %s (%.2f%%)",
                    PhaFormatSize(UInt32x32To64(commitUsage, PAGE_SIZE), -1)->Buffer,
                    commitFraction
                    );
            }
            break;
        case ID_STATUS_PHYSICALMEMORY:
            {
                ULONG physicalUsage = PhSystemBasicInformation.NumberOfPhysicalPages - SystemStatistics.Performance->AvailablePages;
                FLOAT physicalFraction = (FLOAT)physicalUsage / PhSystemBasicInformation.NumberOfPhysicalPages * 100;

                text[count] = PhFormatString(
                    L"Physical Memory: %s (%.2f%%)",
                    PhaFormatSize(UInt32x32To64(physicalUsage, PAGE_SIZE), -1)->Buffer,
                    physicalFraction
                    );
            }
            break;
        case ID_STATUS_FREEMEMORY:
            {
                ULONG physicalFree = SystemStatistics.Performance->AvailablePages;
                FLOAT physicalFreeFraction = (FLOAT)physicalFree / PhSystemBasicInformation.NumberOfPhysicalPages * 100;

                text[count] = PhFormatString(
                    L"Free Memory: %s (%.2f%%)",
                    PhaFormatSize(UInt32x32To64(physicalFree, PAGE_SIZE), -1)->Buffer,
                    physicalFreeFraction
                    );
            }
            break;
        case ID_STATUS_NUMBEROFPROCESSES:
            {
                text[count] = PhConcatStrings2(
                    L"Processes: ",
                    PhaFormatUInt64(SystemStatistics.NumberOfProcesses, TRUE)->Buffer
                    );
            }
            break;
        case ID_STATUS_NUMBEROFTHREADS:
            {
                text[count] = PhConcatStrings2(
                    L"Threads: ",
                    PhaFormatUInt64(SystemStatistics.NumberOfThreads, TRUE)->Buffer
                    );
            }
            break;
        case ID_STATUS_NUMBEROFHANDLES:
            {
                text[count] = PhConcatStrings2(
                    L"Handles: ",
                    PhaFormatUInt64(SystemStatistics.NumberOfHandles, TRUE)->Buffer
                    );
            }
            break;
        case ID_STATUS_IO_RO:
            {
                text[count] = PhConcatStrings2(
                    L"I/O R+O: ",
                    PhaFormatSize(SystemStatistics.IoReadDelta.Delta + SystemStatistics.IoOtherDelta.Delta, -1)->Buffer
                    );
            }
            break;
        case ID_STATUS_IO_W:
            {
                text[count] = PhConcatStrings2(
                    L"I/O W: ",
                    PhaFormatSize(SystemStatistics.IoWriteDelta.Delta, -1)->Buffer
                    );
            }
            break;
        case ID_STATUS_MAX_CPU_PROCESS:
            {
                PPH_PROCESS_ITEM processItem;

                if (SystemStatistics.MaxCpuProcessId && (processItem = PhReferenceProcessItem(SystemStatistics.MaxCpuProcessId)))
                {
                    if (!PH_IS_FAKE_PROCESS_ID(processItem->ProcessId))
                    {
                        text[count] = PhFormatString(
                            L"%s (%lu): %.2f%%",
                            processItem->ProcessName->Buffer,
                            HandleToUlong(processItem->ProcessId),
                            processItem->CpuUsage * 100
                            );
                    }
                    else
                    {
                        text[count] = PhFormatString(
                            L"%s: %.2f%%",
                            processItem->ProcessName->Buffer,
                            processItem->CpuUsage * 100
                            );
                    }

                    PhDereferenceObject(processItem);
                }
                else
                {
                    text[count] = PhCreateString(L"-");
                }
            }
            break;
        case ID_STATUS_MAX_IO_PROCESS:
            {
                PPH_PROCESS_ITEM processItem;

                if (SystemStatistics.MaxIoProcessId && (processItem = PhReferenceProcessItem(SystemStatistics.MaxIoProcessId)))
                {
                    if (!PH_IS_FAKE_PROCESS_ID(processItem->ProcessId))
                    {
                        text[count] = PhFormatString(
                            L"%s (%lu): %s",
                            processItem->ProcessName->Buffer,
                            HandleToUlong(processItem->ProcessId),
                            PhaFormatSize(processItem->IoReadDelta.Delta + processItem->IoWriteDelta.Delta + processItem->IoOtherDelta.Delta, -1)->Buffer
                            );
                    }
                    else
                    {
                        text[count] = PhFormatString(
                            L"%s: %s",
                            processItem->ProcessName->Buffer,
                            PhaFormatSize(processItem->IoReadDelta.Delta + processItem->IoWriteDelta.Delta + processItem->IoOtherDelta.Delta, -1)->Buffer
                            );
                    }

                    PhDereferenceObject(processItem);
                }
                else
                {
                    text[count] = PhCreateString(L"-");
                }
            }
            break;
        case ID_STATUS_NUMBEROFVISIBLEITEMS:
            {
                HWND tnHandle = NULL;

                tnHandle = GetCurrentTreeNewHandle();

                if (tnHandle)
                {
                    ULONG visibleCount = 0;

                    visibleCount = TreeNew_GetFlatNodeCount(tnHandle);

                    text[count] = PhFormatString(
                        L"Visible: %lu",
                        visibleCount
                        );
                }
                else
                {
                    text[count] = PhCreateString(
                        L"Visible: N/A"
                        );
                }
            }
            break;
        case ID_STATUS_NUMBEROFSELECTEDITEMS:
            {
                HWND tnHandle = NULL;

                tnHandle = GetCurrentTreeNewHandle();

                if (tnHandle)
                {
                    ULONG visibleCount = 0;
                    ULONG selectedCount = 0;

                    visibleCount = TreeNew_GetFlatNodeCount(tnHandle);

                    for (ULONG i = 0; i < visibleCount; i++)
                    {
                        if (TreeNew_GetFlatNode(tnHandle, i)->Selected)
                            selectedCount++;
                    }

                    text[count] = PhFormatString(
                        L"Selected: %lu",
                        selectedCount
                        );
                }
                else
                {
                    text[count] = PhCreateString(
                        L"Selected: N/A"
                        );
                }
            }
            break;
        case ID_STATUS_INTERVALSTATUS:
            {
                ULONG interval;

                interval = PhGetIntegerSetting(L"UpdateInterval");

                if (UpdateAutomatically)
                {
                    switch (interval)
                    {
                    case 500:
                        text[count] = PhCreateString(L"Interval: Fast");
                        break;
                    case 1000:
                        text[count] = PhCreateString(L"Interval: Normal");
                        break;
                    case 2000:
                        text[count] = PhCreateString(L"Interval: Below Normal");
                        break;
                    case 5000:
                        text[count] = PhCreateString(L"Interval: Slow");
                        break;
                    case 10000:
                        text[count] = PhCreateString(L"Interval: Very Slow");
                        break;
                    }
                }
                else
                {
                    text[count] = PhCreateString(L"Interval: Paused");
                }
            }
            break;
        }

        if (resetMaxWidths)
            StatusBarMaxWidths[count] = 0;

        if (!GetTextExtentPoint32(hdc, text[count]->Buffer, (ULONG)text[count]->Length / sizeof(WCHAR), &size))
            size.cx = 200;

        if (count != 0)
            widths[count] = widths[count - 1];
        else
            widths[count] = 0;

        width = size.cx + 10;

        if (width <= StatusBarMaxWidths[count])
        {
            width = StatusBarMaxWidths[count];
        }
        else
        {
            StatusBarMaxWidths[count] = width;
        }

        widths[count] += width;

        count++;
    }

    ReleaseDC(StatusBarHandle, hdc);

    SendMessage(StatusBarHandle, SB_SETPARTS, count, (LPARAM)widths);

    for (i = 0; i < count; i++)
    {
        SendMessage(StatusBarHandle, SB_SETTEXT, i, (LPARAM)text[i]->Buffer);
        PhDereferenceObject(text[i]);
    }
}
Esempio n. 7
0
NTSTATUS UpdateDownloadThread(
    _In_ PVOID Parameter
    )
{
    BOOLEAN downloadSuccess = FALSE;
    BOOLEAN hashSuccess = FALSE;
    BOOLEAN signatureSuccess = FALSE;
    HANDLE tempFileHandle = NULL;
    PPH_HTTP_CONTEXT httpContext = NULL;
    PPH_STRING downloadHostPath = NULL;
    PPH_STRING downloadUrlPath = NULL;
    PUPDATER_HASH_CONTEXT hashContext = NULL;
    USHORT httpPort = 0;
    LARGE_INTEGER timeNow;
    LARGE_INTEGER timeStart;
    ULONG64 timeTicks = 0;
    ULONG64 timeBitsPerSecond = 0;
    PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)Parameter;

    SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Initializing download request...");

    if (!PhHttpSocketParseUrl(
        context->SetupFileDownloadUrl,
        &downloadHostPath, 
        &downloadUrlPath,
        &httpPort
        ))
    {
        context->ErrorCode = GetLastError();
        goto CleanupExit;
    }

    // Create the local path string.
    context->SetupFilePath = UpdaterParseDownloadFileName(downloadUrlPath);
    if (PhIsNullOrEmptyString(context->SetupFilePath))
        goto CleanupExit;

    // Create temporary output file.
    if (!NT_SUCCESS(PhCreateFileWin32(
        &tempFileHandle,
        PhGetString(context->SetupFilePath),
        FILE_GENERIC_WRITE,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ,
        FILE_OVERWRITE_IF,
        FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
        )))
    {
        goto CleanupExit;
    }

    SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Connecting...");

    if (!PhHttpSocketCreate(&httpContext, NULL))
    {
        context->ErrorCode = GetLastError();
        goto CleanupExit;
    }

    if (!PhHttpSocketConnect(
        httpContext, 
        PhGetString(downloadHostPath), 
        httpPort
        ))
    {
        context->ErrorCode = GetLastError();
        goto CleanupExit;
    }

    if (!PhHttpSocketBeginRequest(
        httpContext, 
        NULL, 
        PhGetString(downloadUrlPath), 
        PH_HTTP_FLAG_REFRESH | (httpPort == PH_HTTP_DEFAULT_HTTPS_PORT ? PH_HTTP_FLAG_SECURE : 0)
        ))
    {
        context->ErrorCode = GetLastError();
        goto CleanupExit;
    }

    SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Sending download request...");

    if (!PhHttpSocketSendRequest(httpContext, NULL, 0))
    {
        context->ErrorCode = GetLastError();
        goto CleanupExit;
    }

    SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Waiting for response...");

    if (!PhHttpSocketEndRequest(httpContext))
    {
        context->ErrorCode = GetLastError();
        goto CleanupExit;
    }
    else
    {
        ULONG bytesDownloaded = 0;
        ULONG downloadedBytes = 0;
        ULONG contentLength = 0;
        PPH_STRING status;
        IO_STATUS_BLOCK isb;
        BYTE buffer[PAGE_SIZE];

        status = PhFormatString(L"Downloading update %s...", PhGetStringOrEmpty(context->Version));

        SendMessage(context->DialogHandle, TDM_SET_MARQUEE_PROGRESS_BAR, FALSE, 0);
        SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)status->Buffer);
        PhDereferenceObject(status);

        if (!PhHttpSocketQueryHeaderUlong(
            httpContext,
            PH_HTTP_QUERY_CONTENT_LENGTH,
            &contentLength
            ))
        {
            context->ErrorCode = GetLastError();
            goto CleanupExit;
        }

        // Initialize hash algorithm.
        if (!(hashContext = UpdaterInitializeHash()))
            goto CleanupExit;

        // Zero the buffer.
        memset(buffer, 0, PAGE_SIZE);

        // Start the clock.
        PhQuerySystemTime(&timeStart);

        // Download the data.
        while (PhHttpSocketReadData(httpContext, buffer, PAGE_SIZE, &bytesDownloaded))
        {
            // If we get zero bytes, the file was uploaded or there was an error
            if (bytesDownloaded == 0)
                break;

            // If the dialog was closed, just cleanup and exit
            if (!UpdateDialogThreadHandle)
                goto CleanupExit;

            // Update the hash of bytes we downloaded.
            UpdaterUpdateHash(hashContext, buffer, bytesDownloaded);

            // Write the downloaded bytes to disk.
            if (!NT_SUCCESS(NtWriteFile(
                tempFileHandle,
                NULL,
                NULL,
                NULL,
                &isb,
                buffer,
                bytesDownloaded,
                NULL,
                NULL
                )))
            {
                goto CleanupExit;
            }

            downloadedBytes += (DWORD)isb.Information;

            // Check the number of bytes written are the same we downloaded.
            if (bytesDownloaded != isb.Information)
                goto CleanupExit;

            // Query the current time
            PhQuerySystemTime(&timeNow);

            // Calculate the number of ticks
            timeTicks = (timeNow.QuadPart - timeStart.QuadPart) / PH_TICKS_PER_SEC;
            timeBitsPerSecond = downloadedBytes / __max(timeTicks, 1);

            // TODO: Update on timer callback.
            {
                FLOAT percent = ((FLOAT)downloadedBytes / contentLength * 100);
                PPH_STRING totalLength = PhFormatSize(contentLength, -1);
                PPH_STRING totalDownloaded = PhFormatSize(downloadedBytes, -1);
                PPH_STRING totalSpeed = PhFormatSize(timeBitsPerSecond, -1);

                PPH_STRING statusMessage = PhFormatString(
                    L"Downloaded: %s of %s (%.0f%%)\r\nSpeed: %s/s",
                    PhGetStringOrEmpty(totalDownloaded),
                    PhGetStringOrEmpty(totalLength),
                    percent,
                    PhGetStringOrEmpty(totalSpeed)
                    );

                SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_CONTENT, (LPARAM)statusMessage->Buffer);
                SendMessage(context->DialogHandle, TDM_SET_PROGRESS_BAR_POS, (WPARAM)percent, 0);

                PhDereferenceObject(statusMessage);
                PhDereferenceObject(totalSpeed);
                PhDereferenceObject(totalLength);
                PhDereferenceObject(totalDownloaded);
            }
        }

        if (UpdaterVerifyHash(hashContext, context->SetupFileHash))
        {
            hashSuccess = TRUE;
        }

        if (UpdaterVerifySignature(hashContext, context->SetupFileSignature))
        {
            signatureSuccess = TRUE;
        }

        if (hashSuccess && signatureSuccess)
        {
            downloadSuccess = TRUE;
        }
    }

CleanupExit:

    if (httpContext)
        PhHttpSocketDestroy(httpContext);

    if (hashContext)
        UpdaterDestroyHash(hashContext);

    if (tempFileHandle)
        NtClose(tempFileHandle);

    if (downloadHostPath)
        PhDereferenceObject(downloadHostPath);

    if (downloadUrlPath)
        PhDereferenceObject(downloadUrlPath);

    if (UpdateDialogThreadHandle)
    {
        if (downloadSuccess && hashSuccess && signatureSuccess)
        {
            ShowUpdateInstallDialog(context);
        }
        else if (downloadSuccess)
        {
            if (signatureSuccess)
                ShowUpdateFailedDialog(context, TRUE, FALSE);
            else if (hashSuccess)
                ShowUpdateFailedDialog(context, FALSE, TRUE);
            else
                ShowUpdateFailedDialog(context, FALSE, FALSE);
        }
        else
        {
            ShowUpdateFailedDialog(context, FALSE, FALSE);
        }
    }

    PhDereferenceObject(context);
    return STATUS_SUCCESS;
}
Esempio n. 8
0
static VOID DbgProcessLogMessageEntry(
    _Inout_ PPH_DBGEVENTS_CONTEXT Context,
    _In_ BOOLEAN GlobalEvents
    )
{
    NTSTATUS status;
    PDBWIN_PAGE_BUFFER debugMessageBuffer;
    PDEBUG_LOG_ENTRY entry = NULL;
    HANDLE processHandle = NULL;
    PPH_STRING fileName = NULL;
    HICON icon = NULL;

    debugMessageBuffer = GlobalEvents ? Context->GlobalDebugBuffer : Context->LocalDebugBuffer;

    entry = PhAllocate(sizeof(DEBUG_LOG_ENTRY));
    memset(entry, 0, sizeof(DEBUG_LOG_ENTRY));

    PhQuerySystemTime(&entry->Time);
    entry->ProcessId = UlongToHandle(debugMessageBuffer->ProcessId);
    entry->Message = PhConvertMultiByteToUtf16(debugMessageBuffer->Buffer);

    if (WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID)
    {
        status = PhGetProcessImageFileNameByProcessId(entry->ProcessId, &fileName);
    }
    else
    {
        if (NT_SUCCESS(status = PhOpenProcess(&processHandle, ProcessQueryAccess, entry->ProcessId)))
        {
            status = PhGetProcessImageFileName(processHandle, &fileName);
            NtClose(processHandle);
        }
    }

    if (!NT_SUCCESS(status))
        fileName = PhGetKernelFileName();

    PhSwapReference2(&fileName, PhGetFileName(fileName));

    icon = PhGetFileShellIcon(PhGetString(fileName), L".exe", TRUE);

    if (icon)
    {
        entry->ImageIndex = ImageList_AddIcon(Context->ListViewImageList, icon);
        DestroyIcon(icon);
    }

    entry->FilePath = fileName;
    entry->ProcessName = PhGetBaseName(fileName);

    // Drop event if it matches a filter
    for (ULONG i = 0; i < Context->ExcludeList->Count; i++)
    {
        PDBG_FILTER_TYPE filterEntry = Context->ExcludeList->Items[i];

        if (filterEntry->Type == FilterByName)
        {
            if (PhEqualString(filterEntry->ProcessName, entry->ProcessName, TRUE))
            {
                DbgFreeLogEntry(entry);
                return;
            }
        }
        else if (filterEntry->Type == FilterByPid)
        {
            if (filterEntry->ProcessId == entry->ProcessId)
            {
                DbgFreeLogEntry(entry);
                return;
            }
        }
    }

    DbgAddLogEntry(Context, entry);
}