C++ 试图通过目标文件接收 Domain Sid

C++ trying to receive Domain Sid with object file

我对以下代码有疑问:

std::string getDomainSid()
{   
    DWORD dw;
    //vector for the domain SID

    std::string myDomainSID;
    std::vector<std::string> domainSID;
    std::wstringstream convertingDomainNameDNS;
    wchar_t wc;
    std::wstring getDomainName;
    std::string domainNameconverted = "";

     //get the domain information
     dw = DsRoleGetPrimaryDomainInformation(NULL,
          DsRolePrimaryDomainInfoBasic,
          (PBYTE *)&info);
     if (dw != ERROR_SUCCESS)
     {
          //wprintf(L"DsRoleGetPrimaryDomainInformation: %u\n", dw);

     }
     if (info->DomainNameDns == NULL)
     {
          wprintf(L"DomainNameDns is NULL\n");
     }
     else
     {
          //printing the domainname
          wprintf(L"DomainNameDns: %s\n", info->DomainNameDns);     
          //converting the DomainNameDNS to a LPWSTR to use it to get the Domain SID

          convertingDomainNameDNS << info->DomainNameDns;
          convertingDomainNameDNS >> getDomainName;
          std::wcout << getDomainName << std::endl;

     }

     std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
     USES_CONVERSION_EX;
     domainNameconverted = myconv.to_bytes(getDomainName);
     std::cout << domainNameconverted << std::endl;
     LPWSTR lp = A2W_EX(domainNameconverted.c_str(), text.length());
     std::wcout << lp << std::endl;
     //getting the Domain SID

     //LPTSTR wszAccName = lp;      

     LPTSTR wszAccName = reinterpret_cast<LPTSTR>(lp);
     std::wcout << wszAccName << std::endl;
     LPTSTR wszDomainName = (LPTSTR)GlobalAlloc(GPTR, sizeof(TCHAR) * 1024);
     printf("%s", wszDomainName);
     std::cout << wszDomainName << std::endl;
     DWORD cchDomainName = 1024;
     SID_NAME_USE eSidType;
     LPTSTR sidstring;
     char sid_buffer[1024];
     DWORD cbSid = 1024;
     SID * sid = (SID *)sid_buffer;
     if (!LookupAccountName(NULL, wszAccName, sid_buffer, &cbSid, wszDomainName, &cchDomainName, &eSidType)) 
     {
          printf("Error");
     }

     if (!ConvertSidToStringSid(sid, &sidstring)) 
     {
         printf("%s",sidstring);

          printf("Error converting Sid");
     }

     printf("%s", sidstring);
     //myDomainSID = myconv.to_bytes(sidstring);        
     wchar_t* test = reinterpret_cast<wchar_t*>(sidstring);
     std::wstring ts(test);
     std::string domain(ts.begin(), ts.end());
     printf("%s", domain);
     myDomainSID = domain;
     //std::string testchar = "test";
     //return testchar;
     return myDomainSID;
}

如果我在 Visual Studio 中启动程序,一切正常,但现在我想创建一个目标文件并打印域 SID,然后我收到以下内容:

ErrorãD$@Error converting SidãD$@ãCC6039CB7C4

为什么我在对象文件中出现此错误,但在 Visual Studio 中却没有?

我这样创建目标文件:

cl /EHsc /c /MT /I. testing.cpp cl /c /nologo /c /MT /I. testprogramm.c testprogramm.c LINK /nologo /OPT:NOREF /NXCOMPAT /DynamicBase /out:test.exe testprogramm.obj SHA1.obj test.obj LIBCPMT.LIB libcmt.lib libvcruntime.lib oldnames.lib kernel32.lib user32.lib netapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib shell32.lib Rpcrt4.lib oleaut32.lib Ole32.lib Wbemuuid.lib wintrust.lib crypt32.lib Ws2_32.lib iphlpapi.lib Psapi.lib advapi32.lib Shlwapi.lib dhcpcsvc.lib userenv.lib atls.lib msvcrtd.lib vcruntimed.lib netapi32.lib Advapi32.lib IPHLPAPI.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

我认为你在那里做了不必要的事情。使用 ATL 从 wide 到 single 然后再次 wide 的转换,又是 single,我有点迷路了。

此外,请注意像 LookupAccountName() 这样的函数应该首先使用空缓冲区调用,以便 return 您需要缓冲区的大小。然后你分配合适的尺寸再调用它。

这里是您的代码的简化,return您是域 SID。请注意它不处理错误,您必须自己处理。对我来说效果很好。

std::string getDomainSid()
{
   std::string domainsid;
   DSROLE_PRIMARY_DOMAIN_INFO_BASIC* info = nullptr;

   auto dw = DsRoleGetPrimaryDomainInformation(
      nullptr,
      DsRolePrimaryDomainInfoBasic,
      (PBYTE *)&info);

   if (dw != ERROR_SUCCESS || info->DomainNameDns == nullptr)
   {
      // TODO
   }

   std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
   auto domainName = myconv.to_bytes(info->DomainNameDns);

   SID_NAME_USE eSidType;

   DWORD cchDomainName = 0;
   DWORD cbSid = 0;
   if (!LookupAccountName(nullptr, domainName.data(), nullptr, &cbSid, nullptr, &cchDomainName, &eSidType))
   {
      std::vector<char> sid_buffer(cbSid);
      std::string refDomainName(cchDomainName, 0);

      if (LookupAccountName(nullptr, domainName.data(), &sid_buffer.front(), &cbSid, &refDomainName.front(), &cchDomainName, &eSidType))
      {
         LPTSTR sidstring;
         if (ConvertSidToStringSid(reinterpret_cast<PSID>(sid_buffer.data()), &sidstring))
         {
            domainsid = sidstring;
            LocalFree(sidstring);
         }
         else 
         {
            // TODO
         }
      }
      else
      {
          // TODO
      }
   }

   DsRoleFreeMemory(info);
   return domainsid;
}