Example #1
0
        /// <summary>
        /// Create a new KCD ANP command message having the minor version and
        /// type specified and a unique ID. The workspace ID is inserted as the
        /// first element of the command.
        /// </summary>
        public AnpMsg NewKcdCmd(UInt32 type)
        {
            AnpMsg msg = Wm.NewKcdCmd(Kcd.MinorVersion, type);

            msg.AddUInt64(Cd.Credentials.ExternalID);
            return(msg);
        }
Example #2
0
        /// <summary>
        /// Import a workspace list from the XML document specified.
        /// </summary>
        public static void ImportKwsListFromXmlDoc(XmlDocument doc)
        {
            UInt32 version = UInt32.Parse(doc.DocumentElement.GetAttribute("version"));

            if (version > 1)
            {
                throw new Exception("unsupported KwsExport version ('" + version + "')");
            }

            // Import all nodes.
            foreach (XmlNode node in doc.DocumentElement.ChildNodes)
            {
                XmlElement el = node as XmlElement;
                if (el == null)
                {
                    throw new Exception("Corrupted document (Node is not an XmlElement).");
                }
                else if (el.Name == "Kws")
                {
                    ImportKws(XmlToKwsCredentials(el));
                }
                else if (el.Name == "KwsBrowser")
                {
                    ImportFolderList(XmlToFolderList(el));
                }
                else
                {
                    throw new Exception("Corrupted document (unknown node '" + el.Name + "'.");
                }
            }

            // Serialize the WM since we may have created workspaces.
            Wm.Serialize();
        }
Example #3
0
 /// <summary>
 /// This method is called when the workspace manager has stopped.
 /// The WM is serialized and the application is told to quit.
 /// </summary>
 private static void HandlePostStop()
 {
     KLogging.Log("WmSm: " + KwmStrings.Kwm + " has stopped.");
     Wm.MainStatus = WmMainStatus.Stopped;
     Wm.Serialize();
     Program.RequestAppExit();
 }
Example #4
0
        /// <summary>
        /// Export the given KWS to the specified path. Set kwsID to 0
        /// to export all the workspaces.
        /// </summary>
        public static void ExportKws(String path, UInt64 kwsID)
        {
            XmlDocument doc  = new XmlDocument();
            XmlNode     node = doc.CreateNode(XmlNodeType.XmlDeclaration, "", "");

            doc.AppendChild(node);

            XmlElement ke = doc.CreateElement("TeamboxExport");

            ke.SetAttribute("version", "1");
            doc.AppendChild(ke);

            if (kwsID == 0)
            {
                // Export all workspaces.
                foreach (Workspace kws in Wm.KwsTree.Values)
                {
                    KwsCredentialsToXml(kws.Cd.Credentials, doc, ke);
                }

                // Export all folders.
                FolderListToXml(Wm.Cd.KwsFolderList, doc, ke);
            }

            else
            {
                // Export only the specified workspace.
                Workspace kws = Wm.GetKwsByInternalID(kwsID);
                KwsCredentialsToXml(kws.Cd.Credentials, doc, ke);
            }

            using (Stream s = File.Open(path, FileMode.Create)) doc.Save(s);
        }
Example #5
0
        /// <summary>
        /// Create a new workspace having the credentials specified and insert
        /// it in the workspace manager, with the current task Stop.
        /// </summary>
        public static Workspace CreateWorkspace(KwsCredentials creds)
        {
            try
            {
                // Clear the public flag if we already have a public workspace.
                if (Cd.PublicKwsID != 0)
                {
                    creds.PublicFlag = false;
                }

                // Get a new internal ID.
                UInt64 internalID = Cd.NextKwsInternalID++;

                // Register the worskpace in the workspace manager.
                KwsCoreData kwsCd = new KwsCoreData();
                kwsCd.Credentials = creds;
                Workspace kws = new Workspace();
                kws.Relink(internalID, kwsCd);
                AdjustPublicKwsID();

                // Insert the workspace in the workpace list in the database.
                LocalDbBroker.AddKwsToKwsList(kws.InternalID, kws.Cd.Credentials.KwsName);

                // The WM state has changed.
                Wm.OnStateChange(WmStateChange.Permanent);

                return(kws);
            }

            catch (Exception ex)
            {
                KBase.HandleException(ex, true);
                return(null);
            }
        }
Example #6
0
        /// <summary>
        /// Complete the operation if we are ready to.
        /// </summary>
        private void CompleteIfNeeded()
        {
            if (DoneFlag ||
                m_step != OpStep.LoggingIn ||
                Kws.Cd.KcdState.LoginStatus != KwsLoginStatus.LoggedIn ||
                Kws.Cd.MainStatus != KwsMainStatus.NotYetSpawned ||
                Kws.Cd.CurrentTask != KwsTask.Spawn)
            {
                return;
            }

            // Update the main status of the workspace.
            Kws.Cd.MainStatus = KwsMainStatus.Good;
            Kws.OnStateChange(WmStateChange.Permanent);

            // Ask the state machine to work online.
            Kws.Sm.RequestTaskSwitch(KwsTask.WorkOnline);

            // Serialize the KWM so we don't lose the workspace if the KWM
            // crashes.
            Wm.Serialize();

            // We're done.
            Complete();
        }
Example #7
0
        /// <summary>
        /// Called when the KMOD ticket query results are available.
        /// </summary>
        private void OnKmodTicketResult(WmLoginTicketQuery query)
        {
            if (m_kmodQuery != query)
            {
                return;
            }
            m_kmodQuery = null;
            Debug.Assert(m_step == OpStep.TicketReply);

            try
            {
                // Update the registry information.
                query.UpdateRegistry();

                // Generic failure.
                if (query.Res != WmLoginTicketQueryRes.OK)
                {
                    throw new Exception(query.OutDesc);
                }

                // We cannot create a workspace.
                if (!KwmCfg.Cur.CanCreateKws())
                {
                    throw new EAnpExInvalidKpsConfig();
                }

                // Update the credentials.
                Creds.Ticket           = query.Ticket.BinaryTicket;
                Creds.UserName         = query.Ticket.AnpTicket.Elements[0].String;
                Creds.UserEmailAddress = query.Ticket.AnpTicket.Elements[1].String;

                // Set the KCD address.
                if (KwmCfg.Cur.CustomKcdFlag)
                {
                    Creds.KcdAddress = KwmCfg.Cur.CustomKcdAddress;
                }
                else
                {
                    Creds.KcdAddress = KwmCfg.Cur.KpsKcdAddr;
                }
                if (Creds.KcdAddress == "")
                {
                    throw new Exception("invalid KCD address");
                }

                // Create the workspace object.
                Kws = Wm.CreateWorkspace(Creds);
                RegisterToKws();

                // Start the spawn operation and wait for the connection.
                m_step = OpStep.Connecting;
                Kws.Sm.RequestTaskSwitch(KwsTask.Spawn);
                SendCreateKwsCmdIfNeeded();
            }

            catch (Exception ex)
            {
                HandleFailure(ex);
            }
        }
Example #8
0
        /// <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);
        }
Example #9
0
        public override void Start()
        {
            try
            {
                // Register to the workspace, if possible.
                Kws = Wm.GetKwsByInternalIDOrThrow(KwsID);
                RegisterToKws();
                Kws.KcdLoginHandler.OnSetLoginPwdRefused += OnLoginPwdRefused;

                // The password was "accepted" without being tried.
                if (!Kws.KcdLoginHandler.SetLoginPwd(Pwd))
                {
                    Complete();
                    return;
                }

                // Wait to be notified. Either we will be told that the
                // password was refused or the login status will change.
            }

            catch (Exception ex)
            {
                HandleFailure(ex);
            }
        }
Example #10
0
        public override void Start()
        {
            try
            {
                // Get the workspace, if possible.
                Kws = Wm.GetKwsByInternalIDOrThrow(KwsID);

                // If the task is delete remotely, start a delete remotely
                // operation.
                if (Task == KwsTask.DeleteRemotely)
                {
                    m_deleteRemotelyOp               = new KwsCoreOpDeleteKwsRemotely();
                    m_deleteRemotelyOp.Kws           = Kws;
                    m_deleteRemotelyOp.OnCompletion += OnDeleteRemotelyCompletion;
                    m_deleteRemotelyOp.Start();
                }

                // Perform the task switch right away.
                else
                {
                    Kws.Sm.RequestTaskSwitch(Task);
                }
            }

            catch (Exception ex)
            {
                HandleFailure(ex);
            }
        }
Example #11
0
 private void SaveLocation(Point loc)
 {
     if (loc.Equals(Wm.Cd.VncOverlayLoc))
     {
         return;
     }
     Wm.Cd.VncOverlayLoc = loc;
     Wm.OnStateChange(WmStateChange.Internal);
 }
Example #12
0
        /// <summary>
        /// Process one workspace to remove.
        /// </summary>
        private static void ProcessOneKwsToRemove(Workspace kws)
        {
            // We can remove the workspace now.
            if (kws.Sm.ReadyToRemove())
            {
                // Remove the workspace from the manager.
                Wm.RemoveWorkspace(kws);

                // Request a run of the state machine in case we want to stop.
                RequestRun("removed " + KwmStrings.Kws);
            }
        }
Example #13
0
        /// <summary>
        /// Create a VNC session.
        /// </summary>
        private void HandleVncCreateSession(AnpMsg cmd, AnpMsg res)
        {
            int       i           = 0;
            UInt64    kwsID       = cmd.Elements[i++].UInt64;
            bool      supportFlag = cmd.Elements[i++].UInt32 > 0;
            String    subject     = cmd.Elements[i++].String;
            Workspace kws         = Wm.GetKwsByInternalIDOrThrow(kwsID);

            byte[] sessionUuid = kws.Vnc.StartServerSession(supportFlag, 0, subject);
            res.Type = (uint)EAnpRes.VncSession;
            res.AddBin(sessionUuid);
        }
Example #14
0
        /// <summary>
        /// Join a VNC session.
        /// </summary>
        private void HandleVncJoinSession(AnpMsg cmd, AnpMsg res)
        {
            int       i         = 0;
            UInt64    kwsID     = cmd.Elements[i++].UInt64;
            UInt64    sessionID = cmd.Elements[i++].UInt64;
            String    subject   = cmd.Elements[i++].String;
            Workspace kws       = Wm.GetKwsByInternalIDOrThrow(kwsID);

            byte[] sessionUuid = kws.Vnc.StartClientSession(sessionID, subject);
            res.Type = (uint)EAnpRes.VncSession;
            res.AddBin(sessionUuid);
        }
Example #15
0
        /// <summary>
        /// Serialize the WM if it is time to do so.
        /// </summary>
        private static void SerializeWmIfNeeded()
        {
            DateTime now = DateTime.Now;

            if (m_lastSerializationDate.AddSeconds(WmSerializationDelay) < now)
            {
                m_lastSerializationDate = now;
                Wm.Serialize();
            }

            ScheduleRun("WM serialization", m_lastSerializationDate.AddSeconds(WmSerializationDelay));
        }
Example #16
0
        /// <summary>
        /// Import or join a workspace that does not exist in the KWM.
        /// </summary>
        private static void ImportNewKws(KwsCredentials creds)
        {
            KLogging.Log("Importing new workspace " + creds.KwsName + ".");

            // Create the workspace.
            Workspace kws = Wm.CreateWorkspace(creds);

            // Set its main status.
            kws.Cd.MainStatus = KwsMainStatus.Good;

            // Make the workspace work online.
            kws.Sm.RequestTaskSwitch(KwsTask.WorkOnline);
        }
Example #17
0
        /// <summary>
        /// Import the workspace specified.
        /// </summary>
        public static void ImportKws(KwsCredentials creds)
        {
            Workspace kws = Wm.GetKwsByExternalID(creds.KcdID, creds.ExternalID);

            if (kws != null)
            {
                ImportExistingKws(kws, creds);
            }
            else
            {
                ImportNewKws(creds);
            }
        }
Example #18
0
        /// <summary>
        /// Create an EAnp event having the parameters specified.
        /// </summary>
        private AnpMsg MakeEAnpEvent(EAnpEvt type, UInt64 date, UInt32 userID, UInt64 freshness)
        {
            AnpMsg m = new AnpMsg();

            m.Minor = 1;
            m.Type  = (UInt32)type;
            m.AddUInt64(InternalID);
            m.AddUInt64(date);
            m.AddUInt32(userID);
            m.AddUInt64(freshness);
            m.AddBin(Wm.MakeUuid());
            return(m);
        }
Example #19
0
 public void Relink(UInt64 internalID, KwsCoreData cd)
 {
     InternalID = internalID;
     Cd         = cd;
     Cd.Relink();
     Wm.KwsTree[InternalID] = this;
     Kcd = Wm.GetOrCreateKcd(Cd.Credentials.KcdID);
     Kcd.KwsTree[InternalID] = this;
     Sm.Relink(this);
     KcdEventHandler.Relink(this);
     KcdLoginHandler.Relink(this);
     Chat.Relink(this);
     Pb.Relink(this);
     Vnc.Relink(this);
     Kfs.Relink(this);
 }
Example #20
0
        /// <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);
            }
        }
Example #21
0
        /// <summary>
        /// Remove the workspace object from the workspace manager. Used by the
        /// WM state machine.
        /// </summary>
        public static void RemoveWorkspace(Workspace kws)
        {
            try
            {
                WmKcd kcd = kws.Kcd;

                // Make sure the state is valid.
                Debug.Assert(KwsTree.ContainsKey(kws.InternalID));
                if (kcd != null)
                {
                    Debug.Assert(kcd.KwsTree.ContainsKey(kws.InternalID));
                    Debug.Assert(!kcd.KwsConnectTree.ContainsKey(kws.InternalID));
                }

                // Unregister the workspace from the workspace manager.
                KwsTree.Remove(kws.InternalID);
                if (KwsRemoveTree.ContainsKey(kws.InternalID))
                {
                    KwsRemoveTree.Remove(kws.InternalID);
                }
                if (kcd != null)
                {
                    kcd.CancelKwsKcdQuery(kws);
                    kcd.KwsTree.Remove(kws.InternalID);
                    RemoveKcdIfNoRef(kcd);
                }
                AdjustPublicKwsID();

                // Delete the workspace data.
                kws.PrepareToRemove();
                foreach (KwsApp app in kws.AppTree.Values)
                {
                    app.PrepareToRemove();
                }

                // The WM state has changed.
                Wm.OnStateChange(WmStateChange.Permanent);
            }

            catch (Exception ex)
            {
                KBase.HandleException(ex, true);
            }
        }
Example #22
0
        /// <summary>
        /// Update and return the freshness time.
        /// </summary>
        public UInt64 UpdateFreshnessTime()
        {
            DateTime now       = DateTime.Now;
            Int64    offset    = (Int64)(now - FreshnessDate).TotalMilliseconds;
            Int64    maxOffset = 24 * 60 * 60 * 1000;

            if (offset < 0)
            {
                offset = 0;
            }
            else if (offset > maxOffset)
            {
                offset = maxOffset;
            }
            FreshnessDate  = now;
            FreshnessTime += (UInt64)offset;
            Wm.OnStateChange(WmStateChange.Internal);
            return(FreshnessTime);
        }
Example #23
0
        /// <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);
        }
Example #24
0
        /// <summary>
        /// Process a KCD disconnection notice.
        /// </summary>
        private static void ProcessKcdDisconnectionNotice(KcdDisconnectionNotice notice)
        {
            Debug.Assert(Wm.KcdTree.ContainsKey(notice.KcdID));
            WmKcd kcd = Wm.KcdTree[notice.KcdID];

            Debug.Assert(kcd.ConnStatus != KcdConnStatus.Disconnected);

            // The KCD died unexpectedly.
            if (kcd.ConnStatus != KcdConnStatus.Disconnecting)
            {
                // Handle the offense.
                if (notice.Ex != null)
                {
                    // Increase the failed connection attempt count if were
                    // connecting.
                    AssignErrorToKcd(kcd, (kcd.ConnStatus == KcdConnStatus.Connecting));
                }
            }

            // The KCD is now disconnected.
            kcd.ConnStatus = KcdConnStatus.Disconnected;

            // Clear the command-reply mappings associated to the KCD.
            kcd.QueryMap.Clear();

            // Notify every workspace that the KCD is disconnected.
            foreach (Workspace kws in kcd.KwsTree.Values)
            {
                kws.Sm.HandleKcdConnStatusChange(KcdConnStatus.Disconnected, notice.Ex);
            }

            // Remove the KCD if we no longer need it.
            Wm.RemoveKcdIfNoRef(kcd);

            // Re-run the state machine, in case we want to reconnect to the KCD
            // or stop.
            RequestRun("KCD disconnected");
        }
Example #25
0
        /// <summary>
        /// Import the workspace folder list specified.
        /// </summary>
        public static void ImportFolderList(List <WmKwsFolder> folderList)
        {
            // Import the missing folders. Update the ET blob of existing folders.
            foreach (WmKwsFolder f in folderList)
            {
                bool foundFlag = false;
                foreach (WmKwsFolder g in Wm.Cd.KwsFolderList)
                {
                    if (g.FullPath == f.FullPath)
                    {
                        foundFlag = true;
                        g.EtBlob  = f.EtBlob;
                        break;
                    }
                }
                if (!foundFlag)
                {
                    Wm.Cd.KwsFolderList.Add(f);
                }
            }

            // The WM state has changed.
            Wm.OnStateChange(WmStateChange.Permanent);
        }
Example #26
0
        /// <summary>
        /// Enter the main mode of the KWM. Return true if the application
        /// must continue.
        /// </summary>
        private static bool EnterMainMode()
        {
            // Perform early linking.
            Wm.LocalDbBroker.Relink(Wm.LocalDb);

            // FIXME.
#if true
            // Open a temporary console.
            ConsoleWindow foo = new ConsoleWindow();
            foo.Show();
            foo.OnConsoleClosing += delegate(Object sender, EventArgs args)
            {
                WmSm.RequestStop();
            };

            // Create an empty database.
            Wm.LocalDb.DeleteDb();
            Wm.LocalDb.OpenOrCreateDb(KwmPath.GetKwmDbPath());
            Wm.LocalDbBroker.InitDb();
            WmDeserializer ds = new WmDeserializer();
            ds.Deserialize();
            Debug.Assert(ds.Ex == null);
#else
            // Open or create the database.
            Wm.LocalDb.OpenOrCreateDb(KwmPath.GetKwmDbPath());
            Wm.LocalDbBroker.InitDb();

            // Try to deserialize.
            WmDeserializer ds = new WmDeserializer();
            ds.Deserialize();

            // The deserialization failed.
            if (ds.Ex != null)
            {
                // If the user doesn't want to recover, bail out.
                if (!TellUserAboutDsrFailure())
                {
                    return(false);
                }

                // Backup, delete and recreate a database.
                BackupDb();
                Wm.LocalDb.DeleteDb();
                Wm.LocalDb.OpenOrCreateDb(KwmPath.GetKwmDbPath());
                Wm.LocalDbBroker.InitDb();

                // Retry to deserialize.
                ds = new WmDeserializer();
                ds.Deserialize();
                if (ds.Ex != null)
                {
                    throw ds.Ex;
                }

                // Set the next internal workspace ID to a high value based on
                // the date to avoid conflicts with old KFS directories.
                ds.WmCd.NextKwsInternalID = (UInt64)(DateTime.Now - new DateTime(2010, 1, 1)).TotalSeconds;
            }
#endif

            // Relink the workspace manager object graphs.
            Wm.Relink(ds);

            // Open the lingering database transaction.
            Wm.LocalDb.BeginTransaction();

            // Serialize the WM state that has changed.
            Wm.Serialize();

            // Export the workspaces, then exit.
            if (ExportKwsPath != "")
            {
                WmKwsImportExport.ExportKws(ExportKwsPath, 0);
                return(false);
            }

            // Set the handle to the message window.
            SetKwmHandle(MsgWindow.Handle);

            // Pass the hand to the WM state machine.
            WmSm.RequestStart();

            return(true);
        }
Example #27
0
 protected override void PrepareStart()
 {
     Kws = Wm.GetKwsByInternalIDOrThrow(KwsId);
 }
Example #28
0
        /// <summary>
        /// Process workspace rebuild if required.
        /// </summary>
        private void ProcessKwsRebuildIfNeeded()
        {
            Debug.Assert(m_rebuildStep == KwsRebuildTaskStep.None);

            if (m_cd.CurrentTask != KwsTask.Rebuild)
            {
                return;
            }

            // Sanity check.
            if (m_cd.MainStatus != KwsMainStatus.RebuildRequired)
            {
                KLogging.Log("cannot execute rebuild task, " + KwmStrings.Kws + " status is not RebuildRequired");
                RequestTaskSwitch(KwsTask.Stop);
                return;
            }

            // We cannot rebuild until the applications are stopped and we're
            // logged out.
            if (m_cd.AppStatus != KwsAppStatus.Stopped || m_ks.LoginStatus != KwsLoginStatus.LoggedOut)
            {
                return;
            }

            // Protect against spurious state changes.
            m_rebuildStep = KwsRebuildTaskStep.InProgress;

            try
            {
                // Ask the workspace to prepare for rebuild.
                m_kws.PrepareToRebuild();
                if (m_rebuildStep != KwsRebuildTaskStep.InProgress)
                {
                    return;
                }

                // Tell the applications to prepare for rebuild.
                foreach (KwsApp app in m_kws.AppTree.Values)
                {
                    app.PrepareToRebuild();
                    if (m_rebuildStep != KwsRebuildTaskStep.InProgress)
                    {
                        return;
                    }
                }
            }

            catch (Exception ex)
            {
                HandleMiscFailure(ex);
                return;
            }

            // We have "rebuilt" the workspace. Update the state.
            m_rebuildStep     = KwsRebuildTaskStep.None;
            m_cd.MainStatus   = KwsMainStatus.Good;
            m_cd.RebuildFlags = 0;
            m_cd.Uuid         = Wm.MakeUuid();
            SetLoginType(KwsLoginType.All);
            m_kws.OnStateChange(WmStateChange.Permanent);

            // Switch to the user task.
            SwitchToUserTask();
        }