思路
- 首先枚举Capture、Render声卡设备;
- 在注册表SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio\\下对上述声卡设备进行属性设置,主要有两个属性键{f19f064d-082c-4e27-bc73-6882a1bb8e4c},0和{e4870e26-3cc5-4cd2-ba46-ca0a9a70ed04},0,MSDN对上述两键值结构的描述为WAVEFORMATEXTENSIBLE。通过观察发现,键值长度为48bytes,而WAVEFORMATEXTENSIBLE结构长度为40bytes,对于键值的前8bytes的具体含义暂时还没有搞清楚,通过观察不同电脑不同声卡的上述两键值,猜测前8bytes为一种标识。
- 本意想通过RegSetValueEx直接对键值进行修改来实现统一配置,后来发现无法获得写的权限(至少我没发现该如何提权获得写入权限)。后发现人为手动编辑注册表是可以修改写入的,通过编写注册表文件并运行也可以修改写入。故采用此法来达到声卡统一配置。
代码
//-----------------------------------------------------------
// This function enumerates all active (plugged in) audio
// rendering endpoint devices. It prints the friendly name
// and endpoint ID string of each endpoint device.
//-----------------------------------------------------------
#include <mmdeviceapi.h>
#include <FunctionDiscoveryKeys_devpkey.h>
#include <iostream>
#include <string>
#include <map>
#include <tchar.h>
#include <queue>
#include <AccCtrl.h>
#include <AclAPI.h>
#include <fstream>
using namespace std;
#define EXIT_ON_ERROR(hres) \
if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
{ (punk)->Release(); (punk) = NULL; }
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
map<string,string> render,capture,parameters;//render存放录音器的名称和CLSID,capture存放播放器的名称和CLSID,parameters存放相应设备CLSID的配置文件标识(8bytes)
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
DWORD dwType = REG_BINARY | REG_DWORD | REG_EXPAND_SZ | REG_MULTI_SZ | REG_NONE | REG_SZ;
std::queue<std::wstring> keystack;
//#define COMMAND_OUTPUT
void query(HKEY rootKey, const wchar_t* path , string clsid)
{
#ifdef COMMAND_OUTPUT
_tprintf(TEXT("\nProcess: %s :\n"), path);
#endif
HKEY hKey;
if (RegOpenKeyEx(rootKey, path, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return;
}
TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
DWORD cbName; // size of name string
TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name
DWORD cchClassName = MAX_PATH; // size of class string
DWORD cSubKeys = 0; // number of subkeys
DWORD cbMaxSubKey; // longest subkey size
DWORD cchMaxClass; // longest class string
DWORD cValues; // number of values for key
DWORD cchMaxValue; //