Link to home
Start Free TrialLog in
Avatar of HStrix
HStrix

asked on

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
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of HStrix
HStrix

ASKER

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
Avatar of HStrix

ASKER

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


Avatar of HStrix

ASKER

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




Avatar of HStrix

ASKER

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

Avatar of HStrix

ASKER

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
---
Avatar of HStrix

ASKER

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