text: /*
   * This file is part of the Process Hacker project - https://processhacker.sourceforge.io/
   *
   * You can redistribute this file and/or modify it under the terms of the 
   * Attribution 4.0 International (CC BY 4.0) license. 
   * 
   * You must give appropriate credit, provide a link to the license, and 
   * indicate if changes were made. You may do so in any reasonable manner, but 
   * not in any way that suggests the licensor endorses you or your use.
   */
  
  #ifndef _NTLDR_H
  #define _NTLDR_H
  
  #if (PHNT_MODE != PHNT_MODE_KERNEL)
  
  // DLLs
  
  typedef BOOLEAN (NTAPI *PLDR_INIT_ROUTINE)(
      _In_ PVOID DllHandle,
      _In_ ULONG Reason,
      _In_opt_ PVOID Context
      );
  
  // symbols
  typedef struct _LDR_SERVICE_TAG_RECORD
  {
      struct _LDR_SERVICE_TAG_RECORD *Next;
      ULONG ServiceTag;
  } LDR_SERVICE_TAG_RECORD, *PLDR_SERVICE_TAG_RECORD;
  
  // symbols
  typedef struct _LDRP_CSLIST
  {
      PSINGLE_LIST_ENTRY Tail;
  } LDRP_CSLIST, *PLDRP_CSLIST;
  
  // symbols
  typedef enum _LDR_DDAG_STATE
  {
      LdrModulesMerged = -5,
      LdrModulesInitError = -4,
      LdrModulesSnapError = -3,
      LdrModulesUnloaded = -2,
      LdrModulesUnloading = -1,
      LdrModulesPlaceHolder = 0,
      LdrModulesMapping = 1,
      LdrModulesMapped = 2,
      LdrModulesWaitingForDependencies = 3,
      LdrModulesSnapping = 4,
      LdrModulesSnapped = 5,
      LdrModulesCondensed = 6,
      LdrModulesReadyToInit = 7,
      LdrModulesInitializing = 8,
      LdrModulesReadyToRun = 9
  } LDR_DDAG_STATE;
  
  // symbols
  typedef struct _LDR_DDAG_NODE
  {
      LIST_ENTRY Modules;
      PLDR_SERVICE_TAG_RECORD ServiceTagList;
      ULONG LoadCount;
      ULONG LoadWhileUnloadingCount;
      ULONG LowestLink;
      union
      {
          LDRP_CSLIST Dependencies;
          SINGLE_LIST_ENTRY RemovalLink;
      };
      LDRP_CSLIST IncomingDependencies;
      LDR_DDAG_STATE State;
      SINGLE_LIST_ENTRY CondenseLink;
      ULONG PreorderNumber;
  } LDR_DDAG_NODE, *PLDR_DDAG_NODE;
  
  // rev
  typedef struct _LDR_DEPENDENCY_RECORD
  {
      SINGLE_LIST_ENTRY DependencyLink;
      PLDR_DDAG_NODE DependencyNode;
      SINGLE_LIST_ENTRY IncomingDependencyLink;
      PLDR_DDAG_NODE IncomingDependencyNode;
  } LDR_DEPENDENCY_RECORD, *PLDR_DEPENDENCY_RECORD;
  
  // symbols
  typedef enum _LDR_DLL_LOAD_REASON
  {
      LoadReasonStaticDependency,
      LoadReasonStaticForwarderDependency,
      LoadReasonDynamicForwarderDependency,
      LoadReasonDelayloadDependency,
      LoadReasonDynamicLoad,
      LoadReasonAsImageLoad,
      LoadReasonAsDataLoad,
      LoadReasonEnclavePrimary, // REDSTONE3
      LoadReasonEnclaveDependency,
      LoadReasonUnknown = -1
  } LDR_DLL_LOAD_REASON, *PLDR_DLL_LOAD_REASON;
  
  #define LDRP_PACKAGED_BINARY 0x00000001
  #define LDRP_STATIC_LINK 0x00000002
  #define LDRP_IMAGE_DLL 0x00000004
  #define LDRP_LOAD_IN_PROGRESS 0x00001000
  #define LDRP_UNLOAD_IN_PROGRESS 0x00002000
  #define LDRP_ENTRY_PROCESSED 0x00004000
  #define LDRP_ENTRY_INSERTED 0x00008000
  #define LDRP_CURRENT_LOAD 0x00010000
  #define LDRP_FAILED_BUILTIN_LOAD 0x00020000
  #define LDRP_DONT_CALL_FOR_THREADS 0x00040000
  #define LDRP_PROCESS_ATTACH_CALLED 0x00080000
  #define LDRP_DEBUG_SYMBOLS_LOADED 0x00100000
  #define LDRP_IMAGE_NOT_AT_BASE 0x00200000 // Vista and below
  #define LDRP_COR_IMAGE 0x00400000
  #define LDRP_DONT_RELOCATE 0x00800000 // LDR_COR_OWNS_UNMAP
  #define LDRP_SYSTEM_MAPPED 0x01000000
  #define LDRP_IMAGE_VERIFYING 0x02000000
  #define LDRP_DRIVER_DEPENDENT_DLL 0x04000000
  #define LDRP_ENTRY_NATIVE 0x08000000
  #define LDRP_REDIRECTED 0x10000000
  #define LDRP_NON_PAGED_DEBUG_INFO 0x20000000
  #define LDRP_MM_LOADED 0x40000000
  #define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000
  
  #define LDR_DATA_TABLE_ENTRY_SIZE_WINXP FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, DdagNode)
  #define LDR_DATA_TABLE_ENTRY_SIZE_WIN7 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, BaseNameHashValue)
  #define LDR_DATA_TABLE_ENTRY_SIZE_WIN8 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, ImplicitPathOptions)
  #define LDR_DATA_TABLE_ENTRY_SIZE_WIN10 sizeof(LDR_DATA_TABLE_ENTRY)
  
  // symbols
  typedef struct _LDR_DATA_TABLE_ENTRY
  {
      LIST_ENTRY InLoadOrderLinks;
      LIST_ENTRY InMemoryOrderLinks;
      union
      {
          LIST_ENTRY InInitializationOrderLinks;
          LIST_ENTRY InProgressLinks;
      };
      PVOID DllBase;
      PLDR_INIT_ROUTINE EntryPoint;
      ULONG SizeOfImage;
      UNICODE_STRING FullDllName;
      UNICODE_STRING BaseDllName;
      union
      {
          UCHAR FlagGroup[4];
          ULONG Flags;
          struct
          {
              ULONG PackagedBinary : 1;
              ULONG MarkedForRemoval : 1;
              ULONG ImageDll : 1;
              ULONG LoadNotificationsSent : 1;
              ULONG TelemetryEntryProcessed : 1;
              ULONG ProcessStaticImport : 1;
              ULONG InLegacyLists : 1;
              ULONG InIndexes : 1;
              ULONG ShimDll : 1;
              ULONG InExceptionTable : 1;
              ULONG ReservedFlags1 : 2;
              ULONG LoadInProgress : 1;
              ULONG LoadConfigProcessed : 1;
              ULONG EntryProcessed : 1;
              ULONG ProtectDelayLoad : 1;
              ULONG ReservedFlags3 : 2;
              ULONG DontCallForThreads : 1;
              ULONG ProcessAttachCalled : 1;
              ULONG ProcessAttachFailed : 1;
              ULONG CorDeferredValidate : 1;
              ULONG CorImage : 1;
              ULONG DontRelocate : 1;
              ULONG CorILOnly : 1;
              ULONG ChpeImage : 1;
              ULONG ReservedFlags5 : 2;
              ULONG Redirected : 1;
              ULONG ReservedFlags6 : 2;
              ULONG CompatDatabaseProcessed : 1;
          };
      };
      USHORT ObsoleteLoadCount;
      USHORT TlsIndex;
      LIST_ENTRY HashLinks;
      ULONG TimeDateStamp;
      struct _ACTIVATION_CONTEXT *EntryPointActivationContext;
      PVOID Lock; // RtlAcquireSRWLockExclusive
      PLDR_DDAG_NODE DdagNode;
      LIST_ENTRY NodeModuleLink;
      struct _LDRP_LOAD_CONTEXT *LoadContext;
      PVOID ParentDllBase;
      PVOID SwitchBackContext;
      RTL_BALANCED_NODE BaseAddressIndexNode;
      RTL_BALANCED_NODE MappingInfoIndexNode;
      ULONG_PTR OriginalBase;
      LARGE_INTEGER LoadTime;
      ULONG BaseNameHashValue;
      LDR_DLL_LOAD_REASON LoadReason;
      ULONG ImplicitPathOptions;
      ULONG ReferenceCount;
      ULONG DependentLoadFlags;
      UCHAR SigningLevel; // since REDSTONE2
  } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
  
  #define LDR_IS_DATAFILE(DllHandle) (((ULONG_PTR)(DllHandle)) & (ULONG_PTR)1)
  #define LDR_IS_IMAGEMAPPING(DllHandle) (((ULONG_PTR)(DllHandle)) & (ULONG_PTR)2)
  #define LDR_IS_RESOURCE(DllHandle) (LDR_IS_IMAGEMAPPING(DllHandle) || LDR_IS_DATAFILE(DllHandle))
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrLoadDll(
      _In_opt_ PWSTR DllPath,
      _In_opt_ PULONG DllCharacteristics,
      _In_ PUNICODE_STRING DllName,
      _Out_ PVOID *DllHandle
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrUnloadDll(
      _In_ PVOID DllHandle
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetDllHandle(
      _In_opt_ PWSTR DllPath,
      _In_opt_ PULONG DllCharacteristics,
      _In_ PUNICODE_STRING DllName,
      _Out_ PVOID *DllHandle
      );
  
  #define LDR_GET_DLL_HANDLE_EX_UNCHANGED_REFCOUNT 0x00000001
  #define LDR_GET_DLL_HANDLE_EX_PIN 0x00000002
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetDllHandleEx(
      _In_ ULONG Flags,
      _In_opt_ PWSTR DllPath,
      _In_opt_ PULONG DllCharacteristics,
      _In_ PUNICODE_STRING DllName,
      _Out_opt_ PVOID *DllHandle
      );
  
  #if (PHNT_VERSION >= PHNT_WIN7)
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetDllHandleByMapping(
      _In_ PVOID BaseAddress,
      _Out_ PVOID *DllHandle
      );
  #endif
  
  #if (PHNT_VERSION >= PHNT_WIN7)
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetDllHandleByName(
      _In_opt_ PUNICODE_STRING BaseDllName,
      _In_opt_ PUNICODE_STRING FullDllName,
      _Out_ PVOID *DllHandle
      );
  #endif
  
  #if (PHNT_VERSION >= PHNT_WIN8)
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetDllFullName(
      _In_ PVOID DllHandle,
      _Out_ PUNICODE_STRING FullDllName
      );
  
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetDllDirectory(
      _Out_ PUNICODE_STRING DllDirectory
      );
  
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrSetDllDirectory(
      _In_ PUNICODE_STRING DllDirectory
      );
  #endif
  
  #define LDR_ADDREF_DLL_PIN 0x00000001
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrAddRefDll(
      _In_ ULONG Flags,
      _In_ PVOID DllHandle
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetProcedureAddress(
      _In_ PVOID DllHandle,
      _In_opt_ PANSI_STRING ProcedureName,
      _In_opt_ ULONG ProcedureNumber,
      _Out_ PVOID *ProcedureAddress
      );
  
  // rev
  #define LDR_GET_PROCEDURE_ADDRESS_DONT_RECORD_FORWARDER 0x00000001
  
  #if (PHNT_VERSION >= PHNT_VISTA)
  // private
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetProcedureAddressEx(
      _In_ PVOID DllHandle,
      _In_opt_ PANSI_STRING ProcedureName,
      _In_opt_ ULONG ProcedureNumber,
      _Out_ PVOID *ProcedureAddress,
      _In_ ULONG Flags
      );
  #endif
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetKnownDllSectionHandle(
      _In_ PCWSTR DllName,
      _In_ BOOLEAN KnownDlls32,
      _Out_ PHANDLE Section
      );
  
  #if (PHNT_VERSION >= PHNT_THRESHOLD)
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetProcedureAddressForCaller(
      _In_ PVOID DllHandle,
      _In_opt_ PANSI_STRING ProcedureName,
      _In_opt_ ULONG ProcedureNumber,
      _Out_ PVOID *ProcedureAddress,
      _In_ ULONG Flags,
      _In_ PVOID *Callback
      );
  #endif
  
  #define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS 0x00000001
  #define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002
  
  #define LDR_LOCK_LOADER_LOCK_DISPOSITION_INVALID 0
  #define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED 1
  #define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED 2
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrLockLoaderLock(
      _In_ ULONG Flags,
      _Out_opt_ ULONG *Disposition,
      _Out_ PVOID *Cookie
      );
  
  #define LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS 0x00000001
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrUnlockLoaderLock(
      _In_ ULONG Flags,
      _Inout_ PVOID Cookie
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrRelocateImage(
      _In_ PVOID NewBase,
      _In_ PSTR LoaderName,
      _In_ NTSTATUS Success,
      _In_ NTSTATUS Conflict,
      _In_ NTSTATUS Invalid
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrRelocateImageWithBias(
      _In_ PVOID NewBase,
      _In_ LONGLONG Bias,
      _In_ PSTR LoaderName,
      _In_ NTSTATUS Success,
      _In_ NTSTATUS Conflict,
      _In_ NTSTATUS Invalid
      );
  
  NTSYSAPI
  PIMAGE_BASE_RELOCATION
  NTAPI
  LdrProcessRelocationBlock(
      _In_ ULONG_PTR VA,
      _In_ ULONG SizeOfBlock,
      _In_ PUSHORT NextOffset,
      _In_ LONG_PTR Diff
      );
  
  NTSYSAPI
  BOOLEAN
  NTAPI
  LdrVerifyMappedImageMatchesChecksum(
      _In_ PVOID BaseAddress,
      _In_ SIZE_T NumberOfBytes,
      _In_ ULONG FileLength
      );
  
  typedef VOID (NTAPI *PLDR_IMPORT_MODULE_CALLBACK)(
      _In_ PVOID Parameter,
      _In_ PSTR ModuleName
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrVerifyImageMatchesChecksum(
      _In_ HANDLE ImageFileHandle,
      _In_opt_ PLDR_IMPORT_MODULE_CALLBACK ImportCallbackRoutine,
      _In_ PVOID ImportCallbackParameter,
      _Out_opt_ PUSHORT ImageCharacteristics
      );
  
  // private
  typedef struct _LDR_IMPORT_CALLBACK_INFO
  {
      PLDR_IMPORT_MODULE_CALLBACK ImportCallbackRoutine;
      PVOID ImportCallbackParameter;
  } LDR_IMPORT_CALLBACK_INFO, *PLDR_IMPORT_CALLBACK_INFO;
  
  // private
  typedef struct _LDR_SECTION_INFO
  {
      HANDLE SectionHandle;
      ACCESS_MASK DesiredAccess;
      POBJECT_ATTRIBUTES ObjA;
      ULONG SectionPageProtection;
      ULONG AllocationAttributes;
  } LDR_SECTION_INFO, *PLDR_SECTION_INFO;
  
  // private
  typedef struct _LDR_VERIFY_IMAGE_INFO
  {
      ULONG Size;
      ULONG Flags;
      LDR_IMPORT_CALLBACK_INFO CallbackInfo;
      LDR_SECTION_INFO SectionInfo;
      USHORT ImageCharacteristics;
  } LDR_VERIFY_IMAGE_INFO, *PLDR_VERIFY_IMAGE_INFO;
  
  #if (PHNT_VERSION >= PHNT_VISTA)
  // private
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrVerifyImageMatchesChecksumEx(
      _In_ HANDLE ImageFileHandle,
      _Inout_ PLDR_VERIFY_IMAGE_INFO VerifyInfo
      );
  #endif
  
  #if (PHNT_VERSION >= PHNT_VISTA)
  // private
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrQueryModuleServiceTags(
      _In_ PVOID DllHandle,
      _Out_writes_(*BufferSize) PULONG ServiceTagBuffer,
      _Inout_ PULONG BufferSize
      );
  #endif
  
  // begin_msdn:"DLL Load Notification"
  
  #define LDR_DLL_NOTIFICATION_REASON_LOADED 1
  #define LDR_DLL_NOTIFICATION_REASON_UNLOADED 2
  
  typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA
  {
      ULONG Flags;
      PUNICODE_STRING FullDllName;
      PUNICODE_STRING BaseDllName;
      PVOID DllBase;
      ULONG SizeOfImage;
  } LDR_DLL_LOADED_NOTIFICATION_DATA, *PLDR_DLL_LOADED_NOTIFICATION_DATA;
  
  typedef struct _LDR_DLL_UNLOADED_NOTIFICATION_DATA
  {
      ULONG Flags;
      PCUNICODE_STRING FullDllName;
      PCUNICODE_STRING BaseDllName;
      PVOID DllBase;
      ULONG SizeOfImage;
  } LDR_DLL_UNLOADED_NOTIFICATION_DATA, *PLDR_DLL_UNLOADED_NOTIFICATION_DATA;
  
  typedef union _LDR_DLL_NOTIFICATION_DATA
  {
      LDR_DLL_LOADED_NOTIFICATION_DATA Loaded;
      LDR_DLL_UNLOADED_NOTIFICATION_DATA Unloaded;
  } LDR_DLL_NOTIFICATION_DATA, *PLDR_DLL_NOTIFICATION_DATA;
  
  typedef VOID (NTAPI *PLDR_DLL_NOTIFICATION_FUNCTION)(
      _In_ ULONG NotificationReason,
      _In_ PLDR_DLL_NOTIFICATION_DATA NotificationData,
      _In_opt_ PVOID Context
      );
  
  #if (PHNT_VERSION >= PHNT_VISTA)
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrRegisterDllNotification(
      _In_ ULONG Flags,
      _In_ PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction,
      _In_ PVOID Context,
      _Out_ PVOID *Cookie
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrUnregisterDllNotification(
      _In_ PVOID Cookie
      );
  
  #endif
  
  // end_msdn
  
  // rev
  NTSYSAPI
  PUNICODE_STRING
  NTAPI
  LdrStandardizeSystemPath(
      _In_ PUNICODE_STRING SystemPath
      );
  
  #if (PHNT_VERSION >= PHNT_WINBLUE)
  typedef struct _LDR_FAILURE_DATA
  {
      NTSTATUS Status;
      WCHAR DllName[0x20];
      WCHAR AdditionalInfo[0x20];
  } LDR_FAILURE_DATA, *PLDR_FAILURE_DATA;
  
  NTSYSAPI
  PLDR_FAILURE_DATA
  NTAPI
  LdrGetFailureData(
      VOID
      );
  #endif
  
  // private
  typedef struct _PS_MITIGATION_OPTIONS_MAP
  {
      ULONG_PTR Map[2];
  } PS_MITIGATION_OPTIONS_MAP, *PPS_MITIGATION_OPTIONS_MAP;
  
  // private
  typedef struct _PS_MITIGATION_AUDIT_OPTIONS_MAP
  {
      ULONG_PTR Map[2];
  } PS_MITIGATION_AUDIT_OPTIONS_MAP, *PPS_MITIGATION_AUDIT_OPTIONS_MAP;
  
  // private
  typedef struct _PS_SYSTEM_DLL_INIT_BLOCK
  {
      ULONG Size;
      ULONG_PTR SystemDllWowRelocation;
      ULONG_PTR SystemDllNativeRelocation;
      ULONG_PTR Wow64SharedInformation[16];
      ULONG RngData;
      union
      {
          ULONG Flags;
          struct
          {
              ULONG CfgOverride : 1;
              ULONG Reserved : 31;
          };
      };
      PS_MITIGATION_OPTIONS_MAP MitigationOptionsMap;
      ULONG_PTR CfgBitMap;
      ULONG_PTR CfgBitMapSize;
      ULONG_PTR Wow64CfgBitMap;
      ULONG_PTR Wow64CfgBitMapSize;
      PS_MITIGATION_AUDIT_OPTIONS_MAP MitigationAuditOptionsMap; // REDSTONE3
  } PS_SYSTEM_DLL_INIT_BLOCK, *PPS_SYSTEM_DLL_INIT_BLOCK;
  
  #if (PHNT_VERSION >= PHNT_THRESHOLD)
  // rev
  NTSYSAPI
  PPS_SYSTEM_DLL_INIT_BLOCK
  NTAPI
  LdrSystemDllInitBlock(
      VOID
      );
  #endif
  
  // Load as data table
  
  #if (PHNT_VERSION >= PHNT_VISTA)
  
  // private
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrAddLoadAsDataTable(
      _In_ PVOID Module,
      _In_ PWSTR FilePath,
      _In_ SIZE_T Size,
      _In_ HANDLE Handle
      );
  
  // private
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrRemoveLoadAsDataTable(
      _In_ PVOID InitModule,
      _Out_opt_ PVOID *BaseModule,
      _Out_opt_ PSIZE_T Size,
      _In_ ULONG Flags
      );
  
  // private
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrGetFileNameFromLoadAsDataTable(
      _In_ PVOID Module,
      _Out_ PVOID *pFileNamePrt
      );
  
  #endif
  
  NTSYSAPI
  NTSTATUS 
  NTAPI 
  LdrDisableThreadCalloutsForDll(
      _In_ PVOID DllImageBase
      );
      
  // Resources
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrAccessResource(
      _In_ PVOID DllHandle,
      _In_ PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,
      _Out_opt_ PVOID *ResourceBuffer,
      _Out_opt_ ULONG *ResourceLength
      );
  
  typedef struct _LDR_RESOURCE_INFO
  {
      ULONG_PTR Type;
      ULONG_PTR Name;
      ULONG_PTR Language;
  } LDR_RESOURCE_INFO, *PLDR_RESOURCE_INFO;
  
  #define RESOURCE_TYPE_LEVEL 0
  #define RESOURCE_NAME_LEVEL 1
  #define RESOURCE_LANGUAGE_LEVEL 2
  #define RESOURCE_DATA_LEVEL 3
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrFindResource_U(
      _In_ PVOID DllHandle,
      _In_ PLDR_RESOURCE_INFO ResourceInfo,
      _In_ ULONG Level,
      _Out_ PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrFindResourceDirectory_U(
      _In_ PVOID DllHandle,
      _In_ PLDR_RESOURCE_INFO ResourceInfo,
      _In_ ULONG Level,
      _Out_ PIMAGE_RESOURCE_DIRECTORY *ResourceDirectory
      );
  
  // private 
  typedef struct _LDR_ENUM_RESOURCE_ENTRY
  {
      union
      {
          ULONG_PTR NameOrId;
          PIMAGE_RESOURCE_DIRECTORY_STRING Name;
          struct
          {
              USHORT Id;
              USHORT NameIsPresent;
          };
      } Path[3];
      PVOID Data;
      ULONG Size;
      ULONG Reserved;
  } LDR_ENUM_RESOURCE_ENTRY, *PLDR_ENUM_RESOURCE_ENTRY;
  
  #define NAME_FROM_RESOURCE_ENTRY(RootDirectory, Entry) \
      ((Entry)->NameIsString ? (ULONG_PTR)PTR_ADD_OFFSET((RootDirectory), (Entry)->NameOffset) : (Entry)->Id)
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrEnumResources(
      _In_ PVOID DllHandle,
      _In_ PLDR_RESOURCE_INFO ResourceInfo,
      _In_ ULONG Level,
      _Inout_ ULONG *ResourceCount,
      _Out_writes_to_opt_(*ResourceCount, *ResourceCount) PLDR_ENUM_RESOURCE_ENTRY Resources
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrFindEntryForAddress(
      _In_ PVOID DllHandle,
      _Out_ PLDR_DATA_TABLE_ENTRY *Entry
      );
  
  #endif // (PHNT_MODE != PHNT_MODE_KERNEL)
  
  // Module information
  
  typedef struct _RTL_PROCESS_MODULE_INFORMATION
  {
      HANDLE Section;
      PVOID MappedBase;
      PVOID ImageBase;
      ULONG ImageSize;
      ULONG Flags;
      USHORT LoadOrderIndex;
      USHORT InitOrderIndex;
      USHORT LoadCount;
      USHORT OffsetToFileName;
      UCHAR FullPathName[256];
  } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
  
  typedef struct _RTL_PROCESS_MODULES
  {
      ULONG NumberOfModules;
      RTL_PROCESS_MODULE_INFORMATION Modules[1];
  } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
  
  // private
  typedef struct _RTL_PROCESS_MODULE_INFORMATION_EX
  {
      USHORT NextOffset;
      RTL_PROCESS_MODULE_INFORMATION BaseInfo;
      ULONG ImageChecksum;
      ULONG TimeDateStamp;
      PVOID DefaultBase;
  } RTL_PROCESS_MODULE_INFORMATION_EX, *PRTL_PROCESS_MODULE_INFORMATION_EX;
  
  #if (PHNT_MODE != PHNT_MODE_KERNEL)
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrQueryProcessModuleInformation(
      _In_opt_ PRTL_PROCESS_MODULES ModuleInformation,
      _In_opt_ ULONG Size,
      _Out_ PULONG ReturnedSize
      );
  
  typedef VOID (NTAPI *PLDR_ENUM_CALLBACK)(
      _In_ PLDR_DATA_TABLE_ENTRY ModuleInformation, 
      _In_ PVOID Parameter, 
      _Out_ BOOLEAN *Stop
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrEnumerateLoadedModules(
      _In_ BOOLEAN ReservedFlag,
      _In_ PLDR_ENUM_CALLBACK EnumProc,
      _In_ PVOID Context
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrOpenImageFileOptionsKey(
      _In_ PUNICODE_STRING SubKey,
      _In_ BOOLEAN Wow64,
      _Out_ PHANDLE NewKeyHandle
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrQueryImageFileKeyOption(
      _In_ HANDLE KeyHandle,
      _In_ PCWSTR ValueName,
      _In_ ULONG Type,
      _Out_ PVOID Buffer,
      _In_ ULONG BufferSize,
      _Out_opt_ PULONG ReturnedLength
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrQueryImageFileExecutionOptions(
      _In_ PUNICODE_STRING SubKey,
      _In_ PCWSTR ValueName,
      _In_ ULONG ValueSize,
      _Out_ PVOID Buffer,
      _In_ ULONG BufferSize,
      _Out_opt_ PULONG ReturnedLength
      );
  
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrQueryImageFileExecutionOptionsEx(
      _In_ PUNICODE_STRING SubKey,
      _In_ PCWSTR ValueName,
      _In_ ULONG Type,
      _Out_ PVOID Buffer,
      _In_ ULONG BufferSize,
      _Out_opt_ PULONG ReturnedLength,
      _In_ BOOLEAN Wow64
      );
  
  // private
  typedef struct _DELAYLOAD_PROC_DESCRIPTOR
  {
      ULONG ImportDescribedByName;
      union
      {
          PCSTR Name;
          ULONG Ordinal;
      } Description;
  } DELAYLOAD_PROC_DESCRIPTOR, *PDELAYLOAD_PROC_DESCRIPTOR;
  
  // private
  typedef struct _DELAYLOAD_INFO
  {
      ULONG Size;
      PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor;
      PIMAGE_THUNK_DATA ThunkAddress;
      PCSTR TargetDllName;
      DELAYLOAD_PROC_DESCRIPTOR TargetApiDescriptor;
      PVOID TargetModuleBase;
      PVOID Unused;
      ULONG LastError;
  } DELAYLOAD_INFO, *PDELAYLOAD_INFO;
  
  // private
  typedef PVOID (NTAPI *PDELAYLOAD_FAILURE_DLL_CALLBACK)(
      _In_ ULONG NotificationReason,
      _In_ PDELAYLOAD_INFO DelayloadInfo
      );
  
  // rev
  typedef PVOID (NTAPI *PDELAYLOAD_FAILURE_SYSTEM_ROUTINE)(
      _In_ PCSTR DllName,
      _In_ PCSTR ProcName
      );
  
  // rev
  NTSYSAPI
  PVOID
  NTAPI
  LdrResolveDelayLoadedAPI(
      _In_ PVOID ParentModuleBase,
      _In_ PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor,
      _In_opt_ PDELAYLOAD_FAILURE_DLL_CALLBACK FailureDllHook,
      _In_opt_ PDELAYLOAD_FAILURE_SYSTEM_ROUTINE FailureSystemHook, // kernel32.DelayLoadFailureHook
      _Out_ PIMAGE_THUNK_DATA ThunkAddress,
      _Reserved_ ULONG Flags
      );
  
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrResolveDelayLoadsFromDll(
      _In_ PVOID ParentBase,
      _In_ PCSTR TargetDllName,
      _Reserved_ ULONG Flags
      );
  
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrSetDefaultDllDirectories(
      _In_ ULONG DirectoryFlags
      );
  
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrShutdownProcess(
      VOID
      );
  
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrShutdownThread(
      VOID
      );
  
  // rev
  NTSYSAPI
  NTSTATUS
  NTAPI
  LdrSetImplicitPathOptions(
      _In_ ULONG ImplicitPathOptions
      );
  
  // rev
  NTSYSAPI
  BOOLEAN
  NTAPI
  LdrControlFlowGuardEnforced(
      VOID
      );
  
  #if (PHNT_VERSION >= PHNT_19H1)
  // rev
  NTSYSAPI
  BOOLEAN
  NTAPI
  LdrIsModuleSxsRedirected(
      _In_ PVOID DllHandle
      );
  #endif
  
  #endif // (PHNT_MODE != PHNT_MODE_KERNEL)
  
  #endif
  