/// <summary>
 /// RPCE unbind and disconnect.
 /// </summary>
 /// <param name="timeout">Timeout period.</param>
 /// <exception cref="InvalidOperationException">
 /// Thrown when RPC has not been bind.
 /// </exception>
 public void Unbind(TimeSpan timeout)
 {
     if (rpceClientTransport != null)
     {
         try
         {
             rpceClientTransport.Unbind(timeout);
             rpceClientTransport.Dispose();
         }
         catch
         {
         }
         finally
         {
             rpceClientTransport = null;
         }
     }
 }
 /// <summary>
 /// Dispose method.
 /// </summary>
 /// <param name="disposing">
 /// True to release both managed and unmanaged resources.<para/>
 /// False to release unmanaged resources only.
 /// </param>
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         // Release managed resources.
         if (rpceClientTransport != null)
         {
             rpceClientTransport.Dispose();
             rpceClientTransport = null;
         }
     }
 }
 /// <summary>
 /// Dispose method.
 /// </summary>
 /// <param name="disposing">
 /// True to release both managed and unmanaged resources.<para/>
 /// False to release unmanaged resources only.
 /// </param>
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         if (rpceClientTransport != null)
         {
             rpceClientTransport.Dispose();
             rpceClientTransport = null;
         }
     }
 }
        /// <summary>
        /// RPC bind to interface, using specified endpoint and authenticate provider.
        /// </summary>
        /// <param name="protocolSequence">RPC protocol sequence.</param>
        /// <param name="networkAddress">RPC network address.</param>
        /// <param name="endpoint">RPC endpoint.</param>
        /// <param name="transportCredential">
        /// If connect by SMB/SMB2, it's the security credential 
        /// used by underlayer transport (SMB/SMB2). 
        /// If connect by TCP, this parameter is ignored.
        /// </param>
        /// <param name="securityContext">RPC security provider.</param>
        /// <param name="authenticationLevel">RPC authentication level.</param>
        /// <param name="timeout">Timeout for bind and all future requests.</param>
        /// <exception cref="InvalidOperationException">
        /// Thrown when rpceClientTransport is not null.
        /// </exception>
        public void Bind(
            string protocolSequence,
            string networkAddress,
            string endpoint,
            AccountCredential transportCredential,
            ClientSecurityContext securityContext,
            RpceAuthenticationLevel authenticationLevel,
            TimeSpan timeout)
        {
            if (rpceClientTransport != null)
            {
                throw new InvalidOperationException("FSRVP has already been bind.");
            }

            rpceTimeout = timeout;

            rpceClientTransport = new RpceClientTransport();

            try
            {
                rpceClientTransport.Bind(
                    protocolSequence,
                    networkAddress,
                    endpoint,
                    transportCredential,
                    FsrvpUtility.FSRVP_INTERFACE_UUID,
                    FsrvpUtility.FSRVP_INTERFACE_MAJOR_VERSION,
                    FsrvpUtility.FSRVP_INTERFACE_MINOR_VERSION,
                    securityContext,
                    authenticationLevel,
                    true,
                    rpceTimeout);
            }
            catch
            {
                rpceClientTransport = null;
                throw;
            }
        }
        /// <summary>
        /// Bind to SAMR RPC server.
        /// </summary>
        /// <param name="protocolSequence">
        /// RPC protocol sequence.
        /// </param>
        /// <param name="networkAddress">
        /// RPC network address.
        /// </param>
        /// <param name="endpoint">
        /// RPC endpoint.
        /// </param>
        /// <param name="transportCredential">
        /// If connect by SMB/SMB2, it's the security credential 
        /// used by under layer transport (SMB/SMB2). 
        /// If connect by TCP, this parameter is ignored.
        /// </param>
        /// <param name="securityContext">
        /// RPC security provider.
        /// </param>
        /// <param name="authenticationLevel">
        /// RPC authentication level.
        /// </param>
        /// <param name="timeout">
        /// Timeout
        /// </param>
        public void Bind(
            string protocolSequence,
            string networkAddress,
            string endpoint,
            AccountCredential transportCredential,
            ClientSecurityContext securityContext,
            RpceAuthenticationLevel authenticationLevel,
            TimeSpan timeout)
        {
            if (rpceClientTransport != null)
            {
                throw new InvalidOperationException("SAMR has already been binded.");
            }

            rpceTimeout = timeout;
            rpceClientTransport = new RpceClientTransport();

            rpceClientTransport.Bind(
                protocolSequence,
                networkAddress,
                endpoint,
                transportCredential,
                SamrUtility.SAMR_RPC_INTERFACE_UUID,
                SamrUtility.SAMR_RPC_INTERFACE_MAJOR_VERSION,
                SamrUtility.SAMR_RPC_INTERFACE_MINOR_VERSION,
                securityContext,
                authenticationLevel,
                false,
                rpceTimeout);
        }
 /// <summary>
 /// RPC unbind.
 /// </summary>
 public void Unbind()
 {
     if (rpceClientTransport != null)
     {
         rpceClientTransport.Unbind(rpceTimeout);
         rpceClientTransport.Dispose();
         rpceClientTransport = null;
     }
 }
        /// <summary>
        /// Dispose method.
        /// </summary>
        /// <param name="disposing">
        /// True to release both managed and unmanaged resources.<para/>
        /// False to release unmanaged resources only.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Release managed resources.
                if (rpceClientTransport != null)
                {
                    try
                    {
                        rpceClientTransport.Unbind(new TimeSpan(0, 0, 3));
                    }
                    catch
                    {
                    }
                    rpceClientTransport.Dispose();

                    rpceClientTransport = null;
                }
            }

            // Release unmanaged resources.
        }
        /// <summary>
        /// Retrieve dynamic TCP endpoint by interface uuid, ver_major and ver_minor.
        /// </summary>
        /// <param name="serverName">Remote host name to query the interface.</param>
        /// <param name="interfaceId">Interface uuid to query.</param>
        /// <param name="interfaceMajorVersion">Interface ver_major to query.</param>
        /// <param name="interfaceMinorVersion">Interface ver_minor to query.</param>
        /// <returns>TCP endpoints which is querying.</returns>
        /// <exception cref="ArgumentNullException">
        /// Thrown when serverName is null.
        /// </exception>
        public static ushort[] QueryDynamicTcpEndpointByInterface(
            string serverName,
            Guid interfaceId,
            ushort interfaceMajorVersion,
            ushort interfaceMinorVersion)
        {
            if (serverName == null)
            {
                throw new ArgumentNullException("serverName");
            }

            byte[] requestStub = new byte[eptMapRequestStub.Length];
            Buffer.BlockCopy(eptMapRequestStub, 0, requestStub, 0, eptMapRequestStub.Length);

            // 37 == offset of interface uuid to query
            byte[] buffer = interfaceId.ToByteArray();
            Buffer.BlockCopy(buffer, 0, requestStub, 37, buffer.Length);

            //53 == offset of interface vers_major to query
            buffer = BitConverter.GetBytes(interfaceMajorVersion);
            Buffer.BlockCopy(buffer, 0, requestStub, 53, buffer.Length);

            //57 == offset of interface vers_minor to query
            buffer = BitConverter.GetBytes(interfaceMinorVersion);
            Buffer.BlockCopy(buffer, 0, requestStub, 57, buffer.Length);

            using (RpceClientTransport rpce = new RpceClientTransport())
            {
                rpce.Bind(
                    eptProtocolSequence,
                    serverName,
                    eptEndpoint.ToString(),
                    null,
                    eptInterfaceUuid,
                    eptInterfaceMajorVersion,
                    eptInterfaceMinorVersion,
                    null,
                    RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_NONE,
                    false,
                    queryEptTimeout);

                byte[] responseStub;

                rpce.Call(
                    eptMapOpnum,
                    requestStub,
                    queryEptTimeout,
                    out responseStub);

                if (responseStub == null)
                {
                    throw new InvalidOperationException("Query NRPC interface failed.");
                }
                if (responseStub.Length < sizeof(uint)) // status
                {
                    throw new InvalidOperationException("Query NRPC interface read status code failed.");
                }

                uint status = BitConverter.ToUInt32(responseStub, responseStub.Length - sizeof(uint));
                if (status != 0)
                {
                    throw new InvalidOperationException(
                              string.Format("Query interface failed with status code 0x{0:x}.", status));
                }

                int  offset    = 20; // skip entry_handle
                uint numTowers = BitConverter.ToUInt32(responseStub, offset);
                offset += 4;
                if (numTowers == 0)
                {
                    throw new InvalidOperationException("Query interface failed, no tower returned.");
                }

                ushort[] endpoints = new ushort[numTowers];

                offset += 12;                 //skip ITowers array size
                offset += 4 * (int)numTowers; //skip ITowers pointer
                for (int i = 0; i < numTowers; i++)
                {
                    offset += 8;  //skip length and tower_length
                    offset += 2;  //skip floor count
                    offset += 25; //skip if_id
                    offset += 25; //skip ndr rep
                    offset += 7;  //skip proto_id
                    offset += 5;  //skip port_addr lhs, id, rhs

                    //Port address is 16-bit unsigned integer, big-endian order.
                    endpoints[i] = (ushort)((responseStub[offset] << 8) + responseStub[offset + 1]);

                    offset += 2; //skip port address
                    offset += 9; //skip host_addr
                    offset += 1; //skip pad
                }

                return(endpoints);
            }
        }
        private void InnerBind(
            string protocolSequence,
            string networkAddress,
            string endpoint,
            AccountCredential transportCredential,
            ClientSecurityContext securityContext)
        {
            if (RpceClientTransport != null)
            {
                throw new InvalidOperationException("SRVS has already been bind");
            }

            RpceClientTransport = new RpceClientTransport();

            try
            {
                RpceClientTransport.Bind(
                    protocolSequence,
                    networkAddress,
                    endpoint,
                    transportCredential,
                    SrvsUtility.SRVS_INTERFACE_UUID,
                    SrvsUtility.SRVS_INTERFACE_MAJOR_VERSION,
                    SrvsUtility.SRVS_INTERFACE_MINOR_VERSION,
                    securityContext,
                    AuthenticationLevel,
                    true,
                    RpceTimeout);
            }
            catch
            {
                RpceClientTransport = null;
                throw;
            }
        }
 /// <summary>
 /// Unbind and release the handle.
 /// </summary>
 public void UnBind()
 {
     if (RpceClientTransport != null)
     {
         RpceClientTransport.Unbind(RpceTimeout);
         RpceClientTransport.Dispose();
         RpceClientTransport = null;
     }
 }
        /// <summary>
        /// Retrieve dynamic TCP endpoint by interface uuid, ver_major and ver_minor.
        /// </summary>
        /// <param name="serverName">Remote host name to query the interface.</param>
        /// <param name="interfaceId">Interface uuid to query.</param>
        /// <param name="interfaceMajorVersion">Interface ver_major to query.</param>
        /// <param name="interfaceMinorVersion">Interface ver_minor to query.</param>
        /// <returns>TCP endpoints which is querying.</returns>
        /// <exception cref="ArgumentNullException">
        /// Thrown when serverName is null.
        /// </exception>
        public static ushort[] QueryDynamicTcpEndpointByInterface(
            string serverName,
            Guid interfaceId,
            ushort interfaceMajorVersion,
            ushort interfaceMinorVersion)
        {
            if (serverName == null)
            {
                throw new ArgumentNullException("serverName");
            }

            byte[] requestStub = new byte[eptMapRequestStub.Length];
            Buffer.BlockCopy(eptMapRequestStub, 0, requestStub, 0, eptMapRequestStub.Length);

            // 37 == offset of interface uuid to query
            byte[] buffer = interfaceId.ToByteArray();
            Buffer.BlockCopy(buffer, 0, requestStub, 37, buffer.Length);

            //53 == offset of interface vers_major to query
            buffer = BitConverter.GetBytes(interfaceMajorVersion);
            Buffer.BlockCopy(buffer, 0, requestStub, 53, buffer.Length);

            //57 == offset of interface vers_minor to query
            buffer = BitConverter.GetBytes(interfaceMinorVersion);
            Buffer.BlockCopy(buffer, 0, requestStub, 57, buffer.Length);

            using (RpceClientTransport rpce = new RpceClientTransport())
            {
                rpce.Bind(
                    eptProtocolSequence,
                    serverName,
                    eptEndpoint.ToString(),
                    null,
                    eptInterfaceUuid,
                    eptInterfaceMajorVersion,
                    eptInterfaceMinorVersion,
                    null,
                    RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_NONE,
                    false,
                    queryEptTimeout);

                byte[] responseStub;

                rpce.Call(
                    eptMapOpnum,
                    requestStub,
                    queryEptTimeout,
                    out responseStub);

                if (responseStub == null)
                {
                    throw new InvalidOperationException("Query NRPC interface failed.");
                }
                if (responseStub.Length < sizeof(uint)) // status
                {
                    throw new InvalidOperationException("Query NRPC interface read status code failed.");
                }

                uint status = BitConverter.ToUInt32(responseStub, responseStub.Length - sizeof(uint));
                if (status != 0)
                {
                    throw new InvalidOperationException(
                        string.Format("Query interface failed with status code 0x{0:x}.", status));
                }

                int offset = 20; // skip entry_handle
                uint numTowers = BitConverter.ToUInt32(responseStub, offset);
                offset += 4;
                if (numTowers == 0)
                {
                    throw new InvalidOperationException("Query interface failed, no tower returned.");
                }

                ushort[] endpoints = new ushort[numTowers];

                offset += 12; //skip ITowers array size
                offset += 4 * (int)numTowers; //skip ITowers pointer
                for (int i = 0; i < numTowers; i++)
                {
                    offset += 8; //skip length and tower_length
                    offset += 2; //skip floor count
                    offset += 25; //skip if_id
                    offset += 25; //skip ndr rep
                    offset += 7; //skip proto_id
                    offset += 5; //skip port_addr lhs, id, rhs

                    //Port address is 16-bit unsigned integer, big-endian order.
                    endpoints[i] = (ushort)((responseStub[offset] << 8) + responseStub[offset + 1]);

                    offset += 2; //skip port address
                    offset += 9; //skip host_addr
                    offset += 1; //skip pad
                }

                return endpoints;
            }
        }
        /// <summary>
        /// RPC bind to interface, using specified endpoint and authenticate provider.
        /// </summary>
        /// <param name="protocolSequence">
        /// RPC protocol sequence.
        /// </param>
        /// <param name="networkAddress">
        /// RPC network address.
        /// </param>
        /// <param name="endpoint">
        /// RPC endpoint.
        /// </param>
        /// <param name="transportCred">
        /// Credential to bind SWN server
        /// </param>
        /// <param name="secContext">
        /// RPC security provider.
        /// </param>
        /// <param name="authLevel">
        /// RPC authentication level.
        /// </param>
        /// <param name="timeout">
        /// Timeout
        /// </param>
        /// <exception cref="InvalidOperationException">
        /// Thrown when there's existing connection.
        /// </exception>
        private bool RpcBind(
            string protocolSequence,
            string networkAddress,
            string endpoint,
            AccountCredential transportCred,
            ClientSecurityContext secContext,
            RpceAuthenticationLevel authLevel,
            TimeSpan timeout)
        {
            if (rpceClientTransport != null)
            {
                throw new InvalidOperationException("Connection has been established");
            }

            rpceTimeout = timeout;
            rpceClientTransport = new RpceClientTransport();

            try
            {
                rpceClientTransport.Bind(
                    protocolSequence,
                    networkAddress,
                    endpoint,
                    transportCred,
                    SwnUtility.SWN_INTERFACE_UUID,
                    SwnUtility.SWN_INTERFACE_MAJOR_VERSION,
                    SwnUtility.SWN_INTERFACE_MINOR_VERSION,
                    secContext,
                    authLevel,
                    true,
                    rpceTimeout);
            }
            catch (Exception)
            {
                rpceClientTransport.Dispose();
                rpceClientTransport = null;
                throw;
            }

            return true;
        }
 /// <summary>
 /// RPCE unbind and disconnect.
 /// </summary>
 /// <param name="timeout">
 /// Timeout period.
 /// </param>
 /// <exception cref="InvalidOperationException">
 /// Thrown when RPC has not been bind.
 /// </exception>
 public void SwnUnbind(TimeSpan timeout)
 {
     if (rpceClientTransport != null)
     {
         rpceClientTransport.Unbind(timeout);
         rpceClientTransport.Dispose();
         rpceClientTransport = null;
     }
 }