2

Context: I wrote a non-elevated WinForms app, from which I want to allow the user to query the file system using NTFS' MFT (Master File Table) because it's so damn fast! However, starting with Windows 8 or 10 or 1809 or something or other, querying the MFT requires process elevation, and I don't want to run my app elevated. So I plan to build another executable, running elevated, to query the MFT. If I do that, then I need to use inter-process communication (IPC). Seems like named pipes is simple enough (and safe?).

The challenge: I wrote a test program that uses .NET's NamedPipeServerStream and NamedPipeClientStream classes to do some IPC. When client and server processes run either both elevated or both unelevated, they can communicate using the pipe. However, if one is elevated and the other isn't, then the client throws a System.UnauthorizedAccessException exception when trying to connect to the server. I kind of expected that.

My question: Is it a simple matter of constructing the server and client pipe objects with a carefully-crafted System.IO.Pipes.PipeSecurity object? If so, please help me to craft that object, both for the client and the server.

Ouroborus
  • 16,237
  • 4
  • 39
  • 62
Craig Silver
  • 587
  • 4
  • 25

1 Answers1

2

Below is what I got working, with the first two lines being the relevant ones and the rest just to demonstrate its use.

var ps = new PipeSecurity();
ps.AddAccessRule(new PipeAccessRule(Environment.UserName, PipeAccessRights.ReadWrite, AccessControlType.Allow));

using(var pipe = new NamedPipeServerStream(
        pipeName: PipeName, 
        direction: PipeDirection.InOut, 
        maxNumberOfServerInstances: 1, 
        options: PipeOptions.None,
        transmissionMode: PipeTransmissionMode.Byte, 
        inBufferSize: 1024, 
        outBufferSize: 1024, 
        pipeSecurity: ps))
{
    ...
}
Craig Silver
  • 587
  • 4
  • 25