1 /*
   2  * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef _NT4INTERNALS_H_
  26 #define _NT4INTERNALS_H_
  27 
  28 #include <windows.h>
  29 
  30 namespace NT4 {
  31 extern "C" {
  32 
  33 // Data structures and constants required to be able to get necessary
  34 // debugging-related information on Windows NT 4.0 through internal
  35 // (i.e., non-public) APIs. These are adapted from those in the
  36 // _Windows NT/2000 Native API Reference_ by Gary Nebbett, Macmillan
  37 // Technical Publishing, 201 West 103rd Street, Indianapolis, IN
  38 // 46290, 2000.
  39 
  40 typedef LONG NTSTATUS;
  41 typedef LONG KPRIORITY;
  42 
  43 #if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
  44 #define NTAPI __stdcall
  45 #else
  46 #define _cdecl
  47 #define NTAPI
  48 #endif
  49 
  50 #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
  51 
  52 typedef enum _SYSTEM_INFORMATION_CLASS {
  53   SystemProcessesAndThreadsInformation = 5
  54 } SYSTEM_INFORMATION_CLASS;
  55 
  56 typedef struct _UNICODE_STRING {
  57   USHORT Length;
  58   USHORT MaximumLength;
  59   PWSTR  Buffer;
  60 } UNICODE_STRING;
  61 
  62 typedef struct _VM_COUNTERS {
  63   ULONG PeakVirtualSize;
  64   ULONG VirtualSize;
  65   ULONG PageFaultCount;
  66   ULONG PeakWorkingSetSize;
  67   ULONG WorkingSetSize;
  68   ULONG QuotaPeakPagedPoolUsage;
  69   ULONG QuotaPagedPoolUsage;
  70   ULONG QuotaPeakNonPagedPoolUsage;
  71   ULONG QuotaNonPagedPoolUsage;
  72   ULONG PagefileUsage;
  73   ULONG PeakPagefileUsage;
  74 } VM_COUNTERS, *PVM_COUNTERS;
  75 
  76 typedef struct _IO_COUNTERS {
  77   LARGE_INTEGER ReadOperationCount;
  78   LARGE_INTEGER WriteOperationCount;
  79   LARGE_INTEGER OtherOperationCount;
  80   LARGE_INTEGER ReadTransferCount;
  81   LARGE_INTEGER WriteTransferCount;
  82   LARGE_INTEGER OtherTransferCount;
  83 } IO_COUNTERS, *PIO_COUNTERS;
  84 
  85 typedef struct _CLIENT_ID {
  86   HANDLE UniqueProcess;
  87   HANDLE UniqueThread;
  88 } CLIENT_ID, *PCLIENT_ID;
  89 
  90 typedef enum {
  91   StateInitialized,
  92   StateReady,
  93   StateRunning,
  94   StateStandby,
  95   StateTerminated,
  96   StateWait,
  97   StateTransition,
  98   StateUnknown
  99 } THREAD_STATE;
 100 
 101 typedef enum {
 102   Executive,
 103   FreePage,
 104   PageIn,
 105   PoolAllocation,
 106   DelayExecution,
 107   Suspended,
 108   UserRequest,
 109   WrExecutive,
 110   WrFreePage,
 111   WrPageIn,
 112   WrPoolAllocation,
 113   WrDelayExecution,
 114   WrSuspended,
 115   WrUserRequest,
 116   WrEventPair,
 117   WrQueue,
 118   WrLpcReceive,
 119   WrLpcReply,
 120   WrVirtualMemory,
 121   WrPageOut,
 122   WrRendezvous,
 123   Spare2,
 124   Spare3,
 125   Spare4,
 126   Spare5,
 127   Spare6,
 128   WrKernel
 129 } KWAIT_REASON;
 130 
 131 typedef struct _SYSTEM_THREADS {
 132   LARGE_INTEGER KernelTime;
 133   LARGE_INTEGER UserTime;
 134   LARGE_INTEGER CreateTime;
 135   ULONG WaitTime;
 136   PVOID StartAddress;
 137   CLIENT_ID ClientId;
 138   KPRIORITY Priority;
 139   KPRIORITY BasePriority;
 140   ULONG ContextSwitchCount;
 141   THREAD_STATE State;
 142   KWAIT_REASON WaitReason;
 143 } SYSTEM_THREADS, *PSYSTEM_THREADS;
 144 
 145 typedef struct _SYSTEM_PROCESSES { // Information class 5
 146   ULONG NextEntryDelta;
 147   ULONG ThreadCount;
 148   ULONG Reserved1[6];
 149   LARGE_INTEGER CreateTime;
 150   LARGE_INTEGER UserTime;
 151   LARGE_INTEGER KernelTime;
 152   UNICODE_STRING ProcessName;
 153   KPRIORITY BasePriority;
 154   ULONG ProcessId;
 155   ULONG InheritedFromProcessId;
 156   ULONG HandleCount;
 157   ULONG Reserved2[2];
 158   ULONG PrivatePageCount;
 159   VM_COUNTERS VmCounters;
 160   IO_COUNTERS IoCounters; // Windows 2000 only
 161   SYSTEM_THREADS Threads[1];
 162 } SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
 163 
 164 typedef NTSTATUS NTAPI
 165 ZwQuerySystemInformationFunc(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
 166                              IN OUT PVOID SystemInformation,
 167                              IN ULONG SystemInformationLength,
 168                              OUT PULONG ReturnLength OPTIONAL
 169                              );
 170 
 171 typedef struct _DEBUG_BUFFER {
 172   HANDLE SectionHandle;
 173   PVOID  SectionBase;
 174   PVOID  RemoteSectionBase;
 175   ULONG  SectionBaseDelta;
 176   HANDLE EventPairHandle;
 177   ULONG  Unknown[2];
 178   HANDLE RemoteThreadHandle;
 179   ULONG  InfoClassMask;
 180   ULONG  SizeOfInfo;
 181   ULONG  AllocatedSize;
 182   ULONG  SectionSize;
 183   PVOID  ModuleInformation;
 184   PVOID  BackTraceInformation;
 185   PVOID  HeapInformation;
 186   PVOID  LockInformation;
 187   PVOID  Reserved[8];
 188 } DEBUG_BUFFER, *PDEBUG_BUFFER;
 189 
 190 typedef PDEBUG_BUFFER NTAPI
 191 RtlCreateQueryDebugBufferFunc(IN ULONG Size,
 192                               IN BOOLEAN EventPair);
 193 
 194 #define PDI_MODULES     0x01 // The loaded modules of the process
 195 #define PDI_BACKTRACE   0x02 // The heap stack back traces
 196 #define PDI_HEAPS       0x04 // The heaps of the process
 197 #define PDI_HEAP_TAGS   0x08 // The heap tags
 198 #define PDI_HEAP_BLOCKS 0x10 // The heap blocks
 199 #define PDI_LOCKS       0x20 // The locks created by the process
 200 
 201 typedef struct _DEBUG_MODULE_INFORMATION { // c.f. SYSTEM_MODULE_INFORMATION
 202   ULONG  Reserved[2];
 203   ULONG  Base;
 204   ULONG  Size;
 205   ULONG  Flags;
 206   USHORT Index;
 207   USHORT Unknown;
 208   USHORT LoadCount;
 209   USHORT ModuleNameOffset;
 210   CHAR   ImageName[256];
 211 } DEBUG_MODULE_INFORMATION, *PDEBUG_MODULE_INFORMATION;
 212 
 213 // Flags
 214 #define LDRP_STATIC_LINK             0x00000002
 215 #define LDRP_IMAGE_DLL               0x00000004
 216 #define LDRP_LOAD_IN_PROGRESS        0x00001000
 217 #define LDRP_UNLOAD_IN_PROGRESS      0x00002000
 218 #define LDRP_ENTRY_PROCESSED         0x00004000
 219 #define LDRP_ENTRY_INSERTED          0x00008000
 220 #define LDRP_CURRENT_LOAD            0x00010000
 221 #define LDRP_FAILED_BUILTIN_LOAD     0x00020000
 222 #define LDRP_DONT_CALL_FOR_THREADS   0x00040000
 223 #define LDRP_PROCESS_ATTACH_CALLED   0x00080000
 224 #define LDRP_DEBUG_SYMBOLS_LOADED    0x00100000
 225 #define LDRP_IMAGE_NOT_AT_BASE       0x00200000
 226 #define LDRP_WX86_IGNORE_MACHINETYPE 0x00400000
 227 
 228 // NOTE that this will require creating a thread in the target
 229 // process, implying that we can not call this while the process is
 230 // suspended. May have to run this command in the child processes
 231 // rather than the server.
 232 
 233 typedef NTSTATUS NTAPI
 234 RtlQueryProcessDebugInformationFunc(IN ULONG ProcessId,
 235                                     IN ULONG DebugInfoClassMask,
 236                                     IN OUT PDEBUG_BUFFER DebugBuffer);
 237 
 238 typedef NTSTATUS NTAPI
 239 RtlDestroyQueryDebugBufferFunc(IN PDEBUG_BUFFER DebugBuffer);
 240 
 241 // Routines to load and unload NTDLL.DLL.
 242 HMODULE loadNTDLL();
 243 // Safe to call even if has not been loaded
 244 void    unloadNTDLL();
 245 
 246 } // extern "C"
 247 } // namespace NT4
 248 
 249 //----------------------------------------------------------------------
 250 
 251 // On NT 4 only, we now use PSAPI to enumerate the loaded modules in
 252 // the target processes. RtlQueryProcessDebugInformation creates a
 253 // thread in the target process, which causes problems when we are
 254 // handling events like breakpoints in the debugger. The dependence on
 255 // an external DLL which might not be present is unfortunate, but we
 256 // can either redistribute this DLL (if allowed) or refuse to start on
 257 // NT 4 if it is not present.
 258 
 259 typedef struct _MODULEINFO {
 260     LPVOID lpBaseOfDll;
 261     DWORD SizeOfImage;
 262     LPVOID EntryPoint;
 263 } MODULEINFO, *LPMODULEINFO;
 264 
 265 typedef BOOL (WINAPI EnumProcessModulesFunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
 266 typedef DWORD (WINAPI GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD);
 267 typedef BOOL (WINAPI GetModuleInformationFunc)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
 268 // Routines to load and unload PSAPI.DLL.
 269 HMODULE loadPSAPIDLL();
 270 // Safe to call even if has not been loaded
 271 void    unloadPSAPIDLL();
 272 
 273 #endif // #defined _NT4INTERNALS_H_