set: fix wrong save path / fixed null deref / more env refactor

This commit is contained in:
Hane 2025-01-07 18:53:17 +01:00
commit c87c8d0990
5 changed files with 117 additions and 119 deletions

View file

@ -3,101 +3,6 @@
using namespace Environment; using namespace Environment;
wchar_t* getExeAbsPath(uint32_t *exeAbsPathLength) {
wchar_t *exeAbsPath = (wchar_t*)calloc(UNICODE_STRING_MAX_CHARS, sizeof(wchar_t));
*exeAbsPathLength = GetModuleFileNameW(
NULL,
exeAbsPath,
UNICODE_STRING_MAX_CHARS
);
return exeAbsPath;
}
std::string getSettingsPath(SettingsTargetDirectory target, bool create) {
wchar_t* settingsPath = nullptr;
wchar_t settingsFile[] = L"\\settings.ini";
uint32_t settingsFileLen = (sizeof(settingsFile) / sizeof(wchar_t)) - 1;
wchar_t maxPathBypass[] = L"\\\\?\\";
uint32_t exePathLength = 0;
wchar_t folderPath[] = L"\\mixerq";
uint32_t maxPathBypassLen = (sizeof(maxPathBypass)/ sizeof(wchar_t)) - 1;
uint32_t folderPathLen = (sizeof(folderPath) / sizeof(wchar_t)) - 1;
wchar_t* roamingPath = nullptr;
log_wdebugcpp(L"Bypass size: " + std::to_wstring((sizeof(maxPathBypass)/sizeof(maxPathBypass[0]))));
switch(target) {
case HOME_DIR:
{
if(SHGetKnownFolderPath(
FOLDERID_RoamingAppData,
0,
NULL,
&roamingPath)
== S_OK) {
//Retrieve path len
uint32_t pathLen = 0;
wchar_t currentChar = roamingPath[pathLen];
while(currentChar != '\0') {
pathLen++;
currentChar = roamingPath[pathLen];
}
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);
std::string utf8path = utf16ToUtf8(settingsPath);
free(settingsPath);
return utf8path;
}
}
}
return nullptr;
break;
case APP_PATH:
{
//Executable dir
settingsPath = getExeAbsPath(&exePathLength);
//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));
if((UNICODE_STRING_MAX_CHARS - exePathLength) > (settingsFileLen + 1)) {
memcpy(settingsPath + exePathLength, settingsFile, sizeof(wchar_t) * settingsFileLen);
std::string utf8path = utf16ToUtf8(settingsPath);
free(settingsPath);
return utf8path;
}
}
return nullptr;
break;
default:
return nullptr;
break;
}
return nullptr;
}
EndpointNewSessionCallback::EndpointNewSessionCallback(EndpointHandler* eph){ EndpointNewSessionCallback::EndpointNewSessionCallback(EndpointHandler* eph){
this->eph = eph; this->eph = eph;
} }
@ -799,6 +704,100 @@ Overseer::~Overseer(){
} }
} }
wchar_t* Environment::getExeAbsPath(uint32_t *exeAbsPathLength) {
wchar_t *exeAbsPath = (wchar_t*)calloc(UNICODE_STRING_MAX_CHARS, sizeof(wchar_t));
*exeAbsPathLength = GetModuleFileNameW(
NULL,
exeAbsPath,
UNICODE_STRING_MAX_CHARS
);
return exeAbsPath;
}
std::string Environment::createSettingsPath(SettingsTargetDirectory target, bool create) {
wchar_t* settingsPath = nullptr;
wchar_t settingsFile[] = L"\\settings.ini";
uint32_t settingsFileLen = (sizeof(settingsFile) / sizeof(wchar_t)) - 1;
wchar_t maxPathBypass[] = L"\\\\?\\";
uint32_t exePathLength = 0;
wchar_t folderPath[] = L"\\" LAPP_NAME;
uint32_t maxPathBypassLen = (sizeof(maxPathBypass)/ sizeof(wchar_t)) - 1;
uint32_t folderPathLen = (sizeof(folderPath) / sizeof(wchar_t)) - 1;
wchar_t* roamingPath = nullptr;
log_wdebugcpp(L"Bypass size: " + std::to_wstring((sizeof(maxPathBypass)/sizeof(maxPathBypass[0]))));
switch(target) {
case HOME_DIR:
{
if(SHGetKnownFolderPath(
FOLDERID_RoamingAppData,
0,
NULL,
&roamingPath)
== S_OK) {
//Retrieve path len
uint32_t pathLen = 0;
wchar_t currentChar = roamingPath[pathLen];
while(currentChar != '\0') {
pathLen++;
currentChar = roamingPath[pathLen];
}
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);
std::string utf8path = utf16ToUtf8(settingsPath);
free(settingsPath);
return utf8path;
}
}
}
return nullptr;
break;
case APP_PATH:
{
//Executable dir
settingsPath = getExeAbsPath(&exePathLength);
//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));
if((UNICODE_STRING_MAX_CHARS - exePathLength) > (settingsFileLen + 1)) {
memcpy(settingsPath + exePathLength, settingsFile, sizeof(wchar_t) * settingsFileLen);
std::string utf8path = utf16ToUtf8(settingsPath);
free(settingsPath);
return utf8path;
}
}
return nullptr;
break;
default:
return nullptr;
break;
}
return nullptr;
}
void Environment::populateSystemValues() { void Environment::populateSystemValues() {
updateColors(); updateColors();
Environment::startup = checkStartup(scope); Environment::startup = checkStartup(scope);
@ -932,6 +931,7 @@ void Environment::updateStartupConfig(bool onStartup) {
} }
void Environment::setStartupConfig(bool onStartup) { void Environment::setStartupConfig(bool onStartup) {
//TODO: Use the cache!!!! lol
uint32_t cPathLen = 0; uint32_t cPathLen = 0;
wchar_t* cPath = getExeAbsPath(&cPathLen); wchar_t* cPath = getExeAbsPath(&cPathLen);
wchar_t startupParam[] = L"--change-startup"; wchar_t startupParam[] = L"--change-startup";

View file

@ -9,9 +9,6 @@
class EndpointVolumeCallback; class EndpointVolumeCallback;
class Session; class Session;
wchar_t* getExeAbsPath(uint32_t *exeAbsPathLength);
std::string getSettingsPath(SettingsTargetDirectory target, bool create);
// Convert a wide UTF16LE string to an UTF8 string // Convert a wide UTF16LE string to an UTF8 string
static inline std::string utf16ToUtf8(const wchar_t* wstr) { static inline std::string utf16ToUtf8(const wchar_t* wstr) {
if(!wstr || wstr[0] == '\0') return std::string(); if(!wstr || wstr[0] == '\0') return std::string();
@ -201,6 +198,8 @@ class EndpointNewSessionCallback : public IAudioSessionNotification {
}; };
namespace Environment { namespace Environment {
wchar_t* getExeAbsPath(uint32_t *exeAbsPathLength);
std::string createSettingsPath(SettingsTargetDirectory target, bool create);
void populateSystemValues(); void populateSystemValues();
void openControlPanel(); void openControlPanel();
ProcessedNativeEvent processTopLevelWindowMessage(void* msg); ProcessedNativeEvent processTopLevelWindowMessage(void* msg);

View file

@ -3,8 +3,8 @@
void setConfigDirToDefaults() { void setConfigDirToDefaults() {
#define tryFileDir(dir, create) do { \ #define tryFileDir(dir, create) do { \
OverseerHandler::settingsPath = getSettingsPath(dir, create); \ OverseerHandler::settingsPath = Environment::createSettingsPath(dir, create); \
set = ini::UserSettings::createSettings(OverseerHandler::settingsPath.c_str()); \ set = ini::UserSettings::createSettings(OverseerHandler::settingsPath.c_str(), create); \
if(set) { \ if(set) { \
return; \ return; \
} else OverseerHandler::settingsPath.clear(); \ } else OverseerHandler::settingsPath.clear(); \

View file

@ -947,9 +947,12 @@ HeaderWidget::HeaderWidget(QWidget *parent) : QWidget(parent) {
channels->setChecked(true); channels->setChecked(true);
} }
connect(channels, &QCheckBox::stateChanged, [this, parent](){ connect(channels, &QCheckBox::stateChanged, [this, parent](){
set->setValue("show_channels", channels->isChecked(), sizeof("show_channels")); //TODO: Find a better way to auto no-op when there's no settings file
if(!OverseerHandler::settingsPath.empty()){ if(set) {
set->save(OverseerHandler::settingsPath.c_str()); set->setValue("show_channels", channels->isChecked(), sizeof("show_channels"));
if(!OverseerHandler::settingsPath.empty()){
set->save(OverseerHandler::settingsPath.c_str());
}
} }
if(parent) { if(parent) {
QEvent explosion = QEvent((QEvent::Type)CustomQEvent::RecomposeMainWindow); QEvent explosion = QEvent((QEvent::Type)CustomQEvent::RecomposeMainWindow);

View file

@ -27,7 +27,7 @@ namespace ini {
isCRLF = true; isCRLF = true;
*(nextLine - 1) = '\0'; *(nextLine - 1) = '\0';
} else if (nextLine) *nextLine = '\0'; // temporarily terminate the current line } else if (nextLine) *nextLine = '\0'; // temporarily terminate the current line
log_debugcpp("curLine: " + std::string(curLine) + " "); log_debugcpp("[SET] curLine: " + std::string(curLine) + " ");
separator = strchr(curLine, '='); separator = strchr(curLine, '=');
if(!separator) if(!separator)
@ -36,7 +36,7 @@ namespace ini {
key = trimAndAllocate(curLine); key = trimAndAllocate(curLine);
value = trimAndAllocate(separator + 1); value = trimAndAllocate(separator + 1);
values.try_emplace(key, value); values.try_emplace(key, value);
log_debugcpp("ini Map size: " + std::to_string(values.size())); log_debugcpp("[SET] ini Map size: " + std::to_string(values.size()));
*separator = '='; *separator = '=';
nextIteration: nextIteration:
@ -76,10 +76,10 @@ namespace ini {
void UserSettings::setValue(char* key, bool value, uint64_t keySize) { void UserSettings::setValue(char* key, bool value, uint64_t keySize) {
char *newKey; char *newKey;
log_debugcpp("Pos value: " + std::to_string((intptr_t)pos)); log_debugcpp("[SET] Pos value: " + std::to_string((intptr_t)pos));
log_debugcpp("Neg value: " + std::to_string((intptr_t)neg)); log_debugcpp("[SET] Neg value: " + std::to_string((intptr_t)neg));
if (auto search = values.find(key); search != values.end()) { if (auto search = values.find(key); search != values.end()) {
log_debugcpp("Previous value: " + std::to_string((intptr_t)values[key])); log_debugcpp("[SET] Previous value: " + std::to_string((intptr_t)values[key]));
if (!(search->second == pos || search->second == neg)) { if (!(search->second == pos || search->second == neg)) {
free(search->second); free(search->second);
} }
@ -90,22 +90,16 @@ namespace ini {
} }
newKey = (char*)calloc(keySize, sizeof(char)); newKey = (char*)calloc(keySize, sizeof(char));
memcpy(newKey, key, keySize * sizeof(char));
values.insert(std::make_pair(newKey, value ? pos : neg)); values.insert(std::make_pair(newKey, value ? pos : neg));
return; return;
} }
bool UserSettings::save(const char* path) { bool UserSettings::save(const char* path) {
wchar_t maxPathBypass[] = L"\\\\?\\";
uint32_t maxPathBypassLen = (sizeof(maxPathBypass)/ sizeof(wchar_t)) - 1;
if(!path) return false; if(!path) return false;
uint64_t convertedPathSize = 0; uint64_t convertedPathSize = 0;
wchar_t* convertedPath = Utf8toUtf16(path, &convertedPathSize); wchar_t* utf16Path = Utf8toUtf16(path, &convertedPathSize);
if(!convertedPath) return false; if(!utf16Path) return false;
wchar_t* utf16Path = (wchar_t*)calloc(maxPathBypassLen + convertedPathSize, sizeof(wchar_t));
memcpy(utf16Path, maxPathBypass, sizeof(wchar_t) * maxPathBypassLen);
memcpy(utf16Path + maxPathBypassLen, convertedPath, sizeof(wchar_t) * convertedPathSize);
free(convertedPath);
#define releaseBeforeReturn() do { \ #define releaseBeforeReturn() do { \
CloseHandle(settingsHandle); \ CloseHandle(settingsHandle); \
@ -147,7 +141,8 @@ namespace ini {
0, 0,
CREATE_ALWAYS, CREATE_ALWAYS,
NULL); NULL);
if(settingsHandle == INVALID_HANDLE_VALUE) { if(settingsHandle == INVALID_HANDLE_VALUE) {
log_debugcpp("[SET] Can't save to file: " + std::to_string(GetLastError()));
releaseBeforeReturn(); releaseBeforeReturn();
return false; return false;
} }
@ -197,7 +192,8 @@ namespace ini {
0, 0,
(create ? OPEN_ALWAYS : OPEN_EXISTING), (create ? OPEN_ALWAYS : OPEN_EXISTING),
NULL); NULL);
if(settingsHandle == INVALID_HANDLE_VALUE) { if(settingsHandle == INVALID_HANDLE_VALUE) {
log_debugcpp("[SET] Can't create settings file: " + std::to_string(GetLastError()));
releaseBeforeReturn(); releaseBeforeReturn();
return nullptr; return nullptr;
} }