Skip to content

Latest commit

 

History

History
87 lines (72 loc) · 3.48 KB

如何修改需要权限的注册表项值.md

File metadata and controls

87 lines (72 loc) · 3.48 KB

如何修改需要权限的注册表项值

Q:

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,导致无法写入?

A:

右键查看此注册表项 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;
}

Reference

Registry Key Security and Access Rights