父子进程和匿名管道通信的问题
父进程使用createprocessAsUser启动c:\windows\system32\tracert.exe,冲定向子进程的标准输出到管道,但是为什么父进程里得不到子进程的输出呢?
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.IO;
using Microsoft.Win32.SafeHandles;
//using System.Windows.Forms;
[assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode = true)]
[assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")]
public class ImpersonationDemo
{
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
//[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
//private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource,
// int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* Arguments);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public extern static bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment,
String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess,
ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType,
int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool CreatePipe(out IntPtr readHandle, out IntPtr writeHandle, ref SECURITY_ATTRIBUTES sa, int nSize);
[DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
public static extern Int32 WaitForSingleObject(IntPtr handle, uint milliseconds);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern unsafe Int32 PeekNamedPipe(
IntPtr hNamedPipe,
void* lpBuffer,
uint nBufferSize,
int* lpBytesRead,
int* lpTotalBytesAvail,
int* lpBytesLeftThisMessage
);
[DllImport("kernel32", SetLastError = true)]
static extern unsafe bool ReadFile(
IntPtr hFile, // handle to file
void* pBuffer, // data buffer
int NumberOfBytesToRead, // number of bytes to read
int* pNumberOfBytesRead, // number of bytes read
int Overlapped // overlapped buffer
);
[DllImport("kernel32", SetLastError = true)]
static extern unsafe bool WriteFile(
IntPtr hFile, // handle to file
void* pBuffer, // data buffer
int nNumberOfBytesToWrite, // number of bytes to read
int* lpNumberOfBytesWritten, // number of bytes read
int Overlapped // overlapped buffer
);
[DllImport("Kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(
int nStdHandle
);
[DllImport("Kernel32.dll", SetLastError = true)]
static extern bool SetStdHandle(
int nStdHandle,
IntPtr hHandle
);
[DllImport("Kernel32.dll", SetLastError = true)]
static extern void GetStartupInfo(
ref STARTUPINFO lpStartupInfo
);
public struct SECURITY_ATTRIBUTES
{
public long nLength;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public long dwProcessId;
public long dwThreadId;
}
public struct STARTUPINFO
{
public long cb; //Size of the structure, in bytes.
public string lpReserved; //Reserved. Set this member to NULL before passing the structure to CreateProcess.
public string lpDesktop; //Pointer to a null-terminated string that specifies either the name of the desktop, or the name of both the desktop and window station for this process. A backslash in the string indicates that the string includes both the desktop and window station names.
public string lpTitle; //For console processes, this is the title displayed in the title bar if a new console window is created. If NULL, the name of the executable file is used as the window title instead. This parameter must be NULL for GUI or console processes that do not create a new console window.
public long dwX; //
public long dwY;
public long dwXSize;
public long dwYSize;
public long dwXCountChars;
public long dwYCountChars;
public long dwFillAttribute;
public long dwFlags;
public long wShowWindow;
public long cbReserved2;
public byte lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
public static uint INFINITE = 0xFFFFFFFF;
const uint STARTF_USESHOWWINDOW=0x00000001;
const uint STARTF_USESIZE=0x00000002;
const uint STARTF_USEPOSITION=0x00000004;
const uint STARTF_USECOUNTCHARS=0x00000008;
const uint STARTF_USEFILLATTRIBUTE= 0x00000010;
const uint STARTF_RUNFULLSCREEN=0x00000020 ; // ignored for non-x86 platforms
const uint STARTF_FORCEONFEEDBACK=0x00000040;
const uint STARTF_FORCEOFFFEEDBACK=0x00000080;
const uint STARTF_USESTDHANDLES=0x00000100;
const uint SW_HIDE=0;
const uint SW_SHOWNORMAL=1;
const uint SW_NORMAL=1;
const uint SW_SHOWMINIMIZED=2;
const uint SW_SHOWMAXIMIZED=3;
const uint SW_MAXIMIZE=3;
const uint SW_SHOWNOACTIVATE=4;
const uint SW_SHOW=5;
const uint SW_MINIMIZE=6;
const uint SW_SHOWMINNOACTIVE=7;
const uint SW_SHOWNA=8;
const uint SW_RESTORE=9;
const uint SW_SHOWDEFAULT=10;
const uint SW_FORCEMINIMIZE=11;
const uint SW_MAX = 11;
const int STD_INPUT_HANDLE=-10;
const int STD_OUTPUT_HANDLE=-11;
const int STD_ERROR_HANDLE = -12;
public static unsafe int Read(IntPtr handle, byte[] buffer, int index, int count)
{
int n = 0;
fixed (byte* p = buffer)
{
if (!ReadFile(handle, p + index, count, &n, 0))
return 0;
}
return n;
}