Solved

NTDomain, Workgroup, Active Directory Domain

Posted on 2004-04-28
8
353 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
  • 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
 
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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

746 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now