Files
nt-lite/code/kernel/ke_settings.c
T

95 lines
2.6 KiB
C

// Kernel settings reader. This file loads simple runtime settings from the system configuration file.
// 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 <kernel/ke_settings.h>
#include <kernel/io_file.h>
#include <kernel/mm_virt.h>
#include <common/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;
}