text: /*
   * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
   * Use of this source code is governed by a BSD-style license that can be
   * found in the LICENSE file.
   * Define Windows structs and constants which are considered private.
   */
  
  #if !defined(__NTEXTAPI_H__)
  #define __NTEXTAPI_H__
  #include <winternl.h>
  #include <iphlpapi.h>
  
  typedef LONG NTSTATUS;
  
  // https://github.com/ajkhoury/TestDll/blob/master/nt_ddk.h
  #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
  #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
  #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
  #define STATUS_NOT_FOUND ((NTSTATUS)0xC0000225L)
  #define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
  
  // ================================================================
  // Enums
  // ================================================================
  
  #undef  SystemExtendedHandleInformation
  #define SystemExtendedHandleInformation 64
  #undef  MemoryWorkingSetInformation
  #define MemoryWorkingSetInformation 0x1
  #undef  ObjectNameInformation
  #define ObjectNameInformation 1
  #undef  ProcessIoPriority
  #define ProcessIoPriority 33
  #undef  ProcessWow64Information
  #define ProcessWow64Information 26
  
  // process suspend() / resume()
  typedef enum _KTHREAD_STATE {
      Initialized,
      Ready,
      Running,
      Standby,
      Terminated,
      Waiting,
      Transition,
      DeferredReady,
      GateWait,
      MaximumThreadState
  } KTHREAD_STATE, *PKTHREAD_STATE;
  
  typedef enum _KWAIT_REASON {
      Executive,
      FreePage,
      PageIn,
      PoolAllocation,
      DelayExecution,
      Suspended,
      UserRequest,
      WrExecutive,
      WrFreePage,
      WrPageIn,
      WrPoolAllocation,
      WrDelayExecution,
      WrSuspended,
      WrUserRequest,
      WrEventPair,
      WrQueue,
      WrLpcReceive,
      WrLpcReply,
      WrVirtualMemory,
      WrPageOut,
      WrRendezvous,
      WrKeyedEvent,
      WrTerminated,
      WrProcessInSwap,
      WrCpuRateControl,
      WrCalloutStack,
      WrKernel,
      WrResource,
      WrPushLock,
      WrMutex,
      WrQuantumEnd,
      WrDispatchInt,
      WrPreempted,
      WrYieldExecution,
      WrFastMutex,
      WrGuardedMutex,
      WrRundown,
      WrAlertByThreadId,
      WrDeferredPreempt,
      MaximumWaitReason
  } KWAIT_REASON, *PKWAIT_REASON;
  
  // ================================================================
  // Structs.
  // ================================================================
  
  // cpu_stats(), per_cpu_times()
  typedef struct {
      LARGE_INTEGER IdleTime;
      LARGE_INTEGER KernelTime;
      LARGE_INTEGER UserTime;
      LARGE_INTEGER DpcTime;
      LARGE_INTEGER InterruptTime;
      ULONG InterruptCount;
  } _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
  
  // cpu_stats()
  typedef struct {
      LARGE_INTEGER IdleProcessTime;
      LARGE_INTEGER IoReadTransferCount;
      LARGE_INTEGER IoWriteTransferCount;
      LARGE_INTEGER IoOtherTransferCount;
      ULONG IoReadOperationCount;
      ULONG IoWriteOperationCount;
      ULONG IoOtherOperationCount;
      ULONG AvailablePages;
      ULONG CommittedPages;
      ULONG CommitLimit;
      ULONG PeakCommitment;
      ULONG PageFaultCount;
      ULONG CopyOnWriteCount;
      ULONG TransitionCount;
      ULONG CacheTransitionCount;
      ULONG DemandZeroCount;
      ULONG PageReadCount;
      ULONG PageReadIoCount;
      ULONG CacheReadCount;
      ULONG CacheIoCount;
      ULONG DirtyPagesWriteCount;
      ULONG DirtyWriteIoCount;
      ULONG MappedPagesWriteCount;
      ULONG MappedWriteIoCount;
      ULONG PagedPoolPages;
      ULONG NonPagedPoolPages;
      ULONG PagedPoolAllocs;
      ULONG PagedPoolFrees;
      ULONG NonPagedPoolAllocs;
      ULONG NonPagedPoolFrees;
      ULONG FreeSystemPtes;
      ULONG ResidentSystemCodePage;
      ULONG TotalSystemDriverPages;
      ULONG TotalSystemCodePages;
      ULONG NonPagedPoolLookasideHits;
      ULONG PagedPoolLookasideHits;
      ULONG AvailablePagedPoolPages;
      ULONG ResidentSystemCachePage;
      ULONG ResidentPagedPoolPage;
      ULONG ResidentSystemDriverPage;
      ULONG CcFastReadNoWait;
      ULONG CcFastReadWait;
      ULONG CcFastReadResourceMiss;
      ULONG CcFastReadNotPossible;
      ULONG CcFastMdlReadNoWait;
      ULONG CcFastMdlReadWait;
      ULONG CcFastMdlReadResourceMiss;
      ULONG CcFastMdlReadNotPossible;
      ULONG CcMapDataNoWait;
      ULONG CcMapDataWait;
      ULONG CcMapDataNoWaitMiss;
      ULONG CcMapDataWaitMiss;
      ULONG CcPinMappedDataCount;
      ULONG CcPinReadNoWait;
      ULONG CcPinReadWait;
      ULONG CcPinReadNoWaitMiss;
      ULONG CcPinReadWaitMiss;
      ULONG CcCopyReadNoWait;
      ULONG CcCopyReadWait;
      ULONG CcCopyReadNoWaitMiss;
      ULONG CcCopyReadWaitMiss;
      ULONG CcMdlReadNoWait;
      ULONG CcMdlReadWait;
      ULONG CcMdlReadNoWaitMiss;
      ULONG CcMdlReadWaitMiss;
      ULONG CcReadAheadIos;
      ULONG CcLazyWriteIos;
      ULONG CcLazyWritePages;
      ULONG CcDataFlushes;
      ULONG CcDataPages;
      ULONG ContextSwitches;
      ULONG FirstLevelTbFills;
      ULONG SecondLevelTbFills;
      ULONG SystemCalls;
  } _SYSTEM_PERFORMANCE_INFORMATION;
  
  // cpu_stats()
  typedef struct {
      ULONG ContextSwitches;
      ULONG DpcCount;
      ULONG DpcRate;
      ULONG TimeIncrement;
      ULONG DpcBypassCount;
      ULONG ApcBypassCount;
  } _SYSTEM_INTERRUPT_INFORMATION;
  
  typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX {
      PVOID Object;
      HANDLE UniqueProcessId;
      HANDLE HandleValue;
      ULONG GrantedAccess;
      USHORT CreatorBackTraceIndex;
      USHORT ObjectTypeIndex;
      ULONG HandleAttributes;
      ULONG Reserved;
  } SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;
  
  typedef struct _SYSTEM_HANDLE_INFORMATION_EX {
      ULONG_PTR NumberOfHandles;
      ULONG_PTR Reserved;
      SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
  } SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
  
  typedef struct _CLIENT_ID2 {
      HANDLE UniqueProcess;
      HANDLE UniqueThread;
  } CLIENT_ID2, *PCLIENT_ID2;
  
  #define CLIENT_ID CLIENT_ID2
  #define PCLIENT_ID PCLIENT_ID2
  
  typedef struct _SYSTEM_THREAD_INFORMATION2 {
      LARGE_INTEGER KernelTime;
      LARGE_INTEGER UserTime;
      LARGE_INTEGER CreateTime;
      ULONG WaitTime;
      PVOID StartAddress;
      CLIENT_ID ClientId;
      LONG Priority;
      LONG BasePriority;
      ULONG ContextSwitches;
      ULONG ThreadState;
      KWAIT_REASON WaitReason;
  } SYSTEM_THREAD_INFORMATION2, *PSYSTEM_THREAD_INFORMATION2;
  
  #define SYSTEM_THREAD_INFORMATION SYSTEM_THREAD_INFORMATION2
  #define PSYSTEM_THREAD_INFORMATION PSYSTEM_THREAD_INFORMATION2
  
  typedef struct _SYSTEM_PROCESS_INFORMATION2 {
      ULONG NextEntryOffset;
      ULONG NumberOfThreads;
      LARGE_INTEGER SpareLi1;
      LARGE_INTEGER SpareLi2;
      LARGE_INTEGER SpareLi3;
      LARGE_INTEGER CreateTime;
      LARGE_INTEGER UserTime;
      LARGE_INTEGER KernelTime;
      UNICODE_STRING ImageName;
      LONG BasePriority;
      HANDLE UniqueProcessId;
      HANDLE InheritedFromUniqueProcessId;
      ULONG HandleCount;
      ULONG SessionId;
      ULONG_PTR PageDirectoryBase;
      SIZE_T PeakVirtualSize;
      SIZE_T VirtualSize;
      DWORD PageFaultCount;
      SIZE_T PeakWorkingSetSize;
      SIZE_T WorkingSetSize;
      SIZE_T QuotaPeakPagedPoolUsage;
      SIZE_T QuotaPagedPoolUsage;
      SIZE_T QuotaPeakNonPagedPoolUsage;
      SIZE_T QuotaNonPagedPoolUsage;
      SIZE_T PagefileUsage;
      SIZE_T PeakPagefileUsage;
      SIZE_T PrivatePageCount;
      LARGE_INTEGER ReadOperationCount;
      LARGE_INTEGER WriteOperationCount;
      LARGE_INTEGER OtherOperationCount;
      LARGE_INTEGER ReadTransferCount;
      LARGE_INTEGER WriteTransferCount;
      LARGE_INTEGER OtherTransferCount;
      SYSTEM_THREAD_INFORMATION Threads[1];
  } SYSTEM_PROCESS_INFORMATION2, *PSYSTEM_PROCESS_INFORMATION2;
  
  #define SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION2
  #define PSYSTEM_PROCESS_INFORMATION PSYSTEM_PROCESS_INFORMATION2
  
  // cpu_freq()
  typedef struct _PROCESSOR_POWER_INFORMATION {
     ULONG Number;
     ULONG MaxMhz;
     ULONG CurrentMhz;
     ULONG MhzLimit;
     ULONG MaxIdleState;
     ULONG CurrentIdleState;
  } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
  
  #ifndef __IPHLPAPI_H__
  typedef struct in6_addr {
      union {
          UCHAR Byte[16];
          USHORT Word[8];
      } u;
  } IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;
  #endif
  
  // PEB / cmdline(), cwd(), environ()
  typedef struct {
      BYTE Reserved1[16];
      PVOID Reserved2[5];
      UNICODE_STRING CurrentDirectoryPath;
      PVOID CurrentDirectoryHandle;
      UNICODE_STRING DllPath;
      UNICODE_STRING ImagePathName;
      UNICODE_STRING CommandLine;
      LPCWSTR env;
  } RTL_USER_PROCESS_PARAMETERS_, *PRTL_USER_PROCESS_PARAMETERS_;
  
  // users()
  typedef struct _WINSTATION_INFO {
      BYTE Reserved1[72];
      ULONG SessionId;
      BYTE Reserved2[4];
      FILETIME ConnectTime;
      FILETIME DisconnectTime;
      FILETIME LastInputTime;
      FILETIME LoginTime;
      BYTE Reserved3[1096];
      FILETIME CurrentTime;
  } WINSTATION_INFO, *PWINSTATION_INFO;
  
  // cpu_count_phys()
  #if (_WIN32_WINNT < 0x0601)  // Windows < 7 (Vista and XP)
  typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX {
      LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
      DWORD Size;
      _ANONYMOUS_UNION
      union {
          PROCESSOR_RELATIONSHIP Processor;
          NUMA_NODE_RELATIONSHIP NumaNode;
          CACHE_RELATIONSHIP Cache;
          GROUP_RELATIONSHIP Group;
      } DUMMYUNIONNAME;
  } SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, \
      *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX;
  #endif
  
  // memory_uss()
  typedef struct _MEMORY_WORKING_SET_BLOCK {
      ULONG_PTR Protection : 5;
      ULONG_PTR ShareCount : 3;
      ULONG_PTR Shared : 1;
      ULONG_PTR Node : 3;
  #ifdef _WIN64
      ULONG_PTR VirtualPage : 52;
  #else
      ULONG VirtualPage : 20;
  #endif
  } MEMORY_WORKING_SET_BLOCK, *PMEMORY_WORKING_SET_BLOCK;
  
  // memory_uss()
  typedef struct _MEMORY_WORKING_SET_INFORMATION {
      ULONG_PTR NumberOfEntries;
      MEMORY_WORKING_SET_BLOCK WorkingSetInfo[1];
  } MEMORY_WORKING_SET_INFORMATION, *PMEMORY_WORKING_SET_INFORMATION;
  
  // memory_uss()
  typedef struct _PSUTIL_PROCESS_WS_COUNTERS {
      SIZE_T NumberOfPages;
      SIZE_T NumberOfPrivatePages;
      SIZE_T NumberOfSharedPages;
      SIZE_T NumberOfShareablePages;
  } PSUTIL_PROCESS_WS_COUNTERS, *PPSUTIL_PROCESS_WS_COUNTERS;
  
  // ====================================================================
  // PEB structs for cmdline(), cwd(), environ()
  // ====================================================================
  
  #ifdef _WIN64
  typedef struct {
      BYTE Reserved1[2];
      BYTE BeingDebugged;
      BYTE Reserved2[21];
      PVOID LoaderData;
      PRTL_USER_PROCESS_PARAMETERS_ ProcessParameters;
      // more fields...
  } PEB_;
  
  // When we are a 64 bit process accessing a 32 bit (WoW64)
  // process we need to use the 32 bit structure layout.
  typedef struct {
      USHORT Length;
      USHORT MaxLength;
      DWORD Buffer;
  } UNICODE_STRING32;
  
  typedef struct {
      BYTE Reserved1[16];
      DWORD Reserved2[5];
      UNICODE_STRING32 CurrentDirectoryPath;
      DWORD CurrentDirectoryHandle;
      UNICODE_STRING32 DllPath;
      UNICODE_STRING32 ImagePathName;
      UNICODE_STRING32 CommandLine;
      DWORD env;
  } RTL_USER_PROCESS_PARAMETERS32;
  
  typedef struct {
      BYTE Reserved1[2];
      BYTE BeingDebugged;
      BYTE Reserved2[1];
      DWORD Reserved3[2];
      DWORD Ldr;
      DWORD ProcessParameters;
      // more fields...
  } PEB32;
  #else  // ! _WIN64
  typedef struct {
      BYTE Reserved1[2];
      BYTE BeingDebugged;
      BYTE Reserved2[1];
      PVOID Reserved3[2];
      PVOID Ldr;
      PRTL_USER_PROCESS_PARAMETERS_ ProcessParameters;
      // more fields...
  } PEB_;
  
  // When we are a 32 bit (WoW64) process accessing a 64 bit process
  // we need to use the 64 bit structure layout and a special function
  // to read its memory.
  typedef NTSTATUS (NTAPI *_NtWow64ReadVirtualMemory64)(
      HANDLE ProcessHandle,
      PVOID64 BaseAddress,
      PVOID Buffer,
      ULONG64 Size,
      PULONG64 NumberOfBytesRead);
  
  typedef struct {
      PVOID Reserved1[2];
      PVOID64 PebBaseAddress;
      PVOID Reserved2[4];
      PVOID UniqueProcessId[2];
      PVOID Reserved3[2];
  } PROCESS_BASIC_INFORMATION64;
  
  typedef struct {
      USHORT Length;
      USHORT MaxLength;
      PVOID64 Buffer;
  } UNICODE_STRING64;
  
  typedef struct {
      BYTE Reserved1[16];
      PVOID64 Reserved2[5];
      UNICODE_STRING64 CurrentDirectoryPath;
      PVOID64 CurrentDirectoryHandle;
      UNICODE_STRING64 DllPath;
      UNICODE_STRING64 ImagePathName;
      UNICODE_STRING64 CommandLine;
      PVOID64 env;
  } RTL_USER_PROCESS_PARAMETERS64;
  
  typedef struct {
      BYTE Reserved1[2];
      BYTE BeingDebugged;
      BYTE Reserved2[21];
      PVOID64 LoaderData;
      PVOID64 ProcessParameters;
      // more fields...
  } PEB64;
  #endif  // _WIN64
  
  // ================================================================
  // Type defs for modules loaded at runtime.
  // ================================================================
  
  BOOL (WINAPI *_GetLogicalProcessorInformationEx) (
      LOGICAL_PROCESSOR_RELATIONSHIP relationship,
      PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX Buffer,
      PDWORD ReturnLength);
  
  #define GetLogicalProcessorInformationEx _GetLogicalProcessorInformationEx
  
  BOOLEAN (WINAPI * _WinStationQueryInformationW) (
      HANDLE ServerHandle,
      ULONG SessionId,
      WINSTATIONINFOCLASS WinStationInformationClass,
      PVOID pWinStationInformation,
      ULONG WinStationInformationLength,
      PULONG pReturnLength);
  
  #define WinStationQueryInformationW _WinStationQueryInformationW
  
  NTSTATUS (NTAPI *_NtQueryInformationProcess) (
      HANDLE ProcessHandle,
      DWORD ProcessInformationClass,
      PVOID ProcessInformation,
      DWORD ProcessInformationLength,
      PDWORD ReturnLength);
  
  #define NtQueryInformationProcess _NtQueryInformationProcess
  
  NTSTATUS (NTAPI *_NtQuerySystemInformation) (
      ULONG SystemInformationClass,
      PVOID SystemInformation,
      ULONG SystemInformationLength,
      PULONG ReturnLength);
  
  #define NtQuerySystemInformation _NtQuerySystemInformation
  
  NTSTATUS (NTAPI *_NtSetInformationProcess) (
      HANDLE ProcessHandle,
      DWORD ProcessInformationClass,
      PVOID ProcessInformation,
      DWORD ProcessInformationLength);
  
  #define NtSetInformationProcess _NtSetInformationProcess
  
  PSTR (NTAPI * _RtlIpv4AddressToStringA) (
      struct in_addr *Addr,
      PSTR S);
  
  #define RtlIpv4AddressToStringA _RtlIpv4AddressToStringA
  
  PSTR (NTAPI * _RtlIpv6AddressToStringA) (
      struct in6_addr *Addr,
      PSTR P);
  
  #define RtlIpv6AddressToStringA _RtlIpv6AddressToStringA
  
  DWORD (WINAPI * _GetExtendedTcpTable) (
      PVOID pTcpTable,
      PDWORD pdwSize,
      BOOL bOrder,
      ULONG ulAf,
      TCP_TABLE_CLASS TableClass,
      ULONG Reserved);
  
  #define GetExtendedTcpTable _GetExtendedTcpTable
  
  DWORD (WINAPI * _GetExtendedUdpTable) (
      PVOID pUdpTable,
      PDWORD pdwSize,
      BOOL bOrder,
      ULONG ulAf,
      UDP_TABLE_CLASS TableClass,
      ULONG Reserved);
  
  #define GetExtendedUdpTable _GetExtendedUdpTable
  
  DWORD (CALLBACK *_GetActiveProcessorCount) (
      WORD GroupNumber);
  
  #define GetActiveProcessorCount _GetActiveProcessorCount
  
  ULONGLONG (CALLBACK *_GetTickCount64) (
      void);
  
  #define GetTickCount64 _GetTickCount64
  
  NTSTATUS (NTAPI *_NtQueryObject) (
      HANDLE Handle,
      OBJECT_INFORMATION_CLASS ObjectInformationClass,
      PVOID ObjectInformation,
      ULONG ObjectInformationLength,
      PULONG ReturnLength);
  
  #define NtQueryObject _NtQueryObject
  
  NTSTATUS (WINAPI *_RtlGetVersion) (
      PRTL_OSVERSIONINFOW lpVersionInformation
  );
  
  #define RtlGetVersion _RtlGetVersion
  
  NTSTATUS (WINAPI *_NtResumeProcess) (
      HANDLE hProcess
  );
  
  #define NtResumeProcess _NtResumeProcess
  
  NTSTATUS (WINAPI *_NtSuspendProcess) (
      HANDLE hProcess
  );
  
  #define NtSuspendProcess _NtSuspendProcess
  
  NTSTATUS (NTAPI *_NtQueryVirtualMemory) (
      HANDLE ProcessHandle,
      PVOID BaseAddress,
      int MemoryInformationClass,
      PVOID MemoryInformation,
      SIZE_T MemoryInformationLength,
      PSIZE_T ReturnLength
  );
  
  #define NtQueryVirtualMemory _NtQueryVirtualMemory
  
  ULONG (WINAPI *_RtlNtStatusToDosErrorNoTeb) (
      NTSTATUS status
  );
  
  #define RtlNtStatusToDosErrorNoTeb _RtlNtStatusToDosErrorNoTeb
  
  #endif // __NTEXTAPI_H__
  