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

497 lines
12 KiB
C

/*
* Process Hacker Extra Plugins -
* Network Extras Plugin
*
* Copyright (C) 2016 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"
struct
{
PWSTR CountryCode;
INT ResourceID;
}
CountryResourceTable[] =
{
{ L"AD", AD_PNG },
{ L"AE", AE_PNG },
{ L"AF", AF_PNG },
{ L"AG", AG_PNG },
{ L"AI", AI_PNG },
{ L"AL", AL_PNG },
{ L"AM", AM_PNG },
{ L"AN", AN_PNG },
{ L"AO", AO_PNG },
{ L"AR", AR_PNG },
{ L"AS", AS_PNG },
{ L"AT", AT_PNG },
{ L"AU", AU_PNG },
{ L"AW", AW_PNG },
{ L"AX", AX_PNG },
{ L"AZ", AZ_PNG },
{ L"BA", BA_PNG },
{ L"BB", BB_PNG },
{ L"BD", BD_PNG },
{ L"BE", BE_PNG },
{ L"BF", BF_PNG },
{ L"BG", BG_PNG },
{ L"BH", BH_PNG },
{ L"BI", BI__PNG },
{ L"BJ", BJ_PNG },
{ L"BM", BM_PNG },
{ L"BN", BN_PNG },
{ L"BO", BO_PNG },
{ L"BR", BR_PNG },
{ L"BS", BS_PNG },
{ L"BT", BT_PNG },
{ L"BV", BV_PNG },
{ L"BW", BW_PNG },
{ L"BY", BY_PNG },
{ L"BZ", BZ_PNG },
{ L"CA", CA_PNG },
{ L"CC", CC_PNG },
{ L"CD", CD_PNG },
{ L"CF", CF_PNG },
{ L"CG", CG_PNG },
{ L"CH", CH_PNG },
{ L"CI", CI_PNG },
{ L"CK", CK_PNG },
{ L"CL", CL_PNG },
{ L"CM", CM_PNG },
{ L"CN", CN_PNG },
{ L"CO", CO_PNG },
{ L"CR", CR_PNG },
{ L"CS", CS_PNG },
{ L"CU", CU_PNG },
{ L"CV", CV_PNG },
{ L"CX", CX_PNG },
{ L"CY", CY_PNG },
{ L"CZ", CZ_PNG },
{ L"DE", DE_PNG },
{ L"DJ", DJ_PNG },
{ L"DK", DK_PNG },
{ L"DM", DM_PNG },
{ L"DO", DO_PNG },
{ L"DZ", DZ_PNG },
{ L"EC", EC_PNG },
{ L"EE", EE_PNG },
{ L"EG", EG_PNG },
{ L"EH", EH_PNG },
{ L"ER", ER_PNG },
{ L"ES", ES_PNG },
{ L"ET", ET_PNG },
{ L"FI", FI_PNG },
{ L"FJ", FJ_PNG },
{ L"FK", FK_PNG },
{ L"FO", FO_PNG },
{ L"FR", FR_PNG },
{ L"GA", GA_PNG },
{ L"GB", GB_PNG },
{ L"GD", GD_PNG },
{ L"GE", GE_PNG },
{ L"GF", GF_PNG },
{ L"GH", GH_PNG },
{ L"GI", GI_PNG },
{ L"GL", GL_PNG },
{ L"GM", GM_PNG },
{ L"GN", GN_PNG },
{ L"GP", GP_PNG },
{ L"GQ", GQ_PNG },
{ L"GR", GR_PNG },
{ L"GS", GS_PNG },
{ L"GT", GT_PNG },
{ L"GU", GU_PNG },
{ L"GW", GW_PNG },
{ L"GY", GY_PNG },
{ L"HK", HK_PNG },
{ L"HM", HM_PNG },
{ L"HN", HN_PNG },
{ L"HR", HR_PNG },
{ L"HT", HT_PNG },
{ L"HU", HU_PNG },
{ L"ID", ID_PNG },
{ L"IE", IE_PNG },
{ L"IL", IL_PNG },
{ L"IN", IN_PNG },
{ L"IO", IO_PNG },
{ L"IQ", IQ_PNG },
{ L"IR", IR_PNG },
{ L"IS", IS_PNG },
{ L"IT", IT_PNG },
{ L"JM", JM_PNG },
{ L"JO", JO_PNG },
{ L"JP", JP_PNG },
{ L"KE", KE_PNG },
{ L"KG", KG_PNG },
{ L"KH", KH_PNG },
{ L"KI", KI_PNG },
{ L"KM", KM_PNG },
{ L"KN", KN_PNG },
{ L"KP", KP_PNG },
{ L"KR", KR_PNG },
{ L"KW", KW_PNG },
{ L"KY", KY_PNG },
{ L"KZ", KZ_PNG },
{ L"LA", LA_PNG },
{ L"LB", LB_PNG },
{ L"LC", LC_PNG },
{ L"LI", LI_PNG },
{ L"LK", LK_PNG },
{ L"LR", LR_PNG },
{ L"LS", LS_PNG },
{ L"LT", LT_PNG },
{ L"LU", LU_PNG },
{ L"LV", LV_PNG },
{ L"LY", LY_PNG },
{ L"MA", MA_PNG },
{ L"MC", MC_PNG },
{ L"MD", MD_PNG },
{ L"ME", ME_PNG },
{ L"MG", MG_PNG },
{ L"MH", MH_PNG },
{ L"MK", MK_PNG },
{ L"ML", ML_PNG },
{ L"MM", MM_PNG },
{ L"MN", MN_PNG },
{ L"MO", MO_PNG },
{ L"MP", MP_PNG },
{ L"MQ", MQ_PNG },
{ L"MR", MR_PNG },
{ L"MS", MS_PNG },
{ L"MT", MT_PNG },
{ L"MU", MU_PNG },
{ L"MV", MV_PNG },
{ L"MW", MW_PNG },
{ L"MX", MX_PNG },
{ L"MY", MY_PNG },
{ L"MZ", MZ_PNG },
{ L"NA", NA_PNG },
{ L"NC", NC_PNG },
{ L"NE", NE_PNG },
{ L"NF", NF_PNG },
{ L"NG", NG_PNG },
{ L"NI", NI_PNG },
{ L"NL", NL_PNG },
{ L"NO", NO_PNG },
{ L"NP", NP_PNG },
{ L"NR", NR_PNG },
{ L"NU", NU_PNG },
{ L"NZ", NZ_PNG },
{ L"OM", OM_PNG },
{ L"PA", PA_PNG },
{ L"PE", PE_PNG },
{ L"PF", PF_PNG },
{ L"PG", PG_PNG },
{ L"PH", PH_PNG },
{ L"PK", PK_PNG },
{ L"PL", PL_PNG },
{ L"PM", PM_PNG },
{ L"PN", PN_PNG },
{ L"PR", PR_PNG },
{ L"PS", PS_PNG },
{ L"PT", PT_PNG },
{ L"PW", PW_PNG },
{ L"PY", PY_PNG },
{ L"QA", QA_PNG },
{ L"RE", RE_PNG },
{ L"RO", RO_PNG },
{ L"RS", RS_PNG },
{ L"RU", RU_PNG },
{ L"RW", RW_PNG },
{ L"SA", SA_PNG },
{ L"SB", SB_PNG },
{ L"SC", SC_PNG },
{ L"SD", SD_PNG },
{ L"SE", SE_PNG },
{ L"SG", SG_PNG },
{ L"SH", SH_PNG },
{ L"SI", SI_PNG },
{ L"SJ", SJ_PNG },
{ L"SK", SK_PNG },
{ L"SL", SL_PNG },
{ L"SM", SM_PNG },
{ L"SN", SN_PNG },
{ L"SO", SO_PNG },
{ L"SR", SR_PNG },
{ L"ST", ST_PNG },
{ L"SV", SV_PNG },
{ L"SY", SY_PNG },
{ L"SZ", SZ_PNG },
{ L"TC", TC_PNG },
{ L"TD", TD_PNG },
{ L"TF", TF_PNG },
{ L"TG", TG_PNG },
{ L"TH", TH_PNG },
{ L"TJ", TJ_PNG },
{ L"TK", TK_PNG },
{ L"TL", TL_PNG },
{ L"TM", TM_PNG },
{ L"TN", TN_PNG },
{ L"TO", TO_PNG },
{ L"TR", TR_PNG },
{ L"TT", TT_PNG },
{ L"TV", TV_PNG },
{ L"TW", TW_PNG },
{ L"TZ", TZ_PNG },
{ L"UA", UA_PNG },
{ L"UG", UG_PNG },
{ L"UM", UM_PNG },
{ L"US", US_PNG },
{ L"UY", UY_PNG },
{ L"UZ", UZ_PNG },
{ L"VA", VA_PNG },
{ L"VC", VC_PNG },
{ L"VE", VE_PNG },
{ L"VG", VG_PNG },
{ L"VI", VI_PNG },
{ L"VN", VN_PNG },
{ L"VU", VU_PNG },
{ L"WF", WF_PNG },
{ L"WS", WS_PNG },
{ L"YE", YE_PNG },
{ L"YT", YT_PNG },
{ L"ZA", ZA_PNG },
{ L"ZM", ZM_PNG },
{ L"ZW", ZW_PNG }
};
INT LookupResourceCode(
_In_ PPH_STRING Name
)
{
for (INT i = 0; i < ARRAYSIZE(CountryResourceTable); i++)
{
if (PhEqualString2(Name, CountryResourceTable[i].CountryCode, TRUE))
{
return CountryResourceTable[i].ResourceID;
}
}
return 0;
}
HBITMAP LoadImageFromResources(
_In_ UINT Width,
_In_ UINT Height,
_In_ PPH_STRING Name
)
{
UINT frameCount = 0;
BOOLEAN isSuccess = FALSE;
ULONG resourceLength = 0;
HGLOBAL resourceHandle = NULL;
HRSRC resourceHandleSource = NULL;
WICInProcPointer resourceBuffer = NULL;
HDC screenHdc = NULL;
HDC bufferDc = 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 };
INT resourceCode = LookupResourceCode(Name);
if (resourceCode == 0)
return NULL;
__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, MAKEINTRESOURCE(resourceCode), 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_WICPixelFormat32bppPRGBA))
{
wicBitmapSource = (IWICBitmapSource*)wicFrame;
}
else
{
IWICFormatConverter* wicFormatConverter = NULL;
if (FAILED(IWICImagingFactory_CreateFormatConverter(wicFactory, &wicFormatConverter)))
__leave;
if (FAILED(IWICFormatConverter_Initialize(
wicFormatConverter,
(IWICBitmapSource*)wicFrame,
&GUID_WICPixelFormat32bppPRGBA,
WICBitmapDitherTypeNone,
NULL,
0.0,
WICBitmapPaletteTypeCustom
)))
{
IWICFormatConverter_Release(wicFormatConverter);
__leave;
}
// Convert the image to the correct format:
IWICFormatConverter_QueryInterface(wicFormatConverter, &IID_IWICBitmapSource, &wicBitmapSource);
// Cleanup the converter.
IWICFormatConverter_Release(wicFormatConverter);
// Dispose the old frame now that the converted frame is in wicBitmapSource.
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;
screenHdc = CreateIC(L"DISPLAY", NULL, NULL, NULL);
bufferDc = CreateCompatibleDC(screenHdc);
bitmapHandle = CreateDIBSection(screenHdc, &bitmapInfo, DIB_RGB_COLORS, (PVOID*)&bitmapBuffer, NULL, 0);
// 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 (bufferDc)
{
DeleteDC(bufferDc);
}
if (screenHdc)
{
DeleteDC(screenHdc);
}
if (wicBitmapSource)
{
IWICBitmapSource_Release(wicBitmapSource);
}
if (wicStream)
{
IWICStream_Release(wicStream);
}
if (wicDecoder)
{
IWICBitmapDecoder_Release(wicDecoder);
}
if (wicFactory)
{
IWICImagingFactory_Release(wicFactory);
}
if (resourceHandle)
{
FreeResource(resourceHandle);
}
}
if (isSuccess)
return bitmapHandle;
DeleteObject(bitmapHandle);
return NULL;
}