Exemple #1
0
        private static async void InitializeAppServiceConnection()
        {
            connection = new NamedPipeServerStream($@"FilesInteropService_ServerPipe", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 2048, 2048, null, HandleInheritability.None, PipeAccessRights.ChangePermissions);

            PipeSecurity   Security   = connection.GetAccessControl();
            PipeAccessRule ClientRule = new PipeAccessRule(new SecurityIdentifier("S-1-15-2-1"), PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow);
            PipeAccessRule OwnerRule  = new PipeAccessRule(WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow);

            Security.AddAccessRule(ClientRule);
            Security.AddAccessRule(OwnerRule);
            if (IsAdministrator())
            {
                PipeAccessRule EveryoneRule = new PipeAccessRule(new SecurityIdentifier("S-1-1-0"), PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow);
                Security.AddAccessRule(EveryoneRule); // TODO: find the minimum permission to allow connection when admin
            }
            connection.SetAccessControl(Security);

            await connection.WaitForConnectionAsync();

            if (connection.IsConnected)
            {
                var info = (Buffer : new byte[connection.InBufferSize], Message : new StringBuilder());
                BeginRead(info);
            }
        }
Exemple #2
0
        NamedPipeServerStream CreatePipeAccessControl()
        {
            // Fix up the DACL on the pipe before opening the listener instance
            // This won't disturb the SACL containing the mandatory integrity label
            NamedPipeServerStream pipeServer = new NamedPipeServerStream(
                PipeName,                                                   // The unique pipe name.
                PipeDirection,                                              // The pipe is duplex
                NamedPipeServerStream.MaxAllowedServerInstances,            // MaxAllowedServerInstances
                PipeTransmissionMode.Message,                               // Byte|Message-based communication
                PipeOptions.None,                                           // No additional parameters
                ReceiveBufferSize,                                          // Input buffer size
                SendBufferSize,                                             // Output buffer size
                null,                                                       // Pipe security attributes
                HandleInheritability.None,                                  // Not inheritable
                PipeAccessRights.ChangePermissions);

            PipeSecurity ps = pipeServer.GetAccessControl();

            PipeAccessRule aceClients = new PipeAccessRule(
                new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), // or some other group defining the allowed clients
                PipeAccessRights.ReadWrite,
                AccessControlType.Allow);
            PipeAccessRule aceOwner = new PipeAccessRule(
                WindowsIdentity.GetCurrent().Owner,
                PipeAccessRights.FullControl,
                AccessControlType.Allow);

            ps.AddAccessRule(aceClients);
            ps.AddAccessRule(aceOwner);

            pipeServer.SetAccessControl(ps);

            return(pipeServer);
        }
Exemple #3
0
        private NamedPipeServerStream CreateNewPipeServer()
        {
            var server = new NamedPipeServerStream(PipeName,
                                                   PipeDirection.InOut,
                                                   2,
                                                   PipeTransmissionMode.Byte,
                                                   PipeOptions.Asynchronous,
                                                   0,
                                                   0,
                                                   null,
                                                   HandleInheritability.None,
                                                   0);

            PipeSecurity accessControl = server.GetAccessControl();

            // Prevent 'Everyone' account from accessing pipe
            var securityIdentifier = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
            var rule = new PipeAccessRule(securityIdentifier, PipeAccessRights.Read, AccessControlType.Allow);

            accessControl.RemoveAccessRule(rule);

            // Prevent 'Anonymous' account from accessing pipe
            securityIdentifier = new SecurityIdentifier(WellKnownSidType.AnonymousSid, null);
            rule = new PipeAccessRule(securityIdentifier, PipeAccessRights.Read, AccessControlType.Allow);
            accessControl.RemoveAccessRule(rule);

            return(server);
        }
        public void Create_NullSecurity_PipeOptionsCurrentUserOnly()
        {
            using NamedPipeServerStream pipe = CreateNamedPipe(GetRandomName(), null, options: PipeOptions.CurrentUserOnly);
            PipeSecurity actualSecurity   = pipe.GetAccessControl();
            PipeSecurity expectedSecurity = GetPipeSecurityForCurrentUserOnly();

            VerifyPipeSecurity(expectedSecurity, actualSecurity);
        }
        public void GetAccessControl_NamedPipe_BeforeWaitingToConnect()
        {
            string pipeName = GetUniquePipeName();
            var server = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
            var client = new NamedPipeClientStream(".", pipeName, PipeDirection.In, PipeOptions.Asynchronous);

            Assert.NotNull(server.GetAccessControl());
            server.SetAccessControl(new PipeSecurity());
            Assert.Throws<InvalidOperationException>(() => client.GetAccessControl());
            Assert.Throws<InvalidOperationException>(() => client.SetAccessControl(new PipeSecurity()));
        }
Exemple #6
0
        public void GetAccessControl_NamedPipe_BeforeWaitingToConnect()
        {
            string pipeName = GetUniquePipeName();
            var    server   = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
            var    client   = new NamedPipeClientStream(".", pipeName, PipeDirection.In, PipeOptions.Asynchronous);

            Assert.NotNull(server.GetAccessControl());
            server.SetAccessControl(new PipeSecurity());
            Assert.Throws <InvalidOperationException>(() => client.GetAccessControl());
            Assert.Throws <InvalidOperationException>(() => client.SetAccessControl(new PipeSecurity()));
        }
Exemple #7
0
        private static void PipeServerThread()
        {
            server = new NamedPipeServerStream(pipeName,
                                               PipeDirection.InOut, 1,
                                               PipeTransmissionMode.Message,
                                               PipeOptions.Asynchronous, 1024, 1024, null, HandleInheritability.None,
                                               PipeAccessRights.ChangePermissions);

            PipeSecurity   ps         = server.GetAccessControl();
            PipeAccessRule clientRule = new PipeAccessRule(
                new SecurityIdentifier("S-1-15-2-1"),
                PipeAccessRights.ReadWrite,
                AccessControlType.Allow);
            PipeAccessRule ownerRule = new PipeAccessRule(
                WindowsIdentity.GetCurrent().Owner,
                PipeAccessRights.FullControl,
                AccessControlType.Allow);

            ps.AddAccessRule(clientRule);
            ps.AddAccessRule(ownerRule);
            server.SetAccessControl(ps);


            LogClerk.Info("Waiting for connection.");
            server.WaitForConnection();
            reader = new StreamReader(server);
            writer = new StreamWriter(server);
            LogClerk.Info($"Connection established: {pipeName}");

            while (serverRun)
            {
                //if (!server.IsConnected)
                //{
                //    server.Disconnect();
                //    LogClerk.Info("Disconnected from FancyToys, waiting for its reconnection.");
                //    server.WaitForConnection();
                //    LogClerk.Info("FancyToys reconnected");
                //}
                if (server.IsConnected)
                {
                    string message = reader.ReadLine();
                    if (!string.IsNullOrEmpty(message))
                    {
                        MessageManager.Deal(message);
                    }
                }
                else
                {
                    break;
                }
            }
        }
Exemple #8
0
        private static void InitializeNewNamedPipe(string ID)
        {
            NamedPipeServerStream NewPipeServer = new NamedPipeServerStream($@"Explorer_And_FullTrustProcess_NamedPipe-{ID}", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.None, 2048, 2048, null, HandleInheritability.None, PipeAccessRights.ChangePermissions);
            PipeSecurity          Security      = NewPipeServer.GetAccessControl();
            PipeAccessRule        ClientRule    = new PipeAccessRule(new SecurityIdentifier("S-1-15-2-1"), PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow);
            PipeAccessRule        OwnerRule     = new PipeAccessRule(WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow);

            Security.AddAccessRule(ClientRule);
            Security.AddAccessRule(OwnerRule);
            NewPipeServer.SetAccessControl(Security);

            PipeServers.Add(ID, NewPipeServer);
        }
Exemple #9
0
        public void SetAccessControl_NamedPipeStream()
        {
            string pipeName = GetUniquePipeName();
            var    server   = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
            var    client   = new NamedPipeClientStream(".", pipeName, PipeDirection.In, PipeOptions.Asynchronous);

            Task clientConnect = client.ConnectAsync();

            server.WaitForConnection();
            clientConnect.Wait();

            Assert.NotNull(server.GetAccessControl());
            server.SetAccessControl(new PipeSecurity());
            Assert.NotNull(client.GetAccessControl());
            client.SetAccessControl(new PipeSecurity());
        }
Exemple #10
0
        public void NamedPipeDefaultPermissionsWork()
        {
            if (PlatformID.Win32NT != Environment.OSVersion.Platform)
            {
                Assert.Ignore();
            }

            string name = @"Local\MonoTestPipeNPNPW";

            using (NamedPipeServerStream server = CreateNamedServer(false, name, null, 0)) {
                PipeSecurity security = server.GetAccessControl();

                AuthorizationRuleCollection rules = security.GetAccessRules(true, false,
                                                                            typeof(SecurityIdentifier));
                Assert.AreNotEqual(0, rules.Count);
            }
        }
        protected NamedPipeServerStream CreateServerPipe(string pipePathIn)
        {
            NamedPipeServerStream newPipe = new NamedPipeServerStream(
                pipePathIn,
                PipeDirection.InOut,
                1,
                PipeTransmissionMode.Byte,
                PipeOptions.Asynchronous,
                0,
                0,
                null,
                HandleInheritability.None,
                PipeAccessRights.ChangePermissions
                );

            if (SimplePipeAccessLevel.Default != this.accessLevel)
            {
                PipeSecurity listenerAccess = newPipe.GetAccessControl();

                switch (this.accessLevel)
                {
                case SimplePipeAccessLevel.AuthenticatedUsers:
                    listenerAccess.AddAccessRule(new PipeAccessRule(
                                                     new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null),
                                                     PipeAccessRights.ReadWrite,
                                                     AccessControlType.Allow
                                                     ));
                    break;

                default:
                    // This shouldn't happen.
                    break;
                }

                // Always allow the owner full control.
                listenerAccess.AddAccessRule(new PipeAccessRule(
                                                 WindowsIdentity.GetCurrent().Owner,
                                                 PipeAccessRights.FullControl,
                                                 AccessControlType.Allow
                                                 ));

                newPipe.SetAccessControl(listenerAccess);
            }

            return(newPipe);
        }
Exemple #12
0
        void NamedPipePermissionsActuallyWorkSync(string name, bool addDenyEveryone)
        {
            if (PlatformID.Win32NT != Environment.OSVersion.Platform)
            {
                Assert.Ignore();
            }

            PipeSecurity       security = new PipeSecurity();
            SecurityIdentifier worldSid = new SecurityIdentifier("WD");
            PipeAccessRule     rule     = new PipeAccessRule(worldSid,
                                                             PipeAccessRights.FullControl,
                                                             AccessControlType.Allow);

            security.AddAccessRule(rule);

            using (NamedPipeServerStream server = CreateNamedServer(false, name, security,
                                                                    PipeAccessRights.ChangePermissions)) {
                security = server.GetAccessControl();

                AuthorizationRuleCollection rules;
                rules = security.GetAccessRules(true, true, typeof(SecurityIdentifier));
                Assert.AreEqual(1, rules.Count);

                rule = (PipeAccessRule)rules [0];
                Assert.AreEqual(AccessControlType.Allow, rule.AccessControlType);
                Assert.AreEqual(worldSid, rule.IdentityReference);
                Assert.AreEqual(PipeAccessRights.FullControl, rule.PipeAccessRights);

                if (addDenyEveryone)
                {
                    AddDenyEveryone(server);
                }

                bool unauthorized = false;
                using (NamedPipeClientStream client = CreateNamedClient(false, name)) {
                    try {
                        client.Connect(1000);
                    } catch (UnauthorizedAccessException) {
                        unauthorized = true;
                    }
                }

                Assert.AreEqual(addDenyEveryone, unauthorized);
            }
        }
Exemple #13
0
        public void SetAccessControl_NamedPipeStream_ClientHandleClosed()
        {
            string pipeName = GetUniquePipeName();
            var    server   = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
            var    client   = new NamedPipeClientStream(".", pipeName, PipeDirection.In, PipeOptions.Asynchronous);

            Task clientConnect = client.ConnectAsync();

            server.WaitForConnection();
            clientConnect.Wait();

            // ServerStream.State = Broken, ClientStream.State = Closed
            client.SafePipeHandle.Close();
            Assert.Throws <IOException>(() => server.Write(new byte[] { 0 }, 0, 1));
            Assert.NotNull(server.GetAccessControl());
            server.SetAccessControl(new PipeSecurity());
            Assert.Throws <ObjectDisposedException>(() => client.GetAccessControl());
            Assert.Throws <ObjectDisposedException>(() => client.SetAccessControl(new PipeSecurity()));
        }
Exemple #14
0
        public void SetAccessControl_NamedPipeStream_ServerDisconnected()
        {
            string pipeName = GetUniquePipeName();
            var    server   = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
            var    client   = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);

            Task clientConnect = client.ConnectAsync();

            server.WaitForConnection();
            clientConnect.Wait();

            // ServerStream.State = Disconnected, ClientStream.State = Broken
            server.Disconnect();
            Assert.Throws <IOException>(() => client.Write(new byte[] { 0 }, 0, 1));
            Assert.NotNull(server.GetAccessControl());
            server.SetAccessControl(new PipeSecurity());
            Assert.Throws <InvalidOperationException>(() => client.GetAccessControl());
            Assert.Throws <IOException>(() => client.SetAccessControl(new PipeSecurity()));
        }
        public void GetAccessControl_NamedPipeServerStream_Broken()
        {
            string pipeName = GetUniquePipeName();
            var server = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
            var client = new NamedPipeClientStream(".", pipeName, PipeDirection.In, PipeOptions.Asynchronous);

            Task clientConnect = client.ConnectAsync();
            server.WaitForConnection();
            clientConnect.Wait();

            Assert.NotNull(server.GetAccessControl());
            server.SetAccessControl(new PipeSecurity());
            Assert.NotNull(client.GetAccessControl());
            client.SetAccessControl(new PipeSecurity());

            client.Dispose();
            Assert.Throws<IOException>(() => server.Write(new byte[] { 0 }, 0, 1)); // Sets the servers PipeState to Broken
            server.SetAccessControl(new PipeSecurity());
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NamedPipeServer"/> class.
        /// </summary>
        /// <param name="pipeName">The name of the named pipe used</param>
        public NamedPipeServer(string pipeName) : base(pipeName)
        {
            _connectionsSemaphore = new object();

            _connections = new List <NamedPipeStreamConnection>();
            // set up security so everyone can write to the pipe.
            using (NamedPipeServerStream seedPipe = new NamedPipeServerStream("seedPipe", PipeDirection.In, 1, PipeTransmissionMode.Message, PipeOptions.None, 1000, 1000))
            {
                // just get a copy of the security roles and close this pipe.
                _pipeSecurity = seedPipe.GetAccessControl();
            }
            var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);

            _pipeSecurity.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.ReadWrite, AccessControlType.Allow));
            // close it for network access.
            sid = new SecurityIdentifier(WellKnownSidType.NetworkSid, null);
            _pipeSecurity.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.ReadWrite, AccessControlType.Deny));

            _connector = CreateNamedPipeServerStream();
            _connector.BeginWaitForConnection(new AsyncCallback(this.ClientConnected), _connector);
        }
        private NamedPipeServerStream CreateAndVerifyNamedPipe(
            string pipeName,
            PipeSecurity expectedSecurity,
            PipeDirection direction               = DefaultPipeDirection,
            int maxNumberOfServerInstances        = DefaultNumberOfServerInstances,
            PipeTransmissionMode transmissionMode = DefaultPipeTransmissionMode,
            PipeOptions options = DefaultPipeOptions,
            int inBufferSize    = DefaultBufferSize,
            int outBufferSize   = DefaultBufferSize,
            HandleInheritability inheritability     = DefaultInheritability,
            PipeAccessRights additionalAccessRights = 0)
        {
            NamedPipeServerStream pipe = CreateNamedPipe(pipeName, expectedSecurity, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, inheritability, additionalAccessRights);

            if (expectedSecurity != null)
            {
                PipeSecurity actualSecurity = pipe.GetAccessControl();
                VerifyPipeSecurity(expectedSecurity, actualSecurity);
            }
            return(pipe);
        }
        public static T GetPipelineStream <T>(string tpc, bool isServer) where T : PipeStream
        {
            T ret = null;

            if (isServer)
            {
                var            pipe       = new NamedPipeServerStream(tpc, PipeDirection.InOut, 200, PipeTransmissionMode.Message);
                PipeSecurity   ps         = pipe.GetAccessControl();
                PipeAccessRule clientRule = new PipeAccessRule(
                    //"Authenticated Users"
                    new SecurityIdentifier(WellKnownSidType.AnonymousSid, null),
                    PipeAccessRights.ReadWrite, AccessControlType.Allow);
                PipeAccessRule ownerRule = new PipeAccessRule(
                    WindowsIdentity.GetCurrent().Owner,
                    PipeAccessRights.FullControl,
                    AccessControlType.Allow);
                ps.AddAccessRule(clientRule);
                ps.AddAccessRule(ownerRule);
                ret = (T)(PipeStream)pipe;
            }
            else
            {
                string ip    = "localhost";
                var    topic = tpc.ToString();
                if (topic.IndexOf("@") >= 0)
                {
                    ip    = topic.Split('@')[0];
                    topic = topic.Split('@')[1];
                }
                NamedPipeClientStream client = new NamedPipeClientStream(ip, topic);
                //var access = client.GetAccessControl();
                //var secIden = new SecurityIdentifier(WellKnownSidType.AnonymousSid, null);
                //access.AddAccessRule(new PipeAccessRule(secIden, PipeAccessRights.ReadWrite, AccessControlType.Allow));
                ret = (T)(PipeStream)client;
            }
            return(ret);
        }
Exemple #19
0
        private async static void Connection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            AppServiceDeferral Deferral = args.GetDeferral();

            try
            {
                switch (args.Request.Message["ExecuteType"])
                {
                case "Execute_GetContextMenuItems":
                {
                    IEnumerable <string> ExecutePath = JsonConvert.DeserializeObject <string[]>(Convert.ToString(args.Request.Message["ExecutePath"]));
                    bool IncludeExtensionItem        = Convert.ToBoolean(args.Request.Message["IncludeExtensionItem"]);

                    List <(string, string, string)> ContextMenuItems = ContextMenu.FetchContextMenuItems(ExecutePath, IncludeExtensionItem);

                    ValueSet Value = new ValueSet
                    {
                        { "Success", JsonConvert.SerializeObject(ContextMenuItems) }
                    };

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_InvokeContextMenuItem":
                {
                    string   Verb  = Convert.ToString(args.Request.Message["InvokeVerb"]);
                    string[] Paths = JsonConvert.DeserializeObject <string[]>(Convert.ToString(args.Request.Message["ExecutePath"]));

                    ValueSet Value = new ValueSet();

                    if (!string.IsNullOrEmpty(Verb) && Paths.Length > 0)
                    {
                        if (ContextMenu.InvokeVerb(Paths, Verb))
                        {
                            Value.Add("Success", string.Empty);
                        }
                        else
                        {
                            Value.Add("Error", $"Execute Verb: {Verb} failed");
                        }
                    }
                    else
                    {
                        Value.Add("Error", "Verb is empty or Paths is empty");
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_ElevateAsAdmin":
                {
                    Connection?.Dispose();
                    Connection = null;

                    using (Process AdminProcess = new Process())
                    {
                        AdminProcess.StartInfo.Verb            = "runas";
                        AdminProcess.StartInfo.UseShellExecute = true;
                        AdminProcess.StartInfo.Arguments       = $"Elevation_Restart {ExplorerProcess?.Id}";
                        AdminProcess.StartInfo.FileName        = Process.GetCurrentProcess().MainModule.FileName;
                        AdminProcess.Start();
                    }

                    ExitLocker.Set();
                    break;
                }

                case "Execute_CreateLink":
                {
                    string LinkPath     = Convert.ToString(args.Request.Message["LinkPath"]);
                    string LinkTarget   = Convert.ToString(args.Request.Message["LinkTarget"]);
                    string LinkDesc     = Convert.ToString(args.Request.Message["LinkDesc"]);
                    string LinkArgument = Convert.ToString(args.Request.Message["LinkArgument"]);

                    ShellLink.Create(LinkPath, LinkTarget, description: LinkDesc, arguments: LinkArgument).Dispose();

                    ValueSet Value = new ValueSet
                    {
                        { "Success", string.Empty }
                    };

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_GetVariable_Path":
                {
                    ValueSet Value = new ValueSet();

                    string Variable = Convert.ToString(args.Request.Message["Variable"]);

                    string Env = Environment.GetEnvironmentVariable(Variable);

                    if (string.IsNullOrEmpty(Env))
                    {
                        Value.Add("Error", "Could not found EnvironmentVariable");
                    }
                    else
                    {
                        Value.Add("Success", Env);
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_Rename":
                {
                    string ExecutePath = Convert.ToString(args.Request.Message["ExecutePath"]);
                    string DesireName  = Convert.ToString(args.Request.Message["DesireName"]);

                    ValueSet Value = new ValueSet();

                    if (File.Exists(ExecutePath) || Directory.Exists(ExecutePath))
                    {
                        if (StorageItemController.CheckOccupied(ExecutePath))
                        {
                            Value.Add("Error_Occupied", "FileLoadException");
                        }
                        else
                        {
                            if (StorageItemController.CheckPermission(FileSystemRights.Modify, Path.GetDirectoryName(ExecutePath)))
                            {
                                if (StorageItemController.Rename(ExecutePath, DesireName))
                                {
                                    Value.Add("Success", string.Empty);
                                }
                                else
                                {
                                    Value.Add("Error_Failure", "Error happened when rename");
                                }
                            }
                            else
                            {
                                Value.Add("Error_Failure", "No Modify Permission");
                            }
                        }
                    }
                    else
                    {
                        Value.Add("Error_NotFound", "FileNotFoundException");
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_GetHyperlinkInfo":
                {
                    string ExecutePath = Convert.ToString(args.Request.Message["ExecutePath"]);

                    ValueSet Value = new ValueSet();

                    if (File.Exists(ExecutePath))
                    {
                        using (ShellLink Link = new ShellLink(ExecutePath))
                        {
                            Value.Add("Success", string.Empty);
                            Value.Add("TargetPath", Link.TargetPath);
                            Value.Add("Argument", Link.Arguments);
                            Value.Add("RunAs", Link.RunAsAdministrator);
                            Value.Add("IsFile", File.Exists(Link.TargetPath));
                        }
                    }
                    else
                    {
                        Value.Add("Error", "File is not exist");
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_Intercept_Win_E":
                {
                    ValueSet Value = new ValueSet();

                    string[] EnvironmentVariables = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User).Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);

                    if (EnvironmentVariables.Where((Var) => Var.Contains("WindowsApps")).Select((Var) => Path.Combine(Var, "RX-Explorer.exe")).FirstOrDefault((Path) => File.Exists(Path)) is string AliasLocation)
                    {
                        StorageFile InterceptFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Intercept_WIN_E.reg"));

                        StorageFile TempFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("Intercept_WIN_E_Temp.reg", CreationCollisionOption.ReplaceExisting);

                        using (Stream FileStream = await InterceptFile.OpenStreamForReadAsync().ConfigureAwait(true))
                            using (StreamReader Reader = new StreamReader(FileStream))
                            {
                                string Content = await Reader.ReadToEndAsync().ConfigureAwait(true);

                                using (Stream TempStream = await TempFile.OpenStreamForWriteAsync())
                                    using (StreamWriter Writer = new StreamWriter(TempStream, Encoding.Unicode))
                                    {
                                        await Writer.WriteAsync(Content.Replace("<FillActualAliasPathInHere>", $"{AliasLocation.Replace(@"\", @"\\")} %1"));
                                    }
                            }

                        using (Process Process = Process.Start(TempFile.Path))
                        {
                            SetWindowsZPosition(Process);
                            Process.WaitForExit();
                        }

                        Value.Add("Success", string.Empty);
                    }
                    else
                    {
                        Value.Add("Error", "Alias file is not exists");
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_Restore_Win_E":
                {
                    StorageFile RestoreFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Restore_WIN_E.reg"));

                    using (Process Process = Process.Start(RestoreFile.Path))
                    {
                        SetWindowsZPosition(Process);
                        Process.WaitForExit();
                    }

                    ValueSet Value = new ValueSet
                    {
                        { "Success", string.Empty }
                    };

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_RemoveHiddenAttribute":
                {
                    string ExecutePath = Convert.ToString(args.Request.Message["ExecutePath"]);

                    if (File.Exists(ExecutePath))
                    {
                        File.SetAttributes(ExecutePath, File.GetAttributes(ExecutePath) & ~FileAttributes.Hidden);
                    }
                    else if (Directory.Exists(ExecutePath))
                    {
                        DirectoryInfo Info = new DirectoryInfo(ExecutePath);
                        Info.Attributes &= ~FileAttributes.Hidden;
                    }

                    ValueSet Value = new ValueSet
                    {
                        { "Success", string.Empty }
                    };

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_RequestCreateNewPipe":
                {
                    string Guid = Convert.ToString(args.Request.Message["Guid"]);

                    if (!PipeServers.ContainsKey(Guid))
                    {
                        NamedPipeServerStream NewPipeServer = new NamedPipeServerStream($@"Explorer_And_FullTrustProcess_NamedPipe-{Guid}", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 2048, 2048, null, HandleInheritability.None, PipeAccessRights.ChangePermissions);

                        PipeSecurity   Security   = NewPipeServer.GetAccessControl();
                        PipeAccessRule ClientRule = new PipeAccessRule(new SecurityIdentifier("S-1-15-2-1"), PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow);
                        PipeAccessRule OwnerRule  = new PipeAccessRule(WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow);
                        Security.AddAccessRule(ClientRule);
                        Security.AddAccessRule(OwnerRule);
                        NewPipeServer.SetAccessControl(Security);

                        PipeServers.Add(Guid, NewPipeServer);

                        _ = NewPipeServer.WaitForConnectionAsync(new CancellationTokenSource(3000).Token).ContinueWith((task) =>
                            {
                                if (PipeServers.TryGetValue(Guid, out NamedPipeServerStream Pipe))
                                {
                                    Pipe.Dispose();
                                    PipeServers.Remove(Guid);
                                }
                            }, TaskContinuationOptions.OnlyOnCanceled);
                    }

                    break;
                }

                case "Identity":
                {
                    ValueSet Value = new ValueSet
                    {
                        { "Identity", "FullTrustProcess" }
                    };

                    if (ExplorerProcess != null)
                    {
                        Value.Add("PreviousExplorerId", ExplorerProcess.Id);
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_Quicklook":
                {
                    string ExecutePath = Convert.ToString(args.Request.Message["ExecutePath"]);

                    if (!string.IsNullOrEmpty(ExecutePath))
                    {
                        QuicklookConnector.SendMessageToQuicklook(ExecutePath);
                    }

                    break;
                }

                case "Execute_Check_QuicklookIsAvaliable":
                {
                    bool IsSuccess = QuicklookConnector.CheckQuicklookIsAvaliable();

                    ValueSet Result = new ValueSet
                    {
                        { "Check_QuicklookIsAvaliable_Result", IsSuccess }
                    };

                    await args.Request.SendResponseAsync(Result);

                    break;
                }

                case "Execute_Get_Associate":
                {
                    string Path      = Convert.ToString(args.Request.Message["ExecutePath"]);
                    string Associate = ExtensionAssociate.GetAssociate(Path);

                    ValueSet Result = new ValueSet
                    {
                        { "Associate_Result", Associate }
                    };

                    await args.Request.SendResponseAsync(Result);

                    break;
                }

                case "Execute_Get_RecycleBinItems":
                {
                    ValueSet Result = new ValueSet();

                    string RecycleItemResult = RecycleBinController.GenerateRecycleItemsByJson();

                    if (string.IsNullOrEmpty(RecycleItemResult))
                    {
                        Result.Add("Error", "Could not get recycle items");
                    }
                    else
                    {
                        Result.Add("RecycleBinItems_Json_Result", RecycleItemResult);
                    }

                    await args.Request.SendResponseAsync(Result);

                    break;
                }

                case "Execute_Empty_RecycleBin":
                {
                    ValueSet Result = new ValueSet
                    {
                        { "RecycleBinItems_Clear_Result", RecycleBinController.EmptyRecycleBin() }
                    };

                    await args.Request.SendResponseAsync(Result);

                    break;
                }

                case "Execute_Restore_RecycleItem":
                {
                    string Path = Convert.ToString(args.Request.Message["ExecutePath"]);

                    ValueSet Result = new ValueSet
                    {
                        { "Restore_Result", RecycleBinController.Restore(Path) }
                    };

                    await args.Request.SendResponseAsync(Result);

                    break;
                }

                case "Execute_Delete_RecycleItem":
                {
                    string Path = Convert.ToString(args.Request.Message["ExecutePath"]);

                    ValueSet Result = new ValueSet
                    {
                        { "Delete_Result", RecycleBinController.Delete(Path) }
                    };

                    await args.Request.SendResponseAsync(Result);

                    break;
                }

                case "Execute_EjectUSB":
                {
                    ValueSet Value = new ValueSet();

                    string Path = Convert.ToString(args.Request.Message["ExecutePath"]);

                    if (string.IsNullOrEmpty(Path))
                    {
                        Value.Add("EjectResult", false);
                    }
                    else
                    {
                        Value.Add("EjectResult", USBController.EjectDevice(Path));
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_Unlock_Occupy":
                {
                    ValueSet Value = new ValueSet();

                    string Path = Convert.ToString(args.Request.Message["ExecutePath"]);

                    if (File.Exists(Path))
                    {
                        if (StorageItemController.CheckOccupied(Path))
                        {
                            if (StorageItemController.TryUnoccupied(Path))
                            {
                                Value.Add("Success", string.Empty);
                            }
                            else
                            {
                                Value.Add("Error_Failure", "Unoccupied failed");
                            }
                        }
                        else
                        {
                            Value.Add("Error_NotOccupy", "The file is not occupied");
                        }
                    }
                    else
                    {
                        Value.Add("Error_NotFoundOrNotFile", "Path is not a file");
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_Copy":
                {
                    ValueSet Value = new ValueSet();

                    string SourcePathJson  = Convert.ToString(args.Request.Message["SourcePath"]);
                    string DestinationPath = Convert.ToString(args.Request.Message["DestinationPath"]);
                    string Guid            = Convert.ToString(args.Request.Message["Guid"]);
                    bool   IsUndo          = Convert.ToBoolean(args.Request.Message["Undo"]);

                    List <KeyValuePair <string, string> > SourcePathList = JsonConvert.DeserializeObject <List <KeyValuePair <string, string> > >(SourcePathJson);
                    List <string> OperationRecordList = new List <string>();

                    int Progress = 0;

                    if (SourcePathList.All((Item) => Directory.Exists(Item.Key) || File.Exists(Item.Key)))
                    {
                        if (StorageItemController.CheckPermission(FileSystemRights.Modify, DestinationPath))
                        {
                            if (StorageItemController.Copy(SourcePathList, DestinationPath, (s, e) =>
                                {
                                    lock (Locker)
                                    {
                                        try
                                        {
                                            Progress = e.ProgressPercentage;

                                            if (PipeServers.TryGetValue(Guid, out NamedPipeServerStream Pipeline))
                                            {
                                                using (StreamWriter Writer = new StreamWriter(Pipeline, new UTF8Encoding(false), 1024, true))
                                                {
                                                    Writer.WriteLine(e.ProgressPercentage);
                                                }
                                            }
                                        }
                                        catch
                                        {
                                            Debug.WriteLine("Could not send progress data");
                                        }
                                    }
                                },
                                                           (se, arg) =>
                                {
                                    if (arg.Result == HRESULT.S_OK && !IsUndo)
                                    {
                                        if (arg.DestItem == null || string.IsNullOrEmpty(arg.Name))
                                        {
                                            OperationRecordList.Add($"{arg.SourceItem.FileSystemPath}||Copy||{(Directory.Exists(arg.SourceItem.FileSystemPath) ? "Folder" : "File")}||{Path.Combine(arg.DestFolder.FileSystemPath, arg.SourceItem.Name)}");
                                        }
                                        else
                                        {
                                            OperationRecordList.Add($"{arg.SourceItem.FileSystemPath}||Copy||{(Directory.Exists(arg.SourceItem.FileSystemPath) ? "Folder" : "File")}||{Path.Combine(arg.DestFolder.FileSystemPath, arg.Name)}");
                                        }
                                    }
                                }))
                            {
                                Value.Add("Success", string.Empty);

                                if (OperationRecordList.Count > 0)
                                {
                                    Value.Add("OperationRecord", JsonConvert.SerializeObject(OperationRecordList));
                                }
                            }
                            else
                            {
                                Value.Add("Error_Failure", "An error occurred while copying the folder");
                            }
                        }
                        else
                        {
                            Value.Add("Error_Failure", "An error occurred while copying the folder");
                        }
                    }
                    else
                    {
                        Value.Add("Error_NotFound", "SourcePath is not a file or directory");
                    }

                    if (Progress < 100)
                    {
                        try
                        {
                            if (PipeServers.TryGetValue(Guid, out NamedPipeServerStream Pipeline))
                            {
                                using (StreamWriter Writer = new StreamWriter(Pipeline, new UTF8Encoding(false), 1024, true))
                                {
                                    Writer.WriteLine("Error_Stop_Signal");
                                }
                            }
                        }
                        catch
                        {
                            Debug.WriteLine("Could not send stop signal");
                        }
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_Move":
                {
                    ValueSet Value = new ValueSet();

                    string SourcePathJson  = Convert.ToString(args.Request.Message["SourcePath"]);
                    string DestinationPath = Convert.ToString(args.Request.Message["DestinationPath"]);
                    string Guid            = Convert.ToString(args.Request.Message["Guid"]);
                    bool   IsUndo          = Convert.ToBoolean(args.Request.Message["Undo"]);

                    List <KeyValuePair <string, string> > SourcePathList = JsonConvert.DeserializeObject <List <KeyValuePair <string, string> > >(SourcePathJson);
                    List <string> OperationRecordList = new List <string>();

                    int Progress = 0;

                    if (SourcePathList.All((Item) => Directory.Exists(Item.Key) || File.Exists(Item.Key)))
                    {
                        if (SourcePathList.Any((Item) => StorageItemController.CheckOccupied(Item.Key)))
                        {
                            Value.Add("Error_Capture", "An error occurred while moving the folder");
                        }
                        else
                        {
                            if (StorageItemController.CheckPermission(FileSystemRights.Modify, DestinationPath))
                            {
                                if (StorageItemController.Move(SourcePathList, DestinationPath, (s, e) =>
                                    {
                                        lock (Locker)
                                        {
                                            try
                                            {
                                                Progress = e.ProgressPercentage;

                                                if (PipeServers.TryGetValue(Guid, out NamedPipeServerStream Pipeline))
                                                {
                                                    using (StreamWriter Writer = new StreamWriter(Pipeline, new UTF8Encoding(false), 1024, true))
                                                    {
                                                        Writer.WriteLine(e.ProgressPercentage);
                                                    }
                                                }
                                            }
                                            catch
                                            {
                                                Debug.WriteLine("Could not send progress data");
                                            }
                                        }
                                    },
                                                               (se, arg) =>
                                    {
                                        if (arg.Result == HRESULT.COPYENGINE_S_DONT_PROCESS_CHILDREN && !IsUndo)
                                        {
                                            if (arg.DestItem == null || string.IsNullOrEmpty(arg.Name))
                                            {
                                                OperationRecordList.Add($"{arg.SourceItem.FileSystemPath}||Move||{(Directory.Exists(arg.SourceItem.FileSystemPath) ? "Folder" : "File")}||{Path.Combine(arg.DestFolder.FileSystemPath, arg.SourceItem.Name)}");
                                            }
                                            else
                                            {
                                                OperationRecordList.Add($"{arg.SourceItem.FileSystemPath}||Move||{(Directory.Exists(arg.SourceItem.FileSystemPath) ? "Folder" : "File")}||{Path.Combine(arg.DestFolder.FileSystemPath, arg.Name)}");
                                            }
                                        }
                                    }))
                                {
                                    Value.Add("Success", string.Empty);
                                    if (OperationRecordList.Count > 0)
                                    {
                                        Value.Add("OperationRecord", JsonConvert.SerializeObject(OperationRecordList));
                                    }
                                }
                                else
                                {
                                    Value.Add("Error_Failure", "An error occurred while moving the folder");
                                }
                            }
                            else
                            {
                                Value.Add("Error_Failure", "An error occurred while moving the folder");
                            }
                        }
                    }
                    else
                    {
                        Value.Add("Error_NotFound", "SourcePath is not a file or directory");
                    }

                    if (Progress < 100)
                    {
                        try
                        {
                            if (PipeServers.TryGetValue(Guid, out NamedPipeServerStream Pipeline))
                            {
                                using (StreamWriter Writer = new StreamWriter(Pipeline, new UTF8Encoding(false), 1024, true))
                                {
                                    Writer.WriteLine("Error_Stop_Signal");
                                }
                            }
                        }
                        catch
                        {
                            Debug.WriteLine("Could not send progress data");
                        }
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_Delete":
                {
                    ValueSet Value = new ValueSet();

                    string ExecutePathJson = Convert.ToString(args.Request.Message["ExecutePath"]);
                    string Guid            = Convert.ToString(args.Request.Message["Guid"]);
                    bool   PermanentDelete = Convert.ToBoolean(args.Request.Message["PermanentDelete"]);
                    bool   IsUndo          = Convert.ToBoolean(args.Request.Message["Undo"]);

                    List <string> ExecutePathList     = JsonConvert.DeserializeObject <List <string> >(ExecutePathJson);
                    List <string> OperationRecordList = new List <string>();

                    int Progress = 0;

                    try
                    {
                        if (ExecutePathList.All((Item) => Directory.Exists(Item) || File.Exists(Item)))
                        {
                            if (ExecutePathList.Any((Item) => StorageItemController.CheckOccupied(Item)))
                            {
                                Value.Add("Error_Capture", "An error occurred while deleting the folder");
                            }
                            else
                            {
                                if (ExecutePathList.All((Path) => (Directory.Exists(Path) || File.Exists(Path)) && StorageItemController.CheckPermission(FileSystemRights.Modify, System.IO.Path.GetDirectoryName(Path))))
                                {
                                    if (StorageItemController.Delete(ExecutePathList, PermanentDelete, (s, e) =>
                                        {
                                            lock (Locker)
                                            {
                                                try
                                                {
                                                    Progress = e.ProgressPercentage;

                                                    if (PipeServers.TryGetValue(Guid, out NamedPipeServerStream Pipeline))
                                                    {
                                                        using (StreamWriter Writer = new StreamWriter(Pipeline, new UTF8Encoding(false), 1024, true))
                                                        {
                                                            Writer.WriteLine(e.ProgressPercentage);
                                                        }
                                                    }
                                                }
                                                catch
                                                {
                                                    Debug.WriteLine("Could not send progress data");
                                                }
                                            }
                                        },
                                                                     (se, arg) =>
                                        {
                                            if (!PermanentDelete && !IsUndo)
                                            {
                                                OperationRecordList.Add($"{arg.SourceItem.FileSystemPath}||Delete");
                                            }
                                        }))
                                    {
                                        Value.Add("Success", string.Empty);

                                        if (OperationRecordList.Count > 0)
                                        {
                                            Value.Add("OperationRecord", JsonConvert.SerializeObject(OperationRecordList));
                                        }
                                    }
                                    else
                                    {
                                        Value.Add("Error_Failure", "The specified file could not be deleted");
                                    }
                                }
                                else
                                {
                                    Value.Add("Error_Failure", "The specified file could not be deleted");
                                }
                            }
                        }
                        else
                        {
                            Value.Add("Error_NotFound", "ExecutePath is not a file or directory");
                        }
                    }
                    catch
                    {
                        Value.Add("Error_Failure", "The specified file or folder could not be deleted");
                    }

                    if (Progress < 100)
                    {
                        try
                        {
                            if (PipeServers.TryGetValue(Guid, out NamedPipeServerStream Pipeline))
                            {
                                using (StreamWriter Writer = new StreamWriter(Pipeline, new UTF8Encoding(false), 1024, true))
                                {
                                    Writer.WriteLine("Error_Stop_Signal");
                                }
                            }
                        }
                        catch
                        {
                            Debug.WriteLine("Could not send stop signal");
                        }
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_RunExe":
                {
                    string ExecutePath           = Convert.ToString(args.Request.Message["ExecutePath"]);
                    string ExecuteParameter      = Convert.ToString(args.Request.Message["ExecuteParameter"]);
                    string ExecuteAuthority      = Convert.ToString(args.Request.Message["ExecuteAuthority"]);
                    bool   ExecuteCreateNoWindow = Convert.ToBoolean(args.Request.Message["ExecuteCreateNoWindow"]);

                    ValueSet Value = new ValueSet();

                    if (!string.IsNullOrEmpty(ExecutePath))
                    {
                        if (StorageItemController.CheckPermission(FileSystemRights.ReadAndExecute, ExecutePath))
                        {
                            if (string.IsNullOrEmpty(ExecuteParameter))
                            {
                                using (Process Process = new Process())
                                {
                                    Process.StartInfo.FileName         = ExecutePath;
                                    Process.StartInfo.UseShellExecute  = true;
                                    Process.StartInfo.CreateNoWindow   = ExecuteCreateNoWindow;
                                    Process.StartInfo.WorkingDirectory = Path.GetDirectoryName(ExecutePath);

                                    if (ExecuteAuthority == "Administrator")
                                    {
                                        Process.StartInfo.Verb = "runAs";
                                    }

                                    Process.Start();

                                    SetWindowsZPosition(Process);
                                }
                            }
                            else
                            {
                                using (Process Process = new Process())
                                {
                                    Process.StartInfo.FileName         = ExecutePath;
                                    Process.StartInfo.Arguments        = ExecuteParameter;
                                    Process.StartInfo.UseShellExecute  = true;
                                    Process.StartInfo.CreateNoWindow   = ExecuteCreateNoWindow;
                                    Process.StartInfo.WorkingDirectory = Path.GetDirectoryName(ExecutePath);

                                    if (ExecuteAuthority == "Administrator")
                                    {
                                        Process.StartInfo.Verb = "runAs";
                                    }

                                    Process.Start();

                                    SetWindowsZPosition(Process);
                                }
                            }

                            Value.Add("Success", string.Empty);
                        }
                        else
                        {
                            Value.Add("Error_Failure", "The specified file could not be executed");
                        }
                    }
                    else
                    {
                        Value.Add("Success", string.Empty);
                    }

                    await args.Request.SendResponseAsync(Value);

                    break;
                }

                case "Execute_Test_Connection":
                {
                    try
                    {
                        if (args.Request.Message.TryGetValue("ProcessId", out object Obj) && Obj is int Id && ExplorerProcess?.Id != Id)
                        {
                            ExplorerProcess?.Dispose();
                            ExplorerProcess = Process.GetProcessById(Id);
                        }
                    }
                    catch
                    {
                        Debug.WriteLine("GetProcess from id and register Exit event failed");
                    }

                    await args.Request.SendResponseAsync(new ValueSet { { "Execute_Test_Connection", string.Empty } });

                    break;
                }

                case "Execute_Exit":
                {
                    ExitLocker.Set();
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                ValueSet Value = new ValueSet
                {
                    { "Error", ex.Message }
                };

                await args.Request.SendResponseAsync(Value);
            }
            finally
            {
                Deferral.Complete();
            }
        }
Exemple #20
0
        public PipeServer(string eventName, string pipeName, Func <uint, byte[], Tuple <ErrCode, byte[], uint> > cmdProc)
        {
            var    eventConnect = new EventWaitHandle(false, EventResetMode.AutoReset, eventName);
            string trustee      = "NT Service\\EpgTimer Service";

            try
            {
                // "EpgTimer Service"のサービスセキュリティ識別子(Service-specific SID)に対するアクセス許可を追加する
                EventWaitHandleSecurity sec = eventConnect.GetAccessControl();
                sec.AddAccessRule(new EventWaitHandleAccessRule(trustee, EventWaitHandleRights.Synchronize, AccessControlType.Allow));
                eventConnect.SetAccessControl(sec);
            }
            catch
            {
                trustee = null;
            }
            var pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 1024, 1024,
                                                 null, System.IO.HandleInheritability.None, trustee == null ? 0 : PipeAccessRights.ChangePermissions);

            if (trustee != null)
            {
                try
                {
                    PipeSecurity sec = pipe.GetAccessControl();
                    sec.AddAccessRule(new PipeAccessRule(trustee, PipeAccessRights.ReadWrite, AccessControlType.Allow));
                    pipe.SetAccessControl(sec);
                }
                catch
                {
                }
            }

            m_ServerThread = new Thread(new ThreadStart(() =>
            {
                using (eventConnect)
                    using (pipe)
                    {
                        for (;;)
                        {
                            IAsyncResult ar = pipe.BeginWaitForConnection(null, null);
                            eventConnect.Set();
                            using (ar.AsyncWaitHandle)
                            {
                                if (WaitHandle.WaitAny(new WaitHandle[] { m_StopEvent, ar.AsyncWaitHandle }) != 1)
                                {
                                    pipe.Dispose();
                                    ar.AsyncWaitHandle.WaitOne();
                                    break;
                                }
                                pipe.EndWaitForConnection(ar);
                            }
                            if (pipe.IsConnected)
                            {
                                byte[] bHead = new byte[8];
                                if (ReadAll(pipe, bHead, 0, 8) == 8)
                                {
                                    uint cmdParam  = BitConverter.ToUInt32(bHead, 0);
                                    byte[] cmdData = new byte[BitConverter.ToUInt32(bHead, 4)];
                                    if (ReadAll(pipe, cmdData, 0, cmdData.Length) == cmdData.Length)
                                    {
                                        Tuple <ErrCode, byte[], uint> res = cmdProc.Invoke(cmdParam, cmdData);
                                        BitConverter.GetBytes((uint)res.Item1).CopyTo(bHead, 0);
                                        BitConverter.GetBytes(res.Item2 == null ? 0 : res.Item2.Length).CopyTo(bHead, 4);
                                        pipe.Write(bHead, 0, 8);
                                        if (res.Item2 != null && res.Item2.Length > 0)
                                        {
                                            pipe.Write(res.Item2, 0, res.Item2.Length);
                                        }
                                    }
                                }
                                pipe.WaitForPipeDrain();
                                pipe.Disconnect();
                            }
                        }
                    }
            }));
            m_ServerThread.Start();
        }