0

我不是 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,为什么?

4

4 回答 4

1

您的代码有一些明显的问题......

1) 的原型ConvertSidToStringSid()BOOL ConvertSidToStringSid(PSID Sid, LPTSTR *StringSid); 这意味着您的 typedef 应该是typedef BOOL (WINAPI *tConvertSidToStringSid)(PSID,LPTSTR *);

2)您正在查找 ANSI 版本并传递 wchar_t *... 您应该查找宽字符版本ConvertSidToStringSid(),或者更好的解决方案,恕我直言,查找ConvertSidToStringSid并使用 aTCHAR *而不是 awchar_t *因为无论您使用什么,这都会起作用unicode 编译设置是,它与 typedef 匹配。

3) 最后,由于 typedef 损坏,您被允许将错误的数据类型传递给函数。它需要 aLPTSTR *并且您正在传递它 a LPTSTR(嗯,实际上您正在传递 a wchar_t *...如果您使用宽字符LPTSTR,实际上是映射到 a 的 unicode 感知类型,但您调用的函数需要 awchar_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 版本来强制结果始终为宽字符串。

于 2011-02-08T13:06:16.113 回答
0

也许您的pConvertSidToStringSid(Sid, psz)调用不成功并且SpcLookupName()返回值未定义,因为您没有返回任何内容。

你为什么要ConvertSidToStringSidA和 wchar_t 混在一起?ConvertSidToStringSid直接使用from会更好Sddl.h

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

您还应该LPTSTR从您的函数返回而不是wchar_t *

于 2011-02-08T12:54:06.423 回答
0

您使用ConvertSidToStringSidAwhich 将返回 ANSI 字符串,同时您期望wchar_t*. 尝试ConvertSidToStringSidW改用。或者只是包含Sddl.h并使用ConvertSidToStringSid.

于 2011-02-08T12:54:16.607 回答
0

当您需要 Unicode 版本时,您正在调用函数的 ANSI 版本"ConvertSidToStringSidW"

此外,您的内存泄漏很小,因为您并不总是 freeing Sid

于 2011-02-08T12:55:54.683 回答