mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Common (Windows): adds a unique type for querying registry binary data
This commit is contained in:
+13
-2
@@ -2,6 +2,15 @@
|
||||
|
||||
#include "common/FFstrbuf.h"
|
||||
|
||||
// For ffRegReadValue(s)
|
||||
// If length is 0, data will be allocated with malloc() and must be freed by the caller
|
||||
// Otherwise, data must point to a buffer of at least length bytes, and the actual length of the data will be written to length.
|
||||
typedef struct FFArgBuffer
|
||||
{
|
||||
void* data;
|
||||
uint32_t length;
|
||||
} FFArgBuffer;
|
||||
|
||||
typedef enum __attribute__((__packed__)) FFArgType
|
||||
{
|
||||
FF_ARG_TYPE_NULL = 0,
|
||||
@@ -15,7 +24,8 @@ typedef enum __attribute__((__packed__)) FFArgType
|
||||
FF_ARG_TYPE_FLOAT,
|
||||
FF_ARG_TYPE_DOUBLE,
|
||||
FF_ARG_TYPE_LIST,
|
||||
FF_ARG_TYPE_BOOL
|
||||
FF_ARG_TYPE_BOOL,
|
||||
FF_ARG_TYPE_BUFFER,
|
||||
} FFArgType;
|
||||
|
||||
#define FF_ARG(variable, var_name) { _Generic((variable), \
|
||||
@@ -30,5 +40,6 @@ typedef enum __attribute__((__packed__)) FFArgType
|
||||
float: FF_ARG_TYPE_FLOAT, \
|
||||
double: FF_ARG_TYPE_DOUBLE, \
|
||||
FFlist: FF_ARG_TYPE_LIST, \
|
||||
bool: FF_ARG_TYPE_BOOL \
|
||||
bool: FF_ARG_TYPE_BOOL, \
|
||||
FFArgBuffer: FF_ARG_TYPE_BUFFER \
|
||||
), _Generic((variable), char*: (variable), const char*: (variable), default: &(variable) ), (var_name) }
|
||||
|
||||
@@ -51,6 +51,13 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FF_ARG_TYPE_BUFFER:
|
||||
{
|
||||
// Placeholder for binary data, just print the size for now
|
||||
const FFArgBuffer* argBuffer = (const FFArgBuffer*) formatarg->value;
|
||||
ffStrbufAppendF(buffer, "buffer(%u bytes)", argBuffer->length);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if(formatarg->type != FF_ARG_TYPE_NULL)
|
||||
fprintf(stderr, "Error: format string \"%s\": argument is not implemented: %i\n", buffer->chars, formatarg->type);
|
||||
|
||||
@@ -180,51 +180,56 @@ static bool processRegValue(const FFRegValueArg* arg, const ULONG regType, const
|
||||
|
||||
case FF_ARG_TYPE_LIST:
|
||||
{
|
||||
if (regType != REG_MULTI_SZ && regType != REG_BINARY)
|
||||
if (regType != REG_MULTI_SZ)
|
||||
goto type_mismatch;
|
||||
|
||||
FFlist* list = (FFlist*) arg->value;
|
||||
if (list->elementSize != sizeof(FFstrbuf))
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY nameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
|
||||
ffStrbufAppendF(error, "ffRegReadValues(%s) type mismatch: expected list of strbuf for REG_MULTI_SZ", nameA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ffListClear(list);
|
||||
|
||||
if (regType == REG_MULTI_SZ)
|
||||
for (
|
||||
const wchar_t* ptr = (const wchar_t*) regData;
|
||||
(const uint8_t*) ptr < (const uint8_t*) regData + regDataLen && *ptr;
|
||||
ptr++
|
||||
)
|
||||
{
|
||||
if (list->elementSize != sizeof(FFstrbuf))
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY nameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
|
||||
ffStrbufAppendF(error, "ffRegReadValues(%s) type mismatch: expected list of strbuf for REG_MULTI_SZ", nameA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (
|
||||
const wchar_t* ptr = (const wchar_t*) regData;
|
||||
(const uint8_t*) ptr < (const uint8_t*) regData + regDataLen && *ptr;
|
||||
ptr++
|
||||
)
|
||||
{
|
||||
uint32_t strLen = (uint32_t) wcsnlen(ptr, regDataLen / sizeof(wchar_t) - (size_t) (ptr - (const wchar_t*) regData));
|
||||
ffStrbufInitNWS(FF_LIST_ADD(FFstrbuf, *list), strLen, ptr);
|
||||
ptr += strLen;
|
||||
}
|
||||
uint32_t strLen = (uint32_t) wcsnlen(ptr, regDataLen / sizeof(wchar_t) - (size_t) (ptr - (const wchar_t*) regData));
|
||||
ffStrbufInitNWS(FF_LIST_ADD(FFstrbuf, *list), strLen, ptr);
|
||||
ptr += strLen;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
case FF_ARG_TYPE_BUFFER:
|
||||
{
|
||||
if (regType != REG_BINARY)
|
||||
goto type_mismatch;
|
||||
|
||||
FFArgBuffer* buffer = (FFArgBuffer*) arg->value;
|
||||
if (buffer->length == 0)
|
||||
{
|
||||
if (list->elementSize != sizeof(uint8_t))
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY nameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
|
||||
ffStrbufAppendF(error, "ffRegReadValues(%s) type mismatch: expected list of uint8_t for REG_BINARY", nameA.chars);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ffListReserve(list, regDataLen);
|
||||
memcpy(list->data, regData, regDataLen);
|
||||
list->length = regDataLen;
|
||||
buffer->data = malloc(regDataLen);
|
||||
}
|
||||
else if (buffer->length < regDataLen)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY nameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
|
||||
ffStrbufAppendF(error, "ffRegReadValues(%s) buffer too small (%u): expected %u", nameA.chars, (unsigned) buffer->length, (unsigned) regDataLen);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
buffer->length = regDataLen;
|
||||
memcpy(buffer->data, regData, regDataLen);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,11 +58,11 @@ static inline bool ffRegReadUint64(HANDLE hKey, const wchar_t* valueNameW, uint6
|
||||
.name = valueNameW,
|
||||
}, error);
|
||||
}
|
||||
static inline bool ffRegReadData(HANDLE hKey, const wchar_t* valueNameW, FFlist* result /*list of uint8_t*/, FFstrbuf* error)
|
||||
static inline bool ffRegReadData(HANDLE hKey, const wchar_t* valueNameW, FFArgBuffer* buffer, FFstrbuf* error)
|
||||
{
|
||||
return ffRegReadValue(hKey, &(FFRegValueArg) {
|
||||
.type = FF_ARG_TYPE_LIST,
|
||||
.value = result,
|
||||
.type = FF_ARG_TYPE_BUFFER,
|
||||
.value = buffer,
|
||||
.name = valueNameW,
|
||||
}, error);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,15 @@
|
||||
#include <windows.h>
|
||||
#include <shellscalingapi.h>
|
||||
|
||||
static inline void freeArgBuffer(FFArgBuffer* buffer)
|
||||
{
|
||||
if (buffer->data)
|
||||
free(buffer->data);
|
||||
buffer->data = NULL;
|
||||
buffer->length = 0;
|
||||
}
|
||||
#define FF_AUTO_FREE_ARG_BUFFER __attribute__((__cleanup__(freeArgBuffer)))
|
||||
|
||||
// http://undoc.airesoft.co.uk/user32.dll/IsThreadDesktopComposited.php
|
||||
BOOL WINAPI IsThreadDesktopComposited();
|
||||
BOOL WINAPI GetDpiForMonitorInternal(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT* dpiX, UINT* dpiY);
|
||||
@@ -41,8 +50,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
.id = path->targetInfo.id,
|
||||
},
|
||||
};
|
||||
FF_LIST_AUTO_DESTROY edid = ffListCreate(sizeof(uint8_t));
|
||||
|
||||
FF_AUTO_FREE_ARG_BUFFER FFArgBuffer edid = {};
|
||||
if(DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t regPath[256] = L"SYSTEM\\CurrentControlSet\\Enum";
|
||||
@@ -70,7 +78,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
}
|
||||
else
|
||||
{
|
||||
ffListClear(&edid);
|
||||
edid.length = 0;
|
||||
if (targetName.flags.friendlyNameFromEdid)
|
||||
ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName);
|
||||
else
|
||||
|
||||
@@ -24,35 +24,31 @@ static void generateString(FFFontResult* font)
|
||||
ffStrbufAppendC(&font->display, ']');
|
||||
}
|
||||
|
||||
WINUSERAPI WINBOOL WINAPI ClassicSystemParametersInfoW(UINT uiAction,UINT uiParam,PVOID pvParam,UINT fWinIni);
|
||||
|
||||
const char* ffDetectFontImpl(FFFontResult* result)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD HANDLE hKey = NULL;
|
||||
if (!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Desktop\\WindowMetrics", &hKey, NULL))
|
||||
return "ffRegOpenKeyForRead(HKEY_CURRENT_USER\\Control Panel\\Desktop\\WindowMetrics) failed";
|
||||
|
||||
FF_LIST_AUTO_DESTROY CaptionFont = ffListCreate(sizeof(uint8_t));
|
||||
FF_LIST_AUTO_DESTROY MenuFont = ffListCreate(sizeof(uint8_t));
|
||||
FF_LIST_AUTO_DESTROY MessageFont = ffListCreate(sizeof(uint8_t));
|
||||
FF_LIST_AUTO_DESTROY StatusFont = ffListCreate(sizeof(uint8_t));
|
||||
LOGFONTW fonts[4];
|
||||
FFArgBuffer fontBuffers[4] = {
|
||||
{ .data = &fonts[0], .length = sizeof(fonts[0]) },
|
||||
{ .data = &fonts[1], .length = sizeof(fonts[1]) },
|
||||
{ .data = &fonts[2], .length = sizeof(fonts[2]) },
|
||||
{ .data = &fonts[3], .length = sizeof(fonts[3]) },
|
||||
};
|
||||
|
||||
if (!ffRegReadValues(hKey, 4, (FFRegValueArg[]) {
|
||||
FF_ARG(CaptionFont, L"CaptionFont"),
|
||||
FF_ARG(MenuFont, L"MenuFont"),
|
||||
FF_ARG(MessageFont, L"MessageFont"),
|
||||
FF_ARG(StatusFont, L"StatusFont"),
|
||||
FF_ARG(fontBuffers[0], L"CaptionFont"),
|
||||
FF_ARG(fontBuffers[1], L"MenuFont"),
|
||||
FF_ARG(fontBuffers[2], L"MessageFont"),
|
||||
FF_ARG(fontBuffers[3], L"StatusFont"),
|
||||
}, NULL))
|
||||
return "ffRegReadValues(HKEY_CURRENT_USER\\Control Panel\\Desktop\\WindowMetrics) failed";
|
||||
|
||||
FFlist* fonts[4] = { &CaptionFont, &MenuFont, &MessageFont, &StatusFont };
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(fonts); ++i)
|
||||
{
|
||||
if (fonts[i]->length < sizeof(LOGFONTW))
|
||||
continue;
|
||||
|
||||
LOGFONTW* logFont = (LOGFONTW*) fonts[i]->data;
|
||||
LOGFONTW* logFont = &fonts[i];
|
||||
|
||||
ffStrbufSetWS(&result->fonts[i], logFont->lfFaceName);
|
||||
if (logFont->lfHeight < 0)
|
||||
|
||||
Reference in New Issue
Block a user