From 495e6e45e391a3ecbec84d87554eb690b737bfc7 Mon Sep 17 00:00:00 2001 From: jthedering <51533355+jthedering@users.noreply.github.com> Date: Wed, 15 May 2013 20:43:47 +0000 Subject: [PATCH] Improved: For playback devices, the APO is now installed as a GFX (Post-mix) APO, so only one instance of Eq. APO is running for any number of applications. Existing LFX APO installations are upgraded by the Configurator (shown as "APO will be upgraded"). Added: Support for installation to capture devices. They can be selected on a second tab in the Configurator. --- Configurator/Configurator.cpp | 327 +++++++++++++++++++++++----------- Configurator/Configurator.h | 10 +- Configurator/Configurator.rc | Bin 12148 -> 14010 bytes Configurator/resource.h | Bin 3248 -> 3882 bytes DeviceAPOInfo.cpp | 128 ++++++++++--- DeviceAPOInfo.h | 6 +- EqualizerAPO.cpp | 21 ++- RegistryHelper.cpp | 15 ++ RegistryHelper.h | 1 + 9 files changed, 364 insertions(+), 144 deletions(-) diff --git a/Configurator/Configurator.cpp b/Configurator/Configurator.cpp index 675d17f..fa465be 100644 --- a/Configurator/Configurator.cpp +++ b/Configurator/Configurator.cpp @@ -38,13 +38,26 @@ Configurator::Configurator(HINSTANCE hInstance, const wchar_t* cmdLine) void Configurator::onInitDialog(HWND hDlg) { this->hDlg = hDlg; - deviceList = GetDlgItem(hDlg, IDC_DEVICE_LIST); + categoryTabCtrl = GetDlgItem(hDlg, IDC_CATEGORY_TAB_CTRL); + deviceLists[0] = GetDlgItem(hDlg, IDC_PLAYBACK_LIST); + deviceLists[1] = GetDlgItem(hDlg, IDC_CAPTURE_LIST); okButton = GetDlgItem(hDlg, IDOK); cancelButton = GetDlgItem(hDlg, IDCANCEL); requestLabel = GetDlgItem(hDlg, IDC_REQUEST); copyDeviceCommandButton = GetDlgItem(hDlg, IDC_COPY_DEVICE_COMMAND); wchar_t stringBuf[255]; + + TCITEM tci; + tci.pszText = stringBuf; + tci.mask = TCIF_TEXT; + + LoadStringW(hInstance, IDS_PLAYBACK_DEVICES, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + TabCtrl_InsertItem(categoryTabCtrl, 0, &tci); + + LoadStringW(hInstance, IDS_CAPTURE_DEVICES, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + TabCtrl_InsertItem(categoryTabCtrl, 1, &tci); + LoadStringW(hInstance, IDS_REQUEST, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); SetWindowTextW(requestLabel, stringBuf); @@ -57,115 +70,117 @@ void Configurator::onInitDialog(HWND hDlg) LoadStringW(hInstance, IDS_CANCEL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); SetWindowTextW(cancelButton, stringBuf); - ListView_SetExtendedListViewStyle(deviceList, ListView_GetExtendedListViewStyle(deviceList) | LVS_EX_CHECKBOXES); - LVCOLUMN column; - column.pszText = stringBuf; - column.mask = LVCF_TEXT; - - LoadStringW(hInstance, IDS_CONNECTOR, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); - ListView_InsertColumn(deviceList, 0, &column); - - LoadStringW(hInstance, IDS_DEVICE, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); - ListView_InsertColumn(deviceList, 1, &column); - - LoadStringW(hInstance, IDS_STATUS, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); - ListView_InsertColumn(deviceList, 2, &column); - - LVITEM item; - item.iSubItem = 0; - item.pszText = stringBuf; - item.mask = LVIF_TEXT | LVIF_PARAM; - - try { - apoInfos = DeviceAPOInfo::loadAllInfos(); - - int itemCount=0; - for(vector::iterator it = apoInfos.begin(); it != apoInfos.end(); it++) - { - wcsncpy_s(stringBuf, sizeof(stringBuf)/sizeof(wchar_t), it->connectionName.c_str(), _TRUNCATE); - item.iItem = itemCount; - item.lParam = itemCount; - ListView_InsertItem(deviceList, &item); - wcsncpy_s(stringBuf, sizeof(stringBuf)/sizeof(wchar_t), it->deviceName.c_str(), _TRUNCATE); - ListView_SetItemText(deviceList, itemCount, 1, stringBuf); - - if(it->isInstalled) - { - ListView_SetCheckState(deviceList, itemCount, TRUE); - LoadStringW(hInstance, IDS_ALREADY_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); - ListView_SetItemText(deviceList, itemCount, 2, stringBuf); - } - else if(it->originalApoGuid == APOGUID_NOKEY) - { - LoadStringW(hInstance, IDS_CAN_BE_INSTALLED_EXPERIMENTAL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); - ListView_SetItemText(deviceList, itemCount, 2, stringBuf); - } - else - { - LoadStringW(hInstance, IDS_CAN_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); - ListView_SetItemText(deviceList, itemCount, 2, stringBuf); - } - - itemCount++; - } - } - catch(RegistryException e) + for(int i=0; i<=1; i++) { - MessageBoxW(hDlg, e.getMessage().c_str(), L"Error while accessing the registry", MB_ICONERROR | MB_OK); - } + HWND deviceList = deviceLists[i]; + ListView_SetExtendedListViewStyle(deviceList, ListView_GetExtendedListViewStyle(deviceList) | LVS_EX_CHECKBOXES); + LVCOLUMN column; + column.pszText = stringBuf; + column.mask = LVCF_TEXT; - ListView_SetColumnWidth(deviceList, 0, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(deviceList, 1, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(deviceList, 2, LVSCW_AUTOSIZE); + LoadStringW(hInstance, IDS_CONNECTOR, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + ListView_InsertColumn(deviceList, 0, &column); + + LoadStringW(hInstance, IDS_DEVICE, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + ListView_InsertColumn(deviceList, 1, &column); + + LoadStringW(hInstance, IDS_STATUS, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + ListView_InsertColumn(deviceList, 2, &column); + + LVITEM item; + item.iSubItem = 0; + item.pszText = stringBuf; + item.mask = LVIF_TEXT | LVIF_PARAM; + + try + { + apoInfos[i] = DeviceAPOInfo::loadAllInfos(i==1); + + int itemCount=0; + for(vector::iterator it = apoInfos[i].begin(); it != apoInfos[i].end(); it++) + { + wcsncpy_s(stringBuf, sizeof(stringBuf)/sizeof(wchar_t), it->connectionName.c_str(), _TRUNCATE); + item.iItem = itemCount; + item.lParam = itemCount; + ListView_InsertItem(deviceList, &item); + wcsncpy_s(stringBuf, sizeof(stringBuf)/sizeof(wchar_t), it->deviceName.c_str(), _TRUNCATE); + ListView_SetItemText(deviceList, itemCount, 1, stringBuf); + + if(it->isInstalled) + { + ListView_SetCheckState(deviceList, itemCount, TRUE); + if(!it->isInput && it->isLFX) + LoadStringW(hInstance, IDS_WILL_BE_UPGRADED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + else + LoadStringW(hInstance, IDS_ALREADY_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + ListView_SetItemText(deviceList, itemCount, 2, stringBuf); + } + else if(it->originalApoGuid == APOGUID_NOKEY) + { + LoadStringW(hInstance, IDS_CAN_BE_INSTALLED_EXPERIMENTAL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + ListView_SetItemText(deviceList, itemCount, 2, stringBuf); + } + else + { + LoadStringW(hInstance, IDS_CAN_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + ListView_SetItemText(deviceList, itemCount, 2, stringBuf); + } + + itemCount++; + } + } + catch(RegistryException e) + { + MessageBoxW(hDlg, e.getMessage().c_str(), L"Error while accessing the registry", MB_ICONERROR | MB_OK); + } + + ListView_SetColumnWidth(deviceList, 0, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(deviceList, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(deviceList, 2, LVSCW_AUTOSIZE); + } } void Configurator::onLvnItemChanged(unsigned sourceId, LPNMLISTVIEW info) { + int index = (sourceId == IDC_PLAYBACK_LIST ? 0 : 1); + HWND deviceList = deviceLists[index]; + int itemCount = ListView_GetItemCount(deviceList); - if(apoInfos.size() == itemCount) + if(apoInfos[index].size() == itemCount) { - DeviceAPOInfo apoInfo = apoInfos[info->lParam]; + DeviceAPOInfo apoInfo = apoInfos[index][info->lParam]; bool checked = ListView_GetCheckState(deviceList,info->iItem) != 0; wchar_t stringBuf[255]; if(checked && !apoInfo.isInstalled) LoadStringW(hInstance, IDS_WILL_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); else if(!checked && apoInfo.isInstalled) LoadStringW(hInstance, IDS_WILL_BE_UNINSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + else if(apoInfo.isInstalled && !apoInfo.isInput && apoInfo.isLFX) + LoadStringW(hInstance, IDS_WILL_BE_UPGRADED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); else if(apoInfo.isInstalled) LoadStringW(hInstance, IDS_ALREADY_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + else if(apoInfo.originalApoGuid == APOGUID_NOKEY) + LoadStringW(hInstance, IDS_CAN_BE_INSTALLED_EXPERIMENTAL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); else LoadStringW(hInstance, IDS_CAN_BE_INSTALLED, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); ListView_SetItemText(deviceList, info->iItem, 2, stringBuf); - bool changed = false; - for(int i = 0; i < itemCount; i++) - { - LVITEM item; - item.iItem = i; - item.iSubItem = 0; - item.mask = LVIF_PARAM; - ListView_GetItem(deviceList, &item); - if((ListView_GetCheckState(deviceList, i) != 0) != apoInfos[item.lParam].isInstalled) - { - changed = true; - break; - } - } - - EnableWindow(okButton, changed); + EnableWindow(okButton, isChanged()); EnableWindow(copyDeviceCommandButton, ListView_GetSelectedCount(deviceList) > 0); } } -void Configurator::onButtonClicked(unsigned sourceId) +bool Configurator::onButtonClicked(unsigned sourceId) { if(sourceId == IDOK) { - try + for(int index = 0; index <= 1; index++) { + HWND deviceList = deviceLists[index]; + for(int i = 0; i < ListView_GetItemCount(deviceList); i++) { LVITEM item; @@ -174,22 +189,34 @@ void Configurator::onButtonClicked(unsigned sourceId) item.mask = LVIF_PARAM; ListView_GetItem(deviceList, &item); - DeviceAPOInfo info = apoInfos[item.lParam]; - if(ListView_GetCheckState(deviceList, i) && !info.isInstalled) - info.install(); - else if(!ListView_GetCheckState(deviceList, i) && info.isInstalled) - info.uninstall(); + try + { + DeviceAPOInfo info = apoInfos[index][item.lParam]; + if(ListView_GetCheckState(deviceList, i) && !info.isInstalled) + info.install(); + else if(!ListView_GetCheckState(deviceList, i) && info.isInstalled) + info.uninstall(); + else if(ListView_GetCheckState(deviceList, i) && !info.isInput && info.isLFX) + { + info.uninstall(); + info.load(info.deviceGuid); + info.install(); + } + } + catch(RegistryException e) + { + MessageBoxW(hDlg, e.getMessage().c_str(), L"Error while accessing the registry", MB_ICONERROR | MB_OK); + } } } - catch(RegistryException e) - { - MessageBoxW(hDlg, e.getMessage().c_str(), L"Error while accessing the registry", MB_ICONERROR | MB_OK); - } } - else if(sourceId = IDC_COPY_DEVICE_COMMAND) + else if(sourceId == IDC_COPY_DEVICE_COMMAND) { wstring command = L"Device: "; + int index = TabCtrl_GetCurSel(categoryTabCtrl); + HWND deviceList = deviceLists[index]; + bool first = true; for(int i = 0; i < ListView_GetItemCount(deviceList); i++) { @@ -207,7 +234,7 @@ void Configurator::onButtonClicked(unsigned sourceId) else command += L"; "; - DeviceAPOInfo info = apoInfos[item.lParam]; + DeviceAPOInfo info = apoInfos[index][item.lParam]; command += StringHelper::replaceCharacters(info.deviceName + L" " + info.connectionName + L" " + info.deviceGuid, L";", L' '); } } @@ -224,12 +251,94 @@ void Configurator::onButtonClicked(unsigned sourceId) CloseClipboard(); } - if((sourceId == IDOK || sourceId == IDCANCEL) && cmdLine == L"/i") + if(sourceId == IDCANCEL && hasUpgrades()) { + wchar_t captionBuf[255]; + LoadStringW(hInstance, IDS_CANCEL_UPGRADES_CAPTION, captionBuf, sizeof(captionBuf)/sizeof(wchar_t)); wchar_t stringBuf[255]; - LoadStringW(hInstance, IDS_AFTERINSTALL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); - MessageBoxW(hDlg, stringBuf, L"Info", MB_ICONINFORMATION | MB_OK); + LoadStringW(hInstance, IDS_CANCEL_UPGRADES, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + if(MessageBoxW(hDlg, stringBuf, captionBuf, MB_ICONWARNING | MB_YESNO) == IDNO) + return false; } + + if(sourceId == IDOK || sourceId == IDCANCEL) + { + if(cmdLine == L"/i") + { + wchar_t stringBuf[255]; + LoadStringW(hInstance, IDS_AFTERINSTALL, stringBuf, sizeof(stringBuf)/sizeof(wchar_t)); + MessageBoxW(hDlg, stringBuf, L"Info", MB_ICONINFORMATION | MB_OK); + } + + return true; + } + + return false; +} + +void Configurator::onTcnSelChange(unsigned sourceId) +{ + int index = TabCtrl_GetCurSel(categoryTabCtrl); + + ShowWindow(deviceLists[index], SW_SHOW); + ShowWindow(deviceLists[1 - index], SW_HIDE); + + EnableWindow(copyDeviceCommandButton, ListView_GetSelectedCount(deviceLists[index]) > 0); + + SetFocus(deviceLists[index]); +} + +bool Configurator::isChanged() +{ + bool changed = false; + + for(int index = 0; index <= 1; index++) + { + HWND deviceList = deviceLists[index]; + + for(int i = 0; i < ListView_GetItemCount(deviceList); i++) + { + LVITEM item; + item.iItem = i; + item.iSubItem = 0; + item.mask = LVIF_PARAM; + ListView_GetItem(deviceList, &item); + if((ListView_GetCheckState(deviceList, i) != 0) != apoInfos[index][item.lParam].isInstalled + || ListView_GetCheckState(deviceList, i) && apoInfos[index][item.lParam].isInstalled && !apoInfos[index][item.lParam].isInput && apoInfos[index][item.lParam].isLFX) + { + changed = true; + break; + } + } + } + + return changed; +} + +bool Configurator::hasUpgrades() +{ + bool hasUpgrades = false; + + for(int index = 0; index <= 1; index++) + { + HWND deviceList = deviceLists[index]; + + for(int i = 0; i < ListView_GetItemCount(deviceList); i++) + { + LVITEM item; + item.iItem = i; + item.iSubItem = 0; + item.mask = LVIF_PARAM; + ListView_GetItem(deviceList, &item); + if(ListView_GetCheckState(deviceList, i) && apoInfos[index][item.lParam].isInstalled && !apoInfos[index][item.lParam].isInput && apoInfos[index][item.lParam].isLFX) + { + hasUpgrades = true; + break; + } + } + } + + return hasUpgrades; } INT_PTR CALLBACK dlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); @@ -248,19 +357,22 @@ int APIENTRY wWinMain(HINSTANCE hInstance, if(wcscmp(lpCmdLine, L"/u") == 0) { - vector apoInfos = DeviceAPOInfo::loadAllInfos(); - - for(vector::iterator it = apoInfos.begin(); it != apoInfos.end(); it++) + for(int index = 0; index <= 1; index++) { - try + vector apoInfos = DeviceAPOInfo::loadAllInfos(index == 1); + + for(vector::iterator it = apoInfos.begin(); it != apoInfos.end(); it++) { - if(it->isInstalled) - it->uninstall(); - } - catch (RegistryException e) - { - MessageBoxW(NULL, e.getMessage().c_str(), NULL, MB_ICONERROR | MB_OK); - result = -1; + try + { + if(it->isInstalled) + it->uninstall(); + } + catch (RegistryException e) + { + MessageBoxW(NULL, e.getMessage().c_str(), NULL, MB_ICONERROR | MB_OK); + result = -1; + } } } } @@ -284,9 +396,7 @@ INT_PTR CALLBACK dlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) return (INT_PTR)TRUE; case WM_COMMAND: - configurator->onButtonClicked(LOWORD(wParam)); - - if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) + if(configurator->onButtonClicked(LOWORD(wParam))) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; @@ -299,6 +409,9 @@ INT_PTR CALLBACK dlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case LVN_ITEMCHANGED: configurator->onLvnItemChanged((unsigned)((LPNMHDR)lParam)->idFrom, (LPNMLISTVIEW) lParam); break; + case TCN_SELCHANGE: + configurator->onTcnSelChange((unsigned)((LPNMHDR)lParam)->idFrom); + break; } break; } diff --git a/Configurator/Configurator.h b/Configurator/Configurator.h index 5a6c5f0..faf0bcd 100644 --- a/Configurator/Configurator.h +++ b/Configurator/Configurator.h @@ -30,17 +30,21 @@ public: Configurator(HINSTANCE hInstance, const wchar_t* cmdLine); void onInitDialog(HWND hDlg); void onLvnItemChanged(unsigned sourceId, LPNMLISTVIEW info); - void onButtonClicked(unsigned sourceId); + bool onButtonClicked(unsigned sourceId); + void onTcnSelChange(unsigned sourceId); + bool isChanged(); + bool hasUpgrades(); private: HINSTANCE hInstance; HWND hDlg; - HWND deviceList; + HWND categoryTabCtrl; + HWND deviceLists[2]; HWND okButton; HWND cancelButton; HWND copyDeviceCommandButton; HWND requestLabel; std::wstring cmdLine; - std::vector apoInfos; + std::vector apoInfos[2]; }; diff --git a/Configurator/Configurator.rc b/Configurator/Configurator.rc index 2d5b544f95cd84556db99df450eac04a1a3ed49b..13de4b368c07e73632e144befa7ced3673dab231 100644 GIT binary patch delta 1244 zcmb7DO>a^`6g?VU2&k9_kf3A=x)MJSsa0bP1wtCJkn*r`p)Y(%iImn?Y3s^#=dy9) z#vL2iDmyp+09VFc7rOB$7+0Ej?tmJI_>q@+^X|Mm_ndp?%;!6=S6;mG>MfUdzKA?h zxP>{s)3^>B8Dw!2^Ng}6K@Fb>me4{2bq)tjR8Zwt(?p-}01bWL6-pIhp^QcDoK#04 zLZmM4qQe@?SQ)F*i~98Lfmyv1_8uvth#ae>45ti~ei`=p9CA?HdylAH&TaBq*Dcq{ zgfPw%d34{e9t1mMx=^fHL;M$-1kv2IyWGg)7zi_YeahNBuWM89t$L&e{ZJvejwRkE8EUPeePr}FT^L*$!WcXmoF})+WKRAittW2Ipu=FqU;-qK87vq; qJVPMQV)A>5{friq*Gv9oc4hFJtgpCxvxJ-y*W?aijm=`(OSl2CK^bNM diff --git a/Configurator/resource.h b/Configurator/resource.h index 63c821bf349db645627c563724c4b8cb6c5be57c..1478dae9555af9277c00591392f74f1041822c3d 100644 GIT binary patch delta 348 zcmZ`#O-jQ+6#iy1wlmO$MNmRWweDO<8%z!m(^86|hMEeB&?|TYuONIE5SMPOc!7Ee z*VU8w#$p!*85nr)`+47ci}0nhc(z;`b6BB7jvJiIU*H0B3^2qs#!?M&MWw0t}bsVHPquS}Y3M1j<81TzPyl)yoQbA(wn#O^5E=51XhW9&b?U4QP zvVVA@EX3O<8RHTY9BrOY`q7B?3gK*R#y5Myl{Wmg$8N2bJ@{%*eK+VMVeVpTch~jq pwImve`&4c-mnxSF`MI@pN+u@c${O}t`+U;o{nmYIl`&~O`~ayELXH3c delta 50 zcmV-20L}lZ9+07(Etlg|n*lW+$FlcEYFlOhXRv)BvL0+YH6 I7L&jZYL(UyhyVZp diff --git a/DeviceAPOInfo.cpp b/DeviceAPOInfo.cpp index 51d785b..cb7fe21 100644 --- a/DeviceAPOInfo.cpp +++ b/DeviceAPOInfo.cpp @@ -17,6 +17,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include + #include "DeviceAPOInfo.h" #include "EqualizerAPO.h" @@ -26,16 +28,19 @@ using namespace std; -#define renderKeyPath L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio\\Render" +#define commonKeyPath L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio" +#define renderKeyPath commonKeyPath L"\\Render" +#define captureKeyPath commonKeyPath L"\\Capture" static const wchar_t* connectionValueName = L"{a45c254e-df1c-4efd-8020-67d146a850e0},2"; static const wchar_t* deviceValueName = L"{b3f8fa53-0004-438e-9003-51a46e139bfc},6"; -static const wchar_t* apoGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},1"; +static const wchar_t* lfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},1"; +static const wchar_t* gfxGuidValueName = L"{d04e05a6-594b-4fb6-a80d-01af5eed7d1d},2"; static const wchar_t* fxTitleValueName = L"{b725f130-47ef-101a-a5f1-02608c9eebac},10"; -vector DeviceAPOInfo::loadAllInfos() +vector DeviceAPOInfo::loadAllInfos(bool input) { vector result; - vector deviceGuidStrings = RegistryHelper::enumSubKeys(renderKeyPath); + vector deviceGuidStrings = RegistryHelper::enumSubKeys(input ? captureKeyPath : renderKeyPath); for(vector::iterator it = deviceGuidStrings.begin(); it != deviceGuidStrings.end(); it++) { wstring deviceGuidString = *it; @@ -50,31 +55,75 @@ vector DeviceAPOInfo::loadAllInfos() bool DeviceAPOInfo::load(const wstring& deviceGuid) { + wstring keyPath; + if(RegistryHelper::keyExists(renderKeyPath L"\\" + deviceGuid)) + { + keyPath = renderKeyPath L"\\" + deviceGuid; + isInput = false; + } + else + { + keyPath = captureKeyPath L"\\" + deviceGuid; + isInput = true; + } + + unsigned long deviceState = RegistryHelper::readDWORDValue(keyPath, L"DeviceState"); + if(deviceState & DEVICE_STATE_NOTPRESENT) + return false; + this->deviceGuid = deviceGuid; - connectionName = RegistryHelper::readValue(renderKeyPath L"\\" + deviceGuid + L"\\Properties", connectionValueName); - deviceName = RegistryHelper::readValue(renderKeyPath L"\\" + deviceGuid + L"\\Properties", deviceValueName); + + connectionName = RegistryHelper::readValue(keyPath + L"\\Properties", connectionValueName); + deviceName = RegistryHelper::readValue(keyPath + L"\\Properties", deviceValueName); isInstalled = false; - if(!RegistryHelper::keyExists(renderKeyPath L"\\" + deviceGuid + L"\\FxProperties")) + if(!RegistryHelper::keyExists(keyPath + L"\\FxProperties")) { - unsigned long deviceState = RegistryHelper::readDWORDValue(renderKeyPath L"\\" + deviceGuid, L"DeviceState"); - if(deviceState == 0x10000004) - // Ignore special internal devices - return false; - originalApoGuid = APOGUID_NOKEY; } else { - originalApoGuid = RegistryHelper::readValue(renderKeyPath L"\\" + deviceGuid + L"\\FxProperties", apoGuidValueName); + if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", lfxGuidValueName)) + { + originalApoGuid = RegistryHelper::readValue(keyPath + L"\\FxProperties", lfxGuidValueName); - GUID apoGuid; - if(!SUCCEEDED(CLSIDFromString(originalApoGuid.c_str(), &apoGuid))) - return false; + GUID apoGuid; + if(!SUCCEEDED(CLSIDFromString(originalApoGuid.c_str(), &apoGuid))) + return false; - if(apoGuid == __uuidof(EqualizerAPO)) - isInstalled = true; + if(apoGuid == __uuidof(EqualizerAPO)) + { + isInstalled = true; + isLFX = true; + } + } + else if(isInput) + { + originalApoGuid = APOGUID_NOVALUE; + } + + if(!isInput && !isInstalled) + { + if(RegistryHelper::valueExists(keyPath + L"\\FxProperties", gfxGuidValueName)) + { + originalApoGuid = RegistryHelper::readValue(keyPath + L"\\FxProperties", gfxGuidValueName); + + GUID apoGuid; + if(!SUCCEEDED(CLSIDFromString(originalApoGuid.c_str(), &apoGuid))) + return false; + + if(apoGuid == __uuidof(EqualizerAPO)) + { + isInstalled = true; + isLFX = false; + } + } + else + { + originalApoGuid = APOGUID_NOVALUE; + } + } } return true; @@ -86,40 +135,63 @@ void DeviceAPOInfo::install() RegistryHelper::writeValue(APP_REGPATH L"\\Child APOs", deviceGuid, originalApoGuid); + wstring keyPath; + wstring guidValueName; + if(isInput) + { + keyPath = captureKeyPath L"\\" + deviceGuid; + guidValueName = lfxGuidValueName; + } + else + { + keyPath = renderKeyPath L"\\" + deviceGuid; + guidValueName = gfxGuidValueName; + } + if(originalApoGuid == APOGUID_NOKEY) { try { - RegistryHelper::createKey(renderKeyPath L"\\" + deviceGuid + L"\\FxProperties"); + RegistryHelper::createKey(keyPath + L"\\FxProperties"); } catch(RegistryException e) { // Permissions were not sufficient, so change them - RegistryHelper::takeOwnership(renderKeyPath L"\\" + deviceGuid); - RegistryHelper::makeWritable(renderKeyPath L"\\" + deviceGuid); + RegistryHelper::takeOwnership(keyPath); + RegistryHelper::makeWritable(keyPath); - RegistryHelper::createKey(renderKeyPath L"\\" + deviceGuid + L"\\FxProperties"); + RegistryHelper::createKey(keyPath + L"\\FxProperties"); } - RegistryHelper::writeValue(renderKeyPath L"\\" + deviceGuid + L"\\FxProperties", fxTitleValueName, L"Equalizer APO"); + RegistryHelper::writeValue(keyPath + L"\\FxProperties", fxTitleValueName, L"Equalizer APO"); } else { - RegistryHelper::saveToFile(renderKeyPath L"\\" + deviceGuid + L"\\FxProperties", apoGuidValueName, + RegistryHelper::saveToFile(keyPath + L"\\FxProperties", guidValueName, L"backup_" + StringHelper::replaceIllegalCharacters(deviceName) + L"_" + StringHelper::replaceIllegalCharacters(connectionName) + L".reg"); } - RegistryHelper::writeValue(renderKeyPath L"\\" + deviceGuid + L"\\FxProperties", apoGuidValueName, RegistryHelper::getGuidString(__uuidof(EqualizerAPO))); + RegistryHelper::writeValue(keyPath + L"\\FxProperties", guidValueName, RegistryHelper::getGuidString(__uuidof(EqualizerAPO))); } void DeviceAPOInfo::uninstall() { wstring originalChildApoGuid = RegistryHelper::readValue(APP_REGPATH L"\\Child APOs", deviceGuid); - if(originalChildApoGuid == APOGUID_NOKEY) - RegistryHelper::deleteKey(renderKeyPath L"\\" + deviceGuid + L"\\FxProperties"); + wstring keyPath; + if(!isInput) + keyPath = renderKeyPath L"\\" + deviceGuid; else - RegistryHelper::writeValue(renderKeyPath L"\\" + deviceGuid + L"\\FxProperties", apoGuidValueName, originalChildApoGuid); + keyPath = captureKeyPath L"\\" + deviceGuid; + + if(originalChildApoGuid == APOGUID_NOKEY) + RegistryHelper::deleteKey(keyPath + L"\\FxProperties"); + else if(originalChildApoGuid == APOGUID_NOVALUE) + RegistryHelper::deleteValue(keyPath + L"\\FxProperties", isLFX ? lfxGuidValueName : gfxGuidValueName); + else if(isLFX) + RegistryHelper::writeValue(keyPath + L"\\FxProperties", lfxGuidValueName, originalChildApoGuid); + else + RegistryHelper::writeValue(keyPath + L"\\FxProperties", gfxGuidValueName, originalChildApoGuid); RegistryHelper::deleteValue(APP_REGPATH L"\\Child APOs", deviceGuid); diff --git a/DeviceAPOInfo.h b/DeviceAPOInfo.h index d9e10e4..34ec5df 100644 --- a/DeviceAPOInfo.h +++ b/DeviceAPOInfo.h @@ -22,12 +22,14 @@ #include #include +#define APOGUID_NULL L"{00000000-0000-0000-0000-000000000000}" #define APOGUID_NOKEY L"!KEY" +#define APOGUID_NOVALUE L"!VALUE" class DeviceAPOInfo { public: - static std::vector loadAllInfos(); + static std::vector loadAllInfos(bool input); bool load(const std::wstring& deviceGuid); void install(); void uninstall(); @@ -36,5 +38,7 @@ public: std::wstring connectionName; std::wstring deviceGuid; std::wstring originalApoGuid; + bool isInput; bool isInstalled; + bool isLFX; }; diff --git a/EqualizerAPO.cpp b/EqualizerAPO.cpp index 53a2fd2..c722620 100644 --- a/EqualizerAPO.cpp +++ b/EqualizerAPO.cpp @@ -113,9 +113,16 @@ HRESULT EqualizerAPO::Initialize(UINT32 cbDataSize, BYTE* pbyData) wstring deviceGuid = var.pwszVal; TraceF(L"Endpoint GUID: %s", deviceGuid.c_str()); - DeviceAPOInfo apoInfo; - if(apoInfo.load(deviceGuid)) - peq.setDeviceInfo(apoInfo.deviceName, apoInfo.connectionName, apoInfo.deviceGuid); + try + { + DeviceAPOInfo apoInfo; + if(apoInfo.load(deviceGuid)) + peq.setDeviceInfo(apoInfo.deviceName, apoInfo.connectionName, apoInfo.deviceGuid); + } + catch(RegistryException e) + { + LogF(L"Could not read endpoint device info because of: %s", e.getMessage()); + } wstring apoGuid; try @@ -130,7 +137,7 @@ HRESULT EqualizerAPO::Initialize(UINT32 cbDataSize, BYTE* pbyData) TraceF(L"Child APO GUID: %s", apoGuid.c_str()); - if(apoGuid != APOGUID_NOKEY) + if(apoGuid != APOGUID_NULL && apoGuid != APOGUID_NOKEY && apoGuid != APOGUID_NOVALUE) { GUID childGuid; hr = CLSIDFromString(apoGuid.c_str(), &childGuid); @@ -305,7 +312,11 @@ HRESULT EqualizerAPO::LockForProcess(UINT32 u32NumInputConnections, TraceF(L"Output format in LockForProcess = { %08X, %u, %u, %u, %f, %08X }", outFormat.guidFormatType.Data1, outFormat.dwSamplesPerFrame, outFormat.dwBytesPerSampleContainer, outFormat.dwValidBitsPerSample, outFormat.fFramesPerSecond, outFormat.dwChannelMask); - peq.initialize(outFormat.fFramesPerSecond, outFormat.dwSamplesPerFrame, outFormat.dwChannelMask); + + if(outFormat.dwChannelMask == 0 && inFormat.dwSamplesPerFrame == outFormat.dwSamplesPerFrame) + peq.initialize(outFormat.fFramesPerSecond, outFormat.dwSamplesPerFrame, inFormat.dwChannelMask); + else + peq.initialize(outFormat.fFramesPerSecond, outFormat.dwSamplesPerFrame, outFormat.dwChannelMask); return hr; } diff --git a/RegistryHelper.cpp b/RegistryHelper.cpp index 5f744f4..5c58352 100644 --- a/RegistryHelper.cpp +++ b/RegistryHelper.cpp @@ -291,6 +291,21 @@ bool RegistryHelper::keyExists(wstring key) return result; } +bool RegistryHelper::valueExists(wstring key, wstring valuename) +{ + LSTATUS status; + HKEY keyHandle; + status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &keyHandle); + if(status != ERROR_SUCCESS) + throw RegistryException(L"Error while opening registry key HKEY_LOCAL_MACHINE\\" + key + L": " + getSystemErrorString(status)); + + DWORD type; + DWORD bufSize; + status = RegQueryValueExW(keyHandle, valuename.c_str(), NULL, &type, NULL, &bufSize); + RegCloseKey(keyHandle); + return status == ERROR_SUCCESS; +} + vector RegistryHelper::enumSubKeys(wstring key) { vector result; diff --git a/RegistryHelper.h b/RegistryHelper.h index c66ca30..434f9d0 100644 --- a/RegistryHelper.h +++ b/RegistryHelper.h @@ -38,6 +38,7 @@ public: static void takeOwnership(std::wstring key); static std::vector enumSubKeys(std::wstring key); static bool keyExists(std::wstring key); + static bool valueExists(std::wstring key, std::wstring valuename); static unsigned long valueCount(std::wstring key); static void saveToFile(std::wstring key, std::wstring valuename, std::wstring filepath); static std::wstring getGuidString(GUID guid);