我不是 C++ 开发人员,所以我想我的程序无法运行只是我的错。 我想查找 Windows 组的 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,为什么?
最佳答案
您的代码有几个明显的问题...
1) ConvertSidToStringSid()
的原型(prototype)是 BOOL ConvertSidToStringSid(PSID Sid, LPTSTR *StringSid)
;这意味着您的 typedef 应该是 typedef BOOL (WINAPI *tConvertSidToStringSid)(PSID,LPTSTR *);
2) 您正在查找 ANSI 版本并传递 wchar_t *...您应该查找宽字符版本 ConvertSidToStringSid()
或者,更好的解决方案,恕我直言,查找 ConvertSidToStringSid
并使用 TCHAR *
而不是 wchar_t *
因为无论您的 unicode 编译设置是什么,它都可以工作,并且它与 typedef 匹配。
3) 最后,由于 typedef 损坏,您被允许将错误的数据类型传递给函数。它需要一个 LPTSTR *
而你传递给它一个 LPTSTR
(好吧,实际上你传递一个 wchar_t *
... LPTSTR
实际上是映射到 wchar_t *
的 unicode 感知类型,如果您使用的是宽字符,但您调用的函数需要指向该指针的指针而不是指针本身。
所以,固定的代码是:
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;
}
请注意对 typedef 的更改、对 GetProcAddress 调用的更改(我们使用 # 将函数名称字符串化(根据您的 unicode 设置,这将是 ConvertSidToStringSidA 或 ConvertSidToStringSidW)以及传递 psz 地址的更改而不是指针本身。
现在您唯一的问题是您可能会泄漏该 psz,除非您确保通过调用 LocalFree()
在调用者中释放它。
请注意,根据调用代码,您可能希望将 typedef 转换为 wchar_t **
而不是 LPTSTR *
,然后使用 ConvertSidToStringSidW 版本强制转换结果始终是一个宽字符串。
关于c++ - 将 SID 转换为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4933219/