/// <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; } } }
/// <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]; } } } } } }