public override void Start() { try { // Prepare to start. PrepareStart(); // Register to the workspace. RegisterToKws(); // Make sure the workspace is logged in. if (Kws.Cd.KcdState.LoginStatus != KwsLoginStatus.LoggedIn) { throw new EAnpExInterrupted(); } // Post the command. AnpMsg cmd = Kws.NewKcdCmd(0); PrepareCmd(cmd); m_kcdQuery = Kws.PostKcdCmd(cmd, OnKcdQueryResult); } catch (Exception ex) { HandleFailure(ex); } }
/// <summary> /// Called when the login reply is received. /// </summary> private void HandleConnectKwsReply(KcdQuery query) { KLogging.Log("Got login reply, kws " + m_kws.InternalID + ", status " + m_kws.Cd.MainStatus); Debug.Assert(m_ks.LoginStatus == KwsLoginStatus.LoggingIn); // This is the standard login reply. if (query.Res.Type == KAnp.KANP_RES_KWS_CONNECT_KWS) { // Get the provided information. KwsConnectRes r = new KwsConnectRes(query.Res); KLogging.Log(m_currentStep + " login step: " + r.ErrMsg); // Dispatch. if (r.Code == KAnp.KANP_KWS_LOGIN_OK) { HandleConnectKwsSuccess(r); } else if (r.Code == KAnp.KANP_KWS_LOGIN_BAD_PWD_OR_TICKET) { HandleBadPwdOrTicket(r); } else { HandleLoginFailure(TranslateKcdLoginStatusCode(r.Code), new Exception(r.ErrMsg)); } } // This is an unexpected reply. else { HandleLoginFailure(KwsLoginResult.MiscKcdError, EAnpException.FromKAnpReply(query.Res)); } }
/// <summary> /// Called when the disconnect reply is received. /// </summary> private void HandleDisconnectKwsReply(KcdQuery ctx) { // We're now logged out. Ignore failures from the server, // this can happen legitimately if we send a logout command // before we get the result of the login command. m_kws.Sm.HandleNormalLogout(); }
/// <summary> /// Post a KCD command. /// </summary> public KcdQuery PostKcdCmd(AnpMsg cmd, KcdQueryDelegate callback) { KcdQuery query = new KcdQuery(cmd, callback, Kcd, this); Wm.PostKcdQuery(query); return(query); }
/// <summary> /// This method is called when the ticket query has completed. /// </summary> private void OnTicketReply(KcdQuery query) { if (Status != VncSessionStatus.Ticket) { return; } TicketQuery = null; try { AnpMsg m = query.Res; if (m.Type == KAnp.KANP_RES_VNC_START_TICKET || m.Type == KAnp.KANP_RES_VNC_CONNECT_TICKET) { Ticket = m.Elements[0].Bin; HandleNextSessionStep(); } else { throw EAnpException.FromKAnpReply(m); } } catch (Exception ex) { HandleSessionTrouble(ex); } }
/// <summary> /// Cancel the KCD query specified and set its reference to null, /// if needed. /// </summary> protected void ClearKcdQuery(ref KcdQuery query) { if (query != null) { query.Terminate(); query = null; } }
/// <summary> /// Clean up the state when the session has completed to avoid resource /// leaks. This object CANNOT be reused for another session since some /// recently cancelled threads may still reference the object and try /// to modify its state. /// </summary> private void Terminate() { Status = VncSessionStatus.Completed; AppVnc.SessionPresentFlag = false; App.LocalSession = null; if (Overlay != null) { Overlay.Terminate(); Overlay = null; } if (TicketQuery != null) { TicketQuery.Terminate(); TicketQuery = null; } if (Tunnel != null) { Tunnel.Terminate(); Tunnel = null; } if (TunnelThread != null) { TunnelThread.RequestCancellation(); TunnelThread = null; } if (MainProcess != null) { MainProcess.Terminate(); MainProcess = null; } if (DummyProcess != null) { DummyProcess.Terminate(); DummyProcess = null; } if (Timer != null) { Timer.WakeMeUp(-1); Timer = null; } if (InactivityMonitor != null) { InactivityMonitor.Enabled = false; InactivityMonitor.Dispose(); InactivityMonitor = null; } }
/// <summary> /// Request a ticket to the server. /// </summary> private void RequestTicket() { Status = VncSessionStatus.Ticket; UInt32 t = ServerSessionFlag ? KAnp.KANP_CMD_VNC_START_TICKET : KAnp.KANP_CMD_VNC_CONNECT_TICKET; AnpMsg m = Kws.NewKcdCmd(t); if (!ServerSessionFlag) { m.AddUInt64(SessionID); } TicketQuery = Kws.PostKcdCmd(m, OnTicketReply); }
/// <summary> /// Handle an ANP reply received from the KCD. /// </summary> public void HandleKcdReply(KcdQuery query) { try { // Call the callback. query.Callback(query); } catch (Exception ex) { // The event handler throws if the KCD sends us garbage. BlameKcd(ex); } }
/// <summary> /// Called when the create workspace command reply is received. /// </summary> private void HandleCreateKwsCmdResult(KcdQuery query) { if (m_kcdQuery != query) { return; } m_kcdQuery = null; Debug.Assert(m_step == OpStep.CreateReply); try { AnpMsg res = query.Res; // Failure. if (res.Type != KAnp.KANP_RES_MGT_KWS_CREATED) { throw EAnpException.FromKAnpReply(res); } // Parse the reply. UInt64 externalID = res.Elements[0].UInt64; String emailID = res.Elements[1].String; // Validate that the KCD is not screwing with us. This can // happen if the KCD state has been reverted. if (Wm.GetKwsByExternalID(Kws.Kcd.KcdID, externalID) != null) { throw new Exception("duplicate " + KwmStrings.Kws + " external ID"); } // Update the workspace credentials. Creds.ExternalID = externalID; Creds.EmailID = emailID; // Wait for login. m_step = OpStep.LoggingIn; Kws.Sm.SetLoginType(KwsLoginType.Cached); Kws.Sm.SetSpawnStep(KwsSpawnTaskStep.Login); } catch (Exception ex) { HandleFailure(ex); } }
/// <summary> /// Called when the create workspace command reply is received. /// </summary> private void OnKcdQueryResult(KcdQuery query) { if (m_kcdQuery != query) { return; } m_kcdQuery = null; try { HandleCmdResult(query.Res); Complete(); } catch (Exception ex) { HandleFailure(ex); } }
/// <summary> /// Send the workspace creation command if we are ready to. /// </summary> private void SendCreateKwsCmdIfNeeded() { if (DoneFlag || m_step != OpStep.Connecting || Kws.Kcd.ConnStatus != KcdConnStatus.Connected) { return; } m_step = OpStep.CreateReply; AnpMsg cmd = Wm.NewKcdCmd(Kws.Kcd.MinorVersion, KAnp.KANP_CMD_MGT_CREATE_KWS); cmd.AddString(Creds.KwsName); cmd.AddBin(Creds.Ticket); cmd.AddUInt32(Convert.ToUInt32(Creds.PublicFlag)); cmd.AddUInt32(Convert.ToUInt32(Creds.SecureFlag)); if (cmd.Minor >= 4) { cmd.AddUInt32(Convert.ToUInt32(Creds.ThinKfsFlag)); } m_kcdQuery = Kws.PostKcdCmd(cmd, HandleCreateKwsCmdResult); }
/// <summary> /// Process an ANP reply received from the KCD. /// </summary> private static void ProcessKcdAnpReply(WmKcd kcd, AnpMsg msg) { // We have no knowledge of the query. Ignore the reply. if (!kcd.QueryMap.ContainsKey(msg.ID)) { return; } // Retrieve and remove the query from the query map. KcdQuery query = kcd.QueryMap[msg.ID]; // Set the reply in the query. query.Res = msg; // We don't have non-workspace-related replies yet. Debug.Assert(query.Kws != null); // Dispatch the message to the workspace. query.Kws.Sm.HandleKcdReply(query); query.Terminate(); }
/// <summary> /// Called when the create workspace command reply is received. /// </summary> private void OnKcdQueryResult(KcdQuery query) { if (m_kcdQuery != query) return; m_kcdQuery = null; try { HandleCmdResult(query.Res); Complete(); } catch (Exception ex) { HandleFailure(ex); } }
/// <summary> /// Send the workspace creation command if we are ready to. /// </summary> private void SendCreateKwsCmdIfNeeded() { if (DoneFlag || m_step != OpStep.Connecting || Kws.Kcd.ConnStatus != KcdConnStatus.Connected) return; m_step = OpStep.CreateReply; AnpMsg cmd = Wm.NewKcdCmd(Kws.Kcd.MinorVersion, KAnp.KANP_CMD_MGT_CREATE_KWS); cmd.AddString(Creds.KwsName); cmd.AddBin(Creds.Ticket); cmd.AddUInt32(Convert.ToUInt32(Creds.PublicFlag)); cmd.AddUInt32(Convert.ToUInt32(Creds.SecureFlag)); if (cmd.Minor >= 4) cmd.AddUInt32(Convert.ToUInt32(Creds.ThinKfsFlag)); m_kcdQuery = Kws.PostKcdCmd(cmd, HandleCreateKwsCmdResult); }
public override void Start() { try { // Prepare to start. PrepareStart(); // Register to the workspace. RegisterToKws(); // Make sure the workspace is logged in. if (Kws.Cd.KcdState.LoginStatus != KwsLoginStatus.LoggedIn) throw new EAnpExInterrupted(); // Post the command. AnpMsg cmd = Kws.NewKcdCmd(0); PrepareCmd(cmd); m_kcdQuery = Kws.PostKcdCmd(cmd, OnKcdQueryResult); } catch (Exception ex) { HandleFailure(ex); } }
/// <summary> /// Request a ticket to the server. /// </summary> private void RequestTicket() { Status = VncSessionStatus.Ticket; UInt32 t = ServerSessionFlag ? KAnp.KANP_CMD_VNC_START_TICKET : KAnp.KANP_CMD_VNC_CONNECT_TICKET; AnpMsg m = Kws.NewKcdCmd(t); if (!ServerSessionFlag) m.AddUInt64(SessionID); TicketQuery = Kws.PostKcdCmd(m, OnTicketReply); }
/// <summary> /// Called when the create workspace command reply is received. /// </summary> private void HandleCreateKwsCmdResult(KcdQuery query) { if (m_kcdQuery != query) return; m_kcdQuery = null; Debug.Assert(m_step == OpStep.CreateReply); try { AnpMsg res = query.Res; // Failure. if (res.Type != KAnp.KANP_RES_MGT_KWS_CREATED) throw EAnpException.FromKAnpReply(res); // Parse the reply. UInt64 externalID = res.Elements[0].UInt64; String emailID = res.Elements[1].String; // Validate that the KCD is not screwing with us. This can // happen if the KCD state has been reverted. if (Wm.GetKwsByExternalID(Kws.Kcd.KcdID, externalID) != null) throw new Exception("duplicate " + KwmStrings.Kws + " external ID"); // Update the workspace credentials. Creds.ExternalID = externalID; Creds.EmailID = emailID; // Wait for login. m_step = OpStep.LoggingIn; Kws.Sm.SetLoginType(KwsLoginType.Cached); Kws.Sm.SetSpawnStep(KwsSpawnTaskStep.Login); } catch (Exception ex) { HandleFailure(ex); } }
/// <summary> /// Post the KCD query specified. /// </summary> public static void PostKcdQuery(KcdQuery query) { Debug.Assert(!query.Kcd.QueryMap.ContainsKey(query.MsgID)); query.Kcd.QueryMap[query.MsgID] = query; KcdBroker.SendAnpMsgToKcd(new KcdAnpMsg(query.Cmd, query.Kcd.KcdID)); }
/// <summary> /// Post a KCD command. /// </summary> public KcdQuery PostKcdCmd(AnpMsg cmd, KcdQueryDelegate callback) { KcdQuery query = new KcdQuery(cmd, callback, Kcd, this); Wm.PostKcdQuery(query); return query; }
/// <summary> /// Called when the login reply is received. /// </summary> private void HandleConnectKwsReply(KcdQuery query) { KLogging.Log("Got login reply, kws " + m_kws.InternalID + ", status " + m_kws.Cd.MainStatus); Debug.Assert(m_ks.LoginStatus == KwsLoginStatus.LoggingIn); // This is the standard login reply. if (query.Res.Type == KAnp.KANP_RES_KWS_CONNECT_KWS) { // Get the provided information. KwsConnectRes r = new KwsConnectRes(query.Res); KLogging.Log(m_currentStep + " login step: " + r.ErrMsg); // Dispatch. if (r.Code == KAnp.KANP_KWS_LOGIN_OK) HandleConnectKwsSuccess(r); else if (r.Code == KAnp.KANP_KWS_LOGIN_BAD_PWD_OR_TICKET) HandleBadPwdOrTicket(r); else HandleLoginFailure(TranslateKcdLoginStatusCode(r.Code), new Exception(r.ErrMsg)); } // This is an unexpected reply. else { HandleLoginFailure(KwsLoginResult.MiscKcdError, EAnpException.FromKAnpReply(query.Res)); } }
/// <summary> /// This method is called when the ticket query has completed. /// </summary> private void OnTicketReply(KcdQuery query) { if (Status != VncSessionStatus.Ticket) return; TicketQuery = null; try { AnpMsg m = query.Res; if (m.Type == KAnp.KANP_RES_VNC_START_TICKET || m.Type == KAnp.KANP_RES_VNC_CONNECT_TICKET) { Ticket = m.Elements[0].Bin; HandleNextSessionStep(); } else throw EAnpException.FromKAnpReply(m); } catch (Exception ex) { HandleSessionTrouble(ex); } }