Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;windows API GetSecurityInfo给定的句柄无效_C++_Windows_Security_Winapi_Registry - Fatal编程技术网

C++ C++;windows API GetSecurityInfo给定的句柄无效

C++ C++;windows API GetSecurityInfo给定的句柄无效,c++,windows,security,winapi,registry,C++,Windows,Security,Winapi,Registry,我正在尝试使用Windows API在Windows 10中创建一个新的注册表项,即RegCreateKeyEx函数,然后使用GetSecurityInfo获取其DACL。所有的断言都进行得很顺利,直到我进行了所说的GetSecurityInfo函数调用,该调用给出了一个无效的句柄值错误(错误6)。我做错了什么 这是一个更复杂的项目的一部分,因此我只在这里给出(或我认为是什么,但我也可以添加其余部分)相关部分: RegCreateKeyEx的包装器,使输出更易于处理并设置遇到的任何错误: inl

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

这是一个更复杂的项目的一部分,因此我只在这里给出(或我认为是什么,但我也可以添加其余部分)相关部分:

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

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;
}
上述函数的包装器,在检查创建的键是否有效后,应返回该键的句柄:

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;
}
现在调用这些函数的代码如下所示:

 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));
输出非常清楚问题出在哪里(我实现了一个稍微详细一点的断言,在检查条件后,它会打印它,以及条件失败时的错误文本):

断言:

#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); }
定义详细(1)
#如果((cond)==TRUE),则定义断言(cond)\

{if(_VERBOSE)cout函数
CreateNewRegKey
正在返回一个指向
HKEY
的指针,该指针应按值返回
HKEY
。将该指针传递给
GetSecurityInfo()
它需要一个
句柄
。编译器不会注意到,因为
句柄
被声明为
typedef void*HANDLE;

要更正错误,请更换:


并调用
RegCreateKeyEx_safe()
使用
&createdKey
传递
HKEY

的地址,这个包装器的意义是什么,这使得工作更加困难?这里不需要
SetLastError
——Reg api只返回错误代码,而不是true/false,这确实是更好的设计,更容易操作use@RbMm它们是必需的,因为代码是m的一部分更复杂的项目和一致性使使用更大的代码库变得更容易:)使用返回错误代码的函数-比使用返回真/假和设置最后一个错误的函数容易得多Windwes API中的一些函数使用“经典”返回错误代码而其他人返回winapi BOOL的方式,没有固有的一致性,所以我不得不自己破解它。谢谢!我试图强迫自己主要/仅使用指针、自动变量等来更好地理解它们,所以我实际上通过在
GetSecurityInfo
中取消引用newRegKey来修复它函数调用:
GetSecurityInfo\u safe(*newRegKey,SE\u REGISTRY\u KEY,…
但是如果没有您的帮助,我不会注意到,再次感谢!
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.
#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); }
auto createdKey = static_cast<PHKEY>(malloc(sizeof HKEY));
HKEY createdKey = NULL;