c++ - 将 SID 转换为字符串

标签 c++ winapi sid

我不是 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/

相关文章:

c++ - 如何迭代 vector C++ 中的特定元素?

c# - 添加一个 "Check for Updates"选项

windows - 在最终用户系统上调试 "application configuration is incorrect"问题的好方法?

c - 如何使用 winapi 将 .png 转换为 .bmp?

c++ - 使用 SID 获取 LocalGroup Windows C++ 的名称

c# - 通过 SID 解析显示用户名的最佳方法?

c++ - 为什么while循环不退出?

c++ - 找不到 QtCreator 调试器

c - 如何在进行系统调用时阻止控制台窗口出现?

node.js - nodejs sails : the sails. sid 变量返回未定义