2017-12-28 81 views
1

Windows API, 즉 RegCreateKeyEx 함수를 사용하여 새 레지스트리 키를 만든 다음 GetSecurityInfo을 사용하여 DACL을 가져 오려고합니다. 모든 어설 션은 원활하게 진행될 때까지 GetSecurityInfo 함수 호출이 발생하여 잘못된 핸들 값 오류 (오류 6)가 발생합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?C++ windows API GetSecurityInfo 무효 처리 주어진

이 좀 더 정교한 프로젝트의 일환 그래서 나는 단지 줄 것입니다 (또는 내가 생각하는,하지만 난 너무 나머지를 추가 할 수있는) 여기에 관련 부분을 :

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; 
} 

그리고 RegCreateKey 버전으로 GetSecurityInfo 래퍼, 같은 이유 및 기능 :

다음과
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; 
} 

이제이 함수를 호출하는 코드가 될 때 :

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)); 

출력은 문제가 어디에서 꽤 분명하다 (나는 조건을 검사 한 후에 조건이 실패 할 경우를 대비해 오류 텍스트와 함께 그것을 인쇄하는 약간 더 장황한 주장을 구현했다) :

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); } 

사전에 감사합니다! 그 값을 반환한다 HKEY 여기서

+0

작업을 단단하게하는이 래퍼에서는 감각이란? 및 SetLastError' 여기에 필요하지 않습니다 - Reg API 그냥 true/false 대신 정말 더 나은 디자인 및 사용하기 쉬운 반환 오류 코드 – RbMm

+0

@RbMm 그들은 코드가 더 정교한 프로젝트의 일부이며 일관성, 더 큰 코드베이스로 작업하는 것이 훨씬 더 쉽습니다 :) –

+0

오류 코드를 반환하는 함수로 작업 - 참/거짓을 반환하고 마지막 오류를 설정하는 것보다 훨씬 쉽습니다. – RbMm

답변

3

함수 CreateNewRegKeyHKEY 포인터를 리턴한다. 이 포인터를 GetSecurityInfo()에 전달하면 대신 HANDLE이 필요합니다. 컴파일러에서는 HANDLEtypedef void *HANDLE;으로 선언되어 있기 때문에 알 수 없습니다.

auto createdKey = static_cast<PHKEY>(malloc(sizeof HKEY)); 

HKEY createdKey = NULL; 

로하고 HKEY의 주소를 전달하는 &createdKeyRegCreateKeyEx_safe() 전화 :

는 오류가 대체 해결하려면.

+0

감사합니다. 나는 포인터/자동 변수와 같은 것들을 사용하여 더 나은 느낌을 얻을 수 있도록하기 위해'GetSecurityInfo' 함수 호출에서 newRegKey를 dereferencing함으로써 실제로 수정했습니다 : 'GetSecurityInfo_safe ( * newRegKey , SE_REGISTRY_KEY, ... ' 그러나 나는 당신의 도움이 없었다면 다시는 고마워하지 않을 것입니다! –