static void Main(string[] args) { var channel = PInvoke.WTSVirtualChannelOpenEx(PInvoke.WTS_CURRENT_SESSION, "Channel1", PInvoke.WTS_CHANNEL_OPTION_DYNAMIC); if (channel != IntPtr.Zero) { IntPtr ptr; uint bytes; if (PInvoke.WTSVirtualChannelQuery( channel, PInvoke.WTS_VIRTUAL_CLASS.WTSVirtualFileHandle, out ptr, out bytes)) { var handle = Marshal.ReadIntPtr(ptr); IntPtr file; if (PInvoke.DuplicateHandle( PInvoke.GetCurrentProcess(), handle, PInvoke.GetCurrentProcess(), out file, 0, false, PInvoke.DUPLICATE_SAME_ACCESS)) { PInvoke.WTSFreeMemory(ptr); ptr = IntPtr.Zero; var data = File.ReadAllBytes(@"X:\1G-FILE.dat"); var ovl = new NativeOverlapped(); ovl.EventHandle = PInvoke.CreateEvent(IntPtr.Zero, true, false, null); PInvoke.WriteFile(file, data, (uint)data.Length, out bytes, IntPtr.Zero); if (PInvoke.GetOverlappedResult(file, ref ovl, out bytes, true)) { var header = new PInvoke.CHANNEL_PDU_HEADER(); { var buffer = new byte[Marshal.SizeOf <PInvoke.CHANNEL_PDU_HEADER>()]; PInvoke.ReadFile(file, buffer, (uint)buffer.Length, out bytes, IntPtr.Zero); header = ByteArrayToStructure <PInvoke.CHANNEL_PDU_HEADER>(buffer); } { var buffer = new byte[header.length]; if (PInvoke.ReadFile(file, buffer, (uint)buffer.Length, out bytes, IntPtr.Zero)) { Console.WriteLine(Encoding.UTF8.GetString(buffer)); } else { Console.WriteLine("ReadFile(): {0}", Marshal.GetLastWin32Error()); } } } else { Console.WriteLine("WriteFile(): {0}", Marshal.GetLastWin32Error()); } } else { Console.WriteLine("DuplicateHandle(): {0}", Marshal.GetLastWin32Error()); } } else { Console.WriteLine("WTSVirtualChannelQuery(): {0}", Marshal.GetLastWin32Error()); } PInvoke.WTSVirtualChannelClose(channel); channel = IntPtr.Zero; } else { Console.WriteLine("WTSVirtualChannelOpenEx(): {0}", Marshal.GetLastWin32Error()); } Console.WriteLine("\nPress <any key> to continue."); Console.ReadKey(true); }
public static bool IsUserInAdminGroup() { bool fInAdminGroup = false; SafeTokenHandle hToken = null; SafeTokenHandle hTokenToCheck = null; IntPtr pElevationType = IntPtr.Zero; IntPtr pLinkedToken = IntPtr.Zero; int cbSize = 0; try { // Open the access token of the current process for query and duplicate. if (!NativeMethod.OpenProcessToken(Process.GetCurrentProcess().Handle, NativeMethod.TOKEN_QUERY | NativeMethod.TOKEN_DUPLICATE, out hToken)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Determine whether system is running Windows Vista or later operating // systems (major version >= 6) because they support linked tokens, but // previous versions (major version < 6) do not. if (Environment.OSVersion.Version.Major >= 6) { // Running Windows Vista or later (major version >= 6). // Determine token type: limited, elevated, or default. // Allocate a buffer for the elevation type information. cbSize = sizeof(TOKEN_ELEVATION_TYPE); pElevationType = Marshal.AllocHGlobal(cbSize); if (pElevationType == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Retrieve token elevation type information. if (!NativeMethod.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenElevationType, pElevationType, cbSize, out cbSize)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET. TOKEN_ELEVATION_TYPE elevType = (TOKEN_ELEVATION_TYPE) Marshal.ReadInt32(pElevationType); // If limited, get the linked elevated token for further check. if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited) { // Allocate a buffer for the linked token. cbSize = IntPtr.Size; pLinkedToken = Marshal.AllocHGlobal(cbSize); if (pLinkedToken == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Get the linked token. if (!NativeMethod.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken, cbSize, out cbSize)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Marshal the linked token value from native to .NET. IntPtr hLinkedToken = Marshal.ReadIntPtr(pLinkedToken); hTokenToCheck = new SafeTokenHandle(hLinkedToken); } } // CheckTokenMembership requires an impersonation token. If we just got // a linked token, it already is an impersonation token. If we did not // get a linked token, duplicate the original into an impersonation // token for CheckTokenMembership. if (hTokenToCheck == null) { if (!NativeMethod.DuplicateToken(hToken, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, out hTokenToCheck)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } // Check if the token to be checked contains admin SID. WindowsIdentity id = new WindowsIdentity(hTokenToCheck.DangerousGetHandle()); WindowsPrincipal principal = new WindowsPrincipal(id); fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator); } finally { // Centralized cleanup for all allocated resources. if (hToken != null) { hToken.Close(); hToken = null; } if (hTokenToCheck != null) { hTokenToCheck.Close(); hTokenToCheck = null; } if (pElevationType != IntPtr.Zero) { Marshal.FreeHGlobal(pElevationType); pElevationType = IntPtr.Zero; } if (pLinkedToken != IntPtr.Zero) { Marshal.FreeHGlobal(pLinkedToken); pLinkedToken = IntPtr.Zero; } } return(fInAdminGroup); }