/// <summary>
 ///  Decodes the request stub, and fills the fields of the class
 /// </summary>
 /// <param name="sessionContext">The session context of the request received</param>
 /// <param name="requestStub">The request stub got from RPCE layer</param>
 internal override void Decode(NrpcServerSessionContext sessionContext, byte[] requestStub)
 {
     using (RpceInt3264Collection outParamList = RpceStubDecoder.ToParamList(
       RpceStubHelper.GetPlatform(),
         NrpcRpcStubFormatString.TypeFormatString,
         new RpceStubExprEval[] {
             new RpceStubExprEval(NrpcRpcAdapter.logon__NETLOGON_DELTA_USERExprEval_0000) },
         NrpcRpcStubFormatString.ProcFormatString,
         NrpcRpcStubFormatString.ProcFormatStringOffsetTable[(int)Opnum],
         false,
         requestStub))
     {
         PrimaryName = Marshal.PtrToStringUni(outParamList[0]);
         ComputerName = Marshal.PtrToStringUni(outParamList[1]);
         Authenticator = TypeMarshal.ToNullableStruct<_NETLOGON_AUTHENTICATOR>(outParamList[2]);
         ReturnAuthenticator = TypeMarshal.ToNullableStruct<_NETLOGON_AUTHENTICATOR>(outParamList[3]);
         DatabaseID = (DatabaseID_Values)outParamList[4].ToUInt32();
         RestartState = (_SYNC_STATE)outParamList[5].ToInt32();
         SyncContext = outParamList[6].ToUInt32();
         PreferredMaximumLength = outParamList[8].ToUInt32();
     }
 }
        /// <summary>
        ///  The NetrDatabaseSync2 method returns a set of all changes
        ///  applied to the specified database since its creation.
        ///  It provides an interface for a BDC to fully synchronize
        ///  its databases to those of the PDC. Because returning
        ///  all changes in one call might be prohibitively expensive
        ///  due to a large amount of data being returned, this
        ///  method supports retrieving portions of the database
        ///  changes in a series of calls using a continuation context
        ///  until all changes are received. It is possible for
        ///  the series of calls to be terminated prematurely due
        ///  to external events, such as system restarts. For that
        ///  reason, the method also supports restarting the series
        ///  of calls at a particular point specified by the caller.
        ///  The caller MUST keep track of synchronization progress
        ///  during the series of calls as detailed in this section.
        ///  Opnum: 16 
        /// </summary>
        /// <param name="PrimaryName">
        ///  The custom RPC binding handle, as specified in section
        ///  , that represents the connection to the PDC.
        /// </param>
        /// <param name="ComputerName">
        ///  The null-terminated Unicode string that contains the
        ///  NetBIOS name of the BDC calling this method.
        /// </param>
        /// <param name="Authenticator">
        ///  A pointer to a NETLOGON_AUTHENTICATOR structure, as
        ///  specified in section , that contains the client authenticator.
        /// </param>
        /// <param name="ReturnAuthenticator">
        ///  A pointer to a NETLOGON_AUTHENTICATOR structure, as
        ///  specified in section , that contains the server return
        ///  authenticator.
        /// </param>
        /// <param name="DatabaseID">
        ///  The identifier for a specific database for which the
        ///  changes are requested. It MUST be one of the following
        ///  values.
        /// </param>
        /// <param name="RestartState">
        ///  Specifies whether this is a restart of the series of
        ///  the synchronization calls and how to interpret SyncContext.
        ///  This value MUST be NormalState unless this is the restart,
        ///  in which case the value MUST be set as specified in
        ///  the description of the SyncContext parameter.
        /// </param>
        /// <param name="SyncContext">
        ///  Specifies context needed to continue the operation.
        ///  The value MUST be set to zero on the first call. The
        ///  caller MUST treat this as an opaque value, unless this
        ///  call is a restart of the series of synchronization
        ///  calls. The value returned is to be used on input for
        ///  the next call in the series of synchronization calls. If
        ///  this call is the restart of the series, the values
        ///  of the RestartState and the SyncContext parameters
        ///  are dependent on the DeltaType value received on the
        ///  last call before the restart and MUST be set as follows.
        ///  Find the last NETLOGON_DELTA_ENUM structure in the
        ///  DeltaArray parameter of the call. The DeltaType field
        ///  of this NETLOGON_DELTA_ENUM structure, as specified
        ///  in section , is the DeltaType needed for the restart.
        ///  The values of RestartState and SyncContext are then
        ///  determined from the following table. DeltaTypeRestartStateSyncContextAddOrChangeGroupGroupStateThe
        ///  value of the RID field of the last element AddOrChangeUserUserStateThe
        ///  value of the RID field of the last element ChangeGroupMembershipGroupMemberStateThe
        ///  value of the RID field of the last element AddOrChangeAliasAliasState0x00000000ChangeAliasMembershipAliasMemberState0x00000000Any
        ///  other value not previously listedNormalState0x00000000
        /// </param>
        /// <param name="DeltaArray">
        ///  A pointer to a NETLOGON_DELTA_ENUM_ARRAY structure,
        ///  as specified in section , that contains an array of
        ///  enumerated changes (deltas) to the specified database.
        /// </param>
        /// <param name="PreferredMaximumLength">
        ///  The value that specifies the preferred maximum size,
        ///  in bytes, of data referenced in the DeltaArray parameter.
        ///  This is not a hard upper limit, but serves as a guide
        ///  to the server. The server SHOULDwindows stops including
        ///  elements in the returned DeltaArray once the size of
        ///  the returned data equals or exceeds the value of the
        ///  PreferredMaximumLength parameter. The server SHOULD stop including elements
        ///  in the returned DeltaArray once the size of the returned
        ///  data equals or exceeds the value of the PreferredMaximumLength
        ///  parameter. It is up to the client implementation to
        ///  choose the value for this parameter.
        /// </param>
        public NtStatus NetrDatabaseSync2(
            string PrimaryName,
            string ComputerName,
            _NETLOGON_AUTHENTICATOR? Authenticator,
            ref _NETLOGON_AUTHENTICATOR? ReturnAuthenticator,
            DatabaseID_Values DatabaseID,
            _SYNC_STATE RestartState,
            ref uint? SyncContext,
            out _NETLOGON_DELTA_ENUM_ARRAY? DeltaArray,
            uint PreferredMaximumLength)
        {
            const ushort opnum = 16;

            byte[] requestStub;
            byte[] responseStub;
            Int3264[] paramList;
            int retVal;

            SafeIntPtr pPrimaryName = Marshal.StringToHGlobalUni(PrimaryName);
            SafeIntPtr pComputerName = Marshal.StringToHGlobalUni(ComputerName);
            SafeIntPtr pAuthenticator = TypeMarshal.ToIntPtr(Authenticator);
            SafeIntPtr pReturnAuthenticatorIn = TypeMarshal.ToIntPtr(ReturnAuthenticator);
            SafeIntPtr pSyncContext = TypeMarshal.ToIntPtr(SyncContext);

            paramList = new Int3264[] {
                pPrimaryName,
                pComputerName,
                pAuthenticator,
                pReturnAuthenticatorIn,
                (uint)DatabaseID,
                (uint)RestartState,
                pSyncContext,
                IntPtr.Zero,
                PreferredMaximumLength,
                0 // retVal
            };

            requestStub = RpceStubEncoder.ToBytes(
                     RpceStubHelper.GetPlatform(),
                    NrpcRpcStubFormatString.TypeFormatString,
                    new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) },
                    NrpcRpcStubFormatString.ProcFormatString,
                    NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum],
                    true,
                    paramList);

            rpceClientTransport.Call(opnum, requestStub, rpceTimeout, out responseStub);

            using (RpceInt3264Collection outParamList = RpceStubDecoder.ToParamList(
                     RpceStubHelper.GetPlatform(),
                    NrpcRpcStubFormatString.TypeFormatString,
                    new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) },
                    NrpcRpcStubFormatString.ProcFormatString,
                    NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum],
                    true,
                    responseStub,
                    paramList))
            {
                IntPtr pReturnAuthenticatorOut = outParamList[3];
                ReturnAuthenticator = TypeMarshal.ToNullableStruct<_NETLOGON_AUTHENTICATOR>(pReturnAuthenticatorOut);

                SyncContext = TypeMarshal.ToNullableStruct<uint>(outParamList[6]);

                IntPtr pDeltaArray = outParamList[7];
                pDeltaArray = Marshal.ReadIntPtr(pDeltaArray);
                DeltaArray = TypeMarshal.ToNullableStruct<_NETLOGON_DELTA_ENUM_ARRAY>(pDeltaArray);

                retVal = outParamList[9].ToInt32();
            }

            pPrimaryName.Dispose();
            pComputerName.Dispose();
            pAuthenticator.Dispose();
            pReturnAuthenticatorIn.Dispose();
            pSyncContext.Dispose();

            return (NtStatus)retVal;
        }
        /// <summary>
        ///  The NetrDatabaseSync2 method returns a set of all changes
        ///  applied to the specified database since its creation.
        ///  It provides an interface for a BDC to fully synchronize
        ///  its databases to those of the PDC. Because returning
        ///  all changes in one call might be prohibitively expensive
        ///  due to a large amount of data being returned, this
        ///  method supports retrieving portions of the database
        ///  changes in a series of calls using a continuation context
        ///  until all changes are received. It is possible for
        ///  the series of calls to be terminated prematurely due
        ///  to external events, such as system restarts. For that
        ///  reason, the method also supports restarting the series
        ///  of calls at a particular point specified by the caller.
        ///  The caller MUST keep track of synchronization progress
        ///  during the series of calls.
        ///  Opnum: 16 
        /// </summary>
        /// <param name="primaryName">
        ///  The custom RPC binding handle, 
        ///  that represents the connection to the PDC.
        /// </param>
        /// <param name="computerName">
        ///  The null-terminated Unicode string that contains the
        ///  NetBIOS name of the BDC calling this method.
        /// </param>
        /// <param name="authenticator">
        ///  A pointer to a NETLOGON_AUTHENTICATOR structure, 
        ///  that contains the client authenticator.
        /// </param>
        /// <param name="returnAuthenticator">
        ///  A pointer to a NETLOGON_AUTHENTICATOR structure, 
        ///  that contains the server return
        ///  authenticator.
        /// </param>
        /// <param name="databaseID">
        ///  The identifier for a specific database for which the
        ///  changes are requested. It MUST be one of the following
        ///  values.
        /// </param>
        /// <param name="restartState">
        ///  Specifies whether this is a restart of the series of
        ///  the synchronization calls and how to interpret SyncContext.
        ///  This value MUST be NormalState unless this is the restart,
        ///  in which case the value MUST be set as specified in
        ///  the description of the SyncContext parameter.
        /// </param>
        /// <param name="syncContext">
        ///  Specifies context needed to continue the operation.
        ///  The value MUST be set to zero on the first call. The
        ///  caller MUST treat this as an opaque value, unless this
        ///  call is a restart of the series of synchronization
        ///  calls. The value returned is to be used on input for
        ///  the next call in the series of synchronization calls. If
        ///  this call is the restart of the series, the values
        ///  of the RestartState and the SyncContext parameters
        ///  are dependent on the DeltaType value received on the
        ///  last call before the restart and MUST be set as follows.
        ///  Find the last NETLOGON_DELTA_ENUM structure in the
        ///  DeltaArray parameter of the call. The DeltaType field
        ///  of this NETLOGON_DELTA_ENUM structure 
        ///  is the DeltaType needed for the restart.
        ///  The values of RestartState and SyncContext are then
        ///  determined from the following table.<para/>
        ///  DeltaType  RestartState    SyncContext<para/>
        ///  AddOrChangeGroup   GroupState  The value of the RID field of the last element<para/>
        ///  AddOrChangeUser    UserState   The value of the RID field of the last element<para/>
        ///  ChangeGroupMembership  GroupMemberState    The value of the RID field of the last element<para/>
        ///  AddOrChangeAlias   AliasState 0x00000000<para/>
        ///  ChangeAliasMembership  AliasMemberState    0x00000000<para/>
        ///  Any other value not previously listed  NormalState 0x00000000
        /// </param>
        /// <param name="deltaArray">
        ///  A pointer to a NETLOGON_DELTA_ENUM_ARRAY structure,
        ///  that contains an array of
        ///  enumerated changes (deltas) to the specified database.
        /// </param>
        /// <param name="preferredMaximumLength">
        ///  The value that specifies the preferred maximum size,
        ///  in bytes, of data referenced in the DeltaArray parameter.
        ///  This is not a hard upper limit, but serves as a guide
        ///  to the server. The server SHOULDwindows stops including
        ///  elements in the returned DeltaArray once the size of
        ///  the returned data equals or exceeds the value of the
        ///  PreferredMaximumLength parameter. The server SHOULD stop including elements
        ///  in the returned DeltaArray once the size of the returned
        ///  data equals or exceeds the value of the PreferredMaximumLength
        ///  parameter. It is up to the client implementation to
        ///  choose the value for this parameter.
        /// </param>
        /// <returns>
        /// The method returns 0x00000000 on success; 
        /// otherwise, it returns a nonzero error code.
        /// </returns>
        public NtStatus NetrDatabaseSync2(
            string primaryName,
            string computerName,
            _NETLOGON_AUTHENTICATOR? authenticator,
            ref _NETLOGON_AUTHENTICATOR? returnAuthenticator,
            DatabaseID_Values databaseID,
            _SYNC_STATE restartState,
            ref uint? syncContext,
            out _NETLOGON_DELTA_ENUM_ARRAY? deltaArray,
            uint preferredMaximumLength)
        {
            NtStatus status = rpc.NetrDatabaseSync2(
                primaryName,
                computerName,
                authenticator,
                ref returnAuthenticator,
                databaseID,
                restartState,
                ref syncContext,
                out deltaArray,
                preferredMaximumLength);

            context.ConnectionStatus = status;
            return status;
        }