Example #1
0
 /// <summary>
 /// Called when the invite to workspace command reply is received.
 /// </summary>
 private void HandleKasInviteResult(KasQuery query)
 {
     if (!CheckCtx(KwmCoreKwsOpStep.KasInvite)) return;
     if (m_ih.HandleKasInviteResult(query)) CompleteOp();
 }
Example #2
0
        private void HandleAcceptChatReply(KasQuery ctx)
        {
            UInt32 type = ctx.Res.Type;

            if (type == KAnpType.KANP_RES_OK)
            {
                UInt32 userID = ctx.Cmd.Elements[3].UInt32;
                Logging.Log("Chat with " + m_helper.GetUserByID(userID).UiSimpleName + " accepted.");
                m_helper.ActivateKws();
                m_helper.SelectUser(userID);
            }

            else Logging.Log(2, Misc.HandleUnexpectedKAnpReply("accept public chat", ctx.Res).Message);
        }
Example #3
0
 private void HandleDisconnectKwsReply(KasQuery 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();
 }
Example #4
0
        /// <summary>
        /// Called when the invite to workspace command reply is received.
        /// Return true if the invitation was successful.
        /// </summary>
        public bool HandleKasInviteResult(KasQuery query)
        {
            try
            {
                AnpMsg res = query.Res;

                // Handle failures.
                if (res.Type != KAnpType.KANP_RES_KWS_INVITE_KWS)
                    throw Misc.HandleUnexpectedKAnpReply("invite to " + Base.GetKwsString(), res);

                // Update the invitation information.
                InviteParams.WLEU = res.Elements[0].String;

                if (res.Elements[1].UInt32 != (UInt32)InviteParams.UserArray.Count)
                    throw new Exception("invalid number of users invited");

                int i = 2;
                foreach (KwsInviteOpUser u in InviteParams.UserArray)
                {
                    u.EmailID = res.Elements[i++].String;
                    u.Url = res.Elements[i++].String;
                    u.Error = res.Elements[i++].String;
                }

                return true;
            }

            catch (Exception ex)
            {
                Op.HandleMiscFailure(ex);
                return false;
            }
        }
Example #5
0
        public void OnChatMsgReply(KasQuery ctx)
        {
            AnpMsg cmd = ctx.Cmd;
            AnpMsg res = ctx.Res;

            if (res.Type == KAnpType.KANP_RES_OK)
                DoOnSentChatMsgOK(new OnSentChatMsgOKEventArgs(cmd.Elements[1].UInt32,
                                                               cmd.Elements[2].String));

            else if (res.Type == KAnpType.KANP_RES_FAIL)
                DoOnSentChatMsgFailed(new OnSentChatMsgFailedEventArgs(cmd.Elements[1].UInt32,
                                                                       cmd.Elements[2].String,
                                                                       res.Elements[1].String));
            else
                Logging.Log(2, "unexpected chat command reply");
        }
Example #6
0
        /// <summary>
        /// Called when the login reply is received.
        /// </summary>
        private void HandleConnectKwsReply(KasQuery query)
        {
            Logging.Log("Got login reply, kws " + m_kws.InternalID + ", status " + m_kws.MainStatus);

            Debug.Assert(m_kws.LoginStatus == KwsLoginStatus.LoggingIn);

            // This is the standard login reply.
            if (query.Res.Type == KAnpType.KANP_RES_KWS_CONNECT_KWS)
            {
                // Get the provided information.
                KwsConnectRes r = new KwsConnectRes(query.Res);
                Logging.Log(m_currentStep + " login step: " + r.ErrMsg);

                // Dispatch.
                if (r.Code == KAnpType.KANP_KWS_LOGIN_OK) HandleConnectKwsSuccess(r);
                else if (r.Code == KAnpType.KANP_KWS_LOGIN_BAD_PWD_OR_TICKET) HandleBadPwdOrTicket(r);
                else HandleLoginFailure(TranslateKcdLoginStatusCode(r.Code), r.ErrMsg);
            }

            // This is an unexpected reply.
            else
            {
                HandleLoginFailure(KwsLoginResult.MiscKcdError, Misc.HandleUnexpectedKAnpReply("login", query.Res).Message);
            }
        }
Example #7
0
 /// <summary>
 /// Called when the invite to workspace command reply is received.
 /// </summary>
 private void HandleKasInviteResult(KasQuery query)
 {
     Logging.Log(1, "HandleKasInviteResult()");
     if (!CheckCtx(KwmCoreKwsOpStep.KasInvite)) return;
     if (m_ih.HandleKasInviteResult(query)) CompleteSpawn();
 }
Example #8
0
        private void HandleSetUserPwdResponse(KasQuery ctx)
        {
            if (!CheckCtx(KwmCoreKwsOpStep.SetUserPwd)) return;
            Debug.Assert(m_query == ctx);
            m_query = null;

            // FIXME if version >= 4 check against KANP_RES_KWS_PROP_CHANGE
            if (ctx.Res.Type == KAnpType.KANP_RES_OK)
            {
                m_kws.PostGuiExecRequest(new SetPwdGer(MessageBoxIcon.Information,
                                                       "The new password has been set."));

                // We have changed our own password. Save it.
                if (m_kws.CoreData.Credentials.UserID == m_targetUserId)
                {
                    m_kws.CoreData.Credentials.Pwd = m_stringParam;
                    m_kws.SetDirty();
                }
            }

            else
            {
                try
                {
                    String msg = "Unable to set the new password: " + ctx.Res.Elements[1].String;
                    ReportFailureToUser(msg);
                }

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

            CleanUpOnDone();
        }
Example #9
0
        /// <summary>
        /// Called when the create workspace command reply is received.
        /// </summary>
        private void HandleCreateKwsOnKasResult(KasQuery query)
        {
            if (!CheckCtx(KwmCoreKwsOpStep.KasCreate)) return;

            try
            {
                AnpMsg res = query.Res;

                // Handle failures.
                if (res.Type != KAnpType.KANP_RES_MGT_KWS_CREATED)
                    throw Misc.HandleUnexpectedKAnpReply("create " + Base.GetKwsString(), res);

                // Update the workspace credentials.
                Creds.ExternalID = res.Elements[0].UInt64;
                Creds.EmailID = res.Elements[1].String;

                // Perform the login.
                PerformKasLogin();
            }

            catch (Exception ex)
            {
                HandleMiscFailure(ex);
            }
        }
Example #10
0
        /// <summary>
        /// Handle the result of the SKURL query.
        /// </summary
        private void HandleSkurlQueryResult(KasQuery query)
        {
            if (!CheckCtx(KwmCoreKwsOpStep.KasSkurl)) return;

            try
            {
                AnpMsg res = query.Res;
                AppKfs appKfs = (AppKfs)m_kws.AppTree[KAnpType.KANP_NS_KFS];

                // Handle failures.
                if (res.Type != KAnpType.KANP_RES_KWS_UURL)
                    throw Misc.HandleUnexpectedKAnpReply("get SKURL", res);

                // Get the SKURL.
                string skurl = res.Elements[0].String;

                // Get the date.
                DateTime attachDate = Base.KDateToDateTimeUTC(res.Elements[1].UInt64);

                if (m_attachFile.Count > 0)
                {
                    string attachDest = GetAttachmentDirectory(attachDate);
                    string workDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
                    string attachDir = Path.Combine(workDir, attachDest);
                    string sourceDir = "";
                    List<string> externalFiles = new List<string>();

                    try
                    {
                        // Create the directory structure we are going to upload
                        // on the KCD.
                        Directory.CreateDirectory(attachDir);

                        // This assumes that all files provided by Outlook will
                        // come from the same directory, which is a more than reasonable
                        // assumption considering that it's programmed to do just that.
                        sourceDir = Path.GetDirectoryName(m_attachFile[0]);

                        // Move the Outlook attachments inside that structure.
                        foreach (string externalFile in m_attachFile)
                        {
                            string ef = Path.Combine(attachDir, Path.GetFileName(externalFile));
                            File.Move(externalFile, ef);
                        }

                        // Check if the directory where Outlook put its attachments is
                        // empty and if so delete it.
                        if (sourceDir != null)
                        {
                            if (Directory.GetFiles(sourceDir).Length == 0) Directory.Delete(sourceDir);
                        }

                        string[] dirs = Directory.GetDirectories(workDir, "*", SearchOption.TopDirectoryOnly);

                        // The "Attachments" directory will already exists and it's no big deal
                        // so make sure we don't get a prompt about it.
                        GateConfirmActions confirmActions = new GateConfirmActions();

                        confirmActions.dirExistsAction = "o";
                        appKfs.Share.Gate.AddExternalFiles("", dirs, false, confirmActions);

                        Logging.Log(2, "About to notify user of a file upload");
                        Wm.UiBroker.NotifyUser(new AttachManagementNotificationItem(m_kws, m_outlookRequest.Cmd));
                    }
                    finally
                    {
                        // We can remove our work directory now.
                        Directory.Delete(workDir, true);
                    }
                }

                // Send the reply.
                AnpMsg rep = m_outlookRequest.MakeReply(OAnpType.OANP_RES_GET_SKURL);
                rep.AddString(skurl);

                m_outlookRequest.SendReply(rep);

                // We're done.
                CleanUpOnDone(true);
            }

            catch (Exception ex)
            {
                HandleMiscFailure(ex);
            }
        }
Example #11
0
        /// <summary>
        /// Handle the result of the SKURL query.
        /// </summary>
        private void HandleSkurlQueryResult(KasQuery query)
        {
            if (!CheckCtx(KwmCoreKwsOpStep.KasSkurl)) return;

            try
            {
                AnpMsg res = query.Res;
                AppKfs appKfs = (AppKfs)m_kws.AppTree[KAnpType.KANP_NS_KFS];

                // Handle failures.
                if (res.Type != KAnpType.KANP_RES_KWS_UURL)
                    throw Misc.HandleUnexpectedKAnpReply("get SKURL", res);

                // Get the SKURL.
                m_skurl = res.Elements[0].String;

                // Get the date.
                DateTime attachDate = Base.KDateToDateTimeUTC(res.Elements[1].UInt64);

                // Get the email ID.
                if (m_kws.Kas.MinorVersion >= 6) { m_emailID = res.Elements[2].UInt64; }
                else { m_emailID = 0; }

                // Handle file upload attachments.
                if (m_outlookAttachList.Count > 0)
                {
                    // Set the share attachment directory path.
                    m_shareAttachDirRelPath = m_kws.CoreData.Credentials.UserEmailAddress + "/" +
                                              attachDate.ToString("yyyy-MM-dd HH\\hmm\\mss") + " " +
                                              m_mailSubject + "/" +
                                              "Original attachments";

                    // Wait for the share to become idle.
                    m_opStep = KwmCoreKwsOpStep.KfsIdle;
                    KfsShare share = GetKfsShare();
                    if (share.IsKfsIdle()) OnKfsIdle(null, null);
                    else share.OnKfsIdle += OnKfsIdle;
                }

                // We're done.
                else
                {
                    HandleSuccess();
                }
            }

            catch (Exception ex)
            {
                HandleMiscFailure(ex);
            }
        }
Example #12
0
        /// <summary>
        /// Handles when a Start Ticket is received.
        /// </summary>
        /// <param name="_context"></param>
        private void OnStartTicketResponse(KasQuery ctx)
        {
            Debug.Assert(m_state == AppSharingState.StartTicket);

            AnpMsg cmd = ctx.Cmd;
            AnpMsg res = ctx.Res;

            if (m_state != AppSharingState.StartTicket)
            {
                Logging.Log(2, "Received spurious Screen Sharing Start ticket.");
                return;
            }

            if (res.Type == KAnpType.KANP_RES_VNC_START_TICKET)
            {
                m_ticket = res.Elements[0].Bin;

                /* Start MetaVNC (specify the desired window's handle)*/
                int handle = Int32.Parse((String)ctx.MetaData[0]);
                bool supportSession = (bool)ctx.MetaData[2];

                String vncServerPath = "\"" + Base.GetKwmInstallationPath() + @"vnc\kappserver.exe" + "\"";
                String args = (handle == 0) ? " -shareall" : " -sharehwnd " + (String)ctx.MetaData[0];

                // If a window is being shared (not the desktop), set
                // it visible and in foreground.
                if (handle != 0)
                {
                    IntPtr hWnd = new IntPtr(handle);

                    if (Syscalls.IsIconic(hWnd))
                        Syscalls.ShowWindowAsync(hWnd, (int)Syscalls.WindowStatus.SW_RESTORE);

                    Base.KSetForegroundWindow(hWnd);
                }

                /* Remove any indication of previous server's listening port */
                RegistryKey port = Base.GetKwmCURegKey();
                port.DeleteValue(m_portRegItem, false);
                port.DeleteValue(m_portRegItemWritten, false);
                port.Close();

                // Set registry options in order to allow/deny
                // remote control.
                SetSupportSessionMode(supportSession);

                Logging.Log("Starting the first instance of MetaVNC (no args).");

                m_serverProcess = new RawProcess(vncServerPath);
                m_serverProcess.CreationFlags = (uint)Syscalls.CREATION_FLAGS.CREATE_NO_WINDOW;
                m_serverProcess.InheritHandles = false;
                Syscalls.STARTUPINFO si = new Syscalls.STARTUPINFO();
                si.dwFlags = 1;
                m_serverProcess.StartupInfo = si;

                m_serverProcess.ProcessEnd += HandleOnProcessEnd;

                m_serverProcess.Start();

                Logging.Log("Started.");

                /* Wait until we can get our hands on the process's window handle */
                int retries = 15;
                bool found = false;
                while (retries > 0)
                {
                    Logging.Log("Trying to start WinVNC ( " + retries + ")");

                    IntPtr serverHandle = Syscalls.FindWindow("WinVNC Tray Icon", 0);
                    if (serverHandle != IntPtr.Zero)
                    {
                        found = true;
                        break;
                    }
                    System.Threading.Thread.Sleep(250);
                    retries--;
                }

                if (!found)
                    throw new Exception("Screen sharing error: server could not be started.");

                /* Start another process of metaVNC.
                 * This is needed to pass the window handle
                 * we want, it was easier to do this that way
                 * than to pass it directly on the cmd line when
                 * starting the process the first time. */
                Logging.Log("Starting MetaVNC for the second time (this is normal): " + vncServerPath + args);
                m_dummyServerProcess = new RawProcess(vncServerPath + args);
                m_dummyServerProcess.CreationFlags = (uint)Syscalls.CREATION_FLAGS.CREATE_NO_WINDOW;
                m_dummyServerProcess.InheritHandles = false;
                m_dummyServerProcess.StartupInfo = si;
                m_dummyServerProcess.ProcessEnd += HandleOnProcessEnd;

                m_dummyServerProcess.Start();

                // Find out on which port we need to tell ktlstunnel to
                // connect to the server
                RegistryKey kwmKey = Base.GetKwmCURegKey();
                object readPort = null;
                object portOK = null;

                // Actively poll the synchronization key for 6 seconds.
                retries = 30;
                found = false;

                while (retries > 0)
                {
                    portOK = kwmKey.GetValue(m_portRegItemWritten);

                    if (portOK != null)
                    {
                        found = true;
                        break;
                    }
                    System.Threading.Thread.Sleep(200);
                    retries--;
                }

                if (!found)
                {
                    if (kwmKey != null)
                        kwmKey.Close();

                    ResetToIdle();
                    Misc.KwmTellUser("Screen sharing error: a timeout occured while waiting for the server's listening port.");
                    return;
                }

                // At this stage we can presume the port was
                // correctly really written by the VNC server.
                readPort = kwmKey.GetValue(m_portRegItem);
                kwmKey.Close();

                if (port == null)
                {
                    ResetToIdle();
                    Misc.KwmTellUser("Screen sharing error: unable to read the server's listening port.");
                    return;
                }

                Logging.Log("Screen Sharing server's port: " + (int)readPort);

                /* Connect a new tunnel */
                m_tunnel = Helper.CreateTunnel();
                m_tunnel.Connect("localhost", (int)readPort);

                /* Negociate role */
                AnpMsg inMsg = Helper.NewKAnpMsg(KAnpType.KANP_CMD_MGT_SELECT_ROLE);

                inMsg.AddUInt32(KAnpType.KANP_KCD_ROLE_APP_SHARE);
                m_tunnel.SendMsg(inMsg);
                AnpMsg outMsg = m_tunnel.GetMsg();

                if (outMsg.Type == KAnpType.KANP_RES_FAIL)
                {
                    ResetToIdle();
                    Misc.KwmTellUser(outMsg.Elements[1].String);
                    return;
                }

                Debug.Assert(outMsg.Type == KAnpType.KANP_RES_OK);

                AnpMsg startSession = Helper.NewKAnpMsg(KAnpType.KANP_CMD_VNC_START_SESSION);
                startSession.AddBin(m_ticket);
                startSession.AddString((String)ctx.MetaData[1]);

                m_tunnel.SendMsg(startSession);
                outMsg = m_tunnel.GetMsg();
                if (outMsg.Type == KAnpType.KANP_RES_FAIL)
                {
                    ResetToIdle();
                    Misc.KwmTellUser(outMsg.Elements[1].String);
                    return;
                }
                Debug.Assert(outMsg.Type == KAnpType.KANP_RES_VNC_START_SESSION);

                m_createdSessionID = outMsg.Elements[0].UInt64;

                /* Disconnect tunnel so it can connect to metaVNC server */
                Logging.Log("About to call disconnect on ktlstunnel.");
                m_tunnel.Disconnect();
                CurrentState = AppSharingState.Started;
                m_connectedSessionID = 0;

                StopInactivityMonitor();

                // 10 minutes
                inactivityMonitor = MonitorCreator.CreateInstance(MonitorType.GlobalHookMonitor);
                inactivityMonitor.Interval = 600000;
                inactivityMonitor.Elapsed += new ElapsedEventHandler(HandleSessionTimeout);
                inactivityMonitor.Enabled = true;
            }
            else if (res.Type == KAnpType.KANP_RES_FAIL)
            {
                ResetToIdle();
                Misc.KwmTellUser(res.Elements[1].String);
            }
            else
            {
                Logging.Log(2, "unexpected response in OnStartTicketResponse");
            }
        }
Example #13
0
        private void OnConnectTicketResponse(KasQuery ctx)
        {
            Debug.Assert(m_state == AppSharingState.ConnectTicket);

            AnpMsg cmd = ctx.Cmd;
            AnpMsg res = ctx.Res;

            if (m_state != AppSharingState.ConnectTicket)
            {
                Logging.Log(2, "Received spurious Screen Sharing Connect ticket.");
                return;
            }

            if (res.Type == KAnpType.KANP_RES_VNC_CONNECT_TICKET)
            {
                m_ticket = res.Elements[0].Bin;

                // Remove any indication of previous client's listening port
                RegistryKey port = Base.GetKwmCURegKey();
                port.DeleteValue(m_portRegItem, false);
                port.DeleteValue(m_portRegItemWritten, false);
                port.Close();

                /* Start client. Force one parameter so that it does not
                 * prompt for connection parameters */
                String vncClientPath = "\"" + Base.GetKwmInstallationPath() + @"vnc\kappviewer.exe" + "\"";
                String args = " /shared /notoolbar /disableclipboard /encoding tight /compresslevel 9 localhost";

                m_viewerProcess = new RawProcess(vncClientPath + args);
                m_viewerProcess.InheritHandles = false;
                m_viewerProcess.ProcessEnd += HandleOnProcessEnd;
                m_viewerProcess.Start();

                RegistryKey kwmKey = Base.GetKwmCURegKey();
                object _port = null;
                object _portOK = null;

                // Actively poll the synchronization
                // key for 6 secs
                int retries = 30;
                bool found = false;

                while (retries > 0)
                {
                    _portOK = kwmKey.GetValue(m_portRegItemWritten);

                    if (_portOK != null)
                    {
                        found = true;
                        break;
                    }
                    System.Threading.Thread.Sleep(200);
                    retries--;
                }

                if (!found)
                {
                    if (kwmKey != null)
                        kwmKey.Close();

                    ResetToIdle();
                    Misc.KwmTellUser("a timeout occured while waiting for the client's listening port.");
                    return;
                }

                // At this stage we can presume the port was
                // correctly really written by the VNC server.
                _port = kwmKey.GetValue(m_portRegItem);
                kwmKey.Close();

                if (_port == null)
                {
                    ResetToIdle();
                    Misc.KwmTellUser("could not read client's listening port.");
                    return;
                }

                Logging.Log("Read VNC client's port: " + (int)_port);

                /* Connect a new tunnel */
                IAnpTunnel tunnel = Helper.CreateTunnel();
                tunnel.Connect("localhost", (int)_port);

                /* Negociate role */
                AnpMsg inMsg = Helper.NewKAnpMsg(KAnpType.KANP_CMD_MGT_SELECT_ROLE);
                inMsg.AddUInt32(KAnpType.KANP_KCD_ROLE_APP_SHARE);
                tunnel.SendMsg(inMsg);
                AnpMsg outMsg = tunnel.GetMsg();

                if (outMsg.Type == KAnpType.KANP_RES_FAIL)
                {
                    ResetToIdle();
                    Misc.KwmTellUser(outMsg.Elements[1].String);
                    return;
                }

                Debug.Assert(outMsg.Type == KAnpType.KANP_RES_OK);

                AnpMsg startSession = Helper.NewKAnpMsg(KAnpType.KANP_CMD_VNC_CONNECT_SESSION);
                startSession.AddBin(m_ticket);
                tunnel.SendMsg(startSession);
                outMsg = tunnel.GetMsg();

                if (outMsg.Type == KAnpType.KANP_RES_FAIL)
                {
                    ResetToIdle();
                    Misc.KwmTellUser(outMsg.Elements[1].String);
                    return;
                }

                Debug.Assert(outMsg.Type == KAnpType.KANP_RES_OK);

                Logging.Log("About to call disconnect");
                tunnel.Disconnect();
                CurrentState = AppSharingState.Connected;
            }
            else if (res.Type == KAnpType.KANP_RES_FAIL)
            {
                ResetToIdle();
                Misc.KwmTellUser(res.Elements[1].String);
            }
            else
            {
                Logging.Log("unexpected response in OnConnectTicketResponse");
            }
        }