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); } }
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); }
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())); }
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())); }
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; } } }
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); }
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()); }
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); }
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); } }
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())); }
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); }
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(); } }
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(); }