4.1.10.5 Server Behavior of the IDL_DRSGetNCChanges Method

Informative summary of behavior: The IDL_DRSGetNCChanges method returns a response for a single request in a cycle.

This method is invoked through the drsuapi RPC interface. It is also invoked as a local procedure for requests that are received using the SMTP transport ([MS-SRPL]).

 ULONG
 IDL_DRSGetNCChanges(
     [in, ref] DRS_HANDLE hDrs,
     [in] DWORD dwInVersion,
     [in, ref, switch_is(dwInVersion)]
         DRS_MSG_GETCHGREQ *pmsgIn,
     [out, ref] DWORD *pdwOutVersion,
     [out, ref, switch_is(*pdwOutVersion)]
         DRS_MSG_GETCHGREPLY *pmsgOut)
  
 err: ULONG
 msgIn: DRS_MSG_GETCHGREQ_V10
 ncRoot: DSName
 obj: DSName
 msgOut: DRS_MSG_GETCHGREPLY_NATIVE
 schemaSignature: sequence of BYTE
 prefixEntry: PrefixTableEntry
 responseSmtpAddress: unicodestring
 fullReplicaFlags: set of integer
 fullReplicaRequest : boolean
  
 ValidateDRSInput(hDrs, 3)
  
 pdwOutVersion^ := 1
 pmsgOut^ := 0
  
 err := TransformInput(hDrs, dwInVersion, pmsgIn^, msgIn,
     pdwOutVersion, responseSmtpAddress)
 if err ≠ 0 then
   return err
 endif
  
 /* Perform access checks. */
 if msgIn.pNC = null then
   return ERROR_DS_DRA_INVALID_PARAMETER
 endif
 ncRoot := GetObjectNC(msgIn.pNC^)
  
 if ncRoot = null then
   return ERROR_DS_CANT_FIND_EXPECTED_NC
 endif
  
 if IsGetNCChangesPermissionGranted(msgIn) == FALSE then
   return ERROR_DRA_ACCESS_DENIED
 endif
  
 /* Validate inputs. */
 obj := msgIn.pNC^
 if AmILHServer() = false then  
   /* Downlevel OS does not understand
      DRS_SPECIAL_SECRET_PROCESSING flags. They just ignore it.
    */
   msgIn.ulFlags := msgIn.ulFlags - {DRS_SPECIAL_SECRET_PROCESSING}
 endif
  
 if msgIn.ulExtendedOp = 0 then
   /* Validate normal replication request. */
   if not FullReplicaExists(obj) and not PartialGCReplicaExists(obj) 
       then
     return ERROR_DS_CANT_FIND_EXPECTED_NC
   endif
 else
   /* Validate extended operation request. */
   if not ObjExists(obj) then
     return ERROR_DS_CANT_FIND_EXPECTED_NC
   endif
 endif
  
 if AmILHServer() then 
   if (msgIn.pPartialAttrSet = null and
       msgIn.pPartialAttrSetEx = null) then
     fullReplicaRequest := true
   else
     fullReplicaRequest := false
   endif
 else
   if (DRS_WRITE_REP in msgIn.ulFlags) then
     fullReplicaRequest := true
   else
     fullReplicaRequest := false
   endif
 endif
  
 if (fullReplicaRequest) then
   /* Validate Full Replica request. */
   if not IT_WRITE in obj!instanceType then
     return ERROR_DRA_SOURCE_IS_PARTIAL
   endif
   if DRS_SYNC_PAS in msgIn.ulFlags then
     return ERROR_INVALID_PARAMETER
   endif
 else
   /* Validate Partial Replica request. */
   if msgIn.pPartialAttrSet = null
       or msgIn.pPartialAttrSet.cAttrs = 0 then
     return ERROR_INVALID_PARAMETER
   endif
   if DRS_SYNC_PAS in msgIn.ulFlags and
       (msgIn.pPartialAttrSetEx = null
           or msgIn.pPartialAttrSetEx.cAttrs = 0) then
     return ERROR_INVALID_PARAMETER
   endif
   if msgIn.PrefixTableDest.PrefixCount = 0 then
     return ERROR_INVALID_PARAMETER
   endif
 endif
  
 if IT_NC_GOING in ncRoot!instanceType
   /* NC replica is no longer accepting requests. */
   return ERROR_DRA_NO_REPLICA
 endif
  
 if msgIn.uuidInvocIdSrc ≠ DSAObj()!invocationId then
   msgIn.usnvecFrom := 0
 endif
  
 /* Construct response. */
 if msgIn.ulExtendedOp = 0 then
   /* Perform normal replication. */
   err := GetReplChanges(hDrs, null, null, msgIn, msgOut)
  
 else
   /* Perform extended operation. Errors are returned in
    * msgOut.ulExtendedErr. */
   ProcessFsmoRoleRequest(hDrs, msgIn, msgOut)
   err := 0
 endif
 if err = 0 then
   msgOut.pNC := msgIn.pNC
   msgOut.usnvecFrom := msgIn.usnvecFrom
   msgOut.uuidDsaObjSrc := dc.serverGuid
   msgOut.PrefixTableSrc := ConcretePTFromAbstractPT(dc.prefixTable)
   msgOut.uuidInvocIdSrc := DSAObj()!invocationId
  
   /* Sort msgOut.rgValues into ascending order. */
   SortResponseLinks(msgOut)
   
   /* Add schema signature to msgOut.PrefixTableSrc. */
   schemaSignature := SchemaInfo()
   prefixEntry.ndx := 0
   prefixEntry.prefix.length := schemaSignature.length
   prefixEntry.prefix.element := elements of schemaSignature
   Append prefixEntry to msgOut.PrefixTableSrc.pPrefixEntry
   msgOut.PrefixTableSrc.PrefixCount :=
       msgOut.PrefixTableSrc.PrefixCount+1
  
   err := TransformOutput(msgOut, msgIn.ulFlags, pdwOutVersion^,
                          pmsgOut)
 endif
  
 if responseSmtpAddress ≠ null then
   Send the response using using the SMTP transport to
       responseSmtpAddress
 endif
  
 return err