wip: settings in effect
This commit is contained in:
parent
8e07b1efdd
commit
1ae324b68a
8 changed files with 277 additions and 158 deletions
|
|
@ -1,6 +1,96 @@
|
|||
#include "backlasses.h"
|
||||
#include "backfuncs.h"
|
||||
|
||||
std::string getPath(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 = (wchar_t*)calloc(UNICODE_STRING_MAX_CHARS, sizeof(wchar_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));
|
||||
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){
|
||||
this->eph = eph;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,42 @@
|
|||
|
||||
class EndpointVolumeCallback;
|
||||
class Session;
|
||||
std::string getPath(SettingsTargetDirectory target, bool create);
|
||||
|
||||
// Convert a wide UTF16LE string to an UTF8 string
|
||||
static inline std::string utf16ToUtf8(const wchar_t* wstr) {
|
||||
if(!wstr || wstr[0] == '\0') return std::string();
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wstr,
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
std::string str(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wstr,
|
||||
-1,
|
||||
&str[0],
|
||||
size_needed,
|
||||
NULL,
|
||||
NULL);
|
||||
return str;
|
||||
}
|
||||
|
||||
// Convert an UTF8 string to a wide UTF16LE String
|
||||
/*
|
||||
* std::wstring utf8_decode(const std::string &str)
|
||||
* {
|
||||
* if( str.empty() ) return std::wstring();
|
||||
* int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
|
||||
* std::wstring wstrTo( size_needed, 0 );
|
||||
* MultiByteToWideChar (CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
|
||||
* return wstrTo;
|
||||
* }
|
||||
*/
|
||||
|
||||
class Endpoint {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,27 @@
|
|||
#include "backlasses.h"
|
||||
#include "contclasses.h"
|
||||
//TODO: pragma once
|
||||
|
||||
void setConfigDirToDefaults() {
|
||||
#define tryFileDir(dir, create) do { \
|
||||
OverseerHandler::settingsPath = getPath(dir, create); \
|
||||
set = ini::UserSettings::createSettings(OverseerHandler::settingsPath.c_str()); \
|
||||
if(set) { \
|
||||
return; \
|
||||
} else OverseerHandler::settingsPath.clear(); \
|
||||
} while(0)
|
||||
#define tryOpenFileDir(dir) tryFileDir(dir, false)
|
||||
#define tryCreateFileDir(dir) tryFileDir(dir, true)
|
||||
|
||||
tryOpenFileDir(SettingsTargetDirectory::APP_PATH);
|
||||
tryOpenFileDir(SettingsTargetDirectory::HOME_DIR);
|
||||
tryCreateFileDir(SettingsTargetDirectory::HOME_DIR);
|
||||
tryCreateFileDir(SettingsTargetDirectory::APP_PATH);
|
||||
|
||||
return;
|
||||
#undef tryOpenFileDir
|
||||
#undef tryCreateFileDir
|
||||
#undef tryFileDir
|
||||
}
|
||||
|
||||
EndpointHandler::EndpointHandler(uint64_t idx, Flows flow) {
|
||||
//std::vector<Endpoint*> endpoints = osh->getPlaybackEndpoints().at(idx);
|
||||
|
|
@ -205,6 +226,14 @@ OverseerHandler::OverseerHandler() {
|
|||
this->os = new Overseer();
|
||||
}
|
||||
|
||||
void OverseerHandler::setSettingsPath(std::string path) {
|
||||
OverseerHandler::settingsPath = path;
|
||||
}
|
||||
|
||||
std::string OverseerHandler::getSettingsPath(){
|
||||
return OverseerHandler::settingsPath;
|
||||
}
|
||||
|
||||
void OverseerHandler::populateSystemValues() {
|
||||
this->os->populateSystemValues();
|
||||
}
|
||||
|
|
@ -374,3 +403,4 @@ void OverseerHandler::setRemoveEndpointWidgetFunction(std::function<void(uint64_
|
|||
void OverseerHandler::setEndpointHandlers(std::vector<EndpointHandler*> ephs){
|
||||
this->playbackEndpointHandlers = ephs;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "global.h"
|
||||
#include "settings.h"
|
||||
#include "contsessionclasses.h"
|
||||
//#define invoke_mem_fn(object,ptrToMember) ((object).*(ptrToMember))
|
||||
//#define pinvoke_mem_fn(object,ptrToMember) ((object)->*(ptrToMember))
|
||||
|
|
@ -21,6 +22,8 @@ struct BackEndpointVolumeCallbackInfo {
|
|||
bool updateName = false;
|
||||
};
|
||||
|
||||
void setConfigDirToDefaults();
|
||||
|
||||
class EndpointHandler {
|
||||
|
||||
public:
|
||||
|
|
@ -97,6 +100,9 @@ class OverseerHandler {
|
|||
|
||||
public:
|
||||
OverseerHandler();
|
||||
static void setSettingsPath(std::string path);
|
||||
static std::string getSettingsPath();
|
||||
static inline std::string settingsPath;
|
||||
void populateSystemValues();
|
||||
void openControlPanel();
|
||||
ProcessedNativeEvent processTopLevelWindowMessage(void* msg);
|
||||
|
|
@ -143,6 +149,7 @@ private:
|
|||
|
||||
/* Session's */
|
||||
std::function<void(float)> changeSessionVolume;
|
||||
|
||||
//std::function<void(uint64_t /* device */, uint32_t /* channel */, float /* value */)> updateFrontVolumeCallback;
|
||||
//std::function<void(uint64_t /* device */, bool /* mute */)> updateFrontMuteCallback;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,11 @@
|
|||
|
||||
//INIT BACK
|
||||
|
||||
|
||||
enum SettingsTargetDirectory {
|
||||
HOME_DIR = 0,
|
||||
APP_PATH = (1 << 0),
|
||||
CUSTOM = (1 << 1),
|
||||
};
|
||||
|
||||
enum ProcessedNativeEvent {
|
||||
NONE = 0,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include "qtclasses.h"
|
||||
#include "qtvisuals.h"
|
||||
#include "settings.h"
|
||||
//#include "global.h"
|
||||
|
||||
OverseerHandler *osh = nullptr;
|
||||
ini::UserSettings *set = nullptr;
|
||||
|
|
@ -56,8 +55,14 @@ int main (int argc, char* argv[]) {
|
|||
* log_debugcpp(a.toStdString());
|
||||
* }
|
||||
*/
|
||||
//std::map<const char*, cha>* values = new std::map<const char*, int>{ {"show_channels", false}, {"test", 7} };
|
||||
set = new ini::UserSettings(parseCmdArgs(argc, argv));
|
||||
char* userSettingsPath = parseCmdArgs(argc, argv);
|
||||
if (userSettingsPath)
|
||||
set = ini::UserSettings::createSettings(userSettingsPath, true);
|
||||
|
||||
if (set)
|
||||
OverseerHandler::settingsPath = std::string(userSettingsPath);
|
||||
else setConfigDirToDefaults();
|
||||
|
||||
initialize_file_log();
|
||||
atexit(closeDebugFileLog);
|
||||
|
||||
|
|
|
|||
180
src/settings.cpp
180
src/settings.cpp
|
|
@ -3,69 +3,23 @@
|
|||
|
||||
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; }
|
||||
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;
|
||||
}
|
||||
|
||||
//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);
|
||||
|
||||
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 == curLine + 1 || nextLine == curLine + 2)
|
||||
goto nextIteration;
|
||||
if (nextLine && (isCRLF || *(nextLine - 1) == '\r')) {
|
||||
isCRLF = true;
|
||||
*(nextLine - 1) = '\0';
|
||||
|
|
@ -73,7 +27,8 @@ namespace ini {
|
|||
log_debugcpp("curLine: " + std::string(curLine) + " ");
|
||||
|
||||
separator = strchr(curLine, '=');
|
||||
if(!separator) goto nextIteration;
|
||||
if(!separator)
|
||||
goto nextIteration;
|
||||
*separator = '\0';
|
||||
key = trimAndAllocate(curLine);
|
||||
value = trimAndAllocate(separator + 1);
|
||||
|
|
@ -89,14 +44,7 @@ namespace ini {
|
|||
}
|
||||
curLine = nextLine ? (nextLine + 1) : NULL;
|
||||
}
|
||||
/*
|
||||
* for(const std::pair<char[], int> keyVal : defaultValues) {
|
||||
* if (textContents.find(keyVal.first) {
|
||||
* if (keyVal.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
}
|
||||
free(textContents);
|
||||
}
|
||||
|
||||
//todo: buffer overflow. poc
|
||||
|
|
@ -144,65 +92,63 @@ namespace ini {
|
|||
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);
|
||||
//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::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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace ini {
|
|||
class UserSettings {
|
||||
|
||||
public:
|
||||
UserSettings(char* path = nullptr);
|
||||
static UserSettings* createSettings(const char* path = nullptr, bool create = false);
|
||||
~UserSettings();
|
||||
|
||||
char* const getValue(char* key, uint64_t len = 0);
|
||||
|
|
@ -63,11 +63,12 @@ class UserSettings {
|
|||
|
||||
private:
|
||||
//void* returnValue();
|
||||
UserSettings(char* text = nullptr);
|
||||
|
||||
//std::map<const char*, int> values{ {"show_channels", false}, {"test", 7} };
|
||||
std::unordered_map<char*, char*, Djb12Hasher, StrcmpEqual> values;
|
||||
char* textContents = nullptr;
|
||||
uint64_t textContentsSize = 0;
|
||||
//char* textContents = nullptr;
|
||||
//uint64_t textContentsSize = 0;
|
||||
char* pos = "true";
|
||||
char* neg = "false";
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue