/// <summary> /// Clear all the members except the reconnection relative members. /// </summary> internal void ClearForReconnect() { lock (contextLock) { x224ConnectionRequestPdu = null; x224ConnectionConfirmPdu = null; x224NegotiateFailurePdu = null; mcsConnectInitialPdu = null; mcsConnectResponsePdu = null; userChannelId = 0; ioChannelId = 0; serverChannelId = 0; clientInfo = null; securityExchangePdu = null; licenseErrorPdu = null; demandActivePdu = null; comfirmActivePdu = null; logonInfoV1 = new TS_LOGON_INFO(); logonInfoV2 = new TS_LOGON_INFO_VERSION_2(); logonErrorsInfo = null; encryptionCount = 0; decryptionCount = 0; if (encryptionAlgorithm != null) { encryptionAlgorithm.Dispose(); encryptionAlgorithm = null; } if (ioDecompressor != null) { ioDecompressor.Dispose(); ioDecompressor = null; } if (ioCompressor != null) { ioCompressor.Dispose(); ioCompressor = null; } } }
/// <summary> /// Update some members of context with the specified pdu. /// </summary> /// <param name="pdu">The sending or receiving pdu.</param> public void UpdateContext(StackPacket pdu) { lock (contextLock) { if (!isSwitchOn) { // Don't update context but wait for upper layer TSD to do so. return; } if (pdu.GetType() == typeof(Client_X_224_Connection_Request_Pdu)) { x224ConnectionRequestPdu = (Client_X_224_Connection_Request_Pdu)pdu.Clone(); } else if (pdu.GetType() == typeof(Server_X_224_Connection_Confirm_Pdu)) { x224ConnectionConfirmPdu = ((Server_X_224_Connection_Confirm_Pdu)pdu.Clone()).rdpNegData; } else if (pdu.GetType() == typeof(Server_X_224_Negotiate_Failure_Pdu)) { x224NegotiateFailurePdu = ((Server_X_224_Negotiate_Failure_Pdu)pdu.Clone()).rdpNegFailure; } else if (pdu.GetType() == typeof(Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request)) { mcsConnectInitialPdu = ((Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request) pdu.Clone()).mcsCi; } else if (pdu is Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response) { mcsConnectResponsePdu = (Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response) pdu.Clone(); serverRandom = RdpbcgrUtility.CloneByteArray(mcsConnectResponsePdu.mcsCrsp.gccPdu.serverSecurityData.serverRandom); ioChannelId = mcsConnectResponsePdu.mcsCrsp.gccPdu.serverNetworkData.MCSChannelId; if(mcsConnectResponsePdu.mcsCrsp.gccPdu.serverMessageChannelData != null) mcsMsgChannelId = mcsConnectResponsePdu.mcsCrsp.gccPdu.serverMessageChannelData.MCSChannelID; encryptionAlgorithm = new EncryptionAlgorithm(RdpEncryptionMethod); } else if (pdu.GetType() == typeof(Server_MCS_Attach_User_Confirm_Pdu)) { if (((Server_MCS_Attach_User_Confirm_Pdu)pdu).attachUserConfirm.initiator != null) { userChannelId = (ushort)((Server_MCS_Attach_User_Confirm_Pdu)pdu).attachUserConfirm.initiator.Value; } } else if (pdu.GetType() == typeof(Client_Security_Exchange_Pdu)) { securityExchangePdu = (Client_Security_Exchange_Pdu)pdu.Clone(); clientRandom = RdpbcgrUtility.CloneByteArray( ((Client_Security_Exchange_Pdu)pdu).securityExchangePduData.clientRandom); GenerateSessionKey(); } else if (pdu.GetType() == typeof(Client_Info_Pdu)) { clientInfo = ((Client_Info_Pdu)pdu.Clone()).infoPacket; if (clientInfo != null && (clientInfo.flags & flags_Values.INFO_COMPRESSION) == flags_Values.INFO_COMPRESSION) { ioDecompressor = new Decompressor(SlidingWindowSize.EightKB); ioCompressor = new Compressor(SlidingWindowSize.EightKB); } isWaitingLicenseErrorPdu = true; } else if (pdu.GetType() == typeof(Server_Auto_Detect_Request_PDU)) { NETWORK_DETECTION_REQUEST requestData = ((Server_Auto_Detect_Request_PDU)pdu).autoDetectReqData.Clone(); if (requestData.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_IN_CONNECTTIME || requestData.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_AFTER_CONNECTTIME) { RDP_RTT_REQUEST rttRequest = (RDP_RTT_REQUEST)requestData; rttRequest.sendTime = DateTime.Now; this.serverAutoDetectRequestData.Add(rttRequest.sequenceNumber, rttRequest); } } else if (pdu.GetType() == typeof(Client_Auto_Detect_Response_PDU)) { clientAutoDetectResponsePdu = (Client_Auto_Detect_Response_PDU)pdu.Clone(); NETWORK_DETECTION_RESPONSE responseData = clientAutoDetectResponsePdu.autodetectRspPduData; if (responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_RTT_RESPONSE) { RDP_RTT_REQUEST rttRequest = (RDP_RTT_REQUEST)serverAutoDetectRequestData[responseData.sequenceNumber]; if (rttRequest != null) { TimeSpan interval = DateTime.Now - rttRequest.sendTime; this.autoDetectedRTTList.Add((uint)interval.TotalMilliseconds); serverAutoDetectRequestData.Remove(responseData.sequenceNumber); } } else if (responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_BW_RESULTS_AFTER_CONNECT || responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_BW_RESULTS_DURING_CONNECT) { RDP_BW_RESULTS bwResult = (RDP_BW_RESULTS)responseData; if(bwResult.timeDelta != 0) this.autoDetectedBandwidth = (uint)(bwResult.byteCount / bwResult.timeDelta); } else if (responseData.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_NETCHAR_SYNC) { RDP_NETCHAR_SYNC netSync = (RDP_NETCHAR_SYNC)responseData; this.autoDetectedRTTList.Add(netSync.rtt); this.autoDetectedBandwidth = netSync.bandwidth; } } else if (pdu.GetType() == typeof(Server_License_Error_Pdu_Valid_Client)) { licenseErrorPdu = (Server_License_Error_Pdu_Valid_Client)pdu.Clone(); serverChannelId = licenseErrorPdu.commonHeader.initiator; } else if (pdu.GetType() == typeof(Server_Initiate_Multitransport_Request_PDU)) { Server_Initiate_Multitransport_Request_PDU requestPDU = (Server_Initiate_Multitransport_Request_PDU)pdu; serverInitiateMultitransportRequestPduDictionary.Add(requestPDU.requestId, requestPDU); } else if (pdu.GetType() == typeof(Client_Initiate_Multitransport_Response_PDU)) { clientInitiateMultitransportResponsePdu = (Client_Initiate_Multitransport_Response_PDU)pdu; } else if (pdu.GetType() == typeof(Server_Demand_Active_Pdu)) { serverChannelId = ((Server_Demand_Active_Pdu)pdu.Clone()).commonHeader.initiator; demandActivePdu = ((Server_Demand_Active_Pdu)pdu.Clone()).demandActivePduData; } else if (pdu.GetType() == typeof(Client_Confirm_Active_Pdu)) { comfirmActivePdu = ((Client_Confirm_Active_Pdu)pdu.Clone()).confirmActivePduData; if (channelManager == null) { channelManager = new ServerStaticVirtualChannelManager(this); } } else if (pdu.GetType() == typeof(MCS_Disconnect_Provider_Ultimatum_Server_Pdu)) { lastDisconnectReason = (int)((MCS_Disconnect_Provider_Ultimatum_Server_Pdu) pdu).disconnectProvider.reason.Value; } else if (pdu.GetType() == typeof(MCS_Disconnect_Provider_Ultimatum_Pdu)) { lastDisconnectReason = (int)((MCS_Disconnect_Provider_Ultimatum_Pdu) pdu).disconnectProvider.reason.Value; } else if (pdu.GetType() == typeof(Server_Set_Error_Info_Pdu)) { lastErrorInfo = ((Server_Set_Error_Info_Pdu)pdu).errorInfoPduData.errorInfo; } else if (pdu.GetType() == typeof(Server_Status_Info_Pdu)) { lastStatusInfo = ((Server_Status_Info_Pdu)pdu).statusCode; } else if (pdu.GetType() == typeof(Server_Save_Session_Info_Pdu)) { Server_Save_Session_Info_Pdu saveSessionInfoPdu = (Server_Save_Session_Info_Pdu)pdu.Clone(); switch (saveSessionInfoPdu.saveSessionInfoPduData.infoType) { case infoType_Values.INFOTYPE_LOGON: logonInfoV1 = (TS_LOGON_INFO)saveSessionInfoPdu.saveSessionInfoPduData.infoData; break; case infoType_Values.INFOTYPE_LOGON_LONG: logonInfoV2 = (TS_LOGON_INFO_VERSION_2)saveSessionInfoPdu.saveSessionInfoPduData.infoData; break; case infoType_Values.INFOTYPE_LOGON_EXTENDED_INF: TS_LOGON_INFO_EXTENDED infoExtended = (TS_LOGON_INFO_EXTENDED)saveSessionInfoPdu.saveSessionInfoPduData.infoData; switch (infoExtended.FieldsPresent) { case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE | FieldsPresent_Values.LOGON_EX_LOGONERRORS: autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData; logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[1].FieldData; break; case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE: autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData; break; case FieldsPresent_Values.LOGON_EX_LOGONERRORS: logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[0].FieldData; break; default: break; } break; default: break; } } } }
/// <summary> /// Update some members of context with the specified pdu. /// </summary> /// <param name="pdu">The sending or receiving pdu.</param> public void UpdateContext(StackPacket pdu) { lock (contextLock) { if (!isSwitchOn) { // Don't update context but wait for upper layer TSD to do so. return; } if (pdu.GetType() == typeof(Client_X_224_Connection_Request_Pdu)) { x224ConnectionRequestPdu = (Client_X_224_Connection_Request_Pdu)pdu.Clone(); } else if (pdu.GetType() == typeof(Server_X_224_Connection_Confirm_Pdu)) { x224ConnectionConfirmPdu = ((Server_X_224_Connection_Confirm_Pdu)pdu.Clone()).rdpNegData; } else if (pdu.GetType() == typeof(Server_X_224_Negotiate_Failure_Pdu)) { x224NegotiateFailurePdu = ((Server_X_224_Negotiate_Failure_Pdu)pdu.Clone()).rdpNegFailure; } else if (pdu.GetType() == typeof(Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request)) { mcsConnectInitialPdu = ((Client_MCS_Connect_Initial_Pdu_with_GCC_Conference_Create_Request) pdu.Clone()).mcsCi; } else if (pdu.GetType() == typeof(Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response)) { mcsConnectResponsePdu = (Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response) pdu.Clone(); encryptionAlgorithm = new EncryptionAlgorithm(RdpEncryptionMethod); } else if (pdu.GetType() == typeof(Server_MCS_Attach_User_Confirm_Pdu)) { userChannelId = (long)((Server_MCS_Attach_User_Confirm_Pdu)pdu).attachUserConfirm.initiator.Value; } else if (pdu.GetType() == typeof(Client_Security_Exchange_Pdu)) { clientRandom = RdpbcgrUtility.CloneByteArray( ((Client_Security_Exchange_Pdu)pdu).securityExchangePduData.clientRandom); } else if (pdu.GetType() == typeof(Client_Info_Pdu)) { clientInfo = ((Client_Info_Pdu)pdu.Clone()).infoPacket; if (clientInfo != null && (clientInfo.flags & flags_Values.INFO_COMPRESSION) == flags_Values.INFO_COMPRESSION) { ioDecompressor = new Decompressor((SlidingWindowSize)CompressionTypeSupported); } } else if (pdu.GetType() == typeof(Server_License_Error_Pdu_Valid_Client)) { licenseErrorPdu = (Server_License_Error_Pdu_Valid_Client)pdu.Clone(); } else if (pdu.GetType() == typeof(Server_Initiate_Multitransport_Request_PDU)) { Server_Initiate_Multitransport_Request_PDU initRequset = pdu as Server_Initiate_Multitransport_Request_PDU; if (initRequset.requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR) { requestIdReliable = initRequset.requestId; cookieReliable = initRequset.securityCookie; } else { requestIdLossy = initRequset.requestId; cookieLossy = initRequset.securityCookie; } } else if (pdu.GetType() == typeof(Server_Demand_Active_Pdu)) { demandActivePdu = ((Server_Demand_Active_Pdu)pdu.Clone()).demandActivePduData; } else if (pdu.GetType() == typeof(Client_Confirm_Active_Pdu)) { comfirmActivePdu = ((Client_Confirm_Active_Pdu)pdu.Clone()).confirmActivePduData; if (channelManager == null) { channelManager = new ClientStaticVirtualChannelManager(this); } } else if (pdu.GetType() == typeof(MCS_Disconnect_Provider_Ultimatum_Pdu)) { lastDisconnectReason = (int)((MCS_Disconnect_Provider_Ultimatum_Pdu) pdu).disconnectProvider.reason.Value; } else if (pdu.GetType() == typeof(Server_Set_Error_Info_Pdu)) { lastErrorInfo = ((Server_Set_Error_Info_Pdu)pdu).errorInfoPduData.errorInfo; } else if (pdu.GetType() == typeof(Server_Status_Info_Pdu)) { lastStatusInfo = ((Server_Status_Info_Pdu)pdu).statusCode; } else if (pdu.GetType() == typeof(Server_Save_Session_Info_Pdu)) { Server_Save_Session_Info_Pdu saveSessionInfoPdu = (Server_Save_Session_Info_Pdu)pdu.Clone(); switch (saveSessionInfoPdu.saveSessionInfoPduData.infoType) { case infoType_Values.INFOTYPE_LOGON: logonInfoV1 = (TS_LOGON_INFO)saveSessionInfoPdu.saveSessionInfoPduData.infoData; break; case infoType_Values.INFOTYPE_LOGON_LONG: logonInfoV2 = (TS_LOGON_INFO_VERSION_2)saveSessionInfoPdu.saveSessionInfoPduData.infoData; break; case infoType_Values.INFOTYPE_LOGON_EXTENDED_INF: TS_LOGON_INFO_EXTENDED infoExtended = (TS_LOGON_INFO_EXTENDED)saveSessionInfoPdu.saveSessionInfoPduData.infoData; switch (infoExtended.FieldsPresent) { case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE | FieldsPresent_Values.LOGON_EX_LOGONERRORS: autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData; logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[1].FieldData; break; case FieldsPresent_Values.LOGON_EX_AUTORECONNECTCOOKIE: autoReconnectCookie = (ARC_SC_PRIVATE_PACKET)infoExtended.LogonFields[0].FieldData; break; case FieldsPresent_Values.LOGON_EX_LOGONERRORS: logonErrorsInfo = (TS_LOGON_ERRORS_INFO)infoExtended.LogonFields[0].FieldData; break; default: break; } break; default: break; } } } }
/// <summary> /// 2.2.1.11.1 /// </summary> /// <param name="info"></param> public void VerifyStructure(TS_INFO_PACKET info) { //Unicode = 2 * Ansi site.CaptureRequirementIfAreEqual<int>(info.Domain.Length*2, (int)info.cbDomain, 464, @"In the TS_INFO_PACKET structure, cbDomain represents the size in bytes of the character data in the Domain field." + @" This size excludes the length of the mandatory null terminator."); site.CaptureRequirementIfAreEqual<int>(info.UserName.Length*2, (int)info.cbUserName, 466, @"In the TS_INFO_PACKET structure, cbUserName represents the size in bytes of the character data in the UserName " + @"field. This size excludes the length of the mandatory null terminator."); site.CaptureRequirementIfAreEqual<int>(info.Password.Length*2, (int)info.cbPassword, 468, @"In the TS_INFO_PACKET structure, cbPassword represents the size in bytes of the character data in the Password " + @"field. This size excludes the length of the mandatory null terminator."); site.CaptureRequirementIfAreEqual<int>(info.AlternateShell.Length*2, (int)info.cbAlternateShell, 470, @"In the TS_INFO_PACKET structure, cbAlternateShell represents the size in bytes of the character data in the " + @"AlternateShell field. This size excludes the length of the mandatory null terminator."); site.CaptureRequirementIfAreEqual<int>(info.WorkingDir.Length*2, (int)info.cbWorkingDir, 472, @"In the TS_INFO_PACKET structure, cbWorkingDir represents the size in bytes of the character data in the WorkingDir" + @" field. This size excludes the length of the mandatory null terminator."); //<bug> Domain not contains /0 //site.CaptureRequirementIfIsTrue(info.Domain.Contains("\0"), 476, // @"In the TS_INFO_PACKET structure, Domain field MUST contain at least a null terminator character in ANSI or Unicode" // + @" format (depending on the presence of the INFO_UNICODE flag)"); //site.CaptureRequirementIfIsTrue(info.UserName.Contains("\0"), 480, // @"In the TS_INFO_PACKET structure, UserName field MUST contain at least a null terminator character in ANSI or Unicode" // + @" format (depending on the presence of the INFO_UNICODE flag)"); //site.CaptureRequirementIfIsTrue(info.Password.Contains("\0"), 483, // @"In the TS_INFO_PACKET structure, Password field MUST contain at least a null terminator character in ANSI or Unicode" // + @" format (depending on the presence of the INFO_UNICODE flag)"); site.CaptureRequirementIfIsTrue(info.AlternateShell.Length <= 512, 485, @"In the TS_INFO_PACKET structure, for AlternateShell, the maximum allowed length is 512 bytes (including the mandatory" + @" null terminator)."); //site.CaptureRequirementIfIsTrue(info.AlternateShell.Contains("\0"), 487, // @"In the TS_INFO_PACKET structure, AlternateShell field MUST contain at least a null terminator character in ANSI or " // + @"Unicode format (depending on the presence of the INFO_UNICODE flag)"); //site.CaptureRequirementIfIsTrue(info.WorkingDir.Contains("\0"), 491, // @"In the TS_INFO_PACKET structure, WorkingDir field MUST contain at least a null terminator character in ANSI or " // + @"Unicode format (depending on the presence of the INFO_UNICODE flag)"); if (info.extraInfo != null) { //bugbug: //AF_INET 0x00002 //AF_INET6 0x0017 //<hardcode> if (!this.Site.Properties["RDP.Version"].Equals("8.1")) { site.CaptureRequirementIfIsTrue(info.extraInfo.clientAddressFamily == clientAddressFamily_Values.V1 || (int)info.extraInfo.clientAddressFamily == 0x17, 495, @"[In Extended Info Packet (TS_EXTENDED_INFO_PACKET)]clientAddressFamily (2 bytes):clientAddressFamily can have the " + @"following values: 1.AF_INET 0x00002 2.AF_INET6 0x0017"); } Console.WriteLine("RS503, clientDir.Length = " + info.extraInfo.clientDir.Length); Console.WriteLine("RS503, cbClientDir=" + info.extraInfo.cbClientDir); bool isR505Satisfied = info.extraInfo.cbClientDir <= 512; site.CaptureRequirementIfIsTrue(isR505Satisfied, 505, @"[In Extended Info Packet (TS_EXTENDED_INFO_PACKET)] clientDir (variable):The maximum allowed length is 512 bytes " + @"(including the mandatory null terminator)."); bool isR528Satisfied = info.extraInfo.cbAutoReconnectLen <= 128; site.CaptureRequirementIfIsTrue(isR528Satisfied, 528, @"[Extended Info Packet (TS_EXTENDED_INFO_PACKET)]autoReconnectCookie (28 bytes):the maximum allowed length " + @"is 128 bytes."); } }
/// <summary> /// Parse TS_INFO_PACKET /// (parser index is updated according to parsed length) /// </summary> /// <param name="data">data to be parsed</param> /// <param name="currentIndex">current parser index</param> /// <returns>TS_INFO_PACKET</returns> private TS_INFO_PACKET ParseClientInfo(byte[] data, ref int currentIndex) { TS_INFO_PACKET infoData = new TS_INFO_PACKET(); infoData.CodePage = ParseUInt32(data, ref currentIndex, false); infoData.flags = (flags_Values)ParseUInt32(data, ref currentIndex, false); infoData.cbDomain = ParseUInt16(data, ref currentIndex, false); infoData.cbUserName = ParseUInt16(data, ref currentIndex, false); infoData.cbPassword = ParseUInt16(data, ref currentIndex, false); infoData.cbAlternateShell = ParseUInt16(data, ref currentIndex, false); infoData.cbWorkingDir = ParseUInt16(data, ref currentIndex, false); Encoding converter = new UnicodeEncoding(); if ((infoData.flags & flags_Values.INFO_UNICODE) == flags_Values.INFO_UNICODE) { converter = new UnicodeEncoding(); byte[] domain = GetBytes(data, ref currentIndex, (int)infoData.cbDomain); infoData.Domain = converter.GetString(domain); currentIndex += 2; byte[] userName = GetBytes(data, ref currentIndex, (int)infoData.cbUserName); infoData.UserName = converter.GetString(userName); currentIndex += 2; byte[] password = GetBytes(data, ref currentIndex, (int)infoData.cbPassword); infoData.Password = converter.GetString(password); currentIndex += 2; byte[] alternateShell = GetBytes(data, ref currentIndex, (int)infoData.cbAlternateShell); infoData.AlternateShell = converter.GetString(alternateShell); currentIndex += 2; byte[] workingDir = GetBytes(data, ref currentIndex, (int)infoData.cbWorkingDir); infoData.WorkingDir = converter.GetString(workingDir); currentIndex += 2; } else { converter = new ASCIIEncoding(); byte[] domain = GetBytes(data, ref currentIndex, (int)infoData.cbDomain); infoData.Domain = converter.GetString(domain); currentIndex += 1; byte[] userName = GetBytes(data, ref currentIndex, (int)infoData.cbUserName); infoData.UserName = converter.GetString(userName); currentIndex += 1; byte[] password = GetBytes(data, ref currentIndex, (int)infoData.cbPassword); infoData.Password = converter.GetString(password); currentIndex += 1; byte[] alternateShell = GetBytes(data, ref currentIndex, (int)infoData.cbAlternateShell); infoData.AlternateShell = converter.GetString(alternateShell); currentIndex += 1; byte[] workingDir = GetBytes(data, ref currentIndex, (int)infoData.cbWorkingDir); infoData.WorkingDir = converter.GetString(workingDir); currentIndex += 1; } if (currentIndex < data.Length) { infoData.extraInfo = ParseExtendedInfo(data, ref currentIndex, converter); } return infoData; }
/// <summary> /// Encode infoPacket field. /// </summary> /// <param name="infoPacket">The data to be encoded.</param> /// <returns>The encoded data.</returns> private static byte[] EncodeInfoData(TS_INFO_PACKET infoPacket) { List<byte> infoBuffer = new List<byte>(); if (infoPacket != null) { RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.CodePage); RdpbcgrEncoder.EncodeStructure(infoBuffer, (uint)infoPacket.flags); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.cbDomain); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.cbUserName); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.cbPassword); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.cbAlternateShell); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.cbWorkingDir); if ((infoPacket.flags & flags_Values.INFO_UNICODE) == flags_Values.INFO_UNICODE) { // +2 means add a null-terminator for a unicode string RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.Domain, (uint)(infoPacket.cbDomain + 2)); RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.UserName, (uint)(infoPacket.cbUserName + 2)); RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.Password, (uint)(infoPacket.cbPassword + 2)); RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.AlternateShell, (uint)(infoPacket.cbAlternateShell + 2)); RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.WorkingDir, (uint)(infoPacket.cbWorkingDir + 2)); } else { // +1 means add a null-terminator for an ansi string RdpbcgrEncoder.EncodeAnsiString(infoBuffer, infoPacket.Domain, (uint)(infoPacket.cbDomain + 1)); RdpbcgrEncoder.EncodeAnsiString(infoBuffer, infoPacket.UserName, (uint)(infoPacket.cbUserName + 1)); RdpbcgrEncoder.EncodeAnsiString(infoBuffer, infoPacket.Password, (uint)(infoPacket.cbPassword + 1)); RdpbcgrEncoder.EncodeAnsiString(infoBuffer, infoPacket.AlternateShell, (uint)(infoPacket.cbAlternateShell + 1)); RdpbcgrEncoder.EncodeAnsiString(infoBuffer, infoPacket.WorkingDir, (uint)(infoPacket.cbWorkingDir + 1)); } if (infoPacket.extraInfo != null) { RdpbcgrEncoder.EncodeStructure(infoBuffer, (ushort)infoPacket.extraInfo.clientAddressFamily); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.cbClientAddress); if ((infoPacket.flags & flags_Values.INFO_UNICODE) == flags_Values.INFO_UNICODE) { RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.extraInfo.clientAddress, infoPacket.extraInfo.cbClientAddress); } else { RdpbcgrEncoder.EncodeAnsiString(infoBuffer, infoPacket.extraInfo.clientAddress, infoPacket.extraInfo.cbClientAddress); } RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.cbClientDir); if ((infoPacket.flags & flags_Values.INFO_UNICODE) == flags_Values.INFO_UNICODE) { RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.extraInfo.clientDir, infoPacket.extraInfo.cbClientDir); } else { RdpbcgrEncoder.EncodeAnsiString(infoBuffer, infoPacket.extraInfo.clientDir, infoPacket.extraInfo.cbClientDir); } RdpbcgrEncoder.EncodeStructure(infoBuffer, (ushort)infoPacket.extraInfo.clientTimeZone.Bias); RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.extraInfo.clientTimeZone.StandardName, ConstValue.TIME_ZONE_STANDARD_NAME_SIZE); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.clientTimeZone.StandardDate); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.clientTimeZone.StandardBias); RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.extraInfo.clientTimeZone.DaylightName, ConstValue.TIME_ZONE_DAYLIGHT_NAME_SIZE); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.clientTimeZone.DaylightDate); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.clientTimeZone.DaylightBias); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.clientSessionId); RdpbcgrEncoder.EncodeStructure(infoBuffer, (uint)infoPacket.extraInfo.performanceFlags); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.cbAutoReconnectLen); if (infoPacket.extraInfo.cbAutoReconnectLen != 0) { RdpbcgrEncoder.EncodeStructure(infoBuffer, (uint)infoPacket.extraInfo.autoReconnectCookie.cbLen); RdpbcgrEncoder.EncodeStructure(infoBuffer, (uint)infoPacket.extraInfo.autoReconnectCookie.Version); RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.autoReconnectCookie.LogonId); RdpbcgrEncoder.EncodeBytes(infoBuffer, infoPacket.extraInfo.autoReconnectCookie.SecurityVerifier); ; } if (infoPacket.extraInfo.reserved1 != null) { RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.reserved1.actualData); } if (infoPacket.extraInfo.reserved2 != null) { RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.reserved2.actualData); } if (infoPacket.extraInfo.cbDynamicDSTTimeZoneKeyName != null) { RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.cbDynamicDSTTimeZoneKeyName.actualData); } if (infoPacket.extraInfo.dynamicDSTTimeZoneKeyName != null) { RdpbcgrEncoder.EncodeUnicodeString(infoBuffer, infoPacket.extraInfo.dynamicDSTTimeZoneKeyName, infoPacket.extraInfo.cbDynamicDSTTimeZoneKeyName.actualData); } if (infoPacket.extraInfo.dynamicDaylightTimeDisabled != null) { RdpbcgrEncoder.EncodeStructure(infoBuffer, infoPacket.extraInfo.dynamicDaylightTimeDisabled.actualData); } } } return infoBuffer.ToArray(); }