Last active
August 29, 2015 14:04
-
-
Save eric-b/81355e129508b509c5e5 to your computer and use it in GitHub Desktop.
Sample of typical code inside a NativeMethods.cs file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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