95 lines
2.6 KiB
C
95 lines
2.6 KiB
C
// ke_settings.c - small system/settings.ini reader.
|
|
//
|
|
// This intentionally exposes generic string settings only. Subsystems and
|
|
// drivers own the policy for interpreting their sections.
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include <ke_settings.h>
|
|
#include <io_file.h>
|
|
#include <mm_virt.h>
|
|
#include <ini_parser.h>
|
|
|
|
#define KE_SETTINGS_MAX_FILE_BYTES (64u * 1024u)
|
|
|
|
typedef struct KE_FIND_SETTING_CTX {
|
|
const char* Section;
|
|
const char* Key;
|
|
char* Buffer;
|
|
size_t BufferSize;
|
|
KSTATUS Status;
|
|
} KE_FIND_SETTING_CTX;
|
|
|
|
static void KeFindSettingCallback(const char* section, const char* key,
|
|
const char* value, void* userdata) {
|
|
KE_FIND_SETTING_CTX* ctx = (KE_FIND_SETTING_CTX*)userdata;
|
|
if (!ctx || ctx->Status != STATUS_NOT_FOUND)
|
|
return;
|
|
if (!section || !key || !value)
|
|
return;
|
|
if (strcmp(section, ctx->Section) != 0 || strcmp(key, ctx->Key) != 0)
|
|
return;
|
|
|
|
size_t len = strlen(value);
|
|
if (len + 1 > ctx->BufferSize) {
|
|
if (ctx->BufferSize)
|
|
ctx->Buffer[0] = '\0';
|
|
ctx->Status = STATUS_BUFFER_TOO_SMALL;
|
|
return;
|
|
}
|
|
|
|
memcpy(ctx->Buffer, value, len + 1);
|
|
ctx->Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
__declspec(dllexport) KSTATUS KeGetSettingString(const char* section,
|
|
const char* key,
|
|
char* buffer,
|
|
size_t bufferSize) {
|
|
if (!section || !*section || !key || !*key || !buffer || bufferSize == 0)
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
buffer[0] = '\0';
|
|
|
|
FILE_OBJECT* file = NULL;
|
|
KSTATUS st = IoOpenFile(SYS_SV_LITERAL(KE_SETTINGS_PATH), &file);
|
|
if (!KSUCCESS(st))
|
|
return st;
|
|
|
|
uint64_t fileSize64 = IoGetFileSize(file);
|
|
if (fileSize64 >= KE_SETTINGS_MAX_FILE_BYTES) {
|
|
IoCloseFile(file);
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
size_t fileSize = (size_t)fileSize64;
|
|
char* text = (char*)MmAllocatePool(fileSize + 1);
|
|
if (!text) {
|
|
IoCloseFile(file);
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
size_t got = 0;
|
|
st = IoReadFile(file, text, fileSize, &got);
|
|
IoCloseFile(file);
|
|
if (!KSUCCESS(st)) {
|
|
MmFreePool(text);
|
|
return st;
|
|
}
|
|
|
|
text[got] = '\0';
|
|
|
|
KE_FIND_SETTING_CTX ctx;
|
|
ctx.Section = section;
|
|
ctx.Key = key;
|
|
ctx.Buffer = buffer;
|
|
ctx.BufferSize = bufferSize;
|
|
ctx.Status = STATUS_NOT_FOUND;
|
|
|
|
IniParse(text, KeFindSettingCallback, &ctx);
|
|
MmFreePool(text);
|
|
return ctx.Status;
|
|
}
|