/*++ Module Name: RepEnum.cpp Abstract: This file contains the Implementation of the Class CReplicaEnum. This class implements the IEnumVARIANT which enumerates DfsReplicas. --*/ #include "stdafx.h" #include "DfsCore.h" #include "DfsRep.h" #include "RepEnum.h" ///////////////////////////////////////////////////////////////////////////// // ~CReplicaEnum CReplicaEnum :: ~CReplicaEnum() { _FreeMemberVariables(); } ///////////////////////////////////////////////////////////////////////////// // Initialize STDMETHODIMP CReplicaEnum :: Initialize ( REPLICAINFOLIST* i_priList, BSTR i_bstrEntryPath ) { /*++ Routine Description: Initializes the ReplicaEnum object. It copies the replica list passed to it by the junction point object. Sorting is done during the copying. --*/ if (!i_priList || !i_bstrEntryPath) return E_INVALIDARG; _FreeMemberVariables(); HRESULT hr = S_OK; do { m_bstrEntryPath = i_bstrEntryPath; BREAK_OUTOFMEMORY_IF_NULL((BSTR)m_bstrEntryPath, &hr); REPLICAINFOLIST::iterator i; REPLICAINFOLIST::iterator j; for (i = i_priList->begin(); i != i_priList->end(); i++) { // Find insertion position. for (j = m_Replicas.begin(); j != m_Replicas.end(); j++) { if (lstrcmpi((*i)->m_bstrServerName, (*j)->m_bstrServerName) < 0 || lstrcmpi((*i)->m_bstrShareName, (*j)->m_bstrShareName) <= 0) break; } REPLICAINFO* pTemp = (*i)->Copy(); BREAK_OUTOFMEMORY_IF_NULL(pTemp, &hr); m_Replicas.insert(j, pTemp); } } while (0); if (SUCCEEDED(hr)) m_iCurrentInEnumOfReplicas = m_Replicas.begin(); else _FreeMemberVariables(); return hr; } ///////////////////////////////////////////////////////////////////////////// // IEnumVariant Methods ///////////////////////////////////////////////////////////////////////////// // Next STDMETHODIMP CReplicaEnum :: Next ( ULONG i_ulNumOfReplicas, // Number of replicas to fetch VARIANT * o_pIReplicaArray, // VARIANT array to return fetched replicas. ULONG * o_ulNumOfReplicasFetched // Return the number of replicas fetched. ) { /*++ Routine Description: Gets the next object in the list. Arguments: i_ulNumOfReplicas - the number of replicas to return o_pIReplicaArray - an array of variants in which to return the replicas o_ulNumOfReplicasFetched - the number of replicas that are actually returned --*/ if (!i_ulNumOfReplicas || !o_pIReplicaArray) return E_INVALIDARG; HRESULT hr = S_OK; ULONG nCount = 0; //Count of Elements Fetched. IDfsReplica *pIReplicaPtr = NULL; // Create replica object using the internal replica list. for (nCount = 0; nCount < i_ulNumOfReplicas && m_iCurrentInEnumOfReplicas != m_Replicas.end(); m_iCurrentInEnumOfReplicas++) { // Create a replica object. hr = CoCreateInstance(CLSID_DfsReplica, NULL, CLSCTX_INPROC_SERVER, IID_IDfsReplica, (void **)&pIReplicaPtr); BREAK_IF_FAILED(hr); //Initialize the replica object. hr = pIReplicaPtr->Initialize(m_bstrEntryPath, (*m_iCurrentInEnumOfReplicas)->m_bstrServerName, (*m_iCurrentInEnumOfReplicas)->m_bstrShareName, (*m_iCurrentInEnumOfReplicas)->m_lDfsStorageState); if (FAILED(hr)) { pIReplicaPtr->Release(); break; } V_VT (&o_pIReplicaArray[nCount]) = VT_DISPATCH; o_pIReplicaArray[nCount].pdispVal = pIReplicaPtr; nCount++; } //VB does not send o_ulNumOfReplicasFetched; if (o_ulNumOfReplicasFetched) *o_ulNumOfReplicasFetched = nCount; if (SUCCEEDED(hr) && !nCount) return S_FALSE; else return hr; } ///////////////////////////////////////////////////////////////////////////// // Skip STDMETHODIMP CReplicaEnum :: Skip ( ULONG i_ulReplicasToSkip //Number of items to skip. ) { /*++ Routine Description: Skips the next 'n' objects in the list. Arguments: i_ulReplicasToSkip - the number of objects to skip over Return value: S_OK, On success S_FALSE, if the end of the list is reached --*/ for (unsigned int j = 0; j < i_ulReplicasToSkip && m_iCurrentInEnumOfReplicas != m_Replicas.end(); j++) { m_iCurrentInEnumOfReplicas++; } return (m_iCurrentInEnumOfReplicas != m_Replicas.end()) ? S_OK : S_FALSE; } ///////////////////////////////////////////////////////////////////////////// // Reset STDMETHODIMP CReplicaEnum :: Reset() { /*++ Routine Description: Resets the current enumeration pointer to the start of the list --*/ m_iCurrentInEnumOfReplicas = m_Replicas.begin(); return S_OK; } ///////////////////////////////////////////////////////////////////////////// // Clone STDMETHODIMP CReplicaEnum :: Clone ( IEnumVARIANT **o_ppEnum //Return IEnumVARIANT pointer. ) { /*++ Routine Description: Creates a clone of the enumerator object Arguments: o_ppEnum - address of the pointer to the IEnumVARIANT interface of the newly created enumerator object Notes: This has not been implemented. --*/ return E_NOTIMPL; }