You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
863 lines
16 KiB
863 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1994-95 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
domobj.cpp
|
|
|
|
Abstract:
|
|
|
|
Domain object implementation.
|
|
|
|
Author:
|
|
|
|
Don Ryan (donryan) 04-Jan-1995
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "stdafx.h"
|
|
#include "llsmgr.h"
|
|
#include "lmcons.h"
|
|
#include "lmapibuf.h"
|
|
#include "lmserver.h"
|
|
#include "lmaccess.h"
|
|
extern "C" {
|
|
#include "dsgetdc.h"
|
|
}
|
|
|
|
#include <strsafe.h>
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
IMPLEMENT_DYNCREATE(CDomain, CCmdTarget)
|
|
|
|
BEGIN_MESSAGE_MAP(CDomain, CCmdTarget)
|
|
//{{AFX_MSG_MAP(CDomain)
|
|
// NOTE - the ClassWizard will add and remove mapping macros here.
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
BEGIN_DISPATCH_MAP(CDomain, CCmdTarget)
|
|
//{{AFX_DISPATCH_MAP(CDomain)
|
|
DISP_PROPERTY_EX(CDomain, "Name", GetName, SetNotSupported, VT_BSTR)
|
|
DISP_PROPERTY_EX(CDomain, "Parent", GetParent, SetNotSupported, VT_DISPATCH)
|
|
DISP_PROPERTY_EX(CDomain, "Primary", GetPrimary, SetNotSupported, VT_BSTR)
|
|
DISP_PROPERTY_EX(CDomain, "Application", GetApplication, SetNotSupported, VT_DISPATCH)
|
|
DISP_PROPERTY_EX(CDomain, "Controller", GetController, SetNotSupported, VT_BSTR)
|
|
DISP_PROPERTY_EX(CDomain, "IsLogging", IsLogging, SetNotSupported, VT_BOOL)
|
|
DISP_PROPERTY_PARAM(CDomain, "Servers", GetServers, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
|
|
DISP_PROPERTY_PARAM(CDomain, "Users", GetUsers, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
|
|
DISP_PROPERTY_PARAM(CDomain, "TrustedDomains", GetTrustedDomains, SetNotSupported, VT_DISPATCH, VTS_VARIANT)
|
|
DISP_DEFVALUE(CDomain, "Name")
|
|
//}}AFX_DISPATCH_MAP
|
|
END_DISPATCH_MAP()
|
|
|
|
|
|
CDomain::CDomain(CCmdTarget* pParent, LPCTSTR pName)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Constructor for domain object.
|
|
|
|
Arguments:
|
|
|
|
pParent - creator of object.
|
|
pName - name of domain.
|
|
|
|
Return Values:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
EnableAutomation();
|
|
|
|
#ifdef ENABLE_PARENT_CHECK
|
|
ASSERT(pParent && pParent->IsKindOf(RUNTIME_CLASS(CApplication)));
|
|
#endif // ENABLE_PARENT_CHECK
|
|
|
|
m_pParent = pParent;
|
|
|
|
ASSERT(pName && *pName);
|
|
|
|
m_strName = pName;
|
|
|
|
m_strPrimary.Empty();
|
|
m_strController.Empty();
|
|
|
|
m_pServers = NULL;
|
|
m_pDomains = NULL;
|
|
m_pUsers = NULL;
|
|
|
|
m_serverArray.RemoveAll();
|
|
m_domainArray.RemoveAll();
|
|
m_userArray.RemoveAll();
|
|
|
|
m_bServersRefreshed = FALSE;
|
|
m_bDomainsRefreshed = FALSE;
|
|
m_bUsersRefreshed = FALSE;
|
|
}
|
|
|
|
|
|
CDomain::~CDomain()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Destructor for domain object.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (m_pUsers)
|
|
m_pUsers->InternalRelease();
|
|
|
|
if (m_pServers)
|
|
m_pServers->InternalRelease();
|
|
|
|
if (m_pDomains)
|
|
m_pDomains->InternalRelease();
|
|
}
|
|
|
|
void CDomain::OnFinalRelease()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
When the last reference for an automation object is released
|
|
OnFinalRelease is called. This implementation deletes object.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
ResetUsers();
|
|
ResetServers();
|
|
ResetDomains();
|
|
delete this;
|
|
}
|
|
|
|
|
|
LPDISPATCH CDomain::GetApplication()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns the application object.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
VT_DISPATCH.
|
|
|
|
--*/
|
|
|
|
{
|
|
return theApp.GetAppIDispatch();
|
|
}
|
|
|
|
|
|
BSTR CDomain::GetController()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns license controller for domain.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
VT_BSTR.
|
|
|
|
--*/
|
|
|
|
{
|
|
return NULL; // CODEWORK...
|
|
}
|
|
|
|
|
|
BSTR CDomain::GetName()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns the name of the domain.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
return m_strName.AllocSysString();
|
|
}
|
|
|
|
|
|
LPDISPATCH CDomain::GetParent()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns the parent of the object.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
VT_DISPATCH.
|
|
|
|
--*/
|
|
|
|
{
|
|
return m_pParent ? m_pParent->GetIDispatch(TRUE) : NULL;
|
|
}
|
|
|
|
|
|
BSTR CDomain::GetPrimary()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns the name of the ANY domain controller.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
VT_BSTR.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (m_strPrimary.IsEmpty())
|
|
{
|
|
DWORD NetStatus;
|
|
PDOMAIN_CONTROLLER_INFO pDcInfo;
|
|
|
|
NetStatus = DsGetDcName( NULL,
|
|
MKSTR(m_strName),
|
|
(GUID *)NULL,
|
|
NULL,
|
|
DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME,
|
|
&pDcInfo );
|
|
|
|
|
|
if (NetStatus == ERROR_SUCCESS)
|
|
{
|
|
m_strPrimary = pDcInfo->DomainControllerName;
|
|
::NetApiBufferFree((LPBYTE)pDcInfo);
|
|
}
|
|
|
|
LlsSetLastStatus(NetStatus); // called api
|
|
}
|
|
|
|
return m_strPrimary.AllocSysString();
|
|
}
|
|
|
|
|
|
LPDISPATCH CDomain::GetServers(const VARIANT FAR& index)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns a collection object containing all of the
|
|
servers in the domain or returns an individual server
|
|
described by an index into the collection.
|
|
|
|
Arguments:
|
|
|
|
index - optional argument that may be a string (VT_BSTR)
|
|
indicating the server name or a number (VT_I4) indicating
|
|
the position within collection.
|
|
|
|
Return Values:
|
|
|
|
VT_DISPATCH or VT_EMPTY.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPDISPATCH lpdispatch = NULL;
|
|
|
|
if (!m_pServers)
|
|
{
|
|
m_pServers = new CServers(this, &m_serverArray);
|
|
}
|
|
|
|
if (m_pServers)
|
|
{
|
|
if (V_ISVOID((VARIANT FAR*)&index))
|
|
{
|
|
if (RefreshServers())
|
|
{
|
|
lpdispatch = m_pServers->GetIDispatch(TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_bServersRefreshed)
|
|
{
|
|
lpdispatch = m_pServers->GetItem(index);
|
|
}
|
|
else if (RefreshServers())
|
|
{
|
|
lpdispatch = m_pServers->GetItem(index);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LlsSetLastStatus(STATUS_NO_MEMORY);
|
|
}
|
|
|
|
return lpdispatch;
|
|
}
|
|
|
|
|
|
LPDISPATCH CDomain::GetTrustedDomains(const VARIANT FAR& index)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns a collection object containing all of the
|
|
domains trusted bythe domain or returns an individual
|
|
trusted domain described by an index into the collection.
|
|
|
|
Arguments:
|
|
|
|
index - optional argument that may be a string (VT_BSTR)
|
|
indicating the domain name or a number (VT_I4) indicating
|
|
the position within collection.
|
|
|
|
Return Values:
|
|
|
|
VT_DISPATCH or VT_EMPTY.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPDISPATCH lpdispatch = NULL;
|
|
|
|
if (!m_pDomains)
|
|
{
|
|
m_pDomains = new CDomains(this, &m_domainArray);
|
|
}
|
|
|
|
if (m_pDomains)
|
|
{
|
|
if (V_ISVOID((VARIANT FAR*)&index))
|
|
{
|
|
if (RefreshDomains())
|
|
{
|
|
lpdispatch = m_pDomains->GetIDispatch(TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_bDomainsRefreshed)
|
|
{
|
|
lpdispatch = m_pDomains->GetItem(index);
|
|
}
|
|
else if (RefreshDomains())
|
|
{
|
|
lpdispatch = m_pDomains->GetItem(index);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LlsSetLastStatus(STATUS_NO_MEMORY);
|
|
}
|
|
|
|
return lpdispatch;
|
|
}
|
|
|
|
|
|
LPDISPATCH CDomain::GetUsers(const VARIANT FAR& index)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns a collection object containing all of the
|
|
users in the domain or returns an individual user
|
|
described by an index into the collection.
|
|
|
|
Arguments:
|
|
|
|
index - optional argument that may be a string (VT_BSTR)
|
|
indicating the user name or a number (VT_I4) indicating
|
|
the position within collection.
|
|
|
|
Return Values:
|
|
|
|
VT_DISPATCH or VT_EMPTY.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPDISPATCH lpdispatch = NULL;
|
|
|
|
if (!m_pUsers)
|
|
{
|
|
m_pUsers = new CUsers(this, &m_userArray);
|
|
}
|
|
|
|
if (m_pUsers)
|
|
{
|
|
if (V_ISVOID((VARIANT FAR*)&index))
|
|
{
|
|
if (RefreshUsers())
|
|
{
|
|
lpdispatch = m_pUsers->GetIDispatch(TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_bUsersRefreshed)
|
|
{
|
|
lpdispatch = m_pUsers->GetItem(index);
|
|
}
|
|
else if (RefreshUsers())
|
|
{
|
|
lpdispatch = m_pUsers->GetItem(index);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LlsSetLastStatus(STATUS_NO_MEMORY);
|
|
}
|
|
|
|
return lpdispatch;
|
|
}
|
|
|
|
|
|
BOOL CDomain::IsLogging()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns true if primary replicating license information.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
VT_BOOL.
|
|
|
|
--*/
|
|
|
|
{
|
|
return TRUE; // CODEWORK... LlsEnterpriseServerFind??
|
|
}
|
|
|
|
|
|
BOOL CDomain::RefreshDomains()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Refreshs trusted domain array.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
VT_BOOL.
|
|
|
|
--*/
|
|
|
|
{
|
|
ResetDomains();
|
|
|
|
ULONG DomainCount = 0;
|
|
PDS_DOMAIN_TRUSTS pDomains = NULL;
|
|
NET_API_STATUS NetStatus = 0;
|
|
|
|
|
|
OutputDebugString( L"CDomain::RefreshDomains\n" );
|
|
|
|
NetStatus = DsEnumerateDomainTrusts( NULL,
|
|
// DS_DOMAIN_IN_FOREST |
|
|
DS_DOMAIN_DIRECT_OUTBOUND, //|
|
|
// DS_DOMAIN_PRIMARY,
|
|
&pDomains,
|
|
&DomainCount );
|
|
|
|
if (NetStatus == NO_ERROR)
|
|
{
|
|
CDomain* pDomain;
|
|
int DomainsAdded = 0;
|
|
|
|
for ( ;DomainCount--; pDomains++)
|
|
{
|
|
if ( (pDomains->Flags
|
|
& (DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND))
|
|
&& (pDomains->TrustType
|
|
& (TRUST_TYPE_DOWNLEVEL | TRUST_TYPE_UPLEVEL)))
|
|
{
|
|
#ifdef DBG //this was defined as DBGMSG in stdafx.h
|
|
{
|
|
TCHAR tchmsg[80];
|
|
HRESULT hr;
|
|
hr = StringCbPrintf(
|
|
tchmsg,
|
|
sizeof(tchmsg),
|
|
L"\tNetbiosDomainName = %s\n",
|
|
pDomains->NetbiosDomainName);
|
|
ASSERT(SUCCEEDED(hr));
|
|
OutputDebugString( tchmsg );
|
|
}
|
|
#endif //DBG
|
|
|
|
pDomain = new CDomain(this, pDomains->NetbiosDomainName);
|
|
|
|
m_domainArray.SetAtGrow(DomainsAdded, pDomain); // validate later
|
|
DomainsAdded++;
|
|
}
|
|
}
|
|
|
|
m_domainArray.SetSize(DomainsAdded);
|
|
|
|
m_bDomainsRefreshed = TRUE;
|
|
NetApiBufferFree(pDomains);
|
|
}
|
|
|
|
LlsSetLastStatus(NetStatus); // called api
|
|
|
|
return m_bDomainsRefreshed;
|
|
}
|
|
|
|
|
|
BOOL CDomain::RefreshServers()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Refreshs server object array.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
VT_BOOL.
|
|
|
|
--*/
|
|
|
|
{
|
|
ResetServers();
|
|
|
|
NET_API_STATUS NetStatus;
|
|
DWORD ResumeHandle = 0L;
|
|
|
|
int iServer = 0;
|
|
|
|
do
|
|
{
|
|
DWORD EntriesRead;
|
|
DWORD TotalEntries;
|
|
LPBYTE ReturnBuffer = NULL;
|
|
|
|
NetStatus = ::NetServerEnum(
|
|
NULL, // servername
|
|
100, // level
|
|
&ReturnBuffer,
|
|
LLS_PREFERRED_LENGTH,
|
|
&EntriesRead,
|
|
&TotalEntries,
|
|
SV_TYPE_NT,
|
|
MKSTR(m_strName),
|
|
&ResumeHandle
|
|
);
|
|
|
|
if (NetStatus == ERROR_SUCCESS ||
|
|
NetStatus == ERROR_MORE_DATA)
|
|
{
|
|
CServer* pServer;
|
|
PSERVER_INFO_100 pServerInfo100;
|
|
|
|
pServerInfo100 = (PSERVER_INFO_100)ReturnBuffer;
|
|
|
|
ASSERT(iServer == m_serverArray.GetSize());
|
|
m_serverArray.SetSize(m_serverArray.GetSize() + EntriesRead);
|
|
|
|
while (EntriesRead--)
|
|
{
|
|
pServer = new CServer(this, pServerInfo100->sv100_name);
|
|
|
|
m_serverArray.SetAt(iServer++, pServer); // validate later
|
|
pServerInfo100++;
|
|
}
|
|
|
|
NetApiBufferFree(ReturnBuffer);
|
|
}
|
|
|
|
} while (NetStatus == ERROR_MORE_DATA);
|
|
|
|
LlsSetLastStatus(NetStatus); // called api
|
|
|
|
if (NetStatus == ERROR_SUCCESS)
|
|
{
|
|
m_bServersRefreshed = TRUE;
|
|
}
|
|
else
|
|
{
|
|
ResetServers();
|
|
}
|
|
|
|
return m_bServersRefreshed;
|
|
}
|
|
|
|
|
|
BOOL CDomain::RefreshUsers()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Refreshs user object array.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
VT_BOOL.
|
|
|
|
--*/
|
|
|
|
{
|
|
ResetUsers();
|
|
|
|
NET_API_STATUS NetStatus;
|
|
DWORD ResumeHandle = 0L;
|
|
|
|
int iUser = 0;
|
|
|
|
do
|
|
{
|
|
DWORD EntriesRead;
|
|
DWORD TotalEntries;
|
|
LPBYTE ReturnBuffer = NULL;
|
|
|
|
NetStatus = NetUserEnum(
|
|
GetPrimary(), // servername
|
|
0, // level
|
|
FILTER_NORMAL_ACCOUNT,
|
|
&ReturnBuffer,
|
|
LLS_PREFERRED_LENGTH,
|
|
&EntriesRead,
|
|
&TotalEntries,
|
|
&ResumeHandle
|
|
);
|
|
|
|
if (NetStatus == ERROR_SUCCESS ||
|
|
NetStatus == ERROR_MORE_DATA)
|
|
{
|
|
CUser* pUser;
|
|
PUSER_INFO_0 pUserInfo0;
|
|
|
|
pUserInfo0 = (PUSER_INFO_0)ReturnBuffer;
|
|
|
|
ASSERT(iUser == m_userArray.GetSize());
|
|
m_userArray.SetSize(m_userArray.GetSize() + EntriesRead);
|
|
|
|
while (EntriesRead--)
|
|
{
|
|
pUser = new CUser(this, pUserInfo0->usri0_name);
|
|
|
|
m_userArray.SetAt(iUser++, pUser); // validate later
|
|
pUserInfo0++;
|
|
}
|
|
|
|
NetApiBufferFree(ReturnBuffer);
|
|
}
|
|
} while (NetStatus == ERROR_MORE_DATA);
|
|
|
|
LlsSetLastStatus(NetStatus); // called api
|
|
|
|
if (NetStatus == ERROR_SUCCESS)
|
|
{
|
|
m_bUsersRefreshed = TRUE;
|
|
}
|
|
else
|
|
{
|
|
ResetUsers();
|
|
}
|
|
|
|
return m_bUsersRefreshed;
|
|
}
|
|
|
|
|
|
void CDomain::ResetDomains()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Resets domain object array.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
CDomain* pDomain;
|
|
INT_PTR iDomain = m_domainArray.GetSize();
|
|
|
|
while (iDomain--)
|
|
{
|
|
pDomain = (CDomain*)m_domainArray[iDomain];
|
|
if (NULL != pDomain)
|
|
{
|
|
ASSERT(pDomain->IsKindOf(RUNTIME_CLASS(CDomain)));
|
|
pDomain->InternalRelease();
|
|
}
|
|
}
|
|
|
|
m_domainArray.RemoveAll();
|
|
m_bDomainsRefreshed = FALSE;
|
|
}
|
|
|
|
|
|
void CDomain::ResetServers()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Resets server object array.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
CServer* pServer;
|
|
INT_PTR iServer = m_serverArray.GetSize();
|
|
|
|
while (iServer--)
|
|
{
|
|
pServer = (CServer*)m_serverArray[iServer];
|
|
if (NULL != pServer)
|
|
{
|
|
ASSERT(pServer->IsKindOf(RUNTIME_CLASS(CServer)));
|
|
pServer->InternalRelease();
|
|
}
|
|
}
|
|
|
|
m_serverArray.RemoveAll();
|
|
m_bServersRefreshed = FALSE;
|
|
}
|
|
|
|
|
|
void CDomain::ResetUsers()
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Resets user object array.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
CUser* pUser;
|
|
INT_PTR iUser = m_userArray.GetSize();
|
|
|
|
while (iUser--)
|
|
{
|
|
pUser = (CUser*)m_userArray[iUser];
|
|
if (NULL != pUser)
|
|
{
|
|
ASSERT(pUser->IsKindOf(RUNTIME_CLASS(CUser)));
|
|
pUser->InternalRelease();
|
|
}
|
|
}
|
|
|
|
m_userArray.RemoveAll();
|
|
m_bUsersRefreshed = FALSE;
|
|
}
|