#define WIN32_LEAN_AND_MEAN #include #include /* snprintf */ static bool registry_write_string(HKEY reg, const char *name, const char *value, size_t len) { HRESULT hr = RegSetValueExA( reg, name, 0, REG_SZ, reinterpret_cast (value), static_cast((len + 1) * sizeof(char)) ); return hr == ERROR_SUCCESS; } static const char *base_key() { if (sizeof(void *) == 4) { return "Software\\Classes\\WOW6432Node\\CLSID"; } else { return "Software\\Classes\\CLSID"; } } static void format_clsid(REFIID clsid, char *value, size_t max) { snprintf(value, max, "{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}", clsid.Data1, clsid.Data2, clsid.Data3, clsid.Data4[0], clsid.Data4[1], clsid.Data4[2], clsid.Data4[3], clsid.Data4[4], clsid.Data4[5], clsid.Data4[6], clsid.Data4[7]); } extern "C" HRESULT register_faudio_dll(void *DllHandle, REFIID clsid) { // not your typical COM register functions because we're "hijacking" the existing XAudio2 registration // - COM classes are historically registered under HKEY_CLASSES_ROOT // - on modern Windows version this is a merged from on HKEY_LOCAL_MACHINE/Software/Classes and HKEY_CURRENT_USER/Software/Classes // - the system-wide configuration is stored under HKEY_LOCAL_MACHINE // - we override the registration for the XAudio2 DLLs for the current user char str_clsid[40]; format_clsid(clsid, str_clsid, sizeof(str_clsid) / sizeof(char)); char key[2048]; snprintf(key, sizeof(key) / sizeof(char), "%s\\%s\\InProcServer32", base_key(), str_clsid); // open registry (creating key if it does not exist) HKEY registry_key = NULL; if (RegCreateKeyExA(HKEY_CURRENT_USER, key, 0, NULL, 0, KEY_WRITE, NULL, ®istry_key, NULL)) { return E_FAIL; } // retrieve path to the dll char path[2048]; DWORD len = GetModuleFileNameA(reinterpret_cast(DllHandle), path, sizeof(key) / sizeof(char)); // update registry registry_write_string(registry_key, NULL, path, len); RegCloseKey(registry_key); return S_OK; } extern "C" HRESULT unregister_faudio_dll(void *DllHandle, REFIID clsid) { // open registry HKEY registry_key = NULL; if (RegOpenKeyExA(HKEY_CURRENT_USER, base_key(), 0, DELETE | KEY_SET_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, ®istry_key)) { return E_FAIL; } char str_clsid[40]; format_clsid(clsid, str_clsid, sizeof(str_clsid) / sizeof(char)); // delete key HRESULT hr = RegDeleteTreeA(registry_key, str_clsid); RegCloseKey(registry_key); return S_OK; }