263 lines
8.2 KiB
C
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
|
|
);
|
|
} |