2025-05-13 19:49:49 +03:00

263 lines
8.2 KiB
C

/*
* Process Hacker Extra Plugins -
* Nvidia GPU Plugin
*
* Copyright (C) 2015 dmex
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include <windowsx.h>
#pragma comment(lib, "WindowsCodecs.lib")
#include <Wincodec.h>
#define SetDlgItemCheckForSetting(hwndDlg, Id, Name) \
Button_SetCheck(GetDlgItem(hwndDlg, Id), PhGetIntegerSetting(Name) ? BST_CHECKED : BST_UNCHECKED)
#define SetSettingForDlgItemCheckRestartRequired(hwndDlg, Id, Name) \
do { \
BOOLEAN __oldValue = !!PhGetIntegerSetting(Name); \
BOOLEAN __newValue = Button_GetCheck(GetDlgItem(hwndDlg, Id)) == BST_CHECKED; \
if (__newValue != __oldValue) \
RestartRequired = TRUE; \
PhSetIntegerSetting(Name, __newValue); \
} while (0)
HBITMAP LoadImageFromResources(
_In_ UINT Width,
_In_ UINT Height,
_In_ PCWSTR Name
)
{
UINT width = 0;
UINT height = 0;
UINT frameCount = 0;
BOOLEAN isSuccess = FALSE;
ULONG resourceLength = 0;
HGLOBAL resourceHandle = NULL;
HRSRC resourceHandleSource = NULL;
WICInProcPointer resourceBuffer = NULL;
BITMAPINFO bitmapInfo = { 0 };
HBITMAP bitmapHandle = NULL;
PBYTE bitmapBuffer = NULL;
IWICStream* wicStream = NULL;
IWICBitmapSource* wicBitmapSource = NULL;
IWICBitmapDecoder* wicDecoder = NULL;
IWICBitmapFrameDecode* wicFrame = NULL;
IWICImagingFactory* wicFactory = NULL;
IWICBitmapScaler* wicScaler = NULL;
WICPixelFormatGUID pixelFormat;
WICRect rect = { 0, 0, Width, Height };
__try
{
// Create the ImagingFactory
if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, &wicFactory)))
__leave;
// Find the resource
if ((resourceHandleSource = FindResource(PluginInstance->DllBase, Name, L"PNG")) == NULL)
__leave;
// Get the resource length
resourceLength = SizeofResource(PluginInstance->DllBase, resourceHandleSource);
// Load the resource
if ((resourceHandle = LoadResource(PluginInstance->DllBase, resourceHandleSource)) == NULL)
__leave;
if ((resourceBuffer = (WICInProcPointer)LockResource(resourceHandle)) == NULL)
__leave;
// Create the Stream
if (FAILED(IWICImagingFactory_CreateStream(wicFactory, &wicStream)))
__leave;
// Initialize the Stream from Memory
if (FAILED(IWICStream_InitializeFromMemory(wicStream, resourceBuffer, resourceLength)))
__leave;
if (FAILED(IWICImagingFactory_CreateDecoder(wicFactory, &GUID_ContainerFormatPng, NULL, &wicDecoder)))
__leave;
if (FAILED(IWICBitmapDecoder_Initialize(wicDecoder, (IStream*)wicStream, WICDecodeMetadataCacheOnLoad)))
__leave;
// Get the Frame count
if (FAILED(IWICBitmapDecoder_GetFrameCount(wicDecoder, &frameCount)) || frameCount < 1)
__leave;
// Get the Frame
if (FAILED(IWICBitmapDecoder_GetFrame(wicDecoder, 0, &wicFrame)))
__leave;
// Get the WicFrame image format
if (FAILED(IWICBitmapFrameDecode_GetPixelFormat(wicFrame, &pixelFormat)))
__leave;
// Check if the image format is supported:
if (IsEqualGUID(&pixelFormat, &GUID_WICPixelFormat32bppPBGRA)) // GUID_WICPixelFormat32bppRGB
{
wicBitmapSource = (IWICBitmapSource*)wicFrame;
}
else
{
// Convert the image to the correct format:
if (FAILED(WICConvertBitmapSource(&GUID_WICPixelFormat32bppPBGRA, (IWICBitmapSource*)wicFrame, &wicBitmapSource)))
__leave;
IWICBitmapFrameDecode_Release(wicFrame);
}
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = rect.Width;
bitmapInfo.bmiHeader.biHeight = -((LONG)rect.Height);
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
HDC hdc = CreateCompatibleDC(NULL);
bitmapHandle = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (PVOID*)&bitmapBuffer, NULL, 0);
ReleaseDC(NULL, hdc);
// Check if it's the same rect as the requested size.
//if (width != rect.Width || height != rect.Height)
if (FAILED(IWICImagingFactory_CreateBitmapScaler(wicFactory, &wicScaler)))
__leave;
if (FAILED(IWICBitmapScaler_Initialize(wicScaler, wicBitmapSource, rect.Width, rect.Height, WICBitmapInterpolationModeFant)))
__leave;
if (FAILED(IWICBitmapScaler_CopyPixels(wicScaler, &rect, rect.Width * 4, rect.Width * rect.Height * 4, bitmapBuffer)))
__leave;
isSuccess = TRUE;
}
__finally
{
if (wicScaler)
{
IWICBitmapScaler_Release(wicScaler);
}
if (wicBitmapSource)
{
IWICBitmapSource_Release(wicBitmapSource);
}
if (wicStream)
{
IWICStream_Release(wicStream);
}
if (wicDecoder)
{
IWICBitmapDecoder_Release(wicDecoder);
}
if (wicFactory)
{
IWICImagingFactory_Release(wicFactory);
}
if (resourceHandle)
{
FreeResource(resourceHandle);
}
}
return bitmapHandle;
}
INT_PTR CALLBACK OptionsDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
static BOOLEAN RestartRequired;
switch (uMsg)
{
case WM_INITDIALOG:
{
RestartRequired = FALSE;
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
SetDlgItemCheckForSetting(hwndDlg, IDC_ENABLENVIDIASUPPORT, SETTING_NAME_ENABLE_MONITORING);
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDCANCEL:
EndDialog(hwndDlg, IDCANCEL);
break;
case IDOK:
{
SetSettingForDlgItemCheckRestartRequired(hwndDlg, IDC_ENABLENVIDIASUPPORT, SETTING_NAME_ENABLE_MONITORING);
if (RestartRequired)
{
if (PhShowMessage(
PhMainWndHandle,
MB_ICONQUESTION | MB_YESNO,
L"One or more options you have changed requires a restart of Process Hacker. "
L"Do you want to restart Process Hacker now?"
) == IDYES)
{
ProcessHacker_PrepareForEarlyShutdown(PhMainWndHandle);
PhShellProcessHacker(
PhMainWndHandle,
L"-v",
SW_SHOW,
0,
PH_SHELL_APP_PROPAGATE_PARAMETERS | PH_SHELL_APP_PROPAGATE_PARAMETERS_IGNORE_VISIBILITY,
0,
NULL
);
ProcessHacker_Destroy(PhMainWndHandle);
}
}
EndDialog(hwndDlg, IDOK);
}
break;
}
}
break;
}
return FALSE;
}
VOID ShowOptionsDialog(
_In_ HWND ParentHandle
)
{
DialogBox(
PluginInstance->DllBase,
MAKEINTRESOURCE(IDD_OPTIONS),
ParentHandle,
OptionsDlgProc
);
}