我不是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,为什么?
答案 0 :(得分:1)
您的代码有一些明显的问题......
1)ConvertSidToStringSid()
的原型是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
实际上是unicode感知类型如果您使用的是宽字符,则映射到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;
}
注意对typedef的更改,对GetProcAddress调用的更改(我们使用#来字符串化函数名称(根据你的unicode设置将是ConvertSidToStringSidA或ConvertSidToStringSidW)以及传递psz地址的更改而不是指针本身。
现在你唯一的问题是你可能会泄漏psz,除非你确保通过拨打LocalFree()
来确保你在呼叫者中释放它。
请注意,根据调用代码,您可能希望将typedef转换为wchar_t **
而不是LPTSTR *
,然后使用ConvertSidToStringSidW版本强制结果始终为宽字符串。< / p>
答案 1 :(得分:0)
也许您的pConvertSidToStringSid(Sid, psz)
调用不成功,SpcLookupName()
返回值未定义,因为您没有返回任何内容。
为什么要将ConvertSidToStringSidA
与wchar_t混合?最好直接使用ConvertSidToStringSid
中的Sddl.h
:
#define _WIN32_WINNT 0x0500
#include <Sddl.h>
您还应该从函数返回LPTSTR
而不是wchar_t *
答案 2 :(得分:0)
您使用ConvertSidToStringSidA
将返回ANSI字符串,同时您需要wchar_t*
。请尝试使用ConvertSidToStringSidW
。或者只需加入Sddl.h
并使用ConvertSidToStringSid
。
答案 3 :(得分:0)
当您需要Unicode版本"ConvertSidToStringSidW"
时,您正在调用该函数的ANSI版本。
此外,由于您不能释放Sid
,因此内存泄漏很少。