4.1.10.6.1 ProcessGetNCChangesReply

 procedure ProcessGetNCChangesReply(
   hDrs: DRS_HANDLE,
   rf: RepsFrom,
   msgIn: DRS_MSG_GETCHGREQ_V10,
   dwOutVersion: ULONG,
   msgOut: DRS_MSG_GETCHGREPLY) : ULONG

Informative summary of behavior: The ProcessGetNCChangesReply procedure is invoked when an IDL_DRSGetNCChanges response is received over RPC or SMTP, as specified in [MS-SRPL]. Processing of a given response can be separated into five distinct phases: decompression, attribute value decryption, processing object updates, processing link value updates, and updating the "watermark" information.

The arguments to this procedure are as follows:

  • hDrs: The DRS_HANDLE derived by sending IDL_DRSBind to the server.

  • rf: RepsFrom for the server.

  • msgIn: IDL_DRSGetNCChanges request message sent to the server.

  • dwOutVersion: Version of response message received from the server.

  • msgOut: Response message received from the server.

     msgReplyNative: DRS_MSG_GETCHGREPLY_NATIVE
     replEntinfList: REPLENTINFLIST
     continueProcessing: boolean
     writableReplica: boolean
     sourcePrefixTable: PrefixTable
     attributesAndStamps: set of AttributeAndStamp
     linkValueCount: DWORD
     clientSchemaSignature: sequence of BYTE
     serverSchemaSignature: sequence of BYTE
     fServerSchemaMoreRecent: boolean
     lastElement: DWORD
     ulResult : ULONG
      
     /* Decompress and/or translate the response to a Native response,
      * as necessary. */
     if (dwOutVersion = 0x2) or (dwOutVersion = 0x7) then
       msgReplyNative := DecompressReplyMessage(msgOut, dwOutVersion)
     else
       msgReplyNative := GetNCChangesNativeReply(msgOut, dwOutVersion)
     endif
      
     ulResult := msgReplyNative.dwDRSError
      
     if (ulResult = 0) then
      
       sourcePrefixTable :=   
           AbstractPTFromConcretePT(msgReplyNative.PrefixTableSrc)
      
       /* Check whether the schema on client and server match. */ 
       lastElement := sourcePrefixTable.length - 1
       serverSchemaSignature :=
          copy sourcePrefixTable[lastElement].prefix.length bytes of data 
          from sourcePrefixTable[lastElement].prefix.elements
       clientSchemaSignature := SchemaInfo()
       if clientSchemaSignature ≠ serverSchemaSignature and 
          msgReplyNative.pNC^ ≠ SchemaNC())
       then
         return ERROR_DS_DRA_SCHEMA_MISMATCH
       endif
       Remove sourcePrefixTable[lastElement] from sourcePrefixTable
      
     else
       return ulResult
     endif
      
     /* If the source has the Recycle Bin optional feature enabled, then it must
      * be enabled locally, unless the Schema partition is being updating.
      */
     if  msgReplyNative.pNC^ ≠ SchemaNC() and
        ServerExtensions(hDrs).RB and not IsRecycleBinEnabled()
     then
        EnableRecycleBin()
        return ERROR_DS_DRS_EXTENSIONS_CHANGED
     endif
      
     /* If the source has the Privileged Access Management optional feature enabled,
      * then it must be enabled locally unless the Schema partition is being updated.
      */
     if  msgReplyNative.pNC^ ≠ SchemaNC() and
        ServerExtensions(hDrs).GR9 and not IsPrivilegedAccessManagementEnabled()
     then
        EnablePrivilegedAccessManagement()
        return ERROR_DS_DRS_EXTENSIONS_CHANGED
     endif
      
     /* Process object updates. */
     replEntinfList := msgReplyNative.pObjects^
     while (ulResult = 0) and (not replEntinfList = null)
       /* Decrypt any encrypted attribute values. */
       ulResult := DecryptValuesIfNecessary (
                     hDrs,
                     sourcePrefixTable,
                     replEntinfList.Entinf.AttrBlock)
      
       if (ulResult = 0) then
         attributesAndStamps := GetStampsForUpdate(
                              replEntinfList,
                              sourcePrefixTable)
         /* Process objects that are moved across an NC. */
         continueProcessing := PrepareCrossNCMove(
                                 replEntinfList, 
                                 sourcePrefixTable)
       endif
       if continueProcessing and (ulResult = 0) then
         if (DRS_WRIT_REP in msgIn.ulFlags) then
           writableReplica  := true
         else
           writableReplica  := false
         endif
         continueProcessing := AdjustInstanceTypeAttrVal(
                                 msgReplyNative.pNC^,
                                 writableReplica , 
                                 replEntinfList, 
                                 prefixTable)
       endif
       if continueProcessing and (ulResult = 0) then
         if (not ObjExists(replEntinfList.Entinf.pName^)) then
           ulResult := AddObject(
                         replEntinfList, 
                         sourcePrefixTable,
                         attributesAndStamps)
         else
           ulResult := UpdateObject(
                         replEntinfList, 
                         sourcePrefixTable,
                         attributesAndStamps)
         endif
       endif
       replEntinfList := replEntinfList.pNextEntInf^
     endwhile
      
     /* Enable link value updates for outbound replication
      * if inbound link value updates are detected from source. */
     if (msgReplyNative.cNumValues > 0) then
       dc.fLinkValueStampEnabled = true
     endif
      
     /* Process link value updates. */
     linkValueCount := 0
     while (ulResult = 0) and (linkValueCount < msgReplyNative.cNumValues)
       ulResult := ProcessLinkValue(
                     msgReplyNative.rgValues[linkValueCount],
                     msgReplyNative.pNC^,
                     prefixTable,
                     msgIn.ulFlags,
                     msgIn.ulMoreFlags)
       linkValueCount := linkValueCount + 1
     endwhile
      
     if (ulResult = ERROR_DS_DRA_MISSING_PARENT) then
       Send IDL_DRSGetNCChanges message again with the same input 
       parameters specified in msgIn but this time with msgIn.ulFlags 
       containing DRS_GET_ANC field set. It is an error for this 
       condition to occur if (DRS_GET_ANC in msgIn.ulFlags) is true
     else if (ulResult = ERROR_DS_DRA_RECYCLED_TARGET) then
       Send IDL_DRSGetNCChanges message again with the same input 
       parameters specified in the msgIn but this time with msgIn.ulMoreFlags 
       containing DRS_GET_TGT field set. 
     else if (msgIn.ulExtendedOp = 0) then
       /* Not an extended operation. Update "watermark" information. */
       UpdateRepsFrom(
         rf,
         msgReplyNative, 
         dsaServer,
         ulResult)
       
       if (ulResult = 0) and (msgReplyNative.fMoreData = false) then
         UpdateUTDandPAS(
           msgReplyNative,
           msgIn.partialAttrSetEx^)
       endif
     endif
      
     return ulResult