/// <summary>
        /// Loop epm receive process
        /// </summary>
        private static void epmReceiveLoop()
        {
            byte[] responseStub = new byte[eptMapResponseStub.Length];
            Buffer.BlockCopy(eptMapResponseStub, 0, responseStub, 0, eptMapResponseStub.Length);

            while (true)
            {
                RpceServerSessionContext context;
                ushort opnum;
                try
                {
                    byte[] requestStub = epmServer.ExpectCall(EPM_RECEIVE_LOOP_TIMEOUT, out context, out opnum);

                    if (opnum == eptMapOpnum)
                    {
                        p_syntax_id_t ifSpec = new p_syntax_id_t();
                        // 37 == offset of interface uuid, 16 == the size of uuid
                        ifSpec.if_uuid = new Guid(ArrayUtility.SubArray(requestStub, 37, 16));
                        //53 == offset of interface vers_major
                        ifSpec.if_vers_major = BitConverter.ToUInt16(requestStub, 53);
                        //57 == offset of interface vers_minor
                        ifSpec.if_vers_minor = BitConverter.ToUInt16(requestStub, 57);
                        if (endpointMap.ContainsKey(ifSpec))
                        {
                            //copy tower from request stub to response stub
                            //37 is the offset to interface uuid in request
                            //53 is the offset to interface uuid in response
                            Buffer.BlockCopy(requestStub, 37, responseStub, 53, 70);
                            //modify the endpoint in big enddian oder, offset is 112
                            responseStub[112] = (byte)(endpointMap[ifSpec] >> 8);
                            responseStub[113] = (byte)endpointMap[ifSpec];
                            //modify the address, offset is 119
                            Buffer.BlockCopy(hostIp.GetAddressBytes(), 0, responseStub, 119, 4);
                            //todo support Ipv6
                            epmServer.SendResponse(context, responseStub);
                        }
                    }
                }
                catch (TimeoutException)
                {
                    continue;
                }
            }
        }
Example #2
0
        /// <summary>
        /// update context on receiving RPCE CO Bind PDU.
        /// </summary>
        /// <param name="bindPdu">Bind PDU to receive.</param>
        internal void UpdateContextOnReceivingBindPdu(RpceCoBindPdu bindPdu)
        {
            this.MaxTransmitFragmentSize = bindPdu.max_xmit_frag;
            this.MaxReceiveFragmentSize  = bindPdu.max_recv_frag;

            if (bindPdu.assoc_group_id != 0)
            {
                this.AssociateGroupId = bindPdu.assoc_group_id;
            }
            else
            {
                if (this.associateGroupIdList.Count == 0)
                {
                    this.AssociateGroupId = bindPdu.assoc_group_id + 1;
                }
                else
                {
                    this.associateGroupIdList.Sort();
                    this.AssociateGroupId = this.associateGroupIdList[this.associateGroupIdList.Count - 1] + 1;
                }
            }

            associateGroupIdList.Add(this.AssociateGroupId);

            if (bindPdu.p_context_elem.p_cont_elem != null &&
                bindPdu.p_context_elem.p_cont_elem.Length > 0)
            {
                this.InterfaceId
                    = bindPdu.p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid;
                this.InterfaceMajorVersion
                    = bindPdu.p_context_elem.p_cont_elem[0].abstract_syntax.if_vers_major;
                this.InterfaceMinorVersion
                    = bindPdu.p_context_elem.p_cont_elem[0].abstract_syntax.if_vers_minor;

                this.NdrVersion = RpceNdrVersion.None;
                this.PresentationContextsTable.Clear();
                for (int i = 0; i < bindPdu.p_context_elem.p_cont_elem.Length; i++)
                {
                    p_cont_elem_t p_cont_elem = bindPdu.p_context_elem.p_cont_elem[i];

                    if (p_cont_elem.transfer_syntaxes == null)
                    {
                        continue;
                    }
                    for (int j = 0; j < p_cont_elem.transfer_syntaxes.Length; j++)
                    {
                        p_syntax_id_t transfer_syntax = p_cont_elem.transfer_syntaxes[j];

                        if (transfer_syntax.if_uuid == RpceUtility.NDR_INTERFACE_UUID
                            &&
                            transfer_syntax.if_vers_major == RpceUtility.NDR_INTERFACE_MAJOR_VERSION
                            &&
                            transfer_syntax.if_vers_minor == RpceUtility.NDR_INTERFACE_MINOR_VERSION)
                        {
                            this.NdrVersion |= RpceNdrVersion.NDR;
                            this.PresentationContextsTable.Add(p_cont_elem.p_cont_id, RpceNdrVersion.NDR);
                        }
                        else if (transfer_syntax.if_uuid == RpceUtility.NDR64_INTERFACE_UUID
                                 &&
                                 transfer_syntax.if_vers_major == RpceUtility.NDR64_INTERFACE_MAJOR_VERSION
                                 &&
                                 transfer_syntax.if_vers_minor == RpceUtility.NDR64_INTERFACE_MINOR_VERSION)
                        {
                            this.NdrVersion |= RpceNdrVersion.NDR64;
                            this.PresentationContextsTable.Add(p_cont_elem.p_cont_id, RpceNdrVersion.NDR64);
                        }
                        else
                        {
                            byte[] uuid = transfer_syntax.if_uuid.ToByteArray();
                            if (ArrayUtility.CompareArrays(
                                    ArrayUtility.SubArray(
                                        uuid,
                                        0,
                                        RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH),
                                    ArrayUtility.SubArray(
                                        RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_GUID_BYTES,
                                        0,
                                        RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH))
                                &&
                                transfer_syntax.if_vers_major == 1
                                &&
                                transfer_syntax.if_vers_minor == 0)
                            {
                                this.BindTimeFeatureNegotiationBitmask = (RpceBindTimeFeatureNegotiationBitmask)
                                                                         uuid[RpceUtility.BIND_TIME_FEATURE_NEGOTIATION_BITMASK_PREFIX_LENGTH];
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Loop epm receive process
        /// </summary>
        private static void epmReceiveLoop()
        {
            byte[] responseStub = new byte[eptMapResponseStub.Length];
            Buffer.BlockCopy(eptMapResponseStub, 0, responseStub, 0, eptMapResponseStub.Length);

            while (true)
            {
                RpceServerSessionContext context;
                ushort opnum;
                try
                {
                    byte[] requestStub = epmServer.ExpectCall(EPM_RECEIVE_LOOP_TIMEOUT, out context, out opnum);

                    if (opnum == eptMapOpnum)
                    {
                        p_syntax_id_t ifSpec = new p_syntax_id_t();
                        // 37 == offset of interface uuid, 16 == the size of uuid
                        ifSpec.if_uuid = new Guid(ArrayUtility.SubArray(requestStub, 37, 16));
                        //53 == offset of interface vers_major
                        ifSpec.if_vers_major = BitConverter.ToUInt16(requestStub, 53);
                        //57 == offset of interface vers_minor
                        ifSpec.if_vers_minor = BitConverter.ToUInt16(requestStub, 57);
                        if (endpointMap.ContainsKey(ifSpec))
                        {
                            //copy tower from request stub to response stub
                            //37 is the offset to interface uuid in request
                            //53 is the offset to interface uuid in response
                            Buffer.BlockCopy(requestStub, 37, responseStub, 53, 70);
                            //modify the endpoint in big enddian oder, offset is 112
                            responseStub[112] = (byte)(endpointMap[ifSpec] >> 8);
                            responseStub[113] = (byte)endpointMap[ifSpec];
                            //modify the address, offset is 119
                            Buffer.BlockCopy(hostIp.GetAddressBytes(), 0, responseStub, 119, 4);
                            //todo support Ipv6
                            epmServer.SendResponse(context, responseStub);
                        }
                    }
                }
                catch (TimeoutException)
                {
                    continue;
                }
            }
        }