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