wip: ini parse baseline

This commit is contained in:
Hane 2024-12-03 21:13:42 +01:00
commit 8e07b1efdd
9 changed files with 356 additions and 27 deletions

208
src/settings.cpp Normal file
View file

@ -0,0 +1,208 @@
#include "settings.h"
#include "msinclude.h"
namespace ini {
UserSettings::UserSettings(char* path) {
wchar_t* settingsPath = nullptr;
wchar_t settingsFile[] = L"\\settings.ini";
uint32_t settingsFileLen = (sizeof(settingsFile) / sizeof(wchar_t)) - 1;
wchar_t maxPathBypass[] = L"\\\\?\\";
log_wdebugcpp(L"Bypass size: " + std::to_wstring((sizeof(maxPathBypass)/sizeof(maxPathBypass[0]))));
//Executable dir
settingsPath = (wchar_t*)calloc(UNICODE_STRING_MAX_CHARS, sizeof(wchar_t));
uint32_t exePathLength = GetModuleFileNameW(
NULL,
settingsPath,
UNICODE_STRING_MAX_CHARS
);
//reverse wcsstr
while(exePathLength >= 0) {
if(settingsPath[exePathLength] == '\\') {
memset(settingsPath + exePathLength,
0,
(UNICODE_STRING_MAX_CHARS - exePathLength) * sizeof(wchar_t));
break;
} else exePathLength--;
}
log_wdebugcpp(L"Exe folder: " + std::wstring(settingsPath));
HANDLE settingsHandle = nullptr;
if((UNICODE_STRING_MAX_CHARS - exePathLength) > (settingsFileLen + 1)) {
memcpy(settingsPath + exePathLength, settingsFile, sizeof(wchar_t) * settingsFileLen);
settingsHandle = CreateFile2(
settingsPath,
GENERIC_READ | GENERIC_WRITE,
0,
OPEN_ALWAYS,
NULL);
if(settingsHandle != INVALID_HANDLE_VALUE) { log_debugcpp("Filecreated!"); }
else { CloseHandle(settingsHandle); settingsHandle = nullptr; return; }
}
//Calculating file size and reading file
if(settingsHandle) {
uint64_t fileSize;
LARGE_INTEGER fileSizeStruct;
if(!GetFileSizeEx(settingsHandle, &fileSizeStruct)) return;
fileSize = fileSizeStruct.QuadPart;
uint32_t bytesRead = 0;
textContentsSize = fileSize + 1;
textContents = (char*)calloc(textContentsSize, sizeof(char));
if (ReadFile(settingsHandle, textContents, fileSize,
(LPDWORD)&bytesRead, NULL) != TRUE) {
free(textContents);
return;
}
//textContents.assign(tempTextContents);
//free(tempTextContents);
//Parsing values
bool isCRLF = false;
char *curLine = textContents;
char *separator = nullptr, *key = nullptr, *value = nullptr;
while(curLine) {
char* nextLine = strchr(curLine, '\n');
if(nextLine == curLine + 1 || nextLine == curLine + 2) goto nextIteration;
if (nextLine && (isCRLF || *(nextLine - 1) == '\r')) {
isCRLF = true;
*(nextLine - 1) = '\0';
} else if (nextLine) *nextLine = '\0'; // temporarily terminate the current line
log_debugcpp("curLine: " + std::string(curLine) + " ");
separator = strchr(curLine, '=');
if(!separator) goto nextIteration;
*separator = '\0';
key = trimAndAllocate(curLine);
value = trimAndAllocate(separator + 1);
values.try_emplace(key, value);
log_debugcpp("ini Map size: " + std::to_string(values.size()));
*separator = '=';
nextIteration:
if (nextLine) { // then restore newline-char, just to be tidy
if (isCRLF)
*(nextLine - 1) = '\r';
else *nextLine = '\n';
}
curLine = nextLine ? (nextLine + 1) : NULL;
}
/*
* for(const std::pair<char[], int> keyVal : defaultValues) {
* if (textContents.find(keyVal.first) {
* if (keyVal.
* }
* }
*/
}
}
//todo: buffer overflow. poc
char* const UserSettings::getValue(char* key, uint64_t len) {
if (auto search = values.find(key); search != values.end())
return (char* const) search->second;
return nullptr;
}
void UserSettings::setValue(char* key, char* value, uint64_t valueSize, uint64_t keySize) {
char *newValue, *newKey;
if (auto search = values.find(key); search != values.end()) {
if(!(strcmp(value, search->second))) return;
newValue = (char*)calloc(valueSize, sizeof(char));
if (!(search->second == pos || search->second == neg)) {
free(search->second);
}
search->second = newValue;
return;
}
newValue = (char*)calloc(valueSize, sizeof(char));
newKey = (char*)calloc(keySize, sizeof(char));
values.insert(std::make_pair(newKey, newValue));
return;
}
void UserSettings::setValue(char* key, bool value, uint64_t keySize) {
char *newKey;
log_debugcpp("Pos value: " + std::to_string((intptr_t)pos));
log_debugcpp("Neg value: " + std::to_string((intptr_t)neg));
if (auto search = values.find(key); search != values.end()) {
log_debugcpp("Previous value: " + std::to_string((intptr_t)values[key]));
if (!(search->second == pos || search->second == neg)) {
free(search->second);
}
if (value)
search->second = pos;
else search->second = neg;
return;
}
newKey = (char*)calloc(keySize, sizeof(char));
values.insert(std::make_pair(newKey, value ? pos : neg));
return;
}
//AppData path
/*
* wchar_t folderPath[] = L"\\mixerq";
*
* wchar_t* roamingPath = nullptr;
* if(SHGetKnownFolderPath(
* FOLDERID_RoamingAppData,
* 0,
* NULL,
* &roamingPath)
* == S_OK) {
* uint32_t pathLen = 0;
* wchar_t currentChar = roamingPath[pathLen];
* while(currentChar != '\0') {
* pathLen++;
* currentChar = roamingPath[pathLen];
* }
*
* uint32_t maxPathBypassLen = (sizeof(maxPathBypass)/ sizeof(wchar_t)) - 1;
* uint32_t folderPathLen = (sizeof(folderPath) / sizeof(wchar_t)) - 1;
* settingsPath = (wchar_t*)calloc(pathLen +
* maxPathBypassLen +
* folderPathLen +
* settingsFileLen,
* sizeof(wchar_t));
* memcpy(settingsPath, maxPathBypass, sizeof(wchar_t) * maxPathBypassLen);
* memcpy(settingsPath + (maxPathBypassLen), roamingPath, sizeof(wchar_t) * pathLen);
* CoTaskMemFree(roamingPath);
* memcpy(settingsPath + (maxPathBypassLen + pathLen),
* folderPath, sizeof(wchar_t) * folderPathLen);
* log_wdebugcpp(L"Settings folder path: " + std::wstring(settingsPath));
*
* if(CreateDirectoryW(settingsPath, NULL) || GetLastError() == ERROR_ALREADY_EXISTS) {
* memcpy(settingsPath + (maxPathBypassLen + pathLen + folderPathLen),
* settingsFile, sizeof(wchar_t) * settingsFileLen);
*
* HANDLE settingsHandle = CreateFile2(
* settingsPath,
* GENERIC_READ | GENERIC_WRITE,
* 0,
* OPEN_ALWAYS,
* NULL);
* if(settingsHandle != INVALID_HANDLE_VALUE) log_debugcpp("Filecreated!");
*
* }
* //End AppData
*/
UserSettings::~UserSettings() {
if(textContents) free(textContents);
for(std::pair<char*, char*> entry : values) {
free(entry.first);
free(entry.second);
}
}
}