【问题标题】:"The parameter is incorrect" error from LookupAccountSid()来自 LookupAccountSid() 的“参数不正确”错误
【发布时间】:2016-08-11 02:13:03
【问题描述】:

我以为我在 MSDN 上正确阅读了文档,但显然我没有?我不完全确定我到底做错了什么,我已经准备好拔掉头发了。

EVENTLOGRECORD 结构的文档提供了 SID 的偏移量

https://msdn.microsoft.com/en-us/library/windows/desktop/aa363646(v=vs.85).aspx

UserSidOffset
此事件日志记录中安全标识符 (SID) 的偏移量。要获取此 SID 的用户名,请使用 LookupAccountSid 函数。

然后为了转换这个 sid,我们使用LookupAccountSid() API。

https://msdn.microsoft.com/en-us/library/windows/desktop/aa379166(v=vs.85).aspx

lpSid [in]
指向要查找的 SID 的指针。

我无休止地搜索并找到了与我的实现非常相似但给出相同结果的示例。我对 Windows API 生疏了,所以如果我忽略了这个问题,我不会感到惊讶。

最后,这是我的代码:

size_t BytesRemaining = 0;

while (BytesRemaining < BytesInBuffer)
{
    EVENTLOGRECORD *Record = reinterpret_cast<EVENTLOGRECORD *>(buffer + BytesRemaining);

    char UsernameBuffer[256], DomainBuffer[256];
    DWORD UsernameBufferSize = 256, DomainBufferSize = 256;
    SID_NAME_USE SidType;

    PSID SID = (PSID)((LPBYTE)Record + Record->UserSidOffset);

    if (!LookupAccountSid(NULL, SID, UsernameBuffer, &UsernameBufferSize, DomainBuffer, &DomainBufferSize, &SidType))
    {
        std::cout << "Failed reading SID (" << SID << "): " << GetLastErrorMessage().c_str();
    }
    else {
        std::cout << "I didn't shit on the SID.\n";
    }


    BytesRemaining += Record->Length;
}

bytesInBuffer = 0;

编辑

经过一些调试,我发现 StringsOffset 和 UserSidOffset 包含相同的值。所以看起来偏移量指向不正确......这就是为什么我无法将有效的 SID 传递给 API。

有人吗?

【问题讨论】:

  • 该代码中有很多重新解释转换。如果可能的话,我会避免这种情况。
  • @Cheersandhth.-Alf 指责微软在EVENTLOGRECORD 结构中使用了可变长度结构和字节偏移;我不确定你会如何在 C++ 中以更安全的方式编写这个循环...
  • 另外,如果GetLastErrorMessage() 返回一个std::string 或相关的,您在使用iostreams 打印它时不需要调用.c_str()
  • @andlabs:好吧,我猜API是基于重新解释,然后大概对齐就OK了。
  • 您没有检查 Record-&gt;UserSidLength 是否为零(在这种情况下,记录中没有 SID)所以也许这是您的问题?

标签: c++ winapi


【解决方案1】:

cchName [输入,输出]

在输入时,指定 lpName 缓冲区的大小(以 TCHAR 为单位)。 如果函数因缓冲区太小或 cchName 为零而失败,cchName 将接收所需的缓冲区大小,包括终止空字符。

cchReferencedDomainName [输入,输出]

在输入时,指定 lpReferencedDomainName 缓冲区的大小(以 TCHAR 为单位)。 如果函数因缓冲区太小或 cchReferencedDomainName 为零而失败,cchReferencedDomainName 将接收所需的缓冲区大小,包括终止空字符。

在调用LookupAccountSid() 之前,您需要将数组大小分配给UsernameBufferSizeDomainBufferSize。要么这样,要么将它们设置为零,然后动态分配UsernameBufferDomainBuffer,然后再次调用LookupAccountSid()

【讨论】:

  • 即使设置了数组大小,我仍然收到The parameter is incorrect.
  • 我尝试动态分配缓冲区,调用 API 两次,然后......同样的错误:|
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多