/*********************************************************************** * * Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, Novell, Inc. * * To contact Novell about this file by physical or electronic mail, * you may find current contact information at www.novell.com. * ***********************************************************************/ using System; using System.Text; using System.Security; using System.Runtime.InteropServices; namespace AppModule.NamedPipes { #region Comments /// <summary> /// This utility class exposes kernel32.dll methods for named pipes communication. /// </summary> /// <remarks> /// Use the following links for complete information about the exposed methods: /// <list type="bullet"> /// <item> /// <description><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ipc/base/pipe_functions.asp" target="_blank">Named Pipe Functions</a></description> /// </item> /// <item> /// <description><a href="http://msdn.microsoft.com/library/en-us/fileio/base/file_management_functions.asp" target="_blank">File Management Functions</a></description> /// </item> /// <item> /// <description><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/handle_and_object_functions.asp" target="_blank">Handle and Object Functions</a></description> /// </item> /// <item> /// <description><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp" target="_blank">System Error Codes</a></description> /// </item> /// </list> /// </remarks> #endregion [SuppressUnmanagedCodeSecurity] public sealed class ImpersonateNative { #region Comments /// <summary> /// /// </summary> #endregion public const int TOKEN_QUERY = 0X00000008; public enum TOKEN_INFORMATION_CLASS { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId } [StructLayout(LayoutKind.Sequential)] public struct TOKEN_USER { public _SID_AND_ATTRIBUTES User; } [StructLayout(LayoutKind.Sequential)] public struct _SID_AND_ATTRIBUTES { public IntPtr Sid; public int Attributes; } [StructLayout(LayoutKind.Sequential)] public struct _LUID { public int LowPart ; public int HighPart; } //LUID, *PLUID; [StructLayout(LayoutKind.Sequential)] public struct TOKEN_STATISTICS { public _LUID TokenId; public _LUID AuthenticationId; public int ExpirationTime; public int TokenType; // enum ini in 1 TOKEN_TYPE public int ImpersonationLevel; //SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; public int DynamicCharged; ////DWORD public int DynamicAvailable; //DWORD public int GroupCount; //DWORD public int PrivilegeCount; //DWORD public _LUID ModifiedId; }// TOKEN_STATISTICS, *PTOKEN_STATISTICS; #region Comments /// <summary> /// Creates an instance of a named pipe and returns a handle for /// subsequent pipe operations. /// </summary> /// <param name="lpName">Pointer to the null-terminated string that /// uniquely identifies the pipe.</param> /// <param name="dwOpenMode">Pipe access mode, the overlapped mode, /// the write-through mode, and the security access mode of the pipe handle.</param> /// <param name="dwPipeMode">Type, read, and wait modes of the pipe handle.</param> /// <param name="nMaxInstances">Maximum number of instances that can be /// created for this pipe.</param> /// <param name="nOutBufferSize">Number of bytes to reserve for the output buffer.</param> /// <param name="nInBufferSize">Number of bytes to reserve for the input buffer.</param> /// <param name="nDefaultTimeOut">Default time-out value, in milliseconds.</param> /// <param name="pipeSecurityDescriptor">Pointer to a /// <see cref="AppModule.NamedPipes.SecurityAttributes">SecurityAttributes</see> /// object that specifies a security descriptor for the new named pipe.</param> /// <returns>If the function succeeds, the return value is a handle /// to the server end of a named pipe instance.</returns> #endregion [DllImport("kernel32.dll")] public static extern IntPtr CreateNamedPipe( String lpName, // pipe name uint dwOpenMode, // pipe open mode uint dwPipeMode, // pipe-specific modes uint nMaxInstances, // maximum number of instances uint nOutBufferSize, // output buffer size uint nInBufferSize, // input buffer size uint nDefaultTimeOut, // time-out interval IntPtr pipeSecurityDescriptor // SD ); #region Comments /// <summary> /// Enables a named pipe server process to wait for a client /// process to connect to an instance of a named pipe. /// </summary> /// <param name="hHandle">Handle to the server end of a named pipe instance.</param> /// <param name="lpOverlapped">Pointer to an /// <see cref="AppModule.NamedPipes.Overlapped">Overlapped</see> object.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool ConnectNamedPipe( IntPtr hHandle, // handle to named pipe Overlapped lpOverlapped // overlapped structure ); #region Comments /// <summary> /// Connects to a message-type pipe (and waits if an instance of the /// pipe is not available), writes to and reads from the pipe, and then closes the pipe. /// </summary> /// <param name="lpNamedPipeName">Pointer to a null-terminated string /// specifying the pipe name.</param> /// <param name="lpInBuffer">Pointer to the buffer containing the data written /// to the pipe.</param> /// <param name="nInBufferSize">Size of the write buffer, in bytes.</param> /// <param name="lpOutBuffer">Pointer to the buffer that receives the data /// read from the pipe.</param> /// <param name="nOutBufferSize">Size of the read buffer, in bytes.</param> /// <param name="lpBytesRead">Pointer to a variable that receives the number /// of bytes read from the pipe.</param> /// <param name="nTimeOut">Number of milliseconds to wait for the /// named pipe to be available.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool CallNamedPipe( string lpNamedPipeName, byte[] lpInBuffer, uint nInBufferSize, byte[] lpOutBuffer, uint nOutBufferSize, byte[] lpBytesRead, int nTimeOut ); #region Comments /// <summary> /// Creates or opens a file, directory, physical disk, volume, console buffer, /// tape drive, communications resource, mailslot, or named pipe. /// </summary> /// <param name="lpFileName">Pointer to a null-terminated string that /// specifies the name of the object to create or open.</param> /// <param name="dwDesiredAccess">Access to the object (reading, writing, or both).</param> /// <param name="dwShareMode">Sharing mode of the object (reading, writing, both, or neither).</param> /// <param name="attr">Pointer to a /// <see cref="AppModule.NamedPipes.SecurityAttributes">SecurityAttributes</see> /// object that determines whether the returned handle can be inherited /// by child processes.</param> /// <param name="dwCreationDisposition">Action to take on files that exist, /// and which action to take when files do not exist.</param> /// <param name="dwFlagsAndAttributes">File attributes and flags.</param> /// <param name="hTemplateFile">Handle to a template file, with the GENERIC_READ access right.</param> /// <returns>If the function succeeds, the return value is an open handle to the specified file.</returns> #endregion [DllImport("kernel32.dll")] public static extern IntPtr CreateFile( String lpFileName, // file name uint dwDesiredAccess, // access mode uint dwShareMode, // share mode SecurityAttributes attr, // SD uint dwCreationDisposition, // how to create uint dwFlagsAndAttributes, // file attributes uint hTemplateFile); // handle to template file #region Comments /// <summary> /// Reads data from a file, starting at the position indicated by the file pointer. /// </summary> /// <param name="hHandle">Handle to the file to be read.</param> /// <param name="lpBuffer">Pointer to the buffer that receives the data read from the file.</param> /// <param name="nNumberOfBytesToRead">Number of bytes to be read from the file.</param> /// <param name="lpNumberOfBytesRead">Pointer to the variable that receives the number of bytes read.</param> /// <param name="lpOverlapped">Pointer to an /// <see cref="AppModule.NamedPipes.Overlapped">Overlapped</see> object.</param> /// <returns>The ReadFile function returns when one of the following /// conditions is met: a write operation completes on the write end of /// the pipe, the number of bytes requested has been read, or an error occurs.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool ReadFile( IntPtr hHandle, // handle to file byte[] lpBuffer, // data buffer uint nNumberOfBytesToRead, // number of bytes to read byte[] lpNumberOfBytesRead, // number of bytes read uint lpOverlapped // overlapped buffer ); #region Comments /// <summary> /// Writes data to a file at the position specified by the file pointer. /// </summary> /// <param name="hHandle">Handle to the file.</param> /// <param name="lpBuffer">Pointer to the buffer containing the data to be written to the file.</param> /// <param name="nNumberOfBytesToWrite"></param> /// <param name="lpNumberOfBytesWritten">Pointer to the variable that receives the number of bytes written.</param> /// <param name="lpOverlapped">Pointer to an /// <see cref="AppModule.NamedPipes.Overlapped">Overlapped</see> object.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool WriteFile( IntPtr hHandle, // handle to file byte[] lpBuffer, // data buffer uint nNumberOfBytesToWrite, // number of bytes to write byte[] lpNumberOfBytesWritten, // number of bytes written uint lpOverlapped // overlapped buffer ); #region Comments /// <summary> /// Retrieves information about a specified named pipe. /// </summary> /// <param name="hHandle">Handle to the named pipe for which information is wanted.</param> /// <param name="lpState">Pointer to a variable that indicates the current /// state of the handle.</param> /// <param name="lpCurInstances">Pointer to a variable that receives the /// number of current pipe instances.</param> /// <param name="lpMaxCollectionCount">Pointer to a variable that receives /// the maximum number of bytes to be collected on the client's computer /// before transmission to the server.</param> /// <param name="lpCollectDataTimeout">Pointer to a variable that receives /// the maximum time, in milliseconds, that can pass before a remote named /// pipe transfers information over the network.</param> /// <param name="lpUserName">Pointer to a buffer that receives the /// null-terminated string containing the user name string associated /// with the client application. </param> /// <param name="nMaxUserNameSize">Size of the buffer specified by the /// lpUserName parameter.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool GetNamedPipeHandleState( IntPtr hHandle, IntPtr lpState, ref uint lpCurInstances, IntPtr lpMaxCollectionCount, IntPtr lpCollectDataTimeout, IntPtr lpUserName, IntPtr nMaxUserNameSize ); #region Comments /// <summary> /// Cancels all pending input and output (I/O) operations that were /// issued by the calling thread for the specified file handle. /// </summary> /// <param name="hHandle">Handle to a file.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool CancelIo( IntPtr hHandle ); #region Comments /// <summary> /// Waits until either a time-out interval elapses or an instance /// of the specified named pipe is available for connection. /// </summary> /// <param name="name">Pointer to a null-terminated string that specifies /// the name of the named pipe.</param> /// <param name="timeout">Number of milliseconds that the function will /// wait for an instance of the named pipe to be available.</param> /// <returns>If an instance of the pipe is available before the /// time-out interval elapses, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool WaitNamedPipe( String name, int timeout); #region Comments /// <summary> /// Retrieves the calling thread's last-error code value. /// </summary> /// <returns>The return value is the calling thread's last-error code value.</returns> #endregion [DllImport("kernel32.dll")] public static extern uint GetLastError(); #region Comments /// <summary> /// Flushes the buffers of the specified file and causes all buffered data to be written to the file. /// </summary> /// <param name="hHandle">Handle to an open file.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool FlushFileBuffers( IntPtr hHandle); #region Comments /// <summary> /// Disconnects the server end of a named pipe instance from a client process. /// </summary> /// <param name="hHandle">Handle to an instance of a named pipe.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool DisconnectNamedPipe( IntPtr hHandle); #region Comments /// <summary> /// Sets the read mode and the blocking mode of the specified named pipe. /// </summary> /// <remarks> /// If the specified handle is to the client end of a named pipe and if /// the named pipe server process is on a remote computer, the function /// can also be used to control local buffering. /// </remarks> /// <param name="hHandle">Handle to the named pipe instance.</param> /// <param name="mode">Pointer to a variable that supplies the new mode.</param> /// <param name="cc">Pointer to a variable that specifies the maximum /// number of bytes collected on the client computer before /// transmission to the server.</param> /// <param name="cd">Pointer to a variable that specifies the /// maximum time, in milliseconds, that can pass before a remote /// named pipe transfers information over the network.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool SetNamedPipeHandleState( IntPtr hHandle, ref uint mode, IntPtr cc, IntPtr cd); #region Comments /// <summary> /// Closes an open object handle. /// </summary> /// <param name="hHandle">Handle to an open object.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("kernel32.dll")] public static extern bool CloseHandle( IntPtr hHandle); [DllImport("kernel32.dll")] public static extern IntPtr GetCurrentThread(); // native for named pipes #region Comments /// <summary> /// Closes an open object handle. /// </summary> /// <param name="hHandle">Handle to an open object.</param> /// <returns>If the function succeeds, the return value is nonzero.</returns> #endregion [DllImport("advapi32" )] public static extern int ImpersonateNamedPipeClient( IntPtr hHandle); [DllImport("advapi32" )] public static extern bool RevertToSelf(); [DllImport("advapi32", SetLastError=true)] public static extern bool OpenThreadToken( IntPtr hThread, uint desiredInfo, bool openAsSelf, out IntPtr TokenHandle); // handle to open access token [DllImport("advapi32")] public static extern bool OpenProcessToken( IntPtr ProcessHandle, // handle to process int DesiredAccess, // desired access to process ref IntPtr TokenHandle // handle to open access token ); [DllImport("advapi32", CharSet=CharSet.Auto)] public static extern bool GetTokenInformation( IntPtr hToken, TOKEN_INFORMATION_CLASS tokenInfoClass, IntPtr TokenInformation, int tokeInfoLength, ref int reqLength); [DllImport("advapi32", CharSet=CharSet.Auto)] public static extern bool LookupAccountSid ( [In,MarshalAs(UnmanagedType.LPTStr)] string lpSystemName, // name of local or remote computer IntPtr pSid, // security identifier StringBuilder Account, // account name buffer ref int cbName, // size of account name buffer StringBuilder DomainName, // domain name ref int cbDomainName, // size of domain name buffer ref int peUse // SID type // ref _SID_NAME_USE peUse // SID type ); [DllImport("advapi32", CharSet=CharSet.Auto)] public static extern bool ConvertSidToStringSid( IntPtr pSID, [In,Out,MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid); #region Comments /// <summary> /// Sets the security descriptor attributes /// </summary> /// <param name="sd">Reference to a SECURITY_DESCRIPTOR structure.</param> /// <param name="bDaclPresent"></param> /// <param name="Dacl"></param> /// <param name="bDaclDefaulted"></param> /// <returns></returns> #endregion [DllImport("Advapi32.dll", SetLastError=true)] public static extern bool SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR sd, bool bDaclPresent, IntPtr Dacl, bool bDaclDefaulted); #region Comments /// <summary> /// Initializes a SECURITY_DESCRIPTOR structure. /// </summary> /// <param name="sd"></param> /// <param name="dwRevision"></param> /// <returns></returns> #endregion [DllImport("Advapi32.dll", SetLastError=true)] public static extern bool InitializeSecurityDescriptor(out SECURITY_DESCRIPTOR sd, int dwRevision); #region Comments /// <summary> /// Private constructor. /// </summary> #endregion private ImpersonateNative() {} } }