windows-nt/Source/XPSP1/NT/ds/adsi/ldap/system.cxx
2020-09-26 16:20:57 +08:00

1104 lines
21 KiB
C++

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: cPathname.cxx
//
// Contents: Pathname object
//
// History: 11-1-95 krishnag Created.
//
//----------------------------------------------------------------------------
#include "ldap.hxx"
#pragma hdrstop
#define DEFAULT_NC _T(LDAP_OPATT_DEFAULT_NAMING_CONTEXT)
#define SCHEMA_NC _T(LDAP_OPATT_SCHEMA_NAMING_CONTEXT)
HANDLE g_hSecur32Dll = NULL;
// Class CADSystemInfo
DEFINE_IDispatch_Implementation(CADSystemInfo)
//+---------------------------------------------------------------------------
// Function: CADSystemInfo::CADSystemInfo
//
// Synopsis: Constructor
//
// Arguments:
//
// Returns: HRESULT
//
// Modifies: -
//
// History:
//
//----------------------------------------------------------------------------
CADSystemInfo::CADSystemInfo():
_pDispMgr(NULL),
_hSecur32(NULL),
_Secur32LoadAttempted(FALSE),
_hNetApi32(NULL),
_NetApi32LoadAttempted(FALSE)
{
ENLIST_TRACKING(CADSystemInfo);
}
//+---------------------------------------------------------------------------
// Function: CADSystemInfo::CreateADSystemInfo
//
// Synopsis:
//
// Arguments:
//
// Returns: HRESULT
//
// Modifies: -
//
// History:
//
//----------------------------------------------------------------------------
HRESULT
CADSystemInfo::CreateADSystemInfo(
REFIID riid,
void **ppvObj
)
{
CADSystemInfo FAR * pADSystemInfo = NULL;
HRESULT hr = S_OK;
hr = AllocateADSystemInfoObject(&pADSystemInfo);
BAIL_ON_FAILURE(hr);
hr = pADSystemInfo->QueryInterface(riid, ppvObj);
BAIL_ON_FAILURE(hr);
pADSystemInfo->Release();
RRETURN(hr);
error:
delete pADSystemInfo;
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: CADSystemInfo::~CADSystemInfo
//
// Synopsis:
//
// Arguments:
//
// Returns: HRESULT
//
// Modifies: -
//
// History:
//
//----------------------------------------------------------------------------
CADSystemInfo::~CADSystemInfo( )
{
delete _pDispMgr;
if (_hSecur32)
FreeLibrary(_hSecur32);
if (_hNetApi32)
FreeLibrary(_hNetApi32);
}
//+---------------------------------------------------------------------------
// Function: CADSystemInfo::QueryInterface
//
// Synopsis:
//
// Arguments:
//
// Returns: HRESULT
//
// Modifies: -
//
// History:
//
//----------------------------------------------------------------------------
STDMETHODIMP
CADSystemInfo::QueryInterface(
REFIID iid,
LPVOID FAR* ppv
)
{
if (ppv == NULL) {
RRETURN(E_POINTER);
}
if (IsEqualIID(iid, IID_IUnknown))
{
*ppv = (IADsADSystemInfo FAR *) this;
}
else if (IsEqualIID(iid, IID_IADsADSystemInfo))
{
*ppv = (IADsADSystemInfo FAR *) this;
}
else if (IsEqualIID(iid, IID_IDispatch))
{
*ppv = (IADsADSystemInfo FAR *) this;
}
else if (IsEqualIID(iid, IID_ISupportErrorInfo))
{
*ppv = (ISupportErrorInfo FAR *) this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
//+---------------------------------------------------------------------------
// Function: CADSystemInfo::AllocateADSystemInfoObject
//
// Synopsis:
//
// Arguments:
//
// Returns: HRESULT
//
// Modifies: -
//
// History:
//
//----------------------------------------------------------------------------
HRESULT
CADSystemInfo::AllocateADSystemInfoObject(
CADSystemInfo ** ppADSystemInfo
)
{
CADSystemInfo FAR * pADSystemInfo = NULL;
CAggregatorDispMgr FAR * pDispMgr = NULL;
HRESULT hr = S_OK;
pADSystemInfo = new CADSystemInfo();
if (pADSystemInfo == NULL) {
hr = E_OUTOFMEMORY;
}
BAIL_ON_FAILURE(hr);
pDispMgr = new CAggregatorDispMgr;
if (pDispMgr == NULL) {
hr = E_OUTOFMEMORY;
}
BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry(
pDispMgr,
LIBID_ADs,
IID_IADsADSystemInfo,
(IADsADSystemInfo *)pADSystemInfo,
DISPID_REGULAR
);
BAIL_ON_FAILURE(hr);
pADSystemInfo->_pDispMgr = pDispMgr;
*ppADSystemInfo = pADSystemInfo;
RRETURN(hr);
error:
delete pDispMgr;
RRETURN_EXP_IF_ERR(hr);
}
//+---------------------------------------------------------------------------
// Function: CADSystemInfo::InterfaceSupportsErrorInfo
//
// Synopsis:
//
// Arguments:
//
// Returns: HRESULT
//
// Modifies: -
//
// History:
//
//----------------------------------------------------------------------------
HRESULT
CADSystemInfo::InterfaceSupportsErrorInfo(THIS_ REFIID riid)
{
if (IsEqualIID(riid, IID_IADsADSystemInfo)) {
RRETURN(S_OK);
} else {
RRETURN(S_FALSE);
}
}
HRESULT
CADSystemInfo::get_UserName(
BSTR * bstrUserName
)
{
PWSTR pszUserDN = NULL;
ULONG uLength;
GETUSERNAMEEX pGetUserNameEx;
HRESULT hr;
HINSTANCE hModule;
//
// Validate parameters
//
if ( !bstrUserName )
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
//
// Get handle to secur32.dll, and get required entry point
//
hr = GetSecur32Handle(&hModule);
BAIL_ON_FAILURE(hr);
pGetUserNameEx = (GETUSERNAMEEX) GetProcAddress(hModule, "GetUserNameExW");
if (!pGetUserNameEx)
{
RRETURN(E_FAIL);
}
//
// Get length of buffer to be allocated
//
uLength = 0;
(*pGetUserNameEx)(NameFullyQualifiedDN,
NULL,
&uLength);
if (uLength > 0)
{
//
// Allocated memory and do the real work
//
pszUserDN = (PWSTR)AllocADsMem(uLength * sizeof(WCHAR));
if (!pszUserDN)
{
RRETURN(E_OUTOFMEMORY);
}
if ((*pGetUserNameEx)(NameFullyQualifiedDN,
pszUserDN,
&uLength))
{
hr = ADsAllocString(pszUserDN, bstrUserName);
BAIL_ON_FAILURE(hr);
}
else
hr = HRESULT_FROM_WIN32(GetLastError());
}
else
hr = HRESULT_FROM_WIN32(GetLastError());
error:
if (pszUserDN)
{
FreeADsMem(pszUserDN);
}
RRETURN(hr);
}
HRESULT
CADSystemInfo::get_ComputerName(
BSTR * bstrComputerName
)
{
PWSTR pszComputerName = NULL;
ULONG uLength;
GETCOMPUTEROBJECTNAME pGetComputerObjectName;
HRESULT hr;
HINSTANCE hModule;
//
// Validate parameters
//
if (!bstrComputerName)
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
//
// Get handle to secur32.dll, and get required entry point
//
hr = GetSecur32Handle(&hModule);
BAIL_ON_FAILURE(hr);
pGetComputerObjectName = (GETCOMPUTEROBJECTNAME)GetProcAddress(hModule, "GetComputerObjectNameW");
if (!pGetComputerObjectName)
{
RRETURN(E_FAIL);
}
//
// Get length of buffer to be allocated
//
uLength = 0;
(*pGetComputerObjectName)(NameFullyQualifiedDN,
NULL,
&uLength);
if (uLength > 0)
{
//
// Allocated memory and do the real work
//
pszComputerName = (PWSTR)AllocADsMem(uLength * sizeof(WCHAR));
if (!pszComputerName)
{
RRETURN(E_OUTOFMEMORY);
}
if ((*pGetComputerObjectName)(NameFullyQualifiedDN,
pszComputerName,
&uLength))
{
hr = ADsAllocString(pszComputerName, bstrComputerName);
BAIL_ON_FAILURE(hr);
}
else
hr = HRESULT_FROM_WIN32(GetLastError());
}
else
hr = HRESULT_FROM_WIN32(GetLastError());
error:
if (pszComputerName)
{
FreeADsMem(pszComputerName);
}
RRETURN(hr);
}
HRESULT
CADSystemInfo::get_SiteName(
BSTR * bstrSiteName
)
{
DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
DSGETDCNAME pDsGetDcName;
DWORD err;
HRESULT hr = S_OK;
//
// Validate parameters
//
if (!bstrSiteName)
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
//
// Get function pointer to DsGetDcName
//
pDsGetDcName = GetDsGetDcName();
if (! pDsGetDcName)
{
RRETURN(E_FAIL);
}
//
// Call DsGetDcName to find client site
//
err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, 0, &pdcInfo);
if (err != ERROR_SUCCESS)
{
RRETURN(HRESULT_FROM_WIN32(err));
}
hr = ADsAllocString(pdcInfo->ClientSiteName, bstrSiteName);
BAIL_ON_FAILURE(hr);
error:
if (pdcInfo)
{
NetApiBufferFree(pdcInfo);
}
RRETURN(hr);
}
HRESULT
CADSystemInfo::get_DomainShortName(
BSTR * bstrDomainName
)
{
DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
DSGETDCNAME pDsGetDcName;
DWORD err;
HRESULT hr = S_OK;
//
// Validate parameters
//
if (!bstrDomainName )
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
//
// Get function pointer to DsGetDcName
//
pDsGetDcName = GetDsGetDcName();
if (! pDsGetDcName)
{
RRETURN(E_FAIL);
}
//
// Call DsGetDcName to find domain short name
//
err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, DS_RETURN_FLAT_NAME, &pdcInfo);
if (err != ERROR_SUCCESS)
{
RRETURN(HRESULT_FROM_WIN32(err));
}
hr = ADsAllocString(pdcInfo->DomainName, bstrDomainName);
BAIL_ON_FAILURE(hr);
error:
if (pdcInfo)
{
NetApiBufferFree(pdcInfo);
}
RRETURN(hr);
}
HRESULT
CADSystemInfo::get_DomainDNSName(
BSTR * bstrDomainDNSName
)
{
DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
DSGETDCNAME pDsGetDcName;
DWORD err;
HRESULT hr = S_OK;
//
// Validate parameters
//
if (!bstrDomainDNSName )
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
//
// Get function pointer to DsGetDcName
//
pDsGetDcName = GetDsGetDcName();
if (! pDsGetDcName)
{
RRETURN(E_FAIL);
}
//
// Call DsGetDcName to find domain DNS name
//
err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, DS_RETURN_DNS_NAME, &pdcInfo);
if (err != ERROR_SUCCESS)
{
RRETURN(HRESULT_FROM_WIN32(err));
}
hr = ADsAllocString(pdcInfo->DomainName, bstrDomainDNSName);
BAIL_ON_FAILURE(hr);
error:
if (pdcInfo)
{
NetApiBufferFree(pdcInfo);
}
RRETURN(hr);
}
HRESULT
CADSystemInfo::get_ForestDNSName(
BSTR * bstrForestDNSName
)
{
DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
DSGETDCNAME pDsGetDcName;
DWORD err;
HRESULT hr = S_OK;
//
// Validate parameters
//
if (!bstrForestDNSName )
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
//
// Get function pointer to DsGetDcName
//
pDsGetDcName = GetDsGetDcName();
if (! pDsGetDcName)
{
RRETURN(E_FAIL);
}
//
// Call DsGetDcName to find forest DNS name
//
err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, 0, &pdcInfo);
if (err != ERROR_SUCCESS)
{
RRETURN(HRESULT_FROM_WIN32(err));
}
hr = ADsAllocString(pdcInfo->DnsForestName, bstrForestDNSName);
BAIL_ON_FAILURE(hr);
error:
if (pdcInfo)
{
NetApiBufferFree(pdcInfo);
}
RRETURN(hr);
}
HRESULT
CADSystemInfo::get_PDCRoleOwner(
BSTR * bstrPDCRoleOwner
)
{
RRETURN(GetfSMORoleOwner(DEFAULT_NC, bstrPDCRoleOwner));
}
HRESULT
CADSystemInfo::get_SchemaRoleOwner(
BSTR * bstrSchemaRoleOwner
)
{
RRETURN(GetfSMORoleOwner(SCHEMA_NC, bstrSchemaRoleOwner));
}
HRESULT
CADSystemInfo::get_IsNativeMode(
VARIANT_BOOL *retVal
)
{
IADs *pADs = NULL;
IDirectoryObject *pDir = NULL;
HRESULT hr;
ADS_ATTR_INFO *pAttrInfo = NULL;
DWORD dwReturn = 0;
LPWSTR pAttrNames[] = {L"nTMixedDomain" };
DWORD dwNumAttr = sizeof(pAttrNames)/sizeof(LPWSTR);
//
// Validate parameters
//
if (!retVal)
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
hr = GetNCHead(DEFAULT_NC, &pADs);
BAIL_ON_FAILURE(hr);
hr = pADs->QueryInterface(IID_IDirectoryObject, (void**) &pDir);
BAIL_ON_FAILURE(hr);
//
// Get the nTMixedDomain attribute
//
hr = pDir->GetObjectAttributes(pAttrNames,
dwNumAttr,
&pAttrInfo,
&dwReturn);
BAIL_ON_FAILURE(hr);
if (dwReturn == 0)
{
BAIL_ON_FAILURE(hr=E_FAIL);
}
*retVal = pAttrInfo->pADsValues->Boolean == FALSE ? VARIANT_TRUE : VARIANT_FALSE;
error:
//
// Clean-up
//
if (pAttrInfo)
FreeADsMem(pAttrInfo);
if (pDir)
pDir->Release();
if (pADs)
pADs->Release();
return hr;
}
HRESULT
CADSystemInfo::GetAnyDCName(
BSTR *bstrDCName
)
{
DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
DSGETDCNAME pDsGetDcName;
DWORD err;
HRESULT hr = S_OK;
//
// Validate parameters
//
if (!bstrDCName)
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
//
// Get function pointer to DsGetDcName
//
pDsGetDcName = GetDsGetDcName();
if (! pDsGetDcName)
{
RRETURN(E_FAIL);
}
//
// Call DsGetDcName to find DC name
//
err = (*pDsGetDcName)(NULL, NULL, NULL, NULL, 0, &pdcInfo);
if (err != ERROR_SUCCESS)
{
RRETURN(HRESULT_FROM_WIN32(err));
}
hr = ADsAllocString(&pdcInfo->DomainControllerName[2], bstrDCName); // skip "\\"
BAIL_ON_FAILURE(hr);
error:
if (pdcInfo)
{
NetApiBufferFree(pdcInfo);
}
RRETURN(hr);
}
HRESULT
CADSystemInfo::GetDCSiteName(
BSTR bstrDCName,
BSTR *bstrSiteName
)
{
DOMAIN_CONTROLLER_INFO *pdcInfo = NULL;
DSGETDCNAME pDsGetDcName;
DWORD err;
HRESULT hr = S_OK;
//
// Validate parameters
//
if (!bstrDCName|| !bstrSiteName)
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
//
// Get function pointer to DsGetDcName
//
pDsGetDcName = GetDsGetDcName();
if (! pDsGetDcName)
{
RRETURN(E_FAIL);
}
//
// Call DsGetDcName to find DC site name
//
err = (*pDsGetDcName)(bstrDCName, NULL, NULL, NULL, 0, &pdcInfo);
if (err != ERROR_SUCCESS)
{
RRETURN(HRESULT_FROM_WIN32(err));
}
hr = ADsAllocString(pdcInfo->DcSiteName, bstrSiteName);
BAIL_ON_FAILURE(hr);
error:
if (pdcInfo)
{
NetApiBufferFree(pdcInfo);
}
RRETURN(hr);
}
HRESULT
CADSystemInfo::RefreshSchemaCache(
void
)
{
IADs *pRootDSE = NULL;
VARIANT var;
HRESULT hr;
VariantInit( &var );
hr = ADsGetObject(L"LDAP://RootDSE", IID_IADs, (void**) &pRootDSE);
BAIL_ON_FAILURE(hr);
V_VT(&var) = VT_I4;
V_I4(&var) = 1;
hr = pRootDSE->Put(LDAP_OPATT_SCHEMA_UPDATE_NOW_W, var);
BAIL_ON_FAILURE(hr);
hr = pRootDSE->SetInfo();
BAIL_ON_FAILURE(hr);
error:
VariantClear( &var );
if (pRootDSE)
pRootDSE->Release();
RRETURN(hr);
}
HRESULT
CADSystemInfo::GetTrees(
VARIANT *pVar
)
{
PDS_DOMAIN_TRUSTS pDomains = NULL;
DSENUMERATEDOMAINTRUSTS pDsEnumerateDomainTrusts;
SAFEARRAYBOUND rgsabound[1];
SAFEARRAY *psa = NULL;
DWORD dwErr = 0;
ULONG i, lCount;
HRESULT hr = S_OK;
DWORD count;
//
// Validate parameters
//
if (!pVar )
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
//
// Get function pointer to NetEnumerateTrustedDomainsEx
//
pDsEnumerateDomainTrusts = GetDsEnumerateDomainTrusts();
if (! pDsEnumerateDomainTrusts)
{
RRETURN(E_FAIL);
}
//
// Enumerate all trusted domains
//
dwErr = (*pDsEnumerateDomainTrusts)(
NULL,
DS_DOMAIN_PRIMARY
| DS_DOMAIN_IN_FOREST
| DS_DOMAIN_DIRECT_OUTBOUND,
&pDomains,
&lCount
);
if (dwErr) {
hr = HRESULT_FROM_WIN32(dwErr);
}
BAIL_ON_FAILURE(hr);
//
// Count number of domains that are tree roots
//
count = 0;
for(i = 0; i < lCount; i++)
{
if (pDomains[i].Flags & DS_DOMAIN_TREE_ROOT)
{
ASSERT(pDomains[i].DnsDomainName);
count++;
}
}
//
// We have no tree roots - we must be on an NT4 domain, return
// an empty variant
//
if (count == 0)
{
VariantClear(pVar);
V_VT(pVar) = VT_EMPTY;
RRETURN(S_OK);
}
//
// Create Safe Array
//
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = count;
psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
if (! psa)
{
BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
}
VariantClear(pVar);
V_VT(pVar) = VT_VARIANT|VT_ARRAY;
V_ARRAY(pVar) = psa;
VARIANT varItem;
//
// Now iterate through each returned element and
// add it to the variant array if it is a tree root
//
count = 0;
for(i = 0; i < lCount; i++)
{
if (pDomains[i].Flags & DS_DOMAIN_TREE_ROOT)
{
VariantInit(&varItem);
V_VT(&varItem) = VT_BSTR;
hr = ADsAllocString(pDomains[i].DnsDomainName, &(V_BSTR(&varItem)));
BAIL_ON_FAILURE(hr);
hr = SafeArrayPutElement(psa, (long *) &count, &varItem);
VariantClear(&varItem);
BAIL_ON_FAILURE(hr);
count++;
}
}
error:
if (pDomains)
NetApiBufferFree(pDomains);
if (FAILED(hr) && psa)
SafeArrayDestroy(psa);
return hr;
}
HRESULT
CADSystemInfo::GetNCHead(
LPTSTR szNCName,
IADs **pADs
)
{
WCHAR szPathName[MAX_PATH];
VARIANT var;
HRESULT hr;
IADs *pRootDSE = NULL;
//
// Open RootDSE and query for NC object name
//
hr = ADsGetObject(L"LDAP://RootDSE", IID_IADs, (void**) &pRootDSE );
BAIL_ON_FAILURE(hr);
hr = pRootDSE->Get(szNCName, &var);
BAIL_ON_FAILURE(hr);
//
// Build LDAP://<naming context>
//
wcscpy(szPathName, L"LDAP://");
wcscat(szPathName, V_BSTR(&var));
//
// Get pointer to NC object
//
hr = ADsGetObject(szPathName, IID_IADs, (void**) pADs);
BAIL_ON_FAILURE(hr);
error:
if (pRootDSE)
{
pRootDSE->Release();
}
RRETURN(hr);
}
HRESULT
CADSystemInfo::GetfSMORoleOwner(
LPTSTR szNCName,
BSTR *bstrRoleOwner
)
{
IADs *pADs = NULL;
IDirectoryObject *pDir = NULL;
ADS_ATTR_INFO *pAttrInfo = NULL;
LPWSTR pAttrNames[] = {L"fSMORoleOwner" };
DWORD dwNumAttrs = sizeof(pAttrNames)/sizeof(LPWSTR);
HRESULT hr;
DWORD dwReturn;
//
// Validate parameters
//
if (!bstrRoleOwner )
{
RRETURN(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
}
hr = GetNCHead(szNCName, &pADs);
BAIL_ON_FAILURE(hr);
hr = pADs->QueryInterface(IID_IDirectoryObject, (void**) &pDir);
BAIL_ON_FAILURE(hr);
//
// Get the fSMORoleOwner
//
hr = pDir->GetObjectAttributes(pAttrNames,
dwNumAttrs,
&pAttrInfo,
&dwReturn);
BAIL_ON_FAILURE(hr);
if (dwReturn == 0)
{
BAIL_ON_FAILURE(hr=E_FAIL);
}
hr = ADsAllocString(pAttrInfo->pADsValues->CaseIgnoreString, bstrRoleOwner);
BAIL_ON_FAILURE(hr);
error:
//
// Clean-up
//
if (pDir)
pDir->Release();
if (pADs)
pADs->Release();
FreeADsMem(pAttrInfo);
RRETURN(hr);
}
HRESULT
CADSystemInfo::GetSecur32Handle(
HINSTANCE *pHandle
)
{
if (! _Secur32LoadAttempted)
{
_hSecur32 = LoadLibrary(__TEXT("secur32.dll"));
_Secur32LoadAttempted = TRUE;
}
*pHandle = _hSecur32;
if (_hSecur32)
RRETURN(S_OK);
else
RRETURN(E_FAIL);
}
DSGETDCNAME
CADSystemInfo::GetDsGetDcName(
void
)
{
DSGETDCNAME pDsGetDcName = NULL;
if (! _NetApi32LoadAttempted)
{
_hNetApi32 = LoadLibrary(__TEXT("netapi32.dll"));
_NetApi32LoadAttempted = TRUE;
}
if (_hNetApi32)
{
pDsGetDcName = (DSGETDCNAME)GetProcAddress(_hNetApi32, "DsGetDcNameW");
}
return pDsGetDcName;
}
DSENUMERATEDOMAINTRUSTS
CADSystemInfo::GetDsEnumerateDomainTrusts(
void
)
{
DSENUMERATEDOMAINTRUSTS pDsEnumerateDomainTrusts = NULL;
if (! _NetApi32LoadAttempted)
{
_hNetApi32 = LoadLibrary(__TEXT("netapi32.dll"));
_NetApi32LoadAttempted = TRUE;
}
if (_hNetApi32)
{
pDsEnumerateDomainTrusts = (DSENUMERATEDOMAINTRUSTS)
GetProcAddress(
_hNetApi32,
"DsEnumerateDomainTrustsW"
);
}
return pDsEnumerateDomainTrusts;
}
STDMETHODIMP
CADSystemInfoCF::CreateInstance(
IUnknown * pUnkOuter,
REFIID iid,
LPVOID * ppv
)
{
HRESULT hr = E_FAIL;
if (pUnkOuter)
RRETURN(E_FAIL);
hr = CADSystemInfo::CreateADSystemInfo(
iid,
ppv
);
RRETURN(hr);
}