/// <summary> /// [TD Reference 3.2.5.3.4] /// Decode MCS Connect Response PDU with GCC Conference Create Response /// </summary> /// <param name="data">data to be parsed</param> /// <returns>decoded MCS Connect Response PDU with GCC Conference Create Response PDU</returns> public StackPacket DecodeMcsConnectResponsePDU(byte[] data) { // initialize int currentIndex = 0; Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response pdu = new Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response(); // McsConnectResponse: TpktHeader pdu.tpktHeader = ParseTpktHeader(data, ref currentIndex); // McsConnectResponse: X224 pdu.x224Data = ParseX224Data(data, ref currentIndex); // T125 Data: decode McsConnectResponse int t125DataLength = data.Length - currentIndex; if (t125DataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] t125Data = new byte[t125DataLength]; Array.Copy(data, currentIndex, t125Data, 0, t125Data.Length); Connect_Response mcsConnectResponse = new Connect_Response(); Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(t125Data); mcsConnectResponse.BerDecode(decodeBuffer); // McsConnectResponse:result pdu.mcsCrsp.result = (int)mcsConnectResponse.result.Value; byte[] userData = mcsConnectResponse.userData.ByteArrayValue; // T125 Data: decode McsConnectResponse's user data Asn1DecodingBuffer connectDataBuffer = new Asn1DecodingBuffer(userData); ConnectData connectData = new ConnectData(); connectData.PerDecode(connectDataBuffer); // T125 Data: get Gcc data int gccDataLength = userData.Length - ConstValue.GCC_DATA_OFFSET; if (gccDataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] gccData = new byte[gccDataLength]; Array.Copy(userData, ConstValue.GCC_DATA_OFFSET, gccData, 0, gccData.Length); // T125 Data: decode Gcc user data ConnectGCCPDU gccPdu = new ConnectGCCPDU(); Asn1DecodingBuffer gccPduBuffer = new Asn1DecodingBuffer(gccData); gccPdu.PerDecode(gccPduBuffer); // McsConnectResponse: H221Key ConferenceCreateResponse conferenceResponse = (ConferenceCreateResponse)gccPdu.GetData(); H221NonStandardIdentifier identifier = (H221NonStandardIdentifier)conferenceResponse.userData.Elements[0].key.GetData(); pdu.mcsCrsp.gccPdu.H221Key = Encoding.ASCII.GetString(identifier.ByteArrayValue); // McsConnectResponse: ccrResult pdu.mcsCrsp.gccPdu.ccrResult = (int)conferenceResponse.result.Value; // McsConnectResponse: nodeID pdu.mcsCrsp.gccPdu.nodeID = (int)conferenceResponse.nodeID.Value; // McsConnectResponse: tag pdu.mcsCrsp.gccPdu.tag = (int)conferenceResponse.tag.Value; // T125 Data: get Gcc user data byte[] gccUserData = conferenceResponse.userData.Elements[0].value.ByteArrayValue; // Reset current index currentIndex = 0; while (currentIndex < gccUserData.Length) { // Peek data type int tempIndex = currentIndex; TS_UD_HEADER_type_Values type = (TS_UD_HEADER_type_Values)ParseUInt16(gccUserData, ref tempIndex, false); // Parse data by type switch (type) { case TS_UD_HEADER_type_Values.SC_CORE: pdu.mcsCrsp.gccPdu.serverCoreData = ParseTsUdScCore(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_NET: pdu.mcsCrsp.gccPdu.serverNetworkData = ParseTsUdScNet(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_SECURITY: pdu.mcsCrsp.gccPdu.serverSecurityData = ParseTsUdScSec1(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_MCS_MSGCHANNEL: pdu.mcsCrsp.gccPdu.serverMessageChannelData = ParseTsUdScMSGChannel(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.SC_MULTITRANSPORT: pdu.mcsCrsp.gccPdu.serverMultitransportChannelData = ParseTsUdScMultiTransport(gccUserData, ref currentIndex); break; default: throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED); } } // Check if data length exceeded expectation VerifyDataLength(gccUserData.Length, currentIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED); return pdu; }
/// <summary> /// Encode GCC Conference Create Request according to [T124]. /// </summary> /// <param name="gccPdu">The data to be encoded.</param> /// <returns>The encoded data.</returns> private static byte[] EncodeGccRspData(ConnectGCCRsp gccPdu) { if (gccPdu == null) { return null; } #region Encode userData List<byte> userData = new List<byte>(); #region Encode serverCoreData structure TS_UD_CS_CORE if (gccPdu.serverCoreData != null) { List<byte> coreData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.serverCoreData.header); RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.serverCoreData.version); RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.serverCoreData.clientRequestedProtocols); //earlyCapabilityFlags is optional. if(gccPdu.serverCoreData.earlyCapabilityFlags != 0) RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.serverCoreData.earlyCapabilityFlags); userData.AddRange(coreData.ToArray()); } #endregion Encode serverCoreData structure TS_UD_CS_CORE #region Encode serverNetworkData TS_UD_CS_NET if (gccPdu.serverNetworkData != null) { List<byte> networkData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.header); RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.MCSChannelId); RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.channelCount); for (int i = 0; i < gccPdu.serverNetworkData.channelCount; ++i) { RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.serverNetworkData.channelIdArray[i]); } if (gccPdu.serverNetworkData.Pad != null) { RdpbcgrEncoder.EncodeBytes(networkData, gccPdu.serverNetworkData.Pad); } userData.AddRange(networkData.ToArray()); } #endregion Encode serverNetworkData TS_UD_CS_NET #region Encode serverSecurityData TS_UD_CS_SEC if (gccPdu.serverSecurityData != null) { List<byte> securityData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.serverSecurityData.header); RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.serverSecurityData.encryptionMethod); RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.serverSecurityData.encryptionLevel); if (gccPdu.serverSecurityData.encryptionMethod != EncryptionMethods.ENCRYPTION_METHOD_NONE || gccPdu.serverSecurityData.encryptionLevel != EncryptionLevel.ENCRYPTION_LEVEL_NONE) { RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.serverSecurityData.serverRandomLen.actualData); RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.serverSecurityData.serverCertLen.actualData); if (gccPdu.serverSecurityData.serverRandom != null) { RdpbcgrEncoder.EncodeBytes(securityData, gccPdu.serverSecurityData.serverRandom); } #region Encode certificate if (gccPdu.serverSecurityData.serverCertificate != null) { RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.serverSecurityData.serverCertificate.dwVersion); if (gccPdu.serverSecurityData.serverCertificate.dwVersion == SERVER_CERTIFICATE_dwVersion_Values.CERT_CHAIN_VERSION_1) { PROPRIETARYSERVERCERTIFICATE cert = (PROPRIETARYSERVERCERTIFICATE)gccPdu.serverSecurityData.serverCertificate.certData; RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.dwSigAlgId); RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.dwKeyAlgId); RdpbcgrEncoder.EncodeStructure(securityData, (ushort)cert.wPublicKeyBlobType); RdpbcgrEncoder.EncodeStructure(securityData, cert.wPublicKeyBlobLen); RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.PublicKeyBlob.magic); RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.keylen); RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.bitlen); RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.datalen); RdpbcgrEncoder.EncodeStructure(securityData, cert.PublicKeyBlob.pubExp); RdpbcgrEncoder.EncodeBytes(securityData, cert.PublicKeyBlob.modulus); RdpbcgrEncoder.EncodeStructure(securityData, (ushort)cert.wSignatureBlobType); RdpbcgrEncoder.EncodeStructure(securityData, cert.wSignatureBlobLen); RdpbcgrEncoder.EncodeBytes(securityData, cert.SignatureBlob); } else if (gccPdu.serverSecurityData.serverCertificate.dwVersion == SERVER_CERTIFICATE_dwVersion_Values.CERT_CHAIN_VERSION_2) { X509_CERTIFICATE_CHAIN cert = (X509_CERTIFICATE_CHAIN)gccPdu.serverSecurityData.serverCertificate.certData; RdpbcgrEncoder.EncodeStructure(securityData, (uint)cert.NumCertBlobs); for (int i = 0; i < cert.CertBlobArray.Length; i++) { RdpbcgrEncoder.EncodeStructure(securityData, cert.CertBlobArray[i].cbCert); RdpbcgrEncoder.EncodeBytes(securityData, cert.CertBlobArray[i].abCert); } RdpbcgrEncoder.EncodeBytes(securityData, cert.Padding); } } #endregion } userData.AddRange(securityData.ToArray()); } #endregion Encode serverSecurityData TS_UD_CS_SEC #region Encode serverMessageChannelData TS_UD_SC_MCS_MSGCHANNEL if (gccPdu.serverMessageChannelData != null) { List<byte> msgChannelData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(msgChannelData, gccPdu.serverMessageChannelData.header); RdpbcgrEncoder.EncodeStructure(msgChannelData, gccPdu.serverMessageChannelData.MCSChannelID); userData.AddRange(msgChannelData.ToArray()); } #endregion #region Encode serverMultitransportChannelData TS_UD_SC_MULTITRANSPORT if (gccPdu.serverMultitransportChannelData != null) { List<byte> multiTranChannelData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(multiTranChannelData, gccPdu.serverMultitransportChannelData.header); RdpbcgrEncoder.EncodeStructure(multiTranChannelData, (uint)gccPdu.serverMultitransportChannelData.flags); userData.AddRange(multiTranChannelData.ToArray()); } #endregion #endregion Encode userData #region Filling GCC Conference Create Request ConferenceCreateResponse gccCCrsp = new ConferenceCreateResponse(); gccCCrsp.nodeID = new UserID(gccPdu.nodeID); gccCCrsp.tag = new Asn1Integer(gccPdu.tag); gccCCrsp.result = new ConferenceCreateResponse_result(gccPdu.ccrResult); //gccCCrsp.extElem1 = new Asn1OpenExt(); UserDataElement[] dataElements = new UserDataElement[1]; dataElements[0] = new UserDataElement(); dataElements[0].key = new Key(Key.h221NonStandard, new H221NonStandardIdentifier(gccPdu.H221Key)); dataElements[0].value = new Asn1OctetString(userData.ToArray()); gccCCrsp.userData = new UserData(dataElements); ConnectGCCPDU cGccPdu = new ConnectGCCPDU(ConnectGCCPDU.conferenceCreateResponse, gccCCrsp); #endregion Filling GCC Conference Create Request #region Encode ConnectData Asn1PerEncodingBuffer perBuffer = new Asn1PerEncodingBuffer(true); cGccPdu.PerEncode(perBuffer); byte[] asnEncodedData = perBuffer.ByteArrayData; Key key = new Key(Key.obj, new Asn1ObjectIdentifier(ConstValue.MCS_ATTRIBUTE_ID)); ConnectData connectData = new ConnectData(key, new Asn1OctetString(asnEncodedData)); Asn1PerEncodingBuffer perBuffer2 = new Asn1PerEncodingBuffer(true); connectData.PerEncode(perBuffer2); #endregion Encode ConnectData #region Workaround for Windows encoding issue //reset the ConnectPDULength to one-byte length: 0x2A byte[] returnButter = null; if ((perBuffer2.ByteArrayData[7] & 0x80) == 0x80) { //If length is two-byte, delete one byte returnButter = new byte[perBuffer2.ByteArrayData.Length - 1]; Array.Copy(perBuffer2.ByteArrayData, returnButter, 7); Array.Copy(perBuffer2.ByteArrayData, 8, returnButter, 7, returnButter.Length - 7); } else { returnButter = new byte[perBuffer2.ByteArrayData.Length]; Array.Copy(perBuffer2.ByteArrayData, returnButter, perBuffer2.ByteArrayData.Length); } returnButter[7] = 0x2A; #endregion return returnButter; }
/// <summary> /// Decode MCS Connect Initial PDU with GCC Conference Create Initial /// </summary> /// <param name="data">data to be parsed</param> /// <returns>Decoded MCS Connect Initial PDU with GCC Conference Create Initial</returns> public StackPacket DecodeMcsConnectInitialPDU(byte[] data) { // initialize int currentIndex = 0; Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request pdu = new Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request(); // McsConnectResponse: TpktHeader pdu.tpktHeader = ParseTpktHeader(data, ref currentIndex); // McsConnectResponse: X224 pdu.x224Data = ParseX224Data(data, ref currentIndex); // T125 Data: decode McsConnectResponse int t125DataLength = data.Length - currentIndex; if (t125DataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] t125Data = new byte[t125DataLength]; Array.Copy(data, currentIndex, t125Data, 0, t125Data.Length); Connect_Initial mcsConnectInitial = new Connect_Initial(); Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(t125Data); mcsConnectInitial.BerDecode(decodeBuffer); // McsConnectResponse:result pdu.mcsCi.targetParameters.maxChannelIds = (long)mcsConnectInitial.targetParameters.maxChannelIds.Value; pdu.mcsCi.targetParameters.maxHeight = (long)mcsConnectInitial.targetParameters.maxHeight.Value; pdu.mcsCi.targetParameters.maxMcsPduSize = (long)mcsConnectInitial.targetParameters.maxMCSPDUsize.Value; pdu.mcsCi.targetParameters.maxTokenIds = (long)mcsConnectInitial.targetParameters.maxTokenIds.Value; pdu.mcsCi.targetParameters.maxUserIds = (long)mcsConnectInitial.targetParameters.maxUserIds.Value; pdu.mcsCi.targetParameters.minThroughput = (long)mcsConnectInitial.targetParameters.minThroughput.Value; pdu.mcsCi.targetParameters.numPriorities = (long)mcsConnectInitial.targetParameters.numPriorities.Value; pdu.mcsCi.targetParameters.protocolVersion = (long)mcsConnectInitial.targetParameters.protocolVersion.Value; pdu.mcsCi.minimumParameters.maxChannelIds = (long)mcsConnectInitial.minimumParameters.maxChannelIds.Value; pdu.mcsCi.minimumParameters.maxHeight = (long)mcsConnectInitial.minimumParameters.maxHeight.Value; pdu.mcsCi.minimumParameters.maxMcsPduSize = (long)mcsConnectInitial.minimumParameters.maxMCSPDUsize.Value; pdu.mcsCi.minimumParameters.maxTokenIds = (long)mcsConnectInitial.minimumParameters.maxTokenIds.Value; pdu.mcsCi.minimumParameters.maxUserIds = (long)mcsConnectInitial.minimumParameters.maxUserIds.Value; pdu.mcsCi.minimumParameters.minThroughput = (long)mcsConnectInitial.minimumParameters.minThroughput.Value; pdu.mcsCi.minimumParameters.numPriorities = (long)mcsConnectInitial.minimumParameters.numPriorities.Value; pdu.mcsCi.minimumParameters.protocolVersion = (long)mcsConnectInitial.minimumParameters.protocolVersion.Value; pdu.mcsCi.maximumParameters.maxChannelIds = (long)mcsConnectInitial.maximumParameters.maxChannelIds.Value; pdu.mcsCi.maximumParameters.maxHeight = (long)mcsConnectInitial.maximumParameters.maxHeight.Value; pdu.mcsCi.maximumParameters.maxMcsPduSize = (long)mcsConnectInitial.maximumParameters.maxMCSPDUsize.Value; pdu.mcsCi.maximumParameters.maxTokenIds = (long)mcsConnectInitial.maximumParameters.maxTokenIds.Value; pdu.mcsCi.maximumParameters.maxUserIds = (long)mcsConnectInitial.maximumParameters.maxUserIds.Value; pdu.mcsCi.maximumParameters.minThroughput = (long)mcsConnectInitial.maximumParameters.minThroughput.Value; pdu.mcsCi.maximumParameters.numPriorities = (long)mcsConnectInitial.maximumParameters.numPriorities.Value; pdu.mcsCi.maximumParameters.protocolVersion = (long)mcsConnectInitial.maximumParameters.protocolVersion.Value; // T125 User Data: get McsConnectResponse's user data //byte[] userData = new byte[mcsConnectInitial.userData.Length]; //Stream mscInput = mcsConnectInitial.userData.toInputStream(); //mscInput.Read(userData, 0, userData.Length); byte[] userData = mcsConnectInitial.userData.ByteArrayValue; // T125 User Data: decode McsConnectResponse's user data Asn1DecodingBuffer connectDataBuffer = new Asn1DecodingBuffer(userData); ConnectData connectData = new ConnectData(); connectData.PerDecode(connectDataBuffer); // Gcc Data: get Gcc data int gccDataLength = userData.Length - ConstValue.GCC_CCI_DATA_OFFSET; if (gccDataLength <= 0) { throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE); } byte[] gccData = new byte[gccDataLength]; Array.Copy(userData, ConstValue.GCC_CCI_DATA_OFFSET, gccData, 0, gccData.Length); // Gcc Data: decode Gcc data ConnectGCCPDU gccPdu = new ConnectGCCPDU(); Asn1DecodingBuffer gccPduBuffer = new Asn1DecodingBuffer(gccData); gccPdu.PerDecode(gccPduBuffer); // McsConnectResponse: H221Key ConferenceCreateRequest conferenceRequest = (ConferenceCreateRequest)gccPdu.GetData(); H221NonStandardIdentifier identifier = (H221NonStandardIdentifier)conferenceRequest.userData.Elements[0].key.GetData(); pdu.mcsCi.gccPdu.h221Key = Encoding.ASCII.GetString(identifier.ByteArrayValue); // Gcc User Data: get Gcc user data byte[] gccUserData = conferenceRequest.userData.Elements[0].value.ByteArrayValue; // Reset current index currentIndex = 0; while (currentIndex < gccUserData.Length) { // Peek data type int tempIndex = currentIndex; int orgIndex = currentIndex; TS_UD_HEADER_type_Values type = (TS_UD_HEADER_type_Values)ParseUInt16(gccUserData, ref tempIndex, false); ushort userDataLength = ParseUInt16(gccUserData, ref tempIndex, false); // Parse data by type switch (type) { case TS_UD_HEADER_type_Values.CS_CORE: pdu.mcsCi.gccPdu.clientCoreData = ParseTsUdCsCore(gccUserData, ref currentIndex, userDataLength); break; case TS_UD_HEADER_type_Values.CS_NET: pdu.mcsCi.gccPdu.clientNetworkData = ParseTsUdCsNet(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_SECURITY: pdu.mcsCi.gccPdu.clientSecurityData = ParseTsUdCsSec(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_CLUSTER: pdu.mcsCi.gccPdu.clientClusterData = ParseTsUdCsCluster(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_MONITOR: pdu.mcsCi.gccPdu.clientMonitorData = ParseTsUdCsMon(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_MCS_MSGCHANNEL: pdu.mcsCi.gccPdu.clientMessageChannelData = ParseTsUdCsMcsMsgChannel(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_MULTITRANSPORT: pdu.mcsCi.gccPdu.clientMultitransportChannelData = ParseTsUdCsMultiTransport(gccUserData, ref currentIndex); break; case TS_UD_HEADER_type_Values.CS_MONITOR_EX: pdu.mcsCi.gccPdu.clientMonitorExtendedData = ParseTsUdCsMonitorEX(gccUserData, ref currentIndex); break; default: break; //throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED); } currentIndex = orgIndex + userDataLength; } // Check if data length exceeded expectation VerifyDataLength(gccUserData.Length, currentIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED); return pdu; }
/// <summary> /// Encode GCC Conference Create Request according to [T124]. /// </summary> /// <param name="gccPdu">The data to be encoded.</param> /// <returns>The encoded data.</returns> private static byte[] EncodeGccData(ConnectGCC gccPdu) { if (gccPdu == null) { return null; } #region Encode userData List<byte> userData = new List<byte>(); #region Encode clientCoreData structure TS_UD_CS_CORE if (gccPdu.clientCoreData != null) { List<byte> coreData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.header); RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.clientCoreData.version); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.desktopWidth); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.desktopHeight); RdpbcgrEncoder.EncodeStructure(coreData, (ushort)gccPdu.clientCoreData.colorDepth); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.SASSequence); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.keyboardLayout); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.clientBuild); RdpbcgrEncoder.EncodeUnicodeString(coreData, gccPdu.clientCoreData.clientName, ConstValue.CLIENT_CORE_DATA_CLIENT_NAME_SIZE); RdpbcgrEncoder.EncodeStructure(coreData, (uint)gccPdu.clientCoreData.keyboardType); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.keyboardSubType); RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.keyboardFunctionKey); RdpbcgrEncoder.EncodeUnicodeString(coreData, gccPdu.clientCoreData.imeFileName, ConstValue.CLIENT_CORE_DATA_IME_FILE_NAME_SIZE); if (gccPdu.clientCoreData.postBeta2ColorDepth == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.postBeta2ColorDepth.actualData); if (gccPdu.clientCoreData.clientProductId == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.clientProductId.actualData); if (gccPdu.clientCoreData.serialNumber == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.serialNumber.actualData); if (gccPdu.clientCoreData.highColorDepth == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.highColorDepth.actualData); if (gccPdu.clientCoreData.supportedColorDepths == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.supportedColorDepths.actualData); if (gccPdu.clientCoreData.earlyCapabilityFlags == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.earlyCapabilityFlags.actualData); if (gccPdu.clientCoreData.clientDigProductId == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeUnicodeString(coreData, gccPdu.clientCoreData.clientDigProductId, ConstValue.CLIENT_CORE_DATA_CLIENT_DIG_PRODUCT_ID_SIZE); if (gccPdu.clientCoreData.connnectionType == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.connnectionType.actualData); if (gccPdu.clientCoreData.pad1octets == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.pad1octets.actualData); if (gccPdu.clientCoreData.serverSelectedProtocol == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.serverSelectedProtocol.actualData); if (gccPdu.clientCoreData.desktopPhysicalWidth == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.desktopPhysicalWidth.actualData); if (gccPdu.clientCoreData.desktopPhysicalHeight == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.desktopPhysicalHeight.actualData); RdpbcgrEncoder.EncodeStructure(coreData, (ushort)gccPdu.clientCoreData.desktopOrientation); if (gccPdu.clientCoreData.desktopScaleFactor == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.desktopScaleFactor.actualData); if (gccPdu.clientCoreData.deviceScaleFactor == null) { goto labelCoreEnd; } RdpbcgrEncoder.EncodeStructure(coreData, gccPdu.clientCoreData.deviceScaleFactor.actualData); labelCoreEnd: userData.AddRange(coreData.ToArray()); } #endregion Encode clientCoreData structure TS_UD_CS_CORE #region Encode clientSecurityData TS_UD_CS_SEC if (gccPdu.clientSecurityData != null) { List<byte> securityData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.clientSecurityData.header); RdpbcgrEncoder.EncodeStructure(securityData, (uint)gccPdu.clientSecurityData.encryptionMethods); RdpbcgrEncoder.EncodeStructure(securityData, gccPdu.clientSecurityData.extEncryptionMethods); userData.AddRange(securityData.ToArray()); } #endregion Encode clientSecurityData TS_UD_CS_SEC #region Encode clientNetworkData TS_UD_CS_NET if (gccPdu.clientNetworkData != null) { List<byte> networkData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.clientNetworkData.header); RdpbcgrEncoder.EncodeStructure(networkData, gccPdu.clientNetworkData.channelCount); for (int i = 0; i < gccPdu.clientNetworkData.channelCount; ++i) { RdpbcgrEncoder.EncodeAnsiString(networkData, gccPdu.clientNetworkData.channelDefArray[i].name, ConstValue.CHANNEL_DEF_NAME_SIZE); RdpbcgrEncoder.EncodeStructure(networkData, (uint)gccPdu.clientNetworkData.channelDefArray[i].options); } userData.AddRange(networkData.ToArray()); } #endregion Encode clientNetworkData TS_UD_CS_NET #region Encode clientClusterData TS_UD_CS_CLUSTER if (gccPdu.clientClusterData != null) { List<byte> clusterData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(clusterData, gccPdu.clientClusterData.header); RdpbcgrEncoder.EncodeStructure(clusterData, (uint)gccPdu.clientClusterData.Flags); RdpbcgrEncoder.EncodeStructure(clusterData, gccPdu.clientClusterData.RedirectedSessionID); userData.AddRange(clusterData.ToArray()); } #endregion Encode clientClusterData TS_UD_CS_CLUSTER #region Encode clientMonitorData TS_UD_CS_MONITOR if (gccPdu.clientMonitorData != null) { List<byte> monitorData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(monitorData, gccPdu.clientMonitorData.header); RdpbcgrEncoder.EncodeStructure(monitorData, gccPdu.clientMonitorData.Flags); RdpbcgrEncoder.EncodeStructure(monitorData, gccPdu.clientMonitorData.monitorCount); for (int i = 0; i < gccPdu.clientMonitorData.monitorCount; ++i) { RdpbcgrEncoder.EncodeStructure(monitorData, gccPdu.clientMonitorData.monitorDefArray[i].left); RdpbcgrEncoder.EncodeStructure(monitorData, gccPdu.clientMonitorData.monitorDefArray[i].top); RdpbcgrEncoder.EncodeStructure(monitorData, gccPdu.clientMonitorData.monitorDefArray[i].right); RdpbcgrEncoder.EncodeStructure(monitorData, gccPdu.clientMonitorData.monitorDefArray[i].bottom); RdpbcgrEncoder.EncodeStructure(monitorData, (uint)gccPdu.clientMonitorData.monitorDefArray[i].flags); } userData.AddRange(monitorData.ToArray()); } #endregion Encode clientMonitorData TS_UD_CS_MONITOR #region Encode clientMessageChannelData TS_UD_CS_MCS_MSGCHANNEL if (gccPdu.clientMessageChannelData != null) { List<byte> messageChannelData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(messageChannelData, gccPdu.clientMessageChannelData.header); RdpbcgrEncoder.EncodeStructure(messageChannelData, (uint)gccPdu.clientMessageChannelData.flags); userData.AddRange(messageChannelData.ToArray()); } #endregion Encode clientMessageChannelData TS_UD_CS_MCS_MSGCHANNEL #region Encode clientMultitransportChannelData TS_UD_CS_MULTITRANSPORT if (gccPdu.clientMultitransportChannelData != null) { List<byte> multitransportChannelData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(multitransportChannelData, gccPdu.clientMultitransportChannelData.header); RdpbcgrEncoder.EncodeStructure(multitransportChannelData, (uint)gccPdu.clientMultitransportChannelData.flags); userData.AddRange(multitransportChannelData.ToArray()); } #endregion Encode clientMultitransportChannelData TS_UD_CS_MONITOR_EX #region Encode clientMonitorExtendedData TS_UD_CS_MULTITRANSPORT if (gccPdu.clientMonitorExtendedData != null) { List<byte> monitorExtendData = new List<byte>(); RdpbcgrEncoder.EncodeStructure(monitorExtendData, gccPdu.clientMonitorExtendedData.header); RdpbcgrEncoder.EncodeStructure(monitorExtendData, gccPdu.clientMonitorExtendedData.flags); RdpbcgrEncoder.EncodeStructure(monitorExtendData, gccPdu.clientMonitorExtendedData.monitorAttributeSize); RdpbcgrEncoder.EncodeStructure(monitorExtendData, gccPdu.clientMonitorExtendedData.monitorCount); foreach (var attribute in gccPdu.clientMonitorExtendedData.monitorAttributesArray) { RdpbcgrEncoder.EncodeStructure(monitorExtendData, attribute.physicalWidth); RdpbcgrEncoder.EncodeStructure(monitorExtendData, attribute.physicalHeight); RdpbcgrEncoder.EncodeStructure(monitorExtendData, (uint)attribute.orientation); RdpbcgrEncoder.EncodeStructure(monitorExtendData, attribute.desktopScaleFactor); RdpbcgrEncoder.EncodeStructure(monitorExtendData, attribute.deviceScaleFactor); } } #endregion Encode clientMonitorExtendedData TS_UD_CS_MONITOR_EX #endregion Encode userData #region Filling GCC Conference Create Request ConferenceCreateRequest gccCCrq = new ConferenceCreateRequest(); if (gccPdu.conferenceName != null) { gccCCrq.conferenceName = new ConferenceName(gccPdu.conferenceName); } if (gccPdu.convenerPassword != null) { gccCCrq.convenerPassword = new Password(gccPdu.convenerPassword); } if (gccPdu.password != null) { gccCCrq.password = new Password(gccPdu.password); } gccCCrq.lockedConference = new Asn1Boolean(gccPdu.lockedConference); gccCCrq.listedConference = new Asn1Boolean(gccPdu.listedConference); gccCCrq.conductibleConference = new Asn1Boolean(gccPdu.conductibleConference); gccCCrq.terminationMethod = new TerminationMethod(gccPdu.terminationMethod); if (gccPdu.conductorPrivileges != null) { List<Privilege> privilege = new List<Privilege>(); foreach (int i in gccPdu.conductorPrivileges) { privilege.Add(new Privilege(i)); } gccCCrq.conductorPrivileges = new Asn1SetOf<Privilege>(privilege.ToArray()); } if (gccPdu.conductedPrivileges != null) { List<Privilege> privilege = new List<Privilege>(); foreach (int i in gccPdu.conductedPrivileges) { privilege.Add(new Privilege(i)); } gccCCrq.conductedPrivileges = new Asn1SetOf<Privilege>(privilege.ToArray()); } if (gccPdu.nonConductedPrivileges != null) { List<Privilege> privilege = new List<Privilege>(); foreach (int i in gccPdu.nonConductedPrivileges) { privilege.Add(new Privilege(i)); } gccCCrq.nonConductedPrivileges = new Asn1SetOf<Privilege>(privilege.ToArray()); } if (gccPdu.conferenceDescription != null) { gccCCrq.conferenceDescription = new TextString(gccPdu.conferenceDescription); } if (gccPdu.callerIdentifier != null) { gccCCrq.callerIdentifier = new TextString(gccPdu.callerIdentifier); } //gccCCrq.extElem1 = new Asn1OpenExt(); UserDataElement[] dataElements = new UserDataElement[1]; dataElements[0] = new UserDataElement(); dataElements[0].key = new Key(Key.h221NonStandard, new H221NonStandardIdentifier(ConstValue.H221_NON_STANDARD_KEY)); dataElements[0].value = new Asn1OctetString(userData.ToArray()); gccCCrq.userData = new UserData(dataElements); ConnectGCCPDU cGccPdu = new ConnectGCCPDU(ConnectGCCPDU.conferenceCreateRequest, gccCCrq); #endregion Filling GCC Conference Create Request #region Encode ConnectData Asn1PerEncodingBuffer perBuffer = new Asn1PerEncodingBuffer(true); cGccPdu.PerEncode(perBuffer); byte[] asnEncodedData = perBuffer.ByteArrayData; Key key = new Key(Key.obj, new Asn1ObjectIdentifier(ConstValue.MCS_ATTRIBUTE_ID)); ConnectData connectData = new ConnectData(key, new Asn1OctetString(asnEncodedData)); Asn1PerEncodingBuffer perBuffer2 = new Asn1PerEncodingBuffer(true); connectData.PerEncode(perBuffer2); #endregion Encode ConnectData return perBuffer2.ByteArrayData; }