Skip to content

Instantly share code, notes, and snippets.

@eric-b
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eric-b/81355e129508b509c5e5 to your computer and use it in GitHub Desktop.
Save eric-b/81355e129508b509c5e5 to your computer and use it in GitHub Desktop.
Sample of typical code inside a NativeMethods.cs file.
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.ComponentModel;
using System.Collections.Generic;
internal static class NativeMethods
{
public static class NtDll
{
public struct ParentProcessUtilities
{
internal IntPtr Reserved1;
internal IntPtr PebBaseAddress;
internal IntPtr Reserved2_0;
internal IntPtr Reserved2_1;
internal IntPtr UniqueProcessId;
internal IntPtr InheritedFromUniqueProcessId;
}
[DllImport("ntdll.dll")]
private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength);
/// <summary>
/// Gets the parent process of the current process.
/// </summary>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess()
{
return GetParentProcess(Process.GetCurrentProcess().Handle);
}
/// <summary>
/// Gets the parent process of specified process.
/// </summary>
/// <param name="id">The process id.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(int id)
{
Process process = Process.GetProcessById(id);
return GetParentProcess(process.Handle);
}
/// <summary>
/// Gets the parent process of a specified process.
/// </summary>
/// <param name="handle">The process handle.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(IntPtr handle)
{
ParentProcessUtilities pbi = new ParentProcessUtilities();
int returnLength;
int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength);
if (status != 0)
throw new Win32Exception(status);
try
{
return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
}
catch (ArgumentException)
{
// not found
return null;
}
}
}
public static class Kernel32
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MemoryStatusEx
{
public uint dwLength;
public uint dwMemoryLoad;
public ulong ullTotalPhys;
public ulong ullAvailPhys;
public ulong ullTotalPageFile;
public ulong ullAvailPageFile;
public ulong ullTotalVirtual;
public ulong ullAvailVirtual;
public ulong ullAvailExtendedVirtual;
public MemoryStatusEx()
{
this.dwLength = (uint)Marshal.SizeOf(typeof(MemoryStatusEx));
}
}
/// <summary>
/// Retrieves usage info of virtual and physical memory.
/// </summary>
/// <param name="lpBuffer"></param>
/// <returns></returns>
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool GlobalMemoryStatusEx([In, Out] MemoryStatusEx lpBuffer);
[DllImport("kernel32.dll", SetLastError = false)]
internal static extern bool GetProductInfo(
int dwOSMajorVersion,
int dwOSMinorVersion,
int dwSpMajorVersion,
int dwSpMinorVersion,
out int pdwReturnedProductType
);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode, ThrowOnUnmappableChar = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetDiskFreeSpace(
string lpRootPathName,
out int lpSectorsPerCluster,
out int lpBytesPerSector,
out int lpNumberOfFreeClusters,
out int lpTotalNumberOfClusters
);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode, ThrowOnUnmappableChar = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetDiskFreeSpaceEx(
string lpDirectoryName,
ref long lpFreeBytesAvailable,
ref long lpTotalNumberOfBytes,
ref long lpTotalNumberOfFreeBytes
);
[Flags()]
internal enum ProcessAccessFlags : int
{
/// <summary>Specifies all possible access flags for the process object.</summary>
AllAccess = CreateThread | DuplicateHandle | QueryInformation | SetInformation | Terminate | VMOperation | VMRead | VMWrite | Synchronize,
/// <summary>Enables usage of the process handle in the CreateRemoteThread function to create a thread in the process.</summary>
CreateThread = 0x2,
/// <summary>Enables usage of the process handle as either the source or target process in the DuplicateHandle function to duplicate a handle.</summary>
DuplicateHandle = 0x40,
/// <summary>Enables usage of the process handle in the GetExitCodeProcess and GetPriorityClass functions to read information from the process object.</summary>
QueryInformation = 0x400,
QueryLimitedInformation = 0x1000,
/// <summary>Enables usage of the process handle in the SetPriorityClass function to set the priority class of the process.</summary>
SetInformation = 0x200,
/// <summary>Enables usage of the process handle in the TerminateProcess function to terminate the process.</summary>
Terminate = 0x1,
/// <summary>Enables usage of the process handle in the VirtualProtectEx and WriteProcessMemory functions to modify the virtual memory of the process.</summary>
VMOperation = 0x8,
/// <summary>Enables usage of the process handle in the ReadProcessMemory function to' read from the virtual memory of the process.</summary>
VMRead = 0x10,
/// <summary>Enables usage of the process handle in the WriteProcessMemory function to write to the virtual memory of the process.</summary>
VMWrite = 0x20,
/// <summary>Enables usage of the process handle in any of the wait functions to wait for the process to terminate.</summary>
Synchronize = 0x100000,
}
[DllImport("kernel32.dll")]
internal static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool QueryFullProcessImageName(IntPtr hProcess, uint dwFlags,
[Out, MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder lpExeName,
ref uint lpdwSize);
}
public static class Wtsapi32
{
[DllImport("wtsapi32.dll", SetLastError = true)]
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);
[DllImport("wtsapi32.dll")]
static extern void WTSCloseServer(IntPtr hServer);
[DllImport("wtsapi32.dll", SetLastError = true)]
static extern Int32 WTSEnumerateSessions(
IntPtr hServer,
[MarshalAs(UnmanagedType.U4)] Int32 Reserved,
[MarshalAs(UnmanagedType.U4)] Int32 Version,
ref IntPtr ppSessionInfo,
[MarshalAs(UnmanagedType.U4)] ref Int32 pCount);
[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(IntPtr pMemory);
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public Int32 SessionID;
[MarshalAs(UnmanagedType.LPStr)]
public String pWinStationName;
public WTS_CONNECTSTATE_CLASS State;
}
public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType
}
public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}
public static IntPtr OpenServer(String Name)
{
IntPtr server = WTSOpenServer(Name);
return server;
}
public static void CloseServer(IntPtr ServerHandle)
{
WTSCloseServer(ServerHandle);
}
public static List<String> ListSessions(String ServerName)
{
IntPtr server = IntPtr.Zero;
List<String> ret = new List<string>();
server = OpenServer(ServerName);
try
{
IntPtr ppSessionInfo = IntPtr.Zero;
Int32 count = 0;
Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count);
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
Int64 current = (int)ppSessionInfo;
if (retval != 0)
{
for (int i = 0; i < count; i++)
{
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO));
current += dataSize;
ret.Add(si.SessionID + " " + si.State + " " + si.pWinStationName);
}
WTSFreeMemory(ppSessionInfo);
}
}
finally
{
CloseServer(server);
}
return ret;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment