Common (Windows): adds a unique type for querying registry binary data

This commit is contained in:
李通洲
2026-03-24 16:09:25 +08:00
parent 339de56407
commit 246ff0bc88
6 changed files with 87 additions and 60 deletions
+13 -2
View File
@@ -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) }
+7
View File
@@ -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);
+41 -36
View File
@@ -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;
}
+3 -3
View File
@@ -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);
}