C++ C++;windows API GetSecurityInfo给定的句柄无效
我正在尝试使用Windows API在Windows 10中创建一个新的注册表项,即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
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;