4.1.13.3 Server Behavior of the IDL_DRSGetReplInfo Method
Informative summary of behavior: This method retrieves the replication state information of a DC. Based on the value of the InfoType field in the request message, different information is returned, which is summarized in the definition of DS_REPL_INFO in section 4.1.13.1.4.
-
ULONG IDL_DRSGetReplInfo( [in, ref] DRS_HANDLE hDrs, [in] DWORD dwInVersion, [in, ref, switch_is(dwInVersion)] DRS_MSG_GETREPLINFO_REQ *pmsgIn, [out, ref] DWORD *pdwOutVersion, [out, ref, switch_is(*pdwOutVersion)] DRS_MSG_GETREPLINFO_REPLY *pmsgOut) msgIn: DRS_MSG_GETREPLINFO_REQ_V2 infoType: DWORD fAccessGranted: boolean infoTypeValid: boolean defaultNC: DSName object: DSName enumerationContext: DWORD baseIndex: DWORD endIndex: DWORD ncs: set of DSName nc: DSName i, j: DWORD r: RepsFrom q: RepsTo pNeighbor: ADDRESS OF DS_REPL_NEIGHBORW utd: sequence of ReplUpToDateVector pCursor: ADDRESS OF DS_REPL_CURSOR pCursor2: ADDRESS OF DS_REPL_CURSOR_2 pCursor3: ADDRESS OF DS_REPL_CURSOR_3W a: ATTRTYP attr: ATTRTYP attrs: set of ATTRTYP attrsSeq: sequence of ATTRTYP s: AttributeStamp stamp: LinkValueStamp pObjMetaData: ADDRESS OF DS_REPL_OBJ_META_DATA pObjMetaData2: ADDRESS OF DS_REPL_OBJ_META_DATA_2 values: set of attribute value valuesSeq: sequence of attribute value ls: LinkValueStamp pAttrValueMetaData: ADDRESS OF DS_REPL_ATTR_VALUE_META_DATA pAttrValueMetaData2: ADDRESS OF DS_REPL_ATTR_VALUE_META_DATA_2 pFailedConnection: ADDRESS OF DS_REPL_KCC_DSA_FAILUREW pFailedLink: ADDRESS OF DS_REPL_KCC_DSA_FAILUREW pPendingOp: ADDRESS OF DS_REPL_OPW pClientContext: ADDRESS OF DS_REPL_CLIENT_CONTEXT pOutgoingContext: ADDRESS OF DS_REPL_SERVER_OUTGOING_CALL v: attribute value ValidateDRSInput(hDrs, 19) if dwInVersion = 1 then infoType = pmsgIn^ V1.InfoType else infoType = pmsgIn^ V2.InfoType endif pdwOutVersion^ := infoType if infoType = DS_REPL_INFO_NEIGHBORS then pmsgOut^.pNeighbors := null else if infoType = DS_REPL_INFO_CURSORS_FOR_NC then pmsgOut^.pCursors := null else if infoType = DS_REPL_INFO_METADATA_FOR_OBJ then pmsgOut^.pObjMetaData := null else if infoType = DS_REPL_INFO_KCC_DSA_CONNECT_FAILURES then pmsgOut^.pConnectFailures := null else if infoType = DS_REPL_INFO_KCC_DSA_LINK_FAILURES then pmsgOut^.pLinkFailures := null else if infoType = DS_REPL_INFO_PENDING_OPS then pmsgOut^.pPendingOps := null else if infoType = DS_REPL_INFO_METADATA_FOR_ATTR_VALUE then pmsgOut^.pAttrValueMetaData := null else if infoType = DS_REPL_INFO_CURSORS_2_FOR_NC then pmsgOut^.pCursors2 := null else if infoType = DS_REPL_INFO_CURSORS_3_FOR_NC then pmsgOut^.pCursors3 := null else if infoType = DS_REPL_INFO_METADATA_2_FOR_OBJ then pmsgOut^.pObjMetaData2 := null else if infoType = DS_REPL_INFO_METADATA_2_FOR_ATTR_VALUE then pmsgOut^.pAttrValueMetaData2 := null else if infoType = DS_REPL_INFO_SERVER_OUTGOING_CALLS then pmsgOut^.pServerOutgoingCalls := null else if infoType = DS_REPL_INFO_UPTODATE_VECTOR_V1 then pmsgOut^.pUpToDateVec := null else if infoType = DS_REPL_INFO_CLIENT_CONTEXTS then pmsgOut^.pClientContexts := null else if infoType = DS_REPL_INFO_REPSTO then pmsgOut^.pRepsTo := null endif /* Validate the version of the request message */ if (dwInVersion ≠ 1 and dwInVersion ≠ 2) then return ERROR_REVISION_MISMATCH endif if dwInVersion = 1 then msgIn := pmsgIn^.V1 else msgIn := pmsgIn^.V2 endif /* For some of the request types, paging is supported. For these * cases, a starting index into the result set is needed based on * what has already been returned in a previous call. Only version 2 * request messages provide a mechanism for the client to supply the * context information from a previous call. */ if dwInVersion = 1 then baseIndex := 0 else if msgIn.dwEnumerationContext = 0xffffffff then /* No more data is available. */ return ERROR_NO_MORE_ITEMS endif baseIndex := msgIn.dwEnumerationContext endif /* Perform the necessary access checks. */ defaultNC := DefaultNC() fAccessGranted := false infoTypeValid := false object := msgIn.pszObjectDN if (infoType = DS_REPL_INFO_NEIGHBORS and object ≠ null) then infoTypeValid := true fAccessGranted := AccessCheckAttr(object, repsFrom, RIGHT_DS_READ_PROPERTY) or AccessCheckCAR(object, DS-Replication-Manage-Topology) or AccessCheckCAR(object, DS-Replication-Monitor-Topology) endif if (infoType = DS_REPL_INFO_NEIGHBORS and object = null) then infoTypeValid := true fAccessGranted := AccessCheckAttr(defaultNC, repsFrom, RIGHT_DS_READ_PROPERTY) or AccessCheckCAR(defaultNC, DS-Replication-Manage-Topology) or AccessCheckCAR(defaultNC, DS-Replication-Monitor-Topology) endif if (infoType = DS_REPL_INFO_REPSTO and object ≠ null) then infoTypeValid := true fAccessGranted := AccessCheckAttr(object, repsTo, RIGHT_DS_READ_PROPERTY) or AccessCheckCAR(object, DS-Replication-Manage-Topology) or AccessCheckCAR(object, DS-Replication-Monitor-Topology) endif if (infoType = DS_REPL_INFO_REPSTO and object = null) then infoTypeValid := true fAccessGranted := AccessCheckAttr(defaultNC, repsTo, RIGHT_DS_READ_PROPERTY) or AccessCheckCAR(defaultNC, DS-Replication-Manage-Topology) or AccessCheckCAR(defaultNC, DS-Replication-Monitor-Topology) endif if (infoType in {DS_REPL_INFO_CURSORS_FOR_NC, DS_REPL_INFO_CURSORS_2_FOR_NC, DS_REPL_INFO_CURSORS_3_FOR_NC, DS_REPL_INFO_UPTODATE_VECTOR_V1} and object ≠ null) then infoTypeValid := true fAccessGranted := AccessCheckAttr( object, replUpToDateVector, RIGHT_DS_READ_PROPERTY) or AccessCheckCAR(object, DS-Replication-Manage-Topology) or AccessCheckCAR(object, DS-Replication-Monitor-Topology) endif if infoType in {DS_REPL_INFO_METADATA_FOR_OBJ, DS_REPL_INFO_METADATA_2_FOR_OBJ, DS_REPL_INFO_METADATA_FOR_ATTR_VALUE, DS_REPL_INFO_METATDATA_2_FOR_ATTR_VALUE} then if object = null then return ERROR_INVALID_PARAMETER endif if not ObjExists(object) then if object.dn = null then return ERROR_DS_DRA_BAD_DN else return ERROR_DS_OBJ_NOT_FOUND endif endif infoTypeValid := true fAccessGranted := AccessCheckAttr(object, replPropertyMetaData, RIGHT_DS_READ_PROPERTY) or AccessCheckCAR(object, DS-Replication-Manage-Topology) or AccessCheckCAR(object, DS-Replication-Monitor-Topology) endif if infoType in {DS_REPL_INFO_PENDING_OPS, DS_REPL_INFO_KCC_DSA_CONNECT_FAILURES, DS_REPL_INFO_KCC_DSA_LINK_FAILURES, DS_REPL_INFO_CLIENT_CONTEXTS, DS_REPL_INFO_SERVER_OUTGOING_CALLS} then infoTypeValid := true fAccessGranted := AccessCheckCAR(defaultNC, DS-Replication-Manage-Topology) or AccessCheckCAR(defaultNC, DS-Replication-Monitor-Topology) endif if not infoTypeValid then return ERROR_INVALID_PARAMETER endif if not fAccessGranted then return ERROR_DS_DRA_ACCESS_DENIED endif /* Based on the type of information requested, the corresponding * information is retrieved and the response message constructed */ /* DS_REPL_INFO_NEIGHBORS/DS_REPL_INFO_REPSTO */ if infoType in {DS_REPL_INFO_NEIGHBORS, DS_REPL_INFO_REPSTO} /* If an object is specified, it must be an NC root. */ nc := object if nc ≠ null then ncs := {nc} else ncs := GetNCs() endif if infoType = DS_REPL_INFO_NEIGHBORS then i := 0 j := 0 foreach nc in ncs foreach r in nc!repsFrom /* The ordering of ncs hosted by the server and the values of * repsFrom for each nc is arbitrary but consistent from call * to call on a server. */ /* If a source server GUID is specified, only information for * that server is returned. */ If (msgIn.uuidSourceDsaGuid = NULLGUID or msgIn.uuidSourceDsaGuid = r.uuidDsa) then if i >= baseIndex then pNeighbor := ADR(pmsgOut^.pNeighbors^.rgNeighbor[j]) pNeighbor^.pszSourceDsaAddress := r.naDsa pNeighbor^.uuidSourceDsaObjGuid := r.uuidDsa pNeighbor^.pszSourceDsaDN := GetDNFromObjectGuid(r.uuidDsa) pNeighbor^.pszNamingContext := nc!distinguishedName /* If a naming context is specified in the request, * the uuidNamingContextObjGuid field of the response * is set to the NULL GUID. */ if object ≠ null then pNeighbor^.uuidNamingContextObjGuid := NULLGUID else pNeighbor^.uuidNamingContextObjGuid := nc!objectGUID endif pNeighbor^.pszAsyncIntersiteTransportDN := GetDNFromObjectGuid(r.uuidTransportObj) pNeighbor^.uuidSourceDsaInvocationID := r.uuidInvocId pNeighbor^.uuidAsyncIntersiteTransportObjGuid := r.uuidTransportObj pNeighbor^.usnLastObjChangeSynced := r.usnVec.usnHighObjUpdate pNeighbor^.usnAttributeFilter := r.usnVec.usnHighPropUpdate pNeighbor^.ftimeLastSyncSuccess := r.timeLastSuccess pNeighbor^.ftimeLastSyncAttempt := r.timeLastAttempt pNeighbor^.dwLastSyncResult := r.ulResultLastAttempt pNeighbor^.cNumConsecutiveSyncFailures := r.cConsecutiveFailures /* Only a subset of the possible DRS_OPTIONS in r.options * are preserved in pNeighbor^.dwReplicaFlags. * See section 5.169 repsFrom, RepsFrom for more info. */ pNeighbor^.dwReplicaFlags := {} foreach flag in { DRS_WRIT_REP, DRS_INIT_SYNC, DRS_PER_SYNC, DRS_MAIL_REP, DRS_DISABLE_AUTO_SYNC, DRS_DISABLE_PERIODIC_SYNC, DRS_USE_COMPRESSION, DRS_TWOWAY_SYNC, DRS_NONGC_RO_REP, DRS_FULL_SYNC_IN_PROGRESS, DRS_FULL_SYNC_PACKET, DRS_REF_GCSPN, DRS_NEVER_SYNCED, DRS_SPECIAL_SECRET_PROCESSING, DRS_PREEMPTED, DRS_NEVER_NOTIFY, DRS_SYNC_PAS} if flag in r.options then pNeighbor^.dwReplicaFlags := pNeighbor^.dwReplicaFlags + flag endif endfor j := j + 1 endif i := i + 1 endif endfor endfor pmsgOut^.pNeighbors^.cNumNeighbors := j else /* DS_REPL_INFO_REPSTO case. */ i := 0 j := 0 foreach nc in ncs foreach q in nc!repsTo /* The ordering of ncs hosted by the server and the values of * repsTo for each nc is arbitrary but consistent from call * to call on a server. */ if i >= baseIndex then pNeighbor := ADR(pmsgOut^.pRepsTo^.rgNeighbor[j]) pNeighbor^.pszSourceDsaAddress := q.naDsa pNeighbor^.ftimeLastSyncSuccess := q.timeLastSuccess pNeighbor^.ftimeLastSyncAttempt := q.timeLastAttempt pNeighbor^.dwLastSyncResult := q.ulResultLastAttempt pNeighbor^.cNumConsecutiveSyncFailures := q.cConsecutiveFailures pNeighbor^.uuidSourceDsaObjGuid := q.uuidDsa pNeighbor^.pszSourceDsaDN := GetDNFromObjectGuid(q.uuidDsa) pNeighbor^.pszNamingContext := nc!distinguishedName /* If a naming context is specified in the request, * the uuidNamingContextObjGuid field of the response * is set to the NULL GUID. */ if object ≠ null then pNeighbor^.uuidNamingContextObjGuid := NULLGUID else pNeighbor^.uuidNamingContextObjGuid := nc!objectGUID endif /* Only a subset of the possible DRS_OPTIONS in q.options * are preserved in pNeighbor^.dwReplicaFlags. * See section 5.170 repsTo, RepsTo for more info. */ pNeighbor^.dwReplicaFlags := {} foreach flag in { DRS_WRIT_REP, DRS_INIT_SYNC, DRS_PER_SYNC, DRS_MAIL_REP, DRS_DISABLE_AUTO_SYNC, DRS_DISABLE_PERIODIC_SYNC, DRS_USE_COMPRESSION, DRS_TWOWAY_SYNC, DRS_NONGC_RO_REP, DRS_FULL_SYNC_IN_PROGRESS, DRS_FULL_SYNC_PACKET, DRS_REF_GCSPN, DRS_NEVER_SYNCED, DRS_SPECIAL_SECRET_PROCESSING, DRS_PREEMPTED, DRS_NEVER_NOTIFY, DRS_SYNC_PAS} if flag in q.options then pNeighbor^.dwReplicaFlags := pNeighbor^.dwReplicaFlags + flag endif endfor j := j + 1 endif i := i + 1 endfor endfor pmsgOut^.pRepsTo^.cNumNeighbors := j endif endif /* DS_REPL_INFO_METADATA_FOR_OBJ/DS_REPL_INFO_METADATA_2_FOR_OBJ */ if infoType in {DS_REPL_INFO_METADATA_FOR_OBJ, DS_REPL_INFO_METADATA_2_FOR_OBJ) then /* Enumerate all the replicated attributes */ attrsSeq := ReplicatedAttributes() i := 0 j := 0 while (i < attrsSeq.length) attr := attrsSeq[i] s := AttrStamp(object, attr) if (IsForwardLinkAttribute(attr) and dwInVersion = 2 and DS_REPL_INFO_FLAG_IMPROVE_LINKED_ATTRS in msgIn.ulFlags) then ls := null foreach v in GetAttrVals(object, attr, true) stamp := LinkStamp(object, attr, v) /* If v was last updated in win2k forest mode * then it does not have LinkValueStamp associated with it. * LinkStamp() returns null in that case. */ if stamp ≠ null and LinkValueStampCompare(stamp, ls) > 0 then ls := stamp; endif endfor if s = null then s := 0 /* An AttributeStamp with 0 for all fields. */ endif /* Improve the stamp with the link value stamp. */ s.dwVersion := ls.dwVersion s.timeChanged := ls.timeChanged s.uuidOriginating := NULLGUID s.usnOriginating := ls.usnOriginating endif if s ≠ null then if i >= baseIndex if infoType = DS_REPL_INFO_METADATA_FOR_OBJ then pObjMetaData := ADR(pmsgOut^.pObjMetaData^.rgMetaData[j]) pObjMetaData^.pszAttributeName := attr pObjMetaData^.dwVersion := s.dwVersion pObjMetaData^.ftimeLastOriginatingChange := s.timeChanged pObjMetaData^.uuidLastOriginatingDsaInvocationID := s.uuidOriginating pObjMetaData^.usnOriginatingChange := s.usnOriginating pObjMetaData^.usnLocalChange := An implementation-specific value that the server maintains for replicated attributes else pObjMetaData2 := ADR(pmsgOut^.pObjMetaData2^.rgMetaData[j]) pObjMetaData2^.pszAttributeName := attr pObjMetaData2^.dwVersion := s.dwVersion pObjMetaData2^.ftimeLastOriginatingChange := s.timeChanged pObjMetaData2^.uuidLastOriginatingDsaInvocationID := s.uuidOriginating pObjMetaData2^.usnOriginatingChange := s.usnOriginating pObjMetaData2^.usnLocalChange := An implementation-specific value that the server maintains for replicated attributes pObjMetaData2^.pszLastOriginatingDsaDN := GetDNFromInvocationID(s.uuidOriginating) endif j := j + 1 endif i := i + 1 endif endwhile if infoType = DS_REPL_INFO_METADATA_FOR_OBJ then pmsgOut^.pObjMetaData^.cNumEntries = j else pmsgOut^.pObjMetaData2^.cNumEntries = j endif endif /* DS_REPL_INFO_CURSORS_FOR_NC */ if infoType = DS_REPL_INFO_CURSORS_FOR_NC then /* The NC root object must be specified */ nc := object /* Parameter validation */ if nc = null then return ERROR_INVALID_PARAMETER endif if not FullReplicaExists(nc) and not PartialGCReplicaExists(nc) then return ERROR_DS_DRA_BAD_NC endif utd := GetUpToDatenessVector(nc) i := baseIndex j := 0 while i < utd.length pCursor := ADR(pmsgOut^.pCursors^.rgCursor[j]) pCursor^.uuidSourceDsaInvocationID := utd[i].uuidDsa pCursor^.usnAttributeFilter := utd[i].usnHighPropUpdate i := i + 1 j := j + 1 endwhile pmsgOut^.pCursors^.cNumCursors := j endif /* DS_REPL_INFO_CURSORS_2_FOR_NC/ DS_REPL_INFO_CURSORS_3_FOR_NC */ if infoType in {DS_REPL_INFO_CURSORS_2_FOR_NC, DS_REPL_INFO_CURSORS_3_FOR_NC} then /* The NC root object must be specified. */ nc := object /* Parameter validation. */ if (nc = null) then return ERROR_INVALID_PARAMETER endif if not FullReplicaExists(nc) and not PartialGCReplicaExists(nc) then return ERROR_DS_DRA_BAD_NC endif i := baseIndex j := 0 utd := GetUpToDatenessVector(nc) /* A maximum of 1000 items will be sent in each call. */ if utd.length - baseIndex - 1 > 1000 then endIndex = baseIndex + 1000 else endIndex = utd.length endif while i < endIndex if infoType = DS_REPL_INFO_CURSORS_2_FOR_NC then pCursor2 := ADR(pmsgOut^.pCursors2^.rgCursor[j]) pCursor2^.uuidSourceDsaInvocationID := utd[i].uuidDsa pCursor2^.usnAttributeFilter := utd[i].usnHighPropUpdate pCursor2^.ftimeLastSyncSucess := utd[i].timeLastSyncSuccess else pCursor3 := ADR(pmsgOut^.pCursor3^.rgCursor[j]) pCursor3^.uuidSourceDsaInvocationID := utd[i].uuidDsa pCursor3^.usnAttributeFilter := utd[i].usnHighPropUpdate pCursor3^.ftimeLastSyncSucess := utd[i].timeLastSyncSuccess pCursor3^.pszSourceDsaDN := GetDNFromInvocationID(utd[i].uuidDsa) endif j := j + 1 i := i + 1 endwhile if infoType = DS_REPL_INFO_CURSORS_2_NC then pmsgOut^.pCursors2^.cNumCursors := j else pmsgOut^.pCursors3^.cNumCursors := j endif if i < utd.length - 1 then /* Not all items could be sent back in this call, so save the * index of the first item to be sent in the next call. */ If infoType = DS_REPL_INFO_CURSORS_2_NC then pmsgOut^.pCursor2^.dwEnumerationContext := i else pmsgOut^.pCursors3^.dwEnumerationContext := i endif else /* No more data is available. */ If infoType = DS_REPL_INFO_CURSORS_2_NC then pmsgOut^.pCursor2^.dwEnumerationContext := 0xffffffff else pmsgOut^.pCursors3^.dwEnumerationContext := 0xffffffff endif endif endif /* DS_REPL_INFO_UPTODATE_VECTOR_V1 */ if infoType = DS_REPL_INFO_UPTODATE_VECTOR_V1 then /* The NC root object must be specified. */ nc := object /* Parameter validation. */ if (nc = null) then return ERROR_INVALID_PARAMETER endif utd := GetUpToDatenessVector(nc) for i := 0 to utd.length - 1 pCursor := ADR(pmsgOut^.pUpToDateVec^.rgCursors[i]) pCursor^.uuidSourceDsaInvocationID := utd[i].uuidDsa pCursor^.usnAttributeFilter := utd[i].usnHighPropUpdate endfor pmsgOut^.pUpToDateVec^.cNumCursors := utd.length endif /* DS_REPL_INFO_METADATA_FOR_ATTR_VALUE/ * DS_REPL_INFO_METADATA_2_FOR_ATTR_VALUE */ if infoType in {DS_REPL_INFO_METADATA_FOR_ATTR_VALUE, DS_REPL_INFO_METADATA_2_FOR_ATTR_VALUE} then /* If the attribute name is specified it must be a link * attribute. */ attrs := select all a in Link Attributes of object if (pmsgIn^.V2.pszAttributeNameValue ≠ null and pmsgIn^.V2.pszAttributeNameValue not in attrs) then return ERROR_DS_WRONG_LINKED_ATT_SYNTAX endif /* If the attribute name is not specified, replication state for a * link attribute of the object which has a value is returned. */ if (pmsgIn^.V2.pszAttributeNameValue ≠ null) then attr := pmsgIn^.V2.pszAttributeNameValue else attrsSeq := select all a in attrs where GetAttrVals(object, a, true) ≠ null attr := attrsSeq[0] endif if attr ≠ null then valuesSeq := GetAttrVals(object, attr, true) /* If a start value has been specified, then start at the first * occurrence of that value in the sequence of values, otherwise * start at the index determined from the enumeration context * which specifies the index of the next value to be returned. */ if (pmsgIn^.V2.pszValueDN ≠ null and Syntax(attr) = Object(DS-DN)) then i := index of pmsgIn^.V2.pszValueDN in valuesSeq else i := baseIndex endif j := 0 while (i < valuesSeq.length and j < 1000) ls := LinkStamp(object, attr, valuesSeq[i]) if infoType = DS_REPL_INFO_METADATA_FOR_ATTR_VALUE then pAttrValueMetaData := ADR(pmsgOut^.pAttrValueMetaData^.rgMetadata[j]) pAttrValueMetaData^.pszAttributeName := attr pAttrValueMetaData^.pszObjectDN := object!distinguishedName if (Syntax(attr) = Object(DN-Binary) or Syntax(attr) = Object(DN-String)) then pAttrValueMetaData^.cbData := length of data associated with valuesSeq[i] pAttrValueMetaData^.pbData := data associated with valuesSeq[i] endif pAttrValueMetaData^.ftimeCreated := ls.timeCreated pAttrValueMetaData^.ftimeDeleted := ls.timeDeleted pAttrValueMetaData^.dwVersion := ls.dwVersion pAttrValueMetaData^.ftimeLastOriginatingChange := ls.timeChanged pAttrValueMetaData^.uuidLastOriginatingDsaInvocationID := ls.uuidOriginating pAttrValueMetaData^.usnOriginatingChange := ls.usnOriginating pAttrValueMetaData^.usnLocalChange := implementation-specific value maintained for each link attribute value else pAttrValueMetaData2 := ADR(pmsgOut^.pAttrValueMetaData2^.rgMetadata[j]) pAttrValueMetaData2^.pszAttributeName := attr pAttrValueMetaData2^.pszObjectDN := object!distinguishedName if (Syntax(attr) = Object(DN-Binary) or Syntax(attr) = Object(DN-String)) then pAttrValueMetaData2^.cbData := length of data associated with valuesSeq[i] pAttrValueMetaData2^.pbData := data associated with valuesSeq[i] endif pAttrValueMetaData2^.ftimeCreated := ls.timeCreated pAttrValueMetaData2^.ftimeDeleted := ls.timeDeleted pAttrValueMetaData2^.dwVersion := ls.dwVersion pAttrValueMetaData2^.ftimeLastOriginatingChange := ls.timeChanged pAttrValueMetaData2^.uuidLastOriginatingDsaInvocationID := ls.uuidOriginating pAttrValueMetaData2^.usnOriginatingChange := ls.usnOriginating pAttrValueMetaData2^.usnLocalChange := implementation-specific value maintained for each link attribute value pAttrValueMetaData2^.pszLastOriginatingDsaDN := GetDNFromInvocationID(ls.uuidOriginating) endif i := i + 1 j := j + 1 endwhile if infoType = DS_REPL_INFO_METADATA_FOR_ATTR_VALUE then if i < valuesSeq.length - 1 then /* Since there are more entries to be returned, save the index * of the first value to be returned in the next call. */ pmsgOut^.pAttrValueMetaData^.dwEnumerationContext := i else /* No more data is available. */ pmsgOut^.pAttrValueMetaData^.dwEnumerationContext := 0xffffffff endif pmsgOut^.pAttrValueMetaData^.cNumEntries = j else if i < valuesSeq.length - 1 then /* Since there are more entries to be returned, save the index * of the first value to be returned in the next call. */ pmsgOut^.pAttrValueMetaData2^.dwEnumerationContext := i else /* No more data is available. */ pmsgOut^.pAttrValueMetaData2^.dwEnumerationContext := 0xffffffff endif pmsgOut^.pAttrValueMetaData2^.cNumEntries = j endif endif endif /* DS_REPL_INFO_KCC_DSA_CONNECT_FAILURES */ if infoType = DS_REPL_INFO_KCC_DSA_CONNECT_FAILURES then i := 0 foreach t in dc.kccFailedConnections pConnectionFailure := ADR(pmsgOut^.pConnectionFailures^.rgDsaFailure[i]) pConnectionFailure^.pszDsaDN := t.DsaDN pConnectionFailure^.uuidDsaObjGuid := t.UUIDDsa pConnectionFailure^.fTimeFirstFailure := t.TimeFirstFailure pConnectionFailure^.cNumFailures := t.FailureCount pConnectionFailure^.dwLastResult := t.LastResult i := i + 1 endfor pmsgOut^.pConnectionFailures^.cNumEntries := i endif /* DS_REPL_INFO_KCC_DSA_LINK_FAILURES */ if infoType = DS_REPL_INFO_KCC_DSA_LINK_FAILURES then i := 0 foreach t in dc.kccFailedLinks pConnectionLink := ADR(pmsgOut^.pLinkFailures^.rgDsaFailure[i]) pConnectionLink^.pszDsaDN := t.DsaDN pConnectionLink^.uuidDsaObjGuid := t.UUIDDsa pConnectionLink^.fTimeFirstFailure := t.TimeFirstFailure pConnectionLink^.cNumFailures := t.FailureCount pConnectionLink^.dwLastResult := t.LastResult i := i + 1 endfor pmsgOut^.pConnectionLinks^.cNumEntries := i endif /* DS_REPL_INFO_PENDING_OPS */ if infoType = DS_REPL_INFO_PENDING_OPS then i := 0 foreach t in dc.replicationQueue pPendingOp := ADR(pmsgOut^.pPendingOps^.rgPendingOp[i]) pPendingOp^.fTimeEnqueued := t.TimeEnqueued pPendingOp^.ulSerailNumber := t.SerialNumber pPendingOp^.ulPriority := t.Priority pPendingOp^.OpType := t.OperationType pPendingOp^.ulOptions := t.Options pPendingOp^.pszNamingContext := t.NamingContext pPendingOp^.pszDsaDN := t.DsaDN pPendingOp^.pszDsaAddress := t.DsaAddress pPendingOp^.uuidNamingContextObjGuid := t.UUIDNC pPendingOp^.uuidDsaObjGuid := t.UUIDDsa i := i + 1 endfor pmsgOut^.pPendingOps^.cNumPendingOps := i pmsgOut^.pPendingOps^.fTimeCurrentOpStarted := time when current operation was started endif /* DS_REPL_INFO_CLIENT_CONTEXTS */ if infoType = DS_REPL_INFO_CLIENT_CONTEXTS then i := 0 foreach t in dc.rpcClientContexts pClientContext := ADR(pmsgOut^.pClientContexts^.rgContext[i]) pClientContext^.hCtx := t.BindingContext pClientContext^.lReferenceCount := t.RefCount pClientContext^.fIsBound := t.IsBound pClientContext^.uuidClient := t.UUIDClient pClientContext^.timeLastUsed := t.TimeLastUsed pClientContext^.IPAddr := t.IPAddress pClientContext^.pid := t.PID i := i + 1 endfor pmsgOut^.pClientContexts^.cNumContexts := i endif /* DS_REPL_INFO_SERVER_OUTGOING_CALLS */ if infoType = DS_REPL_INFO_SERVER_OUTGOING_CALLS then i := 0 foreach t in dc.rpcOutgoingContexts pOutgoingContext = ADR(pmsgOut^.pServerOutgoingCalls^.rgCall[i]) pOutgoingContext^.pszServerName := t.ServerName pOutgoingContext^.fIsHandleBound := t.IsBound pOutgoingContext^.fIsHandleFromCache := t.HandleFromCache pOutgoingContext^.fIsHandleInCache := t.HandleInCache pOutgoingContext^.dwThreadId := t.ThreadId pOutgoingContext^.dwBindingTimeoutMins := t.BindingTimeOut pOutgoingContext^.dstimeCreated := t.CreateTime pOutgoingContext^.dwCallType := t.CallType i := i + 1 endfor pmsgOut^.pServerOutgoingCalls^.cNumCalls := i endif return 0