C++ ReferenceDomainName为NULL时发生LookupAccountName错误
如果我没有在变量中保存可选的C++ ReferenceDomainName为NULL时发生LookupAccountName错误,c++,windows,winapi,msdn,C++,Windows,Winapi,Msdn,如果我没有在变量中保存可选的ReferencedDomainName,函数将返回false,并且我无法检索使用过的Sid。如果医生说它是可选的,为什么我也需要包括它?这是我的密码: 这将起作用并返回SID: DWORD size; TCHAR lpAccountName[USERNAME_SIZE]; PSID Sid = (PSID)LocalAlloc(LPTR, SECURITY_MAX_SID_SIZE); LPSTR DomainName = (LPST
ReferencedDomainName
,函数将返回false
,并且我无法检索使用过的Sid。如果医生说它是可选的,为什么我也需要包括它?这是我的密码:
这将起作用并返回SID:
DWORD size;
TCHAR lpAccountName[USERNAME_SIZE];
PSID Sid = (PSID)LocalAlloc(LPTR, SECURITY_MAX_SID_SIZE);
LPSTR DomainName = (LPSTR)LocalAlloc(LPTR, sizeof(TCHAR) * 1024);
DWORD cbSid = SECURITY_MAX_SID_SIZE;
LPSTR userSIDBuffer = (LPSTR)LocalAlloc(LPTR, sizeof(TCHAR) * cbSid);
SID_NAME_USE peUse;
size = USERNAME_SIZE;
if (!GetUserName(lpAccountName, &size))
{
_error("Could not retrieve username.");
}
printf("Username found: %s\n", lpAccountName);
size = 1024;
if (!LookupAccountName(NULL, lpAccountName, Sid, &cbSid, DomainName, &size, &peUse))
{
_error("Could not look up account.");
}
return Sid;
但是如果我删除DomainName
并根据MSDN文档更改size=0
,我会得到一个122错误,并且不会返回任何Sid
size = 0;
if (!LookupAccountName(NULL, lpAccountName, Sid, &cbSid, NULL, &size, &peUse))
{
_error("Could not look up account.");
}
如果您提供null而不是
DomainName
,函数将在size
中存储所需的DomainName
缓冲区大小,最后一个错误是error\u buffer
(122)。因此,要获得实际结果,您必须提供足够容量的DomainName
缓冲区。我无法告诉您,当您只需要Sid时,为什么他们会强制您检索域,但API就是这样设计的,您对此无能为力。domain参数是可选的,因为API被设计为两次调用,一次用于检索所需的缓冲区大小,另一次用于实际填充缓冲区
如果您不喜欢此设计,可以使用辅助函数将其抽象出来:
BOOL GetAccountSidFromName(LPCTSTR Account, PSID Sid, const DWORD SidSize)
{
SID_NAME_USE snu;
DWORD cbSid = SidSize, cchRD = 0;
LPTSTR rd = NULL;
BOOL succ = LookupAccountName(NULL, Account, Sid, &cbSid, rd, &cchRD, &snu);
if (!succ)
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
rd = (LPTSTR) LocalAlloc(LPTR, cchRD * sizeof(*rd));
if (!rd)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
cbSid = SidSize;
succ = LookupAccountName(NULL, Account, Sid, &cbSid, rd, &cchRD, &snu);
LocalFree(rd);
}
return succ;
}
...
TCHAR lpAccountName[USERNAME_SIZE];
DWORD size = USERNAME_SIZE;
if (!GetUserName(lpAccountName, &size))
{
_error("Could not retrieve username.");
}
BYTE sidbuf[SECURITY_MAX_SID_SIZE];
PSID sid = (PSID) sidbuf;
BOOL success = GetAccountSidFromName(lpAccountName, sid, sizeof(sidbuf));
if (!success)
{
_error("Could not retrieve sid.");
}
但我不想这样,我只想要Sid,文档上说域名是可选的。如果我必须提供它,它似乎不是可选的。@AlexandruAntochi“可选”表示允许为空。然而,这并不意味着在这种情况下,函数将执行相同的工作。它只报告所需的缓冲区大小,仅此而已。@AlexandruAntochi:您不必提供域名。这是一个
Out
参数。您只需提供一个缓冲区即可接收它。顺便说一句,SID仅在与域结合时才有意义。你是否想要这个域名并不重要。SID是特定于域的。