首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ windows API GetSecurityInfo无效句柄

C++ windows API GetSecurityInfo无效句柄
EN

Stack Overflow用户
提问于 2017-12-28 14:25:46
回答 1查看 456关注 0票数 1

我正在尝试使用Windows (即RegCreateKeyEx函数)在Windows 10中创建一个新的注册表项,然后使用GetSecurityInfo获取其DACL。所有断言都进行得很顺利,直到调用到上述GetSecurityInfo函数为止,这会导致一个无效的句柄值错误(错误6)。我做错了什么?

这是一个更详细的项目的一部分,所以我将只给出(或者我认为是什么,但我也可以在这里添加其他的)相关部分:

用于RegCreateKeyEx的包装器,以使输出更易于处理并设置遇到的任何错误:

代码语言:javascript
复制
inline extern auto RegCreateKeyEx_safe(
    _In_       const HKEY                  hKey,
    _In_       const LPCTSTR               lpSubKey,
    _Reserved_ const DWORD                 Reserved,
    _In_opt_   const LPTSTR                lpClass,
    _In_       const DWORD                 dwOptions,
    _In_       const REGSAM                samDesired,
    _In_opt_   const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    _Out_      const PHKEY                 phkResult,
    _Out_opt_  const LPDWORD               lpdwDisposition)
{
    const auto result = 
        RegCreateKeyEx(
            hKey,
            lpSubKey,
            Reserved,
            lpClass,
            dwOptions,
            samDesired,
            lpSecurityAttributes,
            phkResult,
            lpdwDisposition);
    if (result != ERROR_SUCCESS)
        SetLastError(result);
    return result == ERROR_SUCCESS;
}

上述函数的包装器,它应该在检查创建的键是否有效后返回该键的句柄:

代码语言:javascript
复制
inline extern auto CreateNewRegKey(
    HKEY                  hKey,
    LPCTSTR               lpSubKey,
    DWORD                 Reserved,
    LPTSTR                lpClass,
    DWORD                 dwOptions,
    REGSAM                samDesired,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    LPDWORD               lpdwDisposition)
{
    auto createdKey = static_cast<PHKEY>(malloc(sizeof HKEY));

    assert(
        RegCreateKeyEx_safe(
            hKey,
            lpSubKey,
            Reserved,
            lpClass,
            dwOptions,
            samDesired,
            lpSecurityAttributes,
            createdKey,
            lpdwDisposition));

    assert(createdKey != INVALID_HANDLE_VALUE);

    return createdKey;
}

以及GetSecurityInfo的包装器,与RegCreateKey版本相同的原因和功能:

代码语言:javascript
复制
inline extern auto GetSecurityInfo_safe(
    _In_      const HANDLE                handle,
    _In_      const SE_OBJECT_TYPE        ObjectType,
    _In_      const SECURITY_INFORMATION  SecurityInfo,
    _Out_opt_       PSID*                 ppsidOwner,
    _Out_opt_       PSID*                 ppsidGroup,
    _Out_opt_       PACL*                 ppDacl,
    _Out_opt_       PACL*                 ppSacl,
    _Out_opt_       PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
{
    const auto result =
        GetSecurityInfo(
            handle,
            ObjectType,
            SecurityInfo,
            ppsidOwner,
            ppsidGroup,
            ppDacl,
            ppSacl,
            ppSecurityDescriptor);
    if (result != ERROR_SUCCESS)
        SetLastError(result);
    return result == EXIT_SUCCESS;
}

现在调用这些函数的代码如下:

代码语言:javascript
复制
 const auto newRegKey = 
        CreateNewRegKey(
            HKEY_CURRENT_USER, 
            SUBKEY_PATH, 
            NULL, 
            nullptr, 
            REG_OPTION_NON_VOLATILE, 
            KEY_ALL_ACCESS, 
            NULL,  //securityAttributes, 
            nullptr);

    assert(
        GetSecurityInfo_safe(
            newRegKey,
            SE_REGISTRY_KEY,
            DACL_SECURITY_INFORMATION,
            NULL,
            NULL,
            oldDacl,
            NULL,
            NULL));

输出对于问题的位置非常清楚(我实现了一个稍微冗长的断言,即在检查条件之后,它会打印它,同时打印错误文本,以防条件失败):

代码语言:javascript
复制
SUCCESS:        RegCreateKeyEx_safe( hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, createdKey, lpdwDisposition)
SUCCESS:        createdKey != INVALID_HANDLE_VALUE
FAILURE:        GetSecurityInfo_safe( newRegKey, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, oldDacl, NULL, NULL)

ERROR-6:        The handle is invalid.

断言:

代码语言:javascript
复制
#define _VERBOSE            (1)
#define assert(cond)        if((cond) == TRUE) \
                                { if (_VERBOSE) cout << "SUCCESS:\t" << #cond << endl; } \
                            else \
                                {cout << "FAILURE:\t" << #cond << "\n\nERROR-" << GetLastError() << ":\t" << GetLastErrorAsString() << "\n\n"; exit(EXIT_FAILURE); }

提前谢谢你!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-28 14:42:41

函数CreateNewRegKey返回一个指向HKEY的指针,在那里它应该按值返回HKEY。将这个指针传递给GetSecurityInfo(),后者需要一个HANDLE。编译器不会注意到,因为HANDLE被声明为typedef void *HANDLE;

若要更正错误,请替换:

auto createdKey =static_cast(malloc(大盘));

使用

代码语言:javascript
复制
HKEY createdKey = NULL;

并使用RegCreateKeyEx_safe()调用&createdKey来传递HKEY地址。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48009227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档