将SID转换为String

时间:2011-02-08 12:49:08

标签: 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,为什么?

4 个答案:

答案 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,因此内存泄漏很少。