From 14fae226bc72ed44f8c4dfe68f84f86cb5bb2aee Mon Sep 17 00:00:00 2001 From: Hane Date: Sun, 10 Sep 2023 21:58:01 +0200 Subject: [PATCH] wip: heap corruption (3rd item main volume) --- src/back/backlasses.cpp | 24 ++++++++++++++---- src/back/backlasses.h | 5 +++- src/cont/contclasses.cpp | 54 ++++++++++++++++++++++++++-------------- src/cont/contclasses.h | 8 +++++- src/qt/qtclasses.cpp | 53 +++++++++++++++++++++++---------------- src/qt/qtclasses.h | 15 +++++++---- 6 files changed, 107 insertions(+), 52 deletions(-) diff --git a/src/back/backlasses.cpp b/src/back/backlasses.cpp index f76b8a1..d187a8d 100644 --- a/src/back/backlasses.cpp +++ b/src/back/backlasses.cpp @@ -184,11 +184,9 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){ //todo: preguntitas owindows dword no es uint32_t even tho mingw mingas if(FAILED(endpoint->GetState(&this->endpointState))) {exit(-1);}; - if (this->endpointState == DEVICE_STATE_ACTIVE) { - if(FAILED(endpoint->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&endpointVolume))) { /* log_debugcpp("si"); */ }; + activateEndpointVolume(); - if (FAILED(endpointVolume->GetChannelCount(&channelCount))) {};/* log_debugcpp("get channel count fail"); */ - } + reloadEndpointChannels(); //todo:: atexit into exit Gather ID LPWSTR tempString = nullptr; @@ -206,6 +204,17 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){ friendlyName = std::wstring(pv.pwszVal); } +void Endpoint::activateEndpointVolume() { + if (this->endpointVolume == nullptr) + if(FAILED(endpoint->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&this->endpointVolume))) { log_debugcpp(std::string("no endpointVolume (IAudioEndpointVolume)")); }; +} + +void Endpoint::reloadEndpointChannels() { + if (this->endpointState == DEVICE_STATE_ACTIVE) { + if (FAILED(endpointVolume->GetChannelCount(&channelCount))) {};/* log_debugcpp("get channel count fail"); */ + } +} + void Endpoint::setIndex(uint64_t idx){ this->idx = idx; } @@ -246,6 +255,8 @@ bool Endpoint::getMute(){ void Endpoint::setState(uint8_t state){ this->endpointState = state; + if(state == EndpointState::ENDPOINT_ACTIVE) + this->reloadEndpointChannels(); } size_t Endpoint::getState(){ @@ -264,10 +275,13 @@ void Endpoint::setVolume(NGuid guid, int channel, float volume) { void Endpoint::setMute(NGuid guid, bool muted) { GUID tempMsGuid = NGuidToGUID(guid); - if(FAILED(endpointVolume->SetMute(muted, &tempMsGuid))) { /* TIP: Above */ }; + if(FAILED(endpointVolume->SetMute(muted, &tempMsGuid))) { log_wdebugcpp(std::wstring(L"EndpointVolume null?")); }; } void Endpoint::setVolumeCallback(EndpointVolumeCallback *epc){ + if(endpointVolume == nullptr) { + this->activateEndpointVolume(); + } endpointVolume->RegisterControlChangeNotify((IAudioEndpointVolumeCallback*)epc); } diff --git a/src/back/backlasses.h b/src/back/backlasses.h index 97b52d4..3bf02d3 100644 --- a/src/back/backlasses.h +++ b/src/back/backlasses.h @@ -33,6 +33,7 @@ class Endpoint { public: Endpoint(IMMDevice* endpoint, uint64_t idx); + void reloadEndpointChannels(); uint64_t getIndex(); void setIndex(uint64_t idx); void setVolume(NGuid guid, int channel, float volume); @@ -53,9 +54,11 @@ class Endpoint { ~Endpoint(); private: + void inline activateEndpointVolume(); + uint32_t channelCount = 0; IMMDevice* endpoint; - IAudioEndpointVolume *endpointVolume ; + IAudioEndpointVolume *endpointVolume = nullptr; IPropertyStore *properties; std::wstring friendlyName; std::wstring endpointId; diff --git a/src/cont/contclasses.cpp b/src/cont/contclasses.cpp index ce46d1e..e80d4c1 100644 --- a/src/cont/contclasses.cpp +++ b/src/cont/contclasses.cpp @@ -4,19 +4,13 @@ EndpointHandler::EndpointHandler(uint64_t idx) { //std::vector endpoints = osh->getPlaybackEndpoints().at(idx); + this->idx = idx; this->ep = osh->getPlaybackEndpoints().at(idx); epc = new EndpointVolumeCallback(ep); + this->callbackInfo.caller = osh->getGuid(); + //epName = ep->getName(); - if (this->ep->getState() == EndpointState::ENDPOINT_ACTIVE) { - callbackInfo.muted = this->getMute(); - callbackInfo.mainVolume = this->getVolume(AudioChannel::CHANNEL_MAIN); - callbackInfo.channels = this->getChannelCount(); - ep->setVolumeCallback(epc); - callbackInfo.channelVolumes.resize(this->callbackInfo.channels); - for(uint32_t i = 0; i < this->getChannelCount(); i++){ - callbackInfo.channelVolumes[i] = this->getVolume(i); - } - } + this->setBackEndpointVolumeCallbackInfoContent(this->getState()); } void EndpointHandler::setFrontVisibilityInfo(EndpointState state, uint64_t frontIdx){ @@ -91,8 +85,28 @@ size_t EndpointHandler::getState(){ return ep->getState(); } +void EndpointHandler::setBackEndpointVolumeCallbackInfoContent(uint8_t state) { + if(state == EndpointState::ENDPOINT_ACTIVE) { + callbackInfo.muted = this->getMute(); + callbackInfo.mainVolume = this->getVolume(AudioChannel::CHANNEL_MAIN); + callbackInfo.channels = this->getChannelCount(); + ep->setVolumeCallback(epc); + callbackInfo.channelVolumes.resize(this->callbackInfo.channels); + for(uint32_t i = 0; i < this->getChannelCount(); i++){ + callbackInfo.channelVolumes.at(i) = this->getVolume(i); + } + } +} + void EndpointHandler::setState(uint8_t state){ ep->setState(state); + this->setBackEndpointVolumeCallbackInfoContent(state); +} + +void EndpointHandler::setState(uint8_t state, uint64_t index){ + ep->setState(state); + this->setFrontVisibilityInfo((EndpointState)state, index); + this->setBackEndpointVolumeCallbackInfoContent(state); } uint8_t EndpointHandler::getRoles(){ @@ -168,25 +182,27 @@ void OverseerHandler::changeFrontDefaultsCallback(Roles role, std::wstring endpo } void OverseerHandler::reviseEndpointShowing(std::wstring endpointId, EndpointState state) { - EndpointHandler* affected = nullptr; - for (auto eph : this->endpointHandlers) { - if (eph->getId() == endpointId) { - affected = eph; + EndpointHandler* eph = nullptr; + for (auto loopEph : this->endpointHandlers) { + if (loopEph->getId() == endpointId) { + eph = loopEph; break; } } //todo: if(EndpointState::ENDPOINT_ACTIVE & state) { - //todo: - return; - } else if (affected->getFrontVisibilityState() == EndpointState::ENDPOINT_ACTIVE){ - this->removeEndpointWidget(affected->getFrontVisibilityIndex()); - affected->setFrontVisibilityInfo(EndpointState::ENDPOINT_ALL, INT_MAX); + this->addEndpointWidget(eph); + } else if (eph->getFrontVisibilityState() == EndpointState::ENDPOINT_ACTIVE){ + this->removeEndpointWidget(eph->getFrontVisibilityIndex()); } return; //this->reviseEndpointShowing(endpointId, role); } +void OverseerHandler::setAddEndpointWidgetFunction(std::function addEndpointWidget){ + this->addEndpointWidget = addEndpointWidget; +} + void OverseerHandler::setRemoveEndpointWidgetFunction(std::function removeEndpointWidget){ this->removeEndpointWidget = removeEndpointWidget; } diff --git a/src/cont/contclasses.h b/src/cont/contclasses.h index 8bd07b0..c71e604 100644 --- a/src/cont/contclasses.h +++ b/src/cont/contclasses.h @@ -62,6 +62,8 @@ class EndpointHandler { public: EndpointHandler(uint64_t idx); + void setBackEndpointVolumeCallbackInfoContent(uint8_t state); + //these two, currently unused. If I use them, I should feel bad. //EndpointVolumeCallback* getEndpointVolumeCallback(); //Endpoint* getEndpoint(); @@ -92,12 +94,14 @@ public: void setVolume(NGuid guid, int channel, int value); void setMute(NGuid guid, bool muted); void setState(uint8_t state); + void setState(uint8_t state, uint64_t idx); ~EndpointHandler(); private: uint64_t idx; Endpoint *ep = nullptr; EndpointVolumeCallback *epc = nullptr; + BackEndpointVolumeCallbackInfo callbackInfo; struct EndpointHandlerFrontVisibility { EndpointState visibility = EndpointState::ENDPOINT_ALL; @@ -107,7 +111,6 @@ private: //QSlider *slidy; }; - class OverseerHandler { public: @@ -118,6 +121,8 @@ public: //void setReviseEndpointShowingFunction(std::function reviseEndpointShowing); void reviseEndpointShowing(std::wstring endpointId, EndpointState state); void setRemoveEndpointWidgetFunction(std::function removeEndpointWidget); + void setAddEndpointWidgetFunction(std::function addEndpointWidget); + void setEndpointHandlers(std::vector ephs); std::vector getEndpointHandlers(); std::vector getPlaybackEndpoints(); @@ -130,6 +135,7 @@ private: std::vector endpointHandlers; std::function changeFrontDefaults; std::function removeEndpointWidget; + std::function addEndpointWidget; //std::function updateFrontVolumeCallback; //std::function updateFrontMuteCallback; diff --git a/src/qt/qtclasses.cpp b/src/qt/qtclasses.cpp index 0e47fc6..97330dc 100644 --- a/src/qt/qtclasses.cpp +++ b/src/qt/qtclasses.cpp @@ -1,7 +1,8 @@ #include "qtclasses.h" -EndpointWidgetEvent::EndpointWidgetEvent(QEvent::Type type, int idx) : QEvent(type){ - this->idx = idx; +template +EndpointWidgetEvent::EndpointWidgetEvent(QEvent::Type type, T payload) : QEvent(type){ + this->payload = payload; } void ExtendedCheckBox::customEvent(QEvent* ev) { @@ -28,11 +29,13 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare //todo: based on qgridlayout, name+mute should be its own widget, same with channels this->idx = idx; this->eph = eph; - this->eph->setFrontVisibilityInfo(EndpointState::ENDPOINT_ACTIVE, idx); + //todo: sussy + this->eph->setState(EndpointState::ENDPOINT_ACTIVE, idx); + layout = new QGridLayout(this); //this->setLayout(layout); log_debugcpp("epw main layout parent: " + std::to_string((intptr_t)(layout->parent()))); - if (parent == nullptr) { log_debugcpp("owo?"); } + if (parent == nullptr) { log_debugcpp("ayooooo?"); } defaultRolesCheckBoxes = { {Roles::ROLE_ALL, new ExtendedCheckBox(this)}, @@ -183,31 +186,44 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare log_debugcpp("ENDPOINT_WIDGETED"); } +EndpointWidget::~EndpointWidget() { + this->eph->setFrontVisibilityInfo(EndpointState::ENDPOINT_ALL, INT_MAX); +} + void MainWindow::customEvent(QEvent* ev) { if (ev->type() == CustomQEvent::EndpointWidgetObsolete) { ev->setAccepted(true); - this->removeEndpointWidget((EndpointWidgetEvent*)ev); + this->removeEndpointWidget((EndpointWidgetEvent*)ev); return; - } + } else if (ev->type() == (QEvent::Type)CustomQEvent::EndpointWidgetCreated) { + ev->setAccepted(true); + this->addEndpointWidget((EndpointWidgetEvent*)ev); + } // Make sure the rest of events are handled QMainWindow::customEvent(ev); } -void MainWindow::removeEndpointWidget(EndpointWidgetEvent* ev){ - uint64_t i = ev->idx; +void MainWindow::removeEndpointWidget(EndpointWidgetEvent* ev){ + uint64_t i = ev->payload; this->ews.at(i)->setParent(nullptr); this->layout->removeWidget(ews.at(i)); uint64_t saisu = ews.size(); //delete ews.at(index); while ((i + 1) < ews.size()) { ews.at(i) = ews.at(i + 1); - ews.at(i)->updateEndpointHandlerFrontInfo(i); + ews.at(i)->updateEndpointHandlerFrontIndex(i); i++; } ews.pop_back(); return; } +void MainWindow::addEndpointWidget(EndpointWidgetEvent* ev){ + EndpointWidget* epw = new EndpointWidget(this->ews.size(), ev->payload, widget); + this->layout->addWidget(epw); + ews.push_back(epw); + return; +} void EndpointWidget::updateMute(int checked){ bool muted = (checked == 2 ? true : false); @@ -254,7 +270,7 @@ EndpointHandler* EndpointWidget::getEndpointHandler(){ return this->eph; } -void EndpointWidget::updateEndpointHandlerFrontInfo(uint64_t index){ +void EndpointWidget::updateEndpointHandlerFrontIndex(uint64_t index){ this->eph->setFrontVisibilityInfo(EndpointState::ENDPOINT_ACTIVE, index); } @@ -275,6 +291,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { * Registering needed custom events */ QEvent::registerEventType(CustomQEvent::EndpointWidgetObsolete); + QEvent::registerEventType(CustomQEvent::EndpointWidgetCreated); QEvent::registerEventType(CustomQEvent::EndpointDefaultChange); widget = new QWidget(); @@ -348,20 +365,14 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { }); osh->setRemoveEndpointWidgetFunction([this](uint64_t index) { - EndpointWidgetEvent* removeObsoleteEndpointWidget = new EndpointWidgetEvent((QEvent::Type)CustomQEvent::EndpointWidgetObsolete, index); - QCoreApplication::instance()->postEvent(this, removeObsoleteEndpointWidget); + QCoreApplication::instance()->postEvent(this, new EndpointWidgetEvent((QEvent::Type)CustomQEvent::EndpointWidgetObsolete, index)); }); - /* - * osh->setReviseEndpointShowingFunction([this](std::wstring endpointId, Roles role){ - * - * - * }); - */ - + osh->setAddEndpointWidgetFunction([this](EndpointHandler* eph) { + QCoreApplication::instance()->postEvent(this, new EndpointWidgetEvent((QEvent::Type)CustomQEvent::EndpointWidgetCreated, eph)); + }); } - void MainWindow::closeEvent(QCloseEvent *event) { if (!event->spontaneous() || !isVisible()) return; @@ -389,7 +400,7 @@ void MainWindow::reloadEndpointWidgets() { for (size_t epwIndex = 0; i < (osh->getEndpointHandlers().size()); i++) { if (osh->getEndpointHandlers().at(i)->getState() == EndpointState::ENDPOINT_ACTIVE){ log_debugcpp("EPWidget creation"); - osh->getEndpointHandlers().at(i)->getCallbackInfo()->caller = osh->getGuid(); + //osh->getEndpointHandlers().at(i)->getCallbackInfo()->caller = osh->getGuid(); EndpointWidget *epw = new EndpointWidget(epwIndex, osh->getEndpointHandlers().at(i), widget); epwIndex++; //alfinal estoes solopara inicializarlmao diff --git a/src/qt/qtclasses.h b/src/qt/qtclasses.h index f66b5b3..10e9a98 100644 --- a/src/qt/qtclasses.h +++ b/src/qt/qtclasses.h @@ -58,14 +58,17 @@ */ enum CustomQEvent { EndpointWidgetObsolete = 1001, - EndpointDefaultChange = 1002, + EndpointWidgetCreated = 1002, + EndpointDefaultChange = 1003, }; +template class EndpointWidgetEvent : public QEvent { public: - EndpointWidgetEvent(QEvent::Type type, int idx); - uint64_t idx; + EndpointWidgetEvent(QEvent::Type type, T payload); + T payload; + }; //Q_DECLARE_METATYPE(EndpointWidgetEvent) @@ -89,7 +92,7 @@ public: EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *parent = nullptr); EndpointHandler* getEndpointHandler(); - void updateEndpointHandlerFrontInfo(uint64_t index); + void updateEndpointHandlerFrontIndex(uint64_t index); void setIndex(uint64_t idx); uint64_t getIndex(); @@ -104,6 +107,7 @@ public: QGridLayout *layout = nullptr; QGridLayout *mainMuteLayout = nullptr; std::map defaultRolesCheckBoxes; + ~EndpointWidget(); //void updateMainVolume(float newValue); //void updateVolume(uint32_t channel, float newValue); @@ -143,7 +147,8 @@ protected: private slots: void trayIconActivated(QSystemTrayIcon::ActivationReason reason); - void removeEndpointWidget(EndpointWidgetEvent* ev); + void removeEndpointWidget(EndpointWidgetEvent* ev); + void addEndpointWidget(EndpointWidgetEvent* ev); //TODO: destroy/empty existing EndpointWidgets //void setEndpointHandlers(std::vector *ephs);