wip: settings in effect

This commit is contained in:
Hane 2024-12-06 17:55:46 +01:00
commit 1ae324b68a
8 changed files with 277 additions and 158 deletions

View file

@ -3,100 +3,48 @@
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]))));
wchar_t* utf8toUtf16(const char* str) {
if(!str || str[0] == '\0') return nullptr;
int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
wchar_t* utf16 = (wchar_t*)calloc(sizeNeeded, 1);
MultiByteToWideChar(CP_UTF8, 0, str, -1, utf16, sizeNeeded);
return utf16;
}
//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));
UserSettings::UserSettings(char* textContents) {
//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) + " ");
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; }
}
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 = '=';
//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;
nextIteration:
if (nextLine) { // then restore newline-char, just to be tidy
if (isCRLF)
*(nextLine - 1) = '\r';
else *nextLine = '\n';
}
//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.
* }
* }
*/
curLine = nextLine ? (nextLine + 1) : NULL;
}
free(textContents);
}
//todo: buffer overflow. poc
@ -139,70 +87,68 @@ namespace ini {
return;
}
newKey = (char*)calloc(keySize, sizeof(char));
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);
if (!(entry.second == pos || entry.second == neg))
free(entry.second);
}
}
UserSettings::~UserSettings() {
if(textContents) free(textContents);
for(std::pair<char*, char*> entry : values) {
free(entry.first);
free(entry.second);
UserSettings* UserSettings::createSettings(const char* path, bool create) {
if(!path) return nullptr;
wchar_t* utf16Path = utf8toUtf16(path);
if(!utf16Path) return nullptr;
#define releaseBeforeReturn() do { \
CloseHandle(settingsHandle); \
settingsHandle = nullptr; \
free(utf16Path); \
} while(0)
char* textContents;
HANDLE settingsHandle = nullptr;
settingsHandle = CreateFile2(
utf16Path,
GENERIC_READ | GENERIC_WRITE,
0,
(create ? OPEN_ALWAYS : OPEN_EXISTING),
NULL);
if(settingsHandle == INVALID_HANDLE_VALUE) {
releaseBeforeReturn();
return nullptr;
}
//Calculating file size and reading file
uint64_t fileSize;
LARGE_INTEGER fileSizeStruct;
if(!GetFileSizeEx(settingsHandle, &fileSizeStruct)) {
releaseBeforeReturn();
return nullptr;
}
fileSize = fileSizeStruct.QuadPart;
uint32_t bytesRead = 0;
uint64_t textContentsSize = fileSize + 1;
textContents = (char*)calloc(textContentsSize, sizeof(char));
if (ReadFile(settingsHandle, textContents, fileSize,
(LPDWORD)&bytesRead, NULL) != TRUE) {
releaseBeforeReturn();
return nullptr;
}
releaseBeforeReturn();
return new UserSettings(textContents);
//textContents.assign(tempTextContents);
//free(tempTextContents);
#undef releaseBeforeReturn
}
}
}