internal static SECURITY_ATTRIBUTES GetSecurityAttributes(GCHandle securityDescriptorPinnedHandle, bool inheritHandle = false) { SECURITY_ATTRIBUTES securityAttributes = new NamedPipeNative.SECURITY_ATTRIBUTES(); securityAttributes.InheritHandle = inheritHandle; securityAttributes.NLength = (int)Marshal.SizeOf(securityAttributes); securityAttributes.LPSecurityDescriptor = securityDescriptorPinnedHandle.AddrOfPinnedObject(); return(securityAttributes); }
/// <summary> /// Helper method to create a PowerShell transport named pipe via native API, along /// with a returned .Net NamedPipeServerStream object wrapping the named pipe. /// </summary> /// <param name="pipeName">Named pipe core name.</param> /// <param name="securityDesc"></param> /// <returns>NamedPipeServerStream</returns> internal static NamedPipeServerStream CreateNamedPipe( string serverName, string namespaceName, string pipeName, PipeSecurity pipeSecurity) { if (serverName == null) { throw new ArgumentNullException("serverName"); } if (namespaceName == null) { throw new ArgumentNullException("namespaceName"); } if (pipeName == null) { throw new ArgumentNullException("pipeName"); } string fullPipeName = @"\\" + serverName + @"\" + namespaceName + @"\" + pipeName; CommonSecurityDescriptor securityDesc = new CommonSecurityDescriptor(false, false, pipeSecurity.GetSecurityDescriptorBinaryForm(), 0); // Create optional security attributes based on provided PipeSecurity. NamedPipeNative.SECURITY_ATTRIBUTES securityAttributes = null; GCHandle?securityDescHandle = null; if (securityDesc != null) { byte[] securityDescBuffer = new byte[securityDesc.BinaryLength]; securityDesc.GetBinaryForm(securityDescBuffer, 0); securityDescHandle = GCHandle.Alloc(securityDescBuffer, GCHandleType.Pinned); securityAttributes = NamedPipeNative.GetSecurityAttributes(securityDescHandle.Value); } if (!NamedPipeNative.WaitNamedPipe(fullPipeName, System.Threading.Timeout.Infinite)) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != ERROR_FILE_NOT_FOUND) { throw new InvalidOperationException(); } } // Create named pipe. SafePipeHandle pipeHandle = NamedPipeNative.CreateNamedPipe( fullPipeName, NamedPipeNative.PIPE_ACCESS_DUPLEX | NamedPipeNative.FILE_FLAG_OVERLAPPED, NamedPipeNative.PIPE_TYPE_BYTE | NamedPipeNative.PIPE_READMODE_BYTE, 255, 65536, 65536, 0, securityAttributes); int lastError = Marshal.GetLastWin32Error(); if (securityDescHandle != null) { securityDescHandle.Value.Free(); } if (pipeHandle.IsInvalid) { throw new InvalidOperationException(); } // Create the .Net NamedPipeServerStream wrapper. try { return(new NamedPipeServerStream( PipeDirection.InOut, true, // IsAsync true, // IsConnected pipeHandle)); } catch (Exception) { pipeHandle.Dispose(); throw; } }