[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 366
  • Last Modified:

NTDomain, Workgroup, Active Directory Domain

Hello Experts,
I'm new in VC++.
I created an MFC application (in .Net 2002 unmanaged C++)
and want to detect if my computer where I'm logged in
is member of an NTDomain, of a Workgroup, an Active Directory Domain
or runs in isolated mode (is not connected to any network).
I'm looking for C++ snippets to get this information.
If anyone can help me, please supply an appropriate information.

Thank you for any help.

  HStrix
0
HStrix
Asked:
HStrix
  • 6
  • 2
1 Solution
 
jkrCommented:
For the Active Directory part, see http://support.microsoft.com/default.aspx?scid=kb;en-us;233023 ("http://support.microsoft.com/default.aspx?scid=kb;en-us;233023") and http://support.microsoft.com/default.aspx?scid=kb;en-us;200126 ("HOWTO: Determining the Domain of A User Through ADSI") For the NT domain and workgoup part, you wil need to use 'LsaEnumerateTrustedDomains()'. Check out the sample at http://win32.mvps.org/lsa/lsa_letd.cpp
0
 
HStrixAuthor Commented:
Thank you jkr,
I started incorporating your suggestions with ADSI
(http://support.microsoft.com/default.aspx?scid=kb;en-us;200126).
My question is now:
what arguments are expected for argc and argv:
    extern "C" int wmain (int argc, wchar_t *argv[])
can you give me a sample?

  Thank you HStrix
0
 
HStrixAuthor Commented:
I modified the original line
   extern "C" int wmain (int argc, wchar_t *argv[])
to
   bool detectActiveDirectoryDomainName(int argc, wchar_t *argv[])
Now I need to invoke that routine,
the problem is, how to fill argv.
I need to have something like
  detectActiveDirectoryDomainName(1,"mycomputername");
But this doesn't work.
There is some casting required.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
jkrCommented:
>>I need to have something like
>> detectActiveDirectoryDomainName(1,"mycomputername");

Make the sample read

   #define UNICODE
   #define _UNICODE
   #include <windows.h>
   #include <activeds.h>
   #include <atlbase.h>
   #include <stdio.h>
   #include <assert.h>
   #include <atlimpl.cpp>

   #define RTN_OK      0
   #define RTN_USAGE   1
   #define RTN_ERROR   13

   extern "C" int detectActiveDirectoryDomainName (wchar_t* pwszUser)
   {

       DWORD dwRes;
       CComPtr<IADsUser> pUser;
       CComPtr<IADs> pObject;
       CComBSTR strDomainPath, strUser, strDomain;
       CComBSTR strClass;
       HRESULT hr;

       // initialize COM
       //
       hr = CoInitialize (NULL);
       assert (SUCCEEDED(hr));

       // get the user object
       //
       hr = ADsGetObject (
                   pwszUser,
                   IID_IADsUser,
                   reinterpret_cast<void**>(&pUser)
                   );
       assert (SUCCEEDED(hr));

       // get the user name
       //
       hr = pUser->get_Name (&strUser);
       assert (SUCCEEDED(hr));

       // get the parent of the object
       //
       hr = pUser->get_Parent (&strDomainPath);
       assert (SUCCEEDED (hr));

       hr = ADsGetObject (
                   strDomainPath,
                   IID_IADs,
                   reinterpret_cast<void**>(&pObject)
                   );
       assert (SUCCEEDED(hr));

       // verify that it's a domain - this could have been done by
       // getting an IADsDomain interface in the ADsGetObject call...
       //
       hr = pObject->get_Class (&strClass);
       assert (SUCCEEDED(hr));

       assert (!wcscmp (TEXT("Domain"), strClass));

       // get the domain name
       //
       hr = pObject->get_Name (&strDomain);
       assert (SUCCEEDED(hr));

       printf ("Domain of user %S is %S\n", strUser, strDomain);

       return (RTN_OK);
   }


0
 
HStrixAuthor Commented:
OK jkr,
I think there was a slightly misunderstanding.
--
But using your sample (I incorporated it as a routine into an existing c file),
how do I need to call it?
I need something like
   CString strMyUserName = "myusername";
   detectActiveDirectoryDomainName ( (wchar_t*) strMyUserName); // <== this does not work. What to do?
I tried several more simular things,
but I couldn't get rid of the casting problem (as I mentioned in my yesterdays comment above).
--
Everything else seems working.

 Thank you for any hint

   HStrix




0
 
HStrixAuthor Commented:
In the meantime I could solve something.
-----------------------------------------------
 
I could make the calling working with the following code:
---
 CString MyComputername;
 CString MyUserID;
 //
 using namespace std;
 //
 string strInput;
 wchar_t *wcUserArg;
 
 // this works for a domain user on a domain controller (i.e.. on the local computer):
 strInput = "WinNT://" + (string) MyComputername +"/" + (string) MyUserID + ",user";  
 
 // this works for a workgroup user or a user that isn't connected  to the domain but to the local computer:
 strInput = "WinNT://" + (string) MyComputername +"/" + (string) MyUserID + ",user";  
 
 // this doesn't work for a domain user (i.e. connected to a domain):
 //strInput = "WinNT://" + (string) MyComputername +"/" + (string) MyUserID + ",user";  
 
 // this works for a domain user (i.e. connected to a domain)
 //      but -> I need to know the domain already and that was not my intension
 //strInput = "WinNT://" + (string) MyDomainname +"/" + (string) MyUserID + ",user";  
 
 wchar_t* pwsz = new wchar_t [ strInput.length() + 1];
 mbstowcs ( pwsz, strInput.c_str(), strInput.length() + 1);
 wcUserArg = pwsz;
 detectActiveDirectoryDomainName((wchar_t*) wcUserArg);
 delete [] pwsz;
---
 
in routine extern "C" int detectActiveDirectoryDomainName (wchar_t* pwszUser)
I needed to make the following changes:
---       ...
 
       // get the user object
       //
       hr = ADsGetObject (
                   pwszUser,           // WinNT://<computername>/<username> or WinNT://<domainname>/<username>
                   IID_IADsUser,
                   reinterpret_cast<void**>(&pUser)
                   );
       assert (SUCCEEDED(hr));
 
       // get the user name
       //
       hr = pUser->get_Name (&strUser);
       assert (SUCCEEDED(hr));
 
       // get the parent of the object
       //
       hr = pUser->get_Parent (&strDomainPath); // WinNT://<workgroupname>/<computername>
       assert (SUCCEEDED (hr));
 
       hr = ADsGetObject (
                   strDomainPath,
                   IID_IADs,
                   reinterpret_cast<void**>(&pObject)
                   );
       assert (SUCCEEDED(hr));
 
       // verify that it's a domain - this could have been done by
       // getting an IADsDomain interface in the ADsGetObject call...
       //
       hr = pObject->get_Class (&strClass);  // for Workgroups "Computer"
       assert (SUCCEEDED(hr));
 
 //   assert (!wcscmp ((CComBSTR)TEXT("Domain"), strClass)); // <== does NOT work for Workgroups(assert)

       // get the domain name
       //
       hr = pObject->get_Name (&strDomain);
       assert (SUCCEEDED(hr));
 
       if (wcscmp ((CComBSTR)TEXT("Domain"), strClass) == 0)
      {  
         infoGrouptype = "NT Domain";
         infoGroupname = (CString) strDomain;
      }else
      {  
         CString tmpDomain;
         tmpDomain = (CString) strDomainPath;  // current format is here: WinNT://<workgroup>/<computer>
         // <== here a substr is still required to select the workgroup only
         infoGrouptype = "Workgroup";
         infoGroupname = tmpDomain;
     }
---

I think now I need to incorporate the sample given in
---
   http://win32.mvps.org/lsa/lsa_letd.cpp
---
first.

   HStrix

0
 
HStrixAuthor Commented:
Hi jkr, in the meantime I made some improvements.
Now I found that there is a netapi function called netgetjoininformation,
but I couldn't make it working.
I'ld like to use this function to detect if my computer is running in a domain, workgroup or isolated.
Is there a working snippet for that function?
I couldn't detect what's wrong with my sample below?

  HStrix

I use the following code:
---
      PNETSETUP_JOIN_STATUS lngBufferType = 0;
      LPWSTR lpNameBuffer;
      NET_API_STATUS      nStatus = 0;
      LPCWSTR lpServerName;
      CString cstrServername = "\\\\" + CStringMyComputername;
      lpServerName = (LPCWSTR) cstrServername.AllocSysString();
      nStatus = NetGetJoinInformation(  lpServerName,
                                             (LPWSTR *) &lpNameBuffer,
                                                 lngBufferType);   // Returned BufferType
             // I get always:
      // nStatus==1780 ::= A null reference pointer was passed to the stub.
             // code 1780 => name  RPC_X_NULL_REF_POINTER
---
0
 
HStrixAuthor Commented:
That is a working sample for me:
--------------------------------------
DWORD getNetworkJoinInformation()
{            
      CString my_strDomainName = NULL;
      NET_API_STATUS      nStatusJ = 0;
      LPCWSTR lpszServer = NULL;
      LPWSTR  szDomain;
      LPWSTR* lpszDomain = &szDomain;
      NETSETUP_JOIN_STATUS njsBufferType;
      PNETSETUP_JOIN_STATUS pnjsBufferType = &njsBufferType;
      nStatusJ = NetGetJoinInformation(NULL,                         // Local machine (Server) or NULL (for local environment)
                                                                lpszDomain,        // Returned Domain nam
                                                                pnjsBufferType);          // Returned BufferType
//      NetApiBufferFree(lpszDomain);
// Here it is possible to detect Domain, Workstation, ...  checking njsBufferType.
// The name is contained in szDomain.
      return nStatusJ;
}
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now