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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I modified the original line
extern "C" int wmain (int argc, wchar_t *argv[])
to
bool detectActiveDirectoryDomai nName(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
detectActiveDirectoryDomai nName(1,"m ycomputern ame");
But this doesn't work.
There is some casting required.
extern "C" int wmain (int argc, wchar_t *argv[])
to
bool detectActiveDirectoryDomai
Now I need to invoke that routine,
the problem is, how to fill argv.
I need to have something like
detectActiveDirectoryDomai
But this doesn't work.
There is some casting required.
>>I need to have something like
>> detectActiveDirectoryDomai nName(1,"m ycomputern ame");
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 detectActiveDirectoryDomai nName (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);
}
>> detectActiveDirectoryDomai
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 detectActiveDirectoryDomai
{
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**>(&
);
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**>(&
);
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);
}
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";
detectActiveDirectoryDomai nName ( (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
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";
detectActiveDirectoryDomai
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
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;
detectActiveDirectoryDomai nName((wch ar_t*) wcUserArg);
delete [] pwsz;
---
in routine extern "C" int detectActiveDirectoryDomai nName (wchar_t* pwszUser)
I needed to make the following changes:
--- ...
// get the user object
//
hr = ADsGetObject (
pwszUser, // WinNT://<computername>/<us ername> or WinNT://<domainname>/<user name>
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>/<c omputernam e>
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>/<compu ter>
// <== 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
--------------------------
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;
detectActiveDirectoryDomai
delete [] pwsz;
---
in routine extern "C" int detectActiveDirectoryDomai
I needed to make the following changes:
--- ...
// get the user object
//
hr = ADsGetObject (
pwszUser, // WinNT://<computername>/<us
IID_IADsUser,
reinterpret_cast<void**>(&
);
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>/<c
assert (SUCCEEDED (hr));
hr = ADsGetObject (
strDomainPath,
IID_IADs,
reinterpret_cast<void**>(&
);
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"),
// get the domain name
//
hr = pObject->get_Name (&strDomain);
assert (SUCCEEDED(hr));
if (wcscmp ((CComBSTR)TEXT("Domain"),
{
infoGrouptype = "NT Domain";
infoGroupname = (CString) strDomain;
}else
{
CString tmpDomain;
tmpDomain = (CString) strDomainPath; // current format is here: WinNT://<workgroup>/<compu
// <== 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
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.AllocSysStr ing();
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
---
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.AllocSysStr
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
---
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(lpszDomai n);
// Here it is possible to detect Domain, Workstation, ... checking njsBufferType.
// The name is contained in szDomain.
return nStatusJ;
}
--------------------------
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
lpszDomain, // Returned Domain nam
pnjsBufferType); // Returned BufferType
// NetApiBufferFree(lpszDomai
// Here it is possible to detect Domain, Workstation, ... checking njsBufferType.
// The name is contained in szDomain.
return nStatusJ;
}
ASKER
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