Solved

NTDomain, Workgroup, Active Directory Domain

Posted on 2004-04-28
8
360 Views
Last Modified: 2007-12-19
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
Comment
Question by:HStrix
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 2
8 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 200 total points
ID: 10941262
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
 

Author Comment

by:HStrix
ID: 10946817
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
 

Author Comment

by:HStrix
ID: 10951201
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!

 
LVL 86

Expert Comment

by:jkr
ID: 10951263
>>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
 

Author Comment

by:HStrix
ID: 10957656
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
 

Author Comment

by:HStrix
ID: 10975819
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
 

Author Comment

by:HStrix
ID: 11116604
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
 

Author Comment

by:HStrix
ID: 11178996
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

Independent Software Vendors: 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!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question