//--------------------------------------------------------------------------- // // 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;irItems[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