How to list uniquely font names installed on system? - winapi

I'm setting lf.lfFaceName[0] = '\0'; and lf.lfCharSet = DEFAULT_CHARSET; to enumerate uniquely font names installed on system but I'm still getting duplicates. What am I missing? I'm getting duplicates like this:
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
font-name: [Cascadia Mono SemiBold]
I'm enumerating like this:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#pragma comment(lib, "UxTheme.lib")
#pragma comment(lib, "Comdlg32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam);
int CALLBACK enumFontsCallback(const LOGFONT *lpelfe,
const TEXTMETRIC *lpntme,
DWORD FontType,
LPARAM lParam)
{
wprintf(L"font-name: [%s]\r\n", lpelfe->lfFaceName);
return 1;
}
void list()
{
LOGFONT lf = {0};
lf.lfWeight = FW_DONTCARE;
lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfPitchAndFamily = FF_DONTCARE;
lf.lfFaceName[0] = '\0';
HDC dc = GetDC(NULL);
EnumFontFamiliesEx(dc, &lf, (FONTENUMPROC)enumFontsCallback, 0, 0);
ReleaseDC(NULL, dc);
}
int main()
{
list();
return 0;
}

The reason for the duplications is given in the docs under remarks: "EnumFontFamiliesEx will enumerate the same font as many times as there are distinct character sets in the font. [...] To avoid this, an application should filter the list of fonts".
To filter the list down to unique font names, the LPARAM of the callback can be used to build a running list of previously encountered font names, and skip over duplicates.
The EnumFontFamiliesEx call would need to be changed to something like the following.
unordered_set<wstring> wsFonts;
EnumFontFamiliesEx(dc, &lf, (FONTENUMPROC)enumFontsCallback, (LPARAM)&wsFonts, 0);
The callback could then check the current font name against the list.
wstring wsFont = lpelfe->lfFaceName;
if(((unordered_set<wstring> *)lParam)->insert(wsFont).second)
wcout << L"font-name: " << wsFont << endl;
The above assumes C++ for the convenience of std::unordered_set, but could of course be written into plain C using a handcrafted list of unique strings.

Related

GDI+ methods are missing

So I'm trying to use the method Bitmap::GetHistogram from GDI+ but apparently it doesn't exist. I already made sure to initialize everything with
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
at the start of WinMain, here's the problematic snippet:
UINT numEntries;
Gdiplus::Bitmap myBitmap(pszFilePath);
Gdiplus::Image myImage(pszFilePath);
UINT iHeight = myImage.GetHeight(); // works
UINT iWidth = myImage.GetWidth(); // works
myBitmap.GetHistogramSize(HistogramFormatRGB, &numEntries); // not defined
These are all the header files included:
#include <Unknwn.h>
#include <windows.h>
#include <Gdiplus.h>
#include <stdio.h>
#include <iostream>
#include <commdlg.h>
#include <commctrl.h>
#include <winioctl.h>
#include <Objbase.h>
#include <shobjidl.h>
#include <objidl.h>
#include <strsafe.h>
The method simply isn't' there:
What might causing this and how do I fix it?
I'm curious as to why this happened
Because the method needs the GDIPVER >= 0x0110 in gdiplusbitmap.h:
#if (GDIPVER >= 0x0110)
...
inline Status
Bitmap::GetHistogram(
IN HistogramFormat format,
IN UINT NumberOfEntries,
_Out_writes_bytes_(sizeof(UINT)*256) UINT *channel0,
_Out_writes_bytes_(sizeof(UINT)*256) UINT *channel1,
_Out_writes_bytes_(sizeof(UINT)*256) UINT *channel2,
_Out_writes_bytes_(sizeof(UINT)*256) UINT *channel3
)
{
return DllExports::GdipBitmapGetHistogram(
static_cast<GpBitmap *>(nativeImage),
format,
NumberOfEntries,
channel0,
channel1,
channel2,
channel3
);
}
inline Status
Bitmap::GetHistogramSize(
IN HistogramFormat format,
OUT UINT *NumberOfEntries
)
{
return DllExports::GdipBitmapGetHistogramSize(
format,
NumberOfEntries
);
}
#endif // (GDIPVER >= 0x0110)
All recent OS (>= Vista) have GDIPlus 1.1. But if you do not specify GDIPVER to 0x0110 to enable the function of version 1.1, the default version will be specified as 1.0 in gdiplus.h:
// Define the Current GDIPlus Version
#ifndef GDIPVER
#define GDIPVER 0x0100
#endif

How do i get access to a Windows Whiteboard application and track Pen and Touch Input

I would like to track various input interactions (Pen, Touch and Mouse) of users with a Microsoft Whiteboard application. Is there a way without hooking the application and using WM_POINTER Messages? (Because for some reason i can not make this work)
Programming language is not really important for me.
DLL Code:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#pragma data_seg("Shared")
#pragma data_seg()
#pragma comment(linker,"/section:Shared,rws")
#include <windows.h>
#include <stdio.h>
HHOOK global;
extern "C" __declspec(dllexport) LRESULT WINAPI procedure(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION) {
//lets extract the data
CWPSTRUCT* data = (CWPSTRUCT*)lParam;
if (data->message == WM_CLOSE) {
//lets get the name of the program closed
char name[260];
GetWindowModuleFileNameA(data->hwnd, name, 260);
//extract only the exe from the path
char* extract = (char*)((DWORD)name + lstrlenA(name) - 1);
while (*extract != '\\')
extract--;
extract++;
MessageBoxA(0, "A program has been closed", extract, 0);
}
}
return CallNextHookEx(global, nCode, wParam, lParam);
}
Python Code(Which should receive data like when and where it was touched from dll):
import ctypes
import os
from ctypes import *
from ctypes.wintypes import *
user32 = WinDLL('user32', use_last_error=True)
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
user32.SetWindowsHookExA.errcheck = errcheck_bool
user32.SetWindowsHookExA.restype = HHOOK
user32.SetWindowsHookExA.argtypes = (c_int, # _In_ idHook
HOOKPROC, # _In_ lpfn
HINSTANCE, # _In_ hMod
DWORD) # _In_ dwThreadId
user32.CallNextHookEx.restype = LRESULT
user32.CallNextHookEx.argtypes = (HHOOK, # _In_opt_ hhk
c_int, # _In_ nCode
WPARAM, # _In_ wParam
LPARAM) # _In_ lParam
user32.GetMessageW.argtypes = (LPMSG, # _Out_ lpMsg
HWND, # _In_opt_ hWnd
UINT, # _In_ wMsgFilterMin
UINT) # _In_ wMsgFilterMax
user32.TranslateMessage.argtypes = (LPMSG,)
user32.DispatchMessageW.argtypes = (LPMSG,)
GetModuleHandle = ctypes.windll.kernel32.GetModuleHandleA
GetModuleHandle.restype = POINTER(c_void_p)
#LoadLibrary = ctypes.windll.kernel32.LoadLibraryA
#LoadLibrary.argtypes = [c_wchar_p]
#LoadLibrary.restype = c_int
GetProcAddress = ctypes.windll.kernel32.GetProcAddress
GetProcAddress.restype = HOOKPROC
def pointer_msg_loop():
dll_name = 'Dll.dll'
dll_abspath = os.path.abspath(os.path.join(os.path.dirname(__file__), '.', dll_name))
print(dll_abspath)
lib = kernel32.LoadLibraryA(dll_abspath.encode(encoding='ascii'))
handle = GetModuleHandle(dll_abspath.encode(encoding='ascii'))
print(lib)
print(handle)
procedure = GetProcAddress(handle, "procedure")
print(procedure)
if (procedure):
print('correct value procedure')
tHook = user32.SetWindowsHookExW(WH_CALLWNDPROC, procedure, lib, 0)
print(ctypes.WinError(GetLastError()))
print(tHook)
print(ctypes.WinError(GetLastError()))
msg = MSG()
while True:
bRet = user32.GetMessageW(byref(msg), None, 0, 0)
if not bRet:
break
if bRet == -1:
raise WinError(get_last_error())
user32.TranslateMessage(byref(msg))
user32.DispatchMessageW(byref(msg))
1: Added a working example, which i want to transform to listen to my Microsoft Whiteboard window.
2: Added a dll solution from another example (Does not work)

Step from CertEnumSystemStoreLocation() to CertEnumSystemStore()

My question is about cryptoAPI interface.
Look, CertEnumSystemStoreLocation() is a function to enumerate all certificate store locations available in system. It returns (using callback) enumerated location as wide string (LPCWSTR).
CertEnumSystemStore() enumerates stores by the given location. It takes integer constant for location (DWORD) as argument.
I tried to enumerate locations and the result was a list of strings, that semantically is equal to the list of DWORD location constants from CryptoAPI import module.
And my question is: what should i do to translate wide string representation of store location to DWORD constant? Is there a cryptoAPI function (or, at least, commonly used method) for it?
It looks like the dwFlags passed to your CertEnumSystemStoreLocationCallback callback function actually gives you the store location constant, although this is incredibly badly documented.
The example shown here for Listing System and Physical Stores handles the dwFlags value in its callback like this:
dwFlags &= CERT_SYSTEM_STORE_MASK;
dwFlags |= pEnumArg->dwFlags & ~CERT_SYSTEM_STORE_LOCATION_MASK;
CertEnumSystemStore(dwFlags, ...);
So I think if you do that masking you'll be left with the location constant in dwFlags equivalent to the string passed in the pvszStoreLocation parameter.
The dwFlags argument passed to the CertEnumSystemStoreLocationCallback callback function contains the store location encoded in the bits CERT_SYSTEM_STORE_LOCATION_MASK. Shifting those to the right by CERT_SYSTEM_STORE_LOCATION_SHIFT turns it into the numeric store ID.
The following code retrieves the list of store locations alongside the numeric store IDs:
Structure for communication:
#include <SDKDDKVer.h>
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "Crypt32.lib")
#include <vector>
#include <string>
#include <iostream>
struct Location {
DWORD StoreId;
std::wstring Name;
};
typedef std::vector<Location> StoreLocationsContainer;
Callback:
BOOL WINAPI CertEnumSystemStoreLocationCallback( LPCWSTR pvszStoreLocations,
DWORD dwFlags,
void* pvReserved,
void* pvArg
) {
StoreLocationsContainer& locations = *reinterpret_cast<StoreLocationsContainer*>( pvArg );
DWORD StoreId = ( dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK )
>> CERT_SYSTEM_STORE_LOCATION_SHIFT;
Location location = { StoreId, std::wstring( pvszStoreLocations ) };
locations.push_back( location );
return TRUE;
}
Implementation:
StoreLocationsContainer GetStoreLocations() {
StoreLocationsContainer locations;
if ( !::CertEnumSystemStoreLocation( 0x0,
&locations,
CertEnumSystemStoreLocationCallback ) ) {
throw std::runtime_error( "CertEnumSystemStoreLocation" );
}
return locations;
}
For completeness, here is the remaining code to dump all stores across all locations:
BOOL WINAPI CertEnumSystemStoreCallback( const void* pvSystemStore,
DWORD dwFlags,
PCERT_SYSTEM_STORE_INFO pStoreInfo,
void* pvReserved,
void* pvArg ) {
std::wcout << L" " << static_cast<const wchar_t*>( pvSystemStore ) << std::endl;
return TRUE;
}
void PrintStores( const StoreLocationsContainer& locations ) {
for ( const Location& loc : locations ) {
std::wcout << loc.Name << std::endl;
DWORD dwFlags = ( loc.StoreId << CERT_SYSTEM_STORE_LOCATION_SHIFT )
& CERT_SYSTEM_STORE_LOCATION_MASK;
::CertEnumSystemStore( dwFlags, nullptr, nullptr, CertEnumSystemStoreCallback );
}
}
int main() {
StoreLocationsContainer locations = GetStoreLocations();
PrintStores( locations );
return 0;
}

Compiler cannot convert the arguments passed to swprintf function, winapi

can you help me with this code? I cannot fix it. There is problem with swprintf function.
LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
LPTSTR strPrincipal = new TCHAR[20],
strInterest = new TCHAR[20], strPeriods = new TCHAR[20],
strInterestEarned = new TCHAR[20], strAmountEarned = new TCHAR[20];
double Principal, AnnualRate, InterestEarned;
double FutureValue, RatePerPeriod;
int NumberOfPeriods, CompoundType;
double i;
int n;
swprintf(strInterestEarned, "$%.2f", InterestEarned);
swprintf(strAmountEarned, "$%.2f", FutureValue);
}
Here are errors:
Error 1 error C2665: 'swprintf' : none of the 2 overloads could convert all the argument types
Error 2 error C2665: 'swprintf' : none of the 2 overloads could convert all the argument types
I think you've got your parameters wrong / in the wrong order. Have you checked the MSDN page?
Method signature:
int swprintf(
wchar_t *buffer,
size_t count,
const wchar_t *format [,
argument]...
);
That page gives the following example for swprintf:
// crt_swprintf.c
// wide character example
// also demonstrates swprintf returning error code
#include <stdio.h>
int main( void )
{
wchar_t buf[100];
int len = swprintf( buf, 100, L"%s", L"Hello world" );
printf( "wrote %d characters\n", len );
len = swprintf( buf, 100, L"%s", L"Hello\xffff world" );
// swprintf fails because string contains WEOF (\xffff)
printf( "wrote %d characters\n", len );
}
I think you'd want something along the lines of:
swprintf( strInterestEarned, 20, L"%.2f", InterestEarned );

how to build an executable without import table in c/c++?

I found a tool to repair import table here, but how are PE executable without import table built in the first place in c/c++?
Just don't use CRT, and don't use any imported functions.
#pragma comment(linker, "/entry:start")
int start()
{
return 42;
}
To use WinAPI functions, find kernel32 base, parse it's export directory and find LoadLibrary() function (you should already have something like GetProcAddress() to find LoadLibrary())
This may looks like this:
// compile as console application, "release" configuration with /MT /GS-
#include <Windows.h>
#pragma comment(linker, "/entry:start")
void start()
{
HMODULE kernel32base = *(HMODULE*)(*(DWORD*)(*(DWORD*)(*(DWORD*)(*(DWORD*)(__readfsdword(0x30) + 0x0C) + 0x14))) + 0x10);
DWORD base = (DWORD)kernel32base;
IMAGE_NT_HEADERS* pe = PIMAGE_NT_HEADERS(base + PIMAGE_DOS_HEADER(base)->e_lfanew);
IMAGE_EXPORT_DIRECTORY* exportDir = PIMAGE_EXPORT_DIRECTORY(base + pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD* namePtr = (DWORD*)(base + exportDir->AddressOfNames);
WORD* ordPtr = (WORD*)(base + exportDir->AddressOfNameOrdinals);
for(; strcmp((const char*)(base + *namePtr), "GetProcAddress"); ++namePtr, ++ordPtr)
;
DWORD funcRVA = *(DWORD*)(base + exportDir->AddressOfFunctions + *ordPtr * 4);
typedef FARPROC (WINAPI *GetProcAddress_t)(HMODULE, const char*);
GetProcAddress_t GetProcAddress = (GetProcAddress_t)(base + funcRVA);
HANDLE (WINAPI *GetStdHandle)(DWORD);
*(FARPROC*)&GetStdHandle = GetProcAddress(kernel32base, "GetStdHandle");
HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
BOOL (WINAPI *WriteFile)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
*(FARPROC*)&WriteFile = GetProcAddress(kernel32base, "WriteFile");
const char* greeting = "Hello world!\n";
DWORD written;
WriteFile(stdout, greeting, strlen(greeting), &written, NULL);
}
To strip imports from existing executable module, you should parse it's imports directory to get its imports, then generate and add a code to get those imports, then remove imports directory.

Resources