1229 lines
30 KiB
C++
1229 lines
30 KiB
C++
//---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1995
|
|
//
|
|
// File: cNameTranslate.cxx
|
|
//
|
|
// Contents: NameTranslate object
|
|
//
|
|
// History: 11-1-95 krishnag Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
#include "ldap.hxx"
|
|
#pragma hdrstop
|
|
|
|
#define ABORT_ON_ERROR(err) \
|
|
if ( 0 != (err) ) \
|
|
{ \
|
|
hr = E_FAIL; \
|
|
goto error; \
|
|
}
|
|
|
|
|
|
// Class CNameTranslate
|
|
DEFINE_IDispatch_Implementation(CNameTranslate)
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::CNameTranslate
|
|
//
|
|
// Synopsis: Constructor
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CNameTranslate::CNameTranslate():
|
|
_pDispMgr(NULL)
|
|
{
|
|
ENLIST_TRACKING(CNameTranslate);
|
|
_hDS = NULL;
|
|
_rgszGuid = NULL;
|
|
_rgDomainHandle = NULL;
|
|
_cGuid = 0;
|
|
_bChaseReferral = TRUE;
|
|
_bAuthSet = FALSE;
|
|
_pDomainHandle = new CDomainToHandle;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::CreateNameTranslate
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CNameTranslate::CreateNameTranslate(
|
|
REFIID riid,
|
|
void **ppvObj
|
|
)
|
|
{
|
|
CNameTranslate FAR * pNameTranslate = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = AllocateNameTranslateObject(&pNameTranslate);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pNameTranslate->QueryInterface(riid, ppvObj);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pNameTranslate->Release();
|
|
RRETURN(hr);
|
|
|
|
error:
|
|
delete pNameTranslate;
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::~CNameTranslate
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CNameTranslate::~CNameTranslate( )
|
|
{
|
|
DWORD i;
|
|
if (_hDS) {
|
|
DsUnBindWrapper(&_hDS);
|
|
_hDS = NULL;
|
|
}
|
|
delete _pDispMgr;
|
|
if (_rgszGuid) {
|
|
for (i=0;i<_cGuid;i++) {
|
|
FreeADsMem(_rgszGuid[i]);
|
|
}
|
|
FreeADsMem(_rgszGuid);
|
|
}
|
|
if (_rgDomainHandle) {
|
|
FreeADsMem(_rgDomainHandle);
|
|
}
|
|
if (_bAuthSet) {
|
|
DsFreePasswordCredentialsWrapper(_AuthIdentity);
|
|
_bAuthSet = FALSE;
|
|
}
|
|
if (_pDomainHandle) {
|
|
delete _pDomainHandle;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::QueryInterface
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CNameTranslate::QueryInterface(
|
|
REFIID iid,
|
|
LPVOID FAR* ppv
|
|
)
|
|
{
|
|
if (ppv == NULL) {
|
|
return E_POINTER;
|
|
}
|
|
|
|
if (IsEqualIID(iid, IID_IUnknown))
|
|
{
|
|
*ppv = (IADsNameTranslate FAR *) this;
|
|
}
|
|
else if (IsEqualIID(iid, IID_IADsNameTranslate))
|
|
{
|
|
*ppv = (IADsNameTranslate FAR *) this;
|
|
}
|
|
else if (IsEqualIID(iid, IID_IDispatch))
|
|
{
|
|
*ppv = (IADsNameTranslate FAR *) this;
|
|
}
|
|
else
|
|
{
|
|
*ppv = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
HRESULT MapCrackErrToHR(DWORD dwErr)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
switch (dwErr) {
|
|
case DS_NAME_NO_ERROR:
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case DS_NAME_ERROR_RESOLVING:
|
|
hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_RESOLVING);
|
|
break;
|
|
|
|
case DS_NAME_ERROR_NOT_FOUND:
|
|
hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_NOT_FOUND);
|
|
break;
|
|
|
|
case DS_NAME_ERROR_NOT_UNIQUE:
|
|
hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_NOT_UNIQUE);
|
|
break;
|
|
|
|
case DS_NAME_ERROR_NO_MAPPING:
|
|
hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_NO_MAPPING);
|
|
break;
|
|
|
|
case DS_NAME_ERROR_DOMAIN_ONLY:
|
|
hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_DOMAIN_ONLY);
|
|
break;
|
|
|
|
case DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING:
|
|
hr = HRESULT_FROM_WIN32(
|
|
ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING
|
|
);
|
|
break;
|
|
|
|
case DS_NAME_ERROR_TRUST_REFERRAL:
|
|
|
|
hr = HRESULT_FROM_WIN32(ERROR_DS_NAME_ERROR_TRUST_REFERRAL);
|
|
break;
|
|
|
|
default:
|
|
hr = E_FAIL;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT MapAdsToCrack(DWORD dwType, DS_NAME_FORMAT *pdwReturn)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
switch (dwType) {
|
|
case ADS_NAME_TYPE_1779:
|
|
*pdwReturn = DS_FQDN_1779_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_CANONICAL:
|
|
*pdwReturn = DS_CANONICAL_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_NT4:
|
|
*pdwReturn = DS_NT4_ACCOUNT_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_DISPLAY:
|
|
*pdwReturn = DS_DISPLAY_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_DOMAIN_SIMPLE:
|
|
*pdwReturn = DS_DOMAIN_SIMPLE_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_ENTERPRISE_SIMPLE:
|
|
*pdwReturn = DS_ENTERPRISE_SIMPLE_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_GUID:
|
|
*pdwReturn = DS_UNIQUE_ID_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_USER_PRINCIPAL_NAME:
|
|
*pdwReturn = DS_USER_PRINCIPAL_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_CANONICAL_EX:
|
|
*pdwReturn = DS_CANONICAL_NAME_EX;
|
|
break;
|
|
case ADS_NAME_TYPE_SERVICE_PRINCIPAL_NAME:
|
|
*pdwReturn = DS_SERVICE_PRINCIPAL_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_UNKNOWN:
|
|
*pdwReturn = DS_UNKNOWN_NAME;
|
|
break;
|
|
case ADS_NAME_TYPE_SID_OR_SID_HISTORY_NAME:
|
|
*pdwReturn = DS_SID_OR_SID_HISTORY_NAME;
|
|
break;
|
|
|
|
default:
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
break;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::AllocateNameTranslateObject
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT
|
|
CNameTranslate::AllocateNameTranslateObject(
|
|
CNameTranslate ** ppNameTranslate
|
|
)
|
|
{
|
|
CNameTranslate FAR * pNameTranslate = NULL;
|
|
CDispatchMgr FAR * pDispMgr = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
pNameTranslate = new CNameTranslate();
|
|
if (pNameTranslate == NULL) {
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pDispMgr = new CDispatchMgr;
|
|
if (pDispMgr == NULL) {
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = LoadTypeInfoEntry(
|
|
pDispMgr,
|
|
LIBID_ADs,
|
|
IID_IADsNameTranslate,
|
|
(IADsNameTranslate *)pNameTranslate,
|
|
DISPID_REGULAR
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pNameTranslate->_pDispMgr = pDispMgr;
|
|
*ppNameTranslate = pNameTranslate;
|
|
|
|
RRETURN(hr);
|
|
|
|
error:
|
|
|
|
delete pDispMgr;
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::Set
|
|
//
|
|
// Synopsis: Sets the values of the NameTranslate object
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CNameTranslate::Set(long dwSetType,BSTR bstrADsPath)
|
|
{
|
|
DWORD dwErr = 0;
|
|
DS_NAME_RESULTW *pResult = NULL;
|
|
HANDLE hDS = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
DS_NAME_FORMAT dsFormat;
|
|
DWORD i;
|
|
BOOL fDoNotFree = FALSE;
|
|
|
|
//
|
|
// fDoNotFree is used to determine if we need to free
|
|
// the dsresul pResult or not. There are some cases when
|
|
// the call can fail but the ptr modified, and in those
|
|
// cases it should not be freed.
|
|
//
|
|
if (!bstrADsPath) {
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
if (!_hDS) {
|
|
hr = Init(ADS_NAME_INITTYPE_GC,NULL);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
if (_rgDomainHandle) {
|
|
FreeADsMem(_rgDomainHandle);
|
|
_rgDomainHandle = NULL;
|
|
}
|
|
|
|
|
|
hr = MapAdsToCrack(dwSetType,
|
|
&dsFormat);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
dwErr = DsCrackNamesWrapper(
|
|
_hDS,
|
|
DS_NAME_NO_FLAGS, // flags
|
|
dsFormat, // format in
|
|
DS_UNIQUE_ID_NAME, // format out
|
|
1, // name count
|
|
&bstrADsPath,
|
|
&pResult);
|
|
if (dwErr) {
|
|
fDoNotFree = TRUE;
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
if (_bChaseReferral && pResult->rItems[0].status == DS_NAME_ERROR_DOMAIN_ONLY) {
|
|
if (!pResult->rItems[0].pDomain) {
|
|
BAIL_ON_FAILURE(hr = E_FAIL);
|
|
}
|
|
//
|
|
// Chasing Referral
|
|
//
|
|
|
|
hr = _pDomainHandle->Find(bstrADsPath,
|
|
&hDS);
|
|
if (hr == E_FAIL ) {
|
|
|
|
if (!_bAuthSet) {
|
|
dwErr = DsBindWrapper(
|
|
NULL,
|
|
pResult->rItems[0].pDomain,
|
|
&hDS);
|
|
}
|
|
else {
|
|
dwErr = DsBindWithCredWrapper(
|
|
NULL,
|
|
pResult->rItems[0].pDomain,
|
|
_AuthIdentity,
|
|
&hDS);
|
|
}
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
hr = _pDomainHandle->AddElement(bstrADsPath, hDS);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
dwErr = DsCrackNamesWrapper(
|
|
hDS,
|
|
DS_NAME_NO_FLAGS, // flags
|
|
dsFormat, // format in
|
|
DS_UNIQUE_ID_NAME, // format out
|
|
1, // name count
|
|
&bstrADsPath,
|
|
&pResult);
|
|
if (dwErr) {
|
|
fDoNotFree = FALSE;
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
if (!_rgDomainHandle) {
|
|
_rgDomainHandle = (HANDLE*)AllocADsMem(sizeof(HANDLE));
|
|
if (!_rgDomainHandle) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
}
|
|
_rgDomainHandle [0] = hDS;
|
|
|
|
}
|
|
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
//
|
|
// All below will essentially return E_FAIL on failure.
|
|
//
|
|
ABORT_ON_ERROR(1 != pResult->cItems);
|
|
ABORT_ON_ERROR(NULL == pResult->rItems);
|
|
ABORT_ON_ERROR(pResult->rItems[0].status);
|
|
ABORT_ON_ERROR(NULL == (pResult->rItems[0].pName));
|
|
ABORT_ON_ERROR(0 == wcslen(pResult->rItems[0].pName));
|
|
ABORT_ON_ERROR(NULL == pResult->rItems[0].pDomain);
|
|
|
|
if (_rgszGuid) {
|
|
for (i=0;i<_cGuid;i++) {
|
|
FreeADsMem(_rgszGuid[i]);
|
|
}
|
|
FreeADsMem(_rgszGuid);
|
|
_rgszGuid = NULL;
|
|
}
|
|
|
|
_rgszGuid = (LPWSTR*)AllocADsMem(sizeof(LPWSTR));
|
|
if (!_rgszGuid) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
_rgszGuid[0] = AllocADsStr(pResult->rItems[0].pName);
|
|
if (!_rgszGuid[0]) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
_cGuid = 1;
|
|
|
|
if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
|
|
hr = MapCrackErrToHR(pResult->rItems[0].status);
|
|
}
|
|
|
|
if (pResult) {
|
|
DsFreeNameResultWrapper(pResult);
|
|
}
|
|
return hr;
|
|
|
|
error:
|
|
if (hDS) {
|
|
DsUnBindWrapper(&hDS);
|
|
hDS = NULL;
|
|
}
|
|
if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
|
|
hr = MapCrackErrToHR(pResult->rItems[0].status);
|
|
}
|
|
if (pResult && !fDoNotFree) {
|
|
DsFreeNameResultWrapper(pResult);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::Init
|
|
//
|
|
// Synopsis: Initialize the object
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CNameTranslate::Init(long lnType,BSTR bstrADsPath)
|
|
{
|
|
DWORD dwErr;
|
|
HANDLE hDS;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (_hDS) {
|
|
DsUnBindWrapper(&_hDS);
|
|
_hDS = NULL;
|
|
}
|
|
|
|
_pDomainHandle->Init();
|
|
|
|
switch (lnType) {
|
|
case ADS_NAME_INITTYPE_SERVER:
|
|
if (!bstrADsPath) {
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
dwErr = DsBindWrapper(
|
|
bstrADsPath,
|
|
NULL,
|
|
&hDS);
|
|
break;
|
|
|
|
case ADS_NAME_INITTYPE_DOMAIN:
|
|
if (!bstrADsPath) {
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
dwErr = DsBindWrapper(
|
|
NULL,
|
|
bstrADsPath,
|
|
&hDS);
|
|
break;
|
|
|
|
case ADS_NAME_INITTYPE_GC:
|
|
dwErr = DsBindWrapper(
|
|
NULL,
|
|
NULL,
|
|
&hDS);
|
|
break;
|
|
|
|
default:
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
break;
|
|
}
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
_hDS = hDS;
|
|
hr = S_OK;
|
|
error:
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::InitEx
|
|
//
|
|
// Synopsis: Initialize the object with Credentials
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 14-2-98 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CNameTranslate::InitEx(long lnType,BSTR bstrADsPath,BSTR bstrUserID, BSTR bstrDomain, BSTR bstrPassword)
|
|
{
|
|
DWORD dwErr;
|
|
HANDLE hDS;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (_hDS) {
|
|
DsUnBindWrapper(&_hDS);
|
|
_hDS = NULL;
|
|
}
|
|
|
|
hr = _pDomainHandle->Init();
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (_bAuthSet) {
|
|
DsFreePasswordCredentialsWrapper(_AuthIdentity);
|
|
_bAuthSet = FALSE;
|
|
}
|
|
|
|
dwErr = DsMakePasswordCredentialsWrapper(
|
|
bstrUserID,
|
|
bstrDomain,
|
|
bstrPassword,
|
|
&_AuthIdentity
|
|
);
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
_bAuthSet = TRUE;
|
|
|
|
switch (lnType) {
|
|
case ADS_NAME_INITTYPE_SERVER:
|
|
if (!bstrADsPath) {
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
dwErr = DsBindWithCredWrapper(
|
|
bstrADsPath,
|
|
NULL,
|
|
_AuthIdentity,
|
|
&hDS);
|
|
break;
|
|
|
|
case ADS_NAME_INITTYPE_DOMAIN:
|
|
if (!bstrADsPath) {
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
dwErr = DsBindWithCredWrapper(
|
|
NULL,
|
|
bstrADsPath,
|
|
_AuthIdentity,
|
|
&hDS);
|
|
break;
|
|
|
|
case ADS_NAME_INITTYPE_GC:
|
|
dwErr = DsBindWithCredWrapper(
|
|
NULL,
|
|
NULL,
|
|
_AuthIdentity,
|
|
&hDS);
|
|
break;
|
|
|
|
default:
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
break;
|
|
}
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
_hDS = hDS;
|
|
hr = S_OK;
|
|
return hr;
|
|
error:
|
|
if (_bAuthSet) {
|
|
DsFreePasswordCredentialsWrapper(_AuthIdentity);
|
|
_bAuthSet = FALSE;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CNameTranslate::put_ChaseReferral(THIS_ long lnChase)
|
|
{
|
|
_bChaseReferral = (BOOLEAN)lnChase;
|
|
RRETURN(S_OK);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::Get
|
|
//
|
|
// Synopsis: Retrive the pathname as different formats
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CNameTranslate::Get(THIS_ long dwFormatType, BSTR FAR *pbstrName)
|
|
{
|
|
DS_NAME_RESULTW *pResult = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
DWORD dwErr = 0;
|
|
HANDLE hDS;
|
|
DS_NAME_FORMAT dsFormat;
|
|
BOOL fDoNotFree = FALSE;
|
|
|
|
//
|
|
// Look at ::Set for more info on fDoNotFree
|
|
//
|
|
|
|
if (!_hDS) {
|
|
hr = Init(ADS_NAME_INITTYPE_GC,NULL);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
if (!pbstrName) {
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
if (dwFormatType == ADS_NAME_TYPE_UNKNOWN) {
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
if ((_cGuid) != 1) {
|
|
hr = E_FAIL;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = MapAdsToCrack(dwFormatType,
|
|
&dsFormat);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if (_bChaseReferral && _rgDomainHandle && _rgDomainHandle[0]) {
|
|
dwErr = DsCrackNamesWrapper(
|
|
_rgDomainHandle[0],
|
|
DS_NAME_NO_FLAGS, // flags
|
|
DS_UNIQUE_ID_NAME, // format in
|
|
dsFormat, // format out
|
|
_cGuid, // name count
|
|
_rgszGuid,
|
|
&pResult);
|
|
}
|
|
else {
|
|
dwErr = DsCrackNamesWrapper(
|
|
_hDS,
|
|
DS_NAME_NO_FLAGS, // flags
|
|
DS_UNIQUE_ID_NAME, // format in
|
|
dsFormat, // format out
|
|
_cGuid, // name count
|
|
_rgszGuid,
|
|
&pResult);
|
|
}
|
|
|
|
if (dwErr) {
|
|
fDoNotFree = TRUE;
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
ABORT_ON_ERROR(1 != pResult->cItems);
|
|
ABORT_ON_ERROR(NULL == pResult->rItems);
|
|
ABORT_ON_ERROR(pResult->rItems[0].status);
|
|
ABORT_ON_ERROR(NULL == (pResult->rItems[0].pName));
|
|
ABORT_ON_ERROR(0 == wcslen(pResult->rItems[0].pName));
|
|
ABORT_ON_ERROR(NULL == pResult->rItems[0].pDomain);
|
|
hr = ADsAllocString(pResult->rItems[0].pName,
|
|
pbstrName);
|
|
error:
|
|
if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
|
|
hr = MapCrackErrToHR(pResult->rItems[0].status);
|
|
}
|
|
if (pResult && !fDoNotFree) {
|
|
DsFreeNameResultWrapper(pResult);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::GetEx
|
|
//
|
|
// Synopsis: Retrive the pathname as different formats
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CNameTranslate::GetEx(THIS_ long dwFormatType, VARIANT FAR *pvarstrName)
|
|
{
|
|
long i = 0;
|
|
DWORD dwErr = 0;
|
|
DS_NAME_RESULTW *pResult = NULL;
|
|
HANDLE hDS;
|
|
HRESULT hr = E_FAIL;
|
|
DS_NAME_FORMAT dsFormat;
|
|
LPWSTR szGuid = (LPWSTR)_szGuid;
|
|
SAFEARRAY *aList = NULL;
|
|
SAFEARRAYBOUND aBound;
|
|
BOOL fDoNotFree = FALSE;
|
|
//
|
|
// Look at ::Set for info on fDoNotFree
|
|
//
|
|
|
|
if (!_hDS) {
|
|
hr = Init(ADS_NAME_INITTYPE_GC,NULL);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
if (!pvarstrName) {
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
if (dwFormatType == ADS_NAME_TYPE_UNKNOWN) {
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = MapAdsToCrack(dwFormatType,
|
|
&dsFormat);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
dwErr = DsCrackNamesWrapper(
|
|
_hDS,
|
|
DS_NAME_NO_FLAGS, // flags
|
|
DS_UNIQUE_ID_NAME, // format in
|
|
dsFormat, // format out
|
|
_cGuid, // name count
|
|
_rgszGuid,
|
|
&pResult);
|
|
|
|
if (dwErr) {
|
|
fDoNotFree = TRUE;
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
ABORT_ON_ERROR(NULL == pResult->rItems);
|
|
ABORT_ON_ERROR(pResult->rItems[0].status);
|
|
ABORT_ON_ERROR(NULL == (pResult->rItems[0].pName));
|
|
ABORT_ON_ERROR(0 == wcslen(pResult->rItems[0].pName));
|
|
ABORT_ON_ERROR(NULL == pResult->rItems[0].pDomain);
|
|
|
|
VariantInit( pvarstrName );
|
|
|
|
aBound.lLbound = 0;
|
|
aBound.cElements = pResult->cItems;
|
|
|
|
aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
|
|
|
|
if ( aList == NULL )
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
for ( i = 0; i < (long) pResult->cItems; i++ )
|
|
{
|
|
VARIANT v;
|
|
|
|
VariantInit(&v);
|
|
|
|
hr = ADsAllocString(
|
|
pResult->rItems[i].pName,
|
|
&(v.bstrVal)
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
v.vt = VT_BSTR;
|
|
|
|
hr = SafeArrayPutElement( aList, &i, &v );
|
|
VariantClear(&v);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
V_VT(pvarstrName) = VT_ARRAY | VT_VARIANT;
|
|
V_ARRAY(pvarstrName) = aList;
|
|
|
|
if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
|
|
hr = MapCrackErrToHR(pResult->rItems[0].status);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
if (pResult) {
|
|
DsFreeNameResultWrapper(pResult);
|
|
}
|
|
|
|
RRETURN(S_OK);
|
|
|
|
error:
|
|
if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
|
|
hr = MapCrackErrToHR(pResult->rItems[0].status);
|
|
}
|
|
if (pResult && !fDoNotFree) {
|
|
DsFreeNameResultWrapper(pResult);
|
|
}
|
|
if ( aList ) {
|
|
SafeArrayDestroy( aList );
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
ConvertSafeArrayToBstrArray(
|
|
VARIANT *pvarSafeArray,
|
|
BSTR **ppVarArray,
|
|
DWORD *pdwNumVariants
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwSLBound = 0;
|
|
DWORD dwSUBound = 0;
|
|
DWORD dwNumVariants = 0;
|
|
DWORD i = 0;
|
|
BSTR * pVarArray = NULL;
|
|
SAFEARRAY * pArray = NULL;
|
|
|
|
*pdwNumVariants = 0;
|
|
*ppVarArray = 0;
|
|
|
|
if(!((V_VT(pvarSafeArray) & VT_BSTR) && V_ISARRAY(pvarSafeArray)))
|
|
return(E_FAIL);
|
|
|
|
//
|
|
// This handles by-ref and regular SafeArrays.
|
|
//
|
|
if (V_VT(pvarSafeArray) & VT_BYREF)
|
|
pArray = *(V_ARRAYREF(pvarSafeArray));
|
|
else
|
|
pArray = V_ARRAY(pvarSafeArray);
|
|
|
|
//
|
|
// Check that there is only one dimension in this array
|
|
//
|
|
if (pArray->cDims != 1) {
|
|
hr = E_FAIL;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
//
|
|
// Check that there is at least one element in this array
|
|
//
|
|
|
|
if (pArray->rgsabound[0].cElements == 0){
|
|
return(S_OK); // Return success and null array
|
|
}
|
|
|
|
//
|
|
// We know that this is a valid single dimension array
|
|
//
|
|
|
|
hr = SafeArrayGetLBound(pArray,
|
|
1,
|
|
(long FAR *)&dwSLBound
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = SafeArrayGetUBound(pArray,
|
|
1,
|
|
(long FAR *)&dwSUBound
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
dwNumVariants = dwSUBound - dwSLBound + 1;
|
|
pVarArray = (BSTR*)AllocADsMem(
|
|
sizeof(BSTR)*dwNumVariants
|
|
);
|
|
if (!pVarArray) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
for (i = dwSLBound; i <= dwSUBound; i++) {
|
|
|
|
hr = SafeArrayGetElement(pArray,
|
|
(long FAR *)&i,
|
|
(pVarArray + i)
|
|
);
|
|
if (FAILED(hr)) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
*ppVarArray = pVarArray;
|
|
*pdwNumVariants = dwNumVariants;
|
|
|
|
error:
|
|
|
|
return(hr);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Function: CNameTranslate::SetEx
|
|
//
|
|
// Synopsis: Set multiple objects names
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Modifies: -
|
|
//
|
|
// History: 15-7-97 FelixW Created.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CNameTranslate::SetEx(THIS_ long dwSetType, VARIANT varstrName)
|
|
{
|
|
DWORD dwErr = 0;
|
|
DS_NAME_RESULTW *pResult = NULL;
|
|
HANDLE hDS;
|
|
HRESULT hr = E_FAIL;
|
|
DS_NAME_FORMAT dsFormat;
|
|
VARIANT *vVarArray = NULL;
|
|
PWSTR *ppszStrArray = NULL;
|
|
DWORD dwNum,i;
|
|
BOOL fDoNotFree = FALSE;
|
|
//
|
|
// Look at ::Set for more info on fDoNotFree
|
|
//
|
|
|
|
if (!_hDS) {
|
|
hr = Init(ADS_NAME_INITTYPE_GC,NULL);
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = MapAdsToCrack(dwSetType,
|
|
&dsFormat);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = ConvertSafeArrayToVariantArray(
|
|
varstrName,
|
|
&vVarArray,
|
|
&dwNum
|
|
);
|
|
// returns E_FAIL if varstrname is invalid
|
|
if (hr == E_FAIL)
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = ConvertVariantArrayToLDAPStringArray(
|
|
vVarArray,
|
|
&ppszStrArray,
|
|
dwNum
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
dwErr = DsCrackNamesWrapper(
|
|
_hDS,
|
|
DS_NAME_NO_FLAGS, // flags
|
|
dsFormat, // format in
|
|
DS_UNIQUE_ID_NAME, // format out
|
|
dwNum, // name count
|
|
ppszStrArray,
|
|
&pResult
|
|
);
|
|
|
|
if (dwErr) {
|
|
fDoNotFree = TRUE;
|
|
BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
ABORT_ON_ERROR(NULL == pResult->rItems);
|
|
ABORT_ON_ERROR(pResult->rItems[0].status);
|
|
ABORT_ON_ERROR(NULL == (pResult->rItems[0].pName));
|
|
ABORT_ON_ERROR(0 == wcslen(pResult->rItems[0].pName));
|
|
ABORT_ON_ERROR(NULL == pResult->rItems[0].pDomain);
|
|
|
|
|
|
if (_rgszGuid) {
|
|
for (i=0;i<_cGuid;i++) {
|
|
FreeADsMem(_rgszGuid[i]);
|
|
}
|
|
FreeADsMem(_rgszGuid);
|
|
}
|
|
|
|
_rgszGuid = (LPWSTR*)AllocADsMem(dwNum * sizeof(LPWSTR));
|
|
if (!_rgszGuid) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
for (i=0;i<dwNum;i++) {
|
|
_rgszGuid[i] = AllocADsStr(pResult->rItems[i].pName);
|
|
if (!_rgszGuid[i]) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
}
|
|
_cGuid = dwNum;
|
|
|
|
error:
|
|
if (ppszStrArray) {
|
|
|
|
for (i=0; i < dwNum; i++) {
|
|
if (ppszStrArray[i]) {
|
|
FreeADsStr(ppszStrArray[i]);
|
|
}
|
|
}
|
|
FreeADsMem(ppszStrArray);
|
|
}
|
|
|
|
if (vVarArray) {
|
|
|
|
for (i=0; i < dwNum; i++) {
|
|
VariantClear(vVarArray + i);
|
|
}
|
|
FreeADsMem(vVarArray);
|
|
}
|
|
|
|
if ((dwErr == 0) && (pResult) && (pResult->rItems[0].status != 0)) {
|
|
hr = MapCrackErrToHR(pResult->rItems[0].status);
|
|
}
|
|
if (pResult && !fDoNotFree) {
|
|
DsFreeNameResultWrapper(pResult);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
CDomainToHandle::CDomainToHandle()
|
|
{
|
|
m_cszMax = 0;
|
|
m_iszNext = 0;
|
|
m_rgMap = NULL;
|
|
}
|
|
|
|
CDomainToHandle::~CDomainToHandle()
|
|
{
|
|
Free();
|
|
}
|
|
|
|
DWORD CDomainToHandle::NumElements()
|
|
{
|
|
return m_iszNext;
|
|
}
|
|
|
|
HRESULT CDomainToHandle::Init()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
Free();
|
|
|
|
m_rgMap = (DomainToHandle*)AllocADsMem( STRINGPLEX_INC * sizeof(DomainToHandle) );
|
|
if (!m_rgMap) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
m_cszMax = STRINGPLEX_INC;
|
|
m_iszNext = 0;
|
|
memset(m_rgMap, 0, STRINGPLEX_INC * sizeof(DomainToHandle) );
|
|
|
|
error:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDomainToHandle::AddElement(LPWSTR szValue, HANDLE hDS)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DomainToHandle *rgMap = NULL;
|
|
|
|
if (!szValue) {
|
|
return E_ADS_BAD_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// If next index is larger than largest index
|
|
//
|
|
if (m_iszNext > (m_cszMax-1)) {
|
|
rgMap = (DomainToHandle*)ReallocADsMem(m_rgMap ,
|
|
m_cszMax*sizeof(DomainToHandle),
|
|
(m_cszMax + STRINGPLEX_INC)*sizeof(DomainToHandle));
|
|
if (!rgMap) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
m_rgMap = rgMap;
|
|
m_cszMax+=STRINGPLEX_INC;
|
|
}
|
|
|
|
m_rgMap[m_iszNext].szDomain = AllocADsStr(szValue);
|
|
if (!m_rgMap[m_iszNext].szDomain) {
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
m_rgMap[m_iszNext].hDS = hDS;
|
|
|
|
m_iszNext++;
|
|
error:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CDomainToHandle::Find(LPWSTR szValue, HANDLE *phDS)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
UINT i;
|
|
|
|
if (!szValue) {
|
|
return E_ADS_BAD_PARAMETER;
|
|
}
|
|
|
|
for (i=0;i<m_iszNext;i++) {
|
|
if (wcscmp(m_rgMap[i].szDomain, szValue) == 0) {
|
|
*phDS = m_rgMap[i].hDS;
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
void CDomainToHandle::Free()
|
|
{
|
|
DWORD isz = 0;
|
|
|
|
if (m_rgMap) {
|
|
for (isz=0;isz<m_iszNext;isz++) {
|
|
if (m_rgMap[isz].szDomain) {
|
|
FreeADsMem(m_rgMap[isz].szDomain);
|
|
DsUnBindWrapper(&m_rgMap[isz].hDS);
|
|
}
|
|
}
|
|
FreeADsMem(m_rgMap);
|
|
m_rgMap = NULL;
|
|
}
|
|
m_cszMax = 0;
|
|
m_iszNext = 0;
|
|
}
|
|
|