2011-02-08 5 views
0

저는 C++ 개발자가 아니므로 내 프로그램이 작동하지 않는 것은 내 잘못이라고 생각합니다. Windows 그룹의 SID를 조회하고 읽을 수있는 SID를 반환하고 싶습니다.SID를 문자열로 변환

wchar_t* SpcLookupName(LPCTSTR lpszSystemName, LPCTSTR lpszAccountName) { 

PSID   Sid; 
DWORD  cbReferencedDomainName, cbSid; 
LPTSTR  ReferencedDomainName; 
SID_NAME_USE eUse; 

cbReferencedDomainName = cbSid = 0; 
if (LookupAccountName(lpszSystemName, lpszAccountName, 0, &cbSid, 
        0, &cbReferencedDomainName, &eUse)) { 
    SetLastError(ERROR_NONE_MAPPED); 
    return 0; 
} 

if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return 0; 

if (!(Sid = (PSID)LocalAlloc(LMEM_FIXED, cbSid))) return 0; 

ReferencedDomainName = (LPTSTR)LocalAlloc(LMEM_FIXED, cbReferencedDomainName); 

if (!ReferencedDomainName) { 
    LocalFree(Sid); 
    return 0; 
} 

if (!LookupAccountName(lpszSystemName, lpszAccountName, Sid, &cbSid, 
        ReferencedDomainName, &cbReferencedDomainName, &eUse)) { 
    LocalFree(ReferencedDomainName); 
    LocalFree(Sid); 
    return 0; 
} 

wchar_t* psz; 

// Loading ConvertSidToStringSid 
typedef BOOL (WINAPI *tConvertSidToStringSid)(PSID,wchar_t*); 

tConvertSidToStringSid pConvertSidToStringSid=0; 

HINSTANCE handle = ::LoadLibrary("Advapi32.dll"); 

pConvertSidToStringSid = (tConvertSidToStringSid) ::GetProcAddress(handle, "ConvertSidToStringSidA"); 

if(pConvertSidToStringSid(Sid, psz)){        
    return psz; 
} 
} 

제 문제는 함수가 SID가 아닌 이상한 문자 만 반환한다는 것입니다. 이유는 무엇입니까?

+0

어떻게 지내요? -이 함수는 문자열에 대한 포인터를 반환합니다. print 문을 볼 수 없습니까? – Tom

+0

나는 그것을 메시지 상자로 테스트했지만, 지금은 코드에 나와 있지 않다. – Taram777

+0

정말 PowerShell이나 .net 또는 Python 같은 곳에서 쉽게 사용할 수 있습니다. 이처럼 C++에서 도구를 해킹하는 것은 고통 스럽습니다. 특히 C++에 능통하지 않은 경우 특히 그렇습니다. 어쨌든이 작업을 수행 할 수있는 res 키트 콘솔 앱이있을 것입니다. –

답변

1

1) ConvertSidToStringSid()에 대한 프로토 타입 BOOL ConvertSidToStringSid(PSID Sid, LPTSTR *StringSid)입니다 ... 당신의 코드를 잘못 분명 몇 가지있다; 이는 당신의 형식 정의가되어야한다는 의미는 ANSI 버전을보고하고 wchar_t를 전달하는 typedef BOOL (WINAPI *tConvertSidToStringSid)(PSID,LPTSTR *);

2) * ... 당신도 ConvertSidToStringSid를 검색, 와이드 문자 버전 ConvertSidToStringSid() 또는, 더 나은 솔루션, 이럴를 검색한다 wchar_t * 대신 TCHAR *을 사용하십시오. 이는 유니 코드 컴파일 설정이 무엇이든 관계없이 작동하며 typedef와 일치합니다.

3) 마지막으로 깨진 typedef로 인해 잘못된 데이터 형식을 함수에 전달할 수 있습니다. 그것은 LPTSTR *을 원합니다. 실제로는 wchar_t *을 전달합니다. LPTSTR은 실제 와이드 문자를 사용하는 경우 wchar_t *에 매핑되는 유니 코드 인식 유형입니다. . 그 포인터에 대한 포인터가 아닌 포인터 자체를 원하는 요구하고있다

을 따라서, 고정 된 코드는 다음과 같습니다

typedef BOOL (WINAPI *tConvertSidToStringSid)(PSID,LPTSTR*); 

tConvertSidToStringSid pConvertSidToStringSid=0; 

HINSTANCE handle = ::LoadLibrary("Advapi32.dll"); 



pConvertSidToStringSid = (tConvertSidToStringSid) ::GetProcAddress(handle, #ConvertSidToStringSid); 

if(pConvertSidToStringSid(Sid, &psz)){        
    return psz; 
} 

참고 타입 정의에 대한 변경, 우리가 사용하는 GetProcAddress를 호출에 대한 변화 (함수 이름을 문자열 화하려면 # (유니 코드 설정에 따라 ConvertSidToStringSidA 또는 ConvertSidToStringSidW가 됨) 및 pas로 변경 포인터 자체가 아니라 psz의 주소.

이제 유일한 문제는 LocalFree()으로 전화를 걸어 발신자에게 전화를 걸지 않는 한 해당 psz가 유출 될 가능성이 있다는 것입니다.

호출 코드에 따라 LPTSTR * 대신 typedef를 wchar_t **으로 변환 한 다음 ConvertSidToStringSidW 버전을 사용하여 결과를 항상 와이드 문자열로 만들 수 있습니다.

+0

그런 식으로 시도했지만 지금은이 두 메시지를 얻습니다 : "프로그램에서"# "과"ConvertSidToStringSid '가이 범위에서 선언되지 않았습니다 ". – Taram777

+0

좋아, 나는 그것을 결코 컴파일하지 않았고 텍스트 양식의 이름을위한 또 다른 매크로를 만들 수 없었다. wchar_t 버전과 ConvertSidToStringSidW를 사용하기 만하면 typedef와 함수 호출을 수정해야합니다. –

+0

대단히 감사합니다. – Taram777

0

아무 것도 반환하지 않기 때문에 호출이 성공하지 못하고 SpcLookupName() 반환 값이 정의되지 않았을 수 있습니다.

왜을 wchar_t와 혼합합니까?

#define _WIN32_WINNT 0x0500 
#include <Sddl.h> 

당신은 또한 당신이 wchar_t*을 기대하는 동시에, ANSI 문자열을 반환하는 ConvertSidToStringSidA를 사용 wchar_t *

+0

pConvertSidToStringSid (Sid, psz)가 성공했습니다. 메시지 상자로 테스트했는데, 여기에 붙여 넣은 코드에는 없습니다. – Taram777

0

함수에서 LPTSTR를 반환하는 대신한다 : 직접 Sddl.h에서 ConvertSidToStringSid를 사용하는 것이 좋을 것이다 . 대신 ConvertSidToStringSidW을 사용해보십시오. 또는 Sddl.h을 포함하고 ConvertSidToStringSid을 사용하십시오.

+0

전에 ConvertSidToStringSidW 함께 시도하고 작동하지 않았다. 그래서 ConvertSidToStringSidA는 다른 시도였습니다. 여기에 그것을 섞어서 미안합니다. ssdl.h가 포함되어 있지만 "ConvertSidToStringSid"를 호출하면 컴파일러에서 " 'ConvertSidToStringSid'가이 범위에서 선언되지 않았습니다. '라고 말합니다. – Taram777

0

유니 코드 버전 "ConvertSidToStringSidW"을 사용하려면 ANSI 버전의 함수를 호출해야합니다.

또한 Sid을 항상 해제하지 않으므로 메모리 누수가 적습니다.