-1

I have a problem with the following code:

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;
}

If I start the program in Visual Studio everything works fine, but now I want to create an object file and print the Domain SID and then I receive the following:

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

Why do I get this error in the object file but not in Visual Studio?

I create my object file like this:

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

Marius Bancila
  • 16,053
  • 9
  • 49
  • 91
lucade
  • 1
  • 1

1 Answers1

0

I think you are doing unnecessary things there. Conversions from wide to single then wide again using ATL, the single again, I'm kinda lost.

Also, notice that functions like LookupAccountName() are supposed to be called with null buffers first to return you the required size of the buffers. Then you allocate the right size and call it again.

Here is a simplification of your code that returns you the domain SID. Mind that it does not handle the errors, you have to do that yourself. Works well for me.

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;
}
Marius Bancila
  • 16,053
  • 9
  • 49
  • 91