LONG result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio\\Capture", 0, KEY_ALL_ACCESS, &hKey);
上面代码为何在管理员权限下KEY_ALL_ACCESS还是返回ERROR_ACCESS_DENIED,导致无法写入?
右键查看此注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Capture 的所有者为System,需要修改下访问权限,就可以修改表项了:
/** Author: heqingrui */
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include <mmdeviceapi.h>
#include <aclapi.h>
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
);
int main()
{
HANDLE hProcToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hProcToken);
const TCHAR* szSubKey = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio\\Capture\\{05c28e8c-f4f4-4340-82f0-6d0a55d335c4}";
// open the subkey
HKEY hSubKey;
DWORD dwResult = ERROR_SUCCESS;
dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
if (dwResult == ERROR_ACCESS_DENIED) {
SetPrivilege(hProcToken, SE_TAKE_OWNERSHIP_NAME, TRUE);
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, WRITE_OWNER, &hSubKey)) {
SECURITY_DESCRIPTOR sd = {};
if (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
PSID pSid = nullptr;
SID_IDENTIFIER_AUTHORITY SIDAuthAdmin = SECURITY_NT_AUTHORITY;
if (AllocateAndInitializeSid(&SIDAuthAdmin, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid)) {
if (SetSecurityDescriptorOwner(&sd, pSid, FALSE)) {
dwResult = RegSetKeySecurity(hSubKey, OWNER_SECURITY_INFORMATION, &sd);
RegCloseKey(hSubKey);
if (ERROR_SUCCESS == (dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, WRITE_DAC, &hSubKey))) {
dwResult = RegSetKeySecurity(hSubKey, DACL_SECURITY_INFORMATION, &sd);
RegCloseKey(hSubKey);
}
}
FreeSid(pSid);
}
}
}
dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
}
if (dwResult == ERROR_SUCCESS) {
LONG lRes = ERROR_SUCCESS;
DWORD nValue(0x31000004);
DWORD cbValue(sizeof(DWORD));
lRes = RegSetKeyValueW(hSubKey, NULL, L"DeviceState", REG_DWORD, (LPCVOID)&nValue, cbValue);
if (lRes == ERROR_SUCCESS) {
wprintf(L"Set DeviceState:0x%08x.\n", nValue);
}
DWORD nResult(0);
DWORD dwBufferSize = sizeof(DWORD);
LONG lRes = RegQueryValueExW(hSubKey, L"DeviceState", 0, NULL, reinterpret_cast<LPBYTE>(&nResult), &dwBufferSize);
if (lRes == ERROR_SUCCESS) {
wprintf(L"Get DeviceState:0x%08x.\n", nResult);
}
RegCloseKey(hSubKey);
}
return 0;
}