ReactOS  0.4.15-dev-4927-gfe8f806
handle.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for handle.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define SizeOfHandle(x)   (sizeof(HANDLE) * (x))
 
#define INDEX_TO_HANDLE_VALUE(x)   ((x) << HANDLE_TAG_BITS)
 
#define strtoulptr   strtoul
 

Functions

VOID NTAPI ExpInitializeHandleTables (VOID)
 
PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry (IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle)
 
PVOID NTAPI ExpAllocateTablePagedPool (IN PEPROCESS Process OPTIONAL, IN SIZE_T Size)
 
PVOID NTAPI ExpAllocateTablePagedPoolNoZero (IN PEPROCESS Process OPTIONAL, IN SIZE_T Size)
 
VOID NTAPI ExpFreeTablePagedPool (IN PEPROCESS Process OPTIONAL, IN PVOID Buffer, IN SIZE_T Size)
 
VOID NTAPI ExpFreeLowLevelTable (IN PEPROCESS Process, IN PHANDLE_TABLE_ENTRY TableEntry)
 
VOID NTAPI ExpFreeHandleTable (IN PHANDLE_TABLE HandleTable)
 
VOID NTAPI ExpFreeHandleTableEntry (IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
 
PHANDLE_TABLE NTAPI ExpAllocateHandleTable (IN PEPROCESS Process OPTIONAL, IN BOOLEAN NewTable)
 
PHANDLE_TABLE_ENTRY NTAPI ExpAllocateLowLevelTable (IN PHANDLE_TABLE HandleTable, IN BOOLEAN DoInit)
 
PHANDLE_TABLE_ENTRY *NTAPI ExpAllocateMidLevelTable (IN PHANDLE_TABLE HandleTable, IN BOOLEAN DoInit, OUT PHANDLE_TABLE_ENTRY *LowTableEntry)
 
BOOLEAN NTAPI ExpAllocateHandleTableEntrySlow (IN PHANDLE_TABLE HandleTable, IN BOOLEAN DoInit)
 
ULONG NTAPI ExpMoveFreeHandles (IN PHANDLE_TABLE HandleTable)
 
PHANDLE_TABLE_ENTRY NTAPI ExpAllocateHandleTableEntry (IN PHANDLE_TABLE HandleTable, OUT PEXHANDLE NewHandle)
 
PHANDLE_TABLE NTAPI ExCreateHandleTable (IN PEPROCESS Process OPTIONAL)
 
HANDLE NTAPI ExCreateHandle (IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
 
VOID NTAPI ExpBlockOnLockedHandleEntry (IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
 
BOOLEAN NTAPI ExpLockHandleTableEntry (IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
 
VOID NTAPI ExUnlockHandleTableEntry (IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
 
VOID NTAPI ExRemoveHandleTable (IN PHANDLE_TABLE HandleTable)
 
VOID NTAPI ExDestroyHandleTable (IN PHANDLE_TABLE HandleTable, IN PVOID DestroyHandleProcedure OPTIONAL)
 
BOOLEAN NTAPI ExDestroyHandle (IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL)
 
PHANDLE_TABLE_ENTRY NTAPI ExMapHandleToPointer (IN PHANDLE_TABLE HandleTable, IN HANDLE Handle)
 
PHANDLE_TABLE NTAPI ExDupHandleTable (IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, IN ULONG_PTR Mask)
 
BOOLEAN NTAPI ExChangeHandle (IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, IN ULONG_PTR Context)
 
VOID NTAPI ExSweepHandleTable (IN PHANDLE_TABLE HandleTable, IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, IN PVOID Context)
 
BOOLEAN NTAPI ExEnumHandleTable (IN PHANDLE_TABLE HandleTable, IN PEX_ENUM_HANDLE_CALLBACK EnumHandleProcedure, IN OUT PVOID Context, OUT PHANDLE EnumHandle OPTIONAL)
 

Variables

LIST_ENTRY HandleTableListHead
 
EX_PUSH_LOCK HandleTableListLock
 

Macro Definition Documentation

◆ INDEX_TO_HANDLE_VALUE

#define INDEX_TO_HANDLE_VALUE (   x)    ((x) << HANDLE_TAG_BITS)

Definition at line 21 of file handle.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file handle.c.

◆ SizeOfHandle

#define SizeOfHandle (   x)    (sizeof(HANDLE) * (x))

Definition at line 20 of file handle.c.

◆ strtoulptr

#define strtoulptr   strtoul

Definition at line 28 of file handle.c.

Function Documentation

◆ ExChangeHandle()

BOOLEAN NTAPI ExChangeHandle ( IN PHANDLE_TABLE  HandleTable,
IN HANDLE  Handle,
IN PEX_CHANGE_HANDLE_CALLBACK  ChangeRoutine,
IN ULONG_PTR  Context 
)

Definition at line 1189 of file handle.c.

1193 {
1194  EXHANDLE ExHandle;
1195  PHANDLE_TABLE_ENTRY HandleTableEntry;
1196  BOOLEAN Result = FALSE;
1197  PAGED_CODE();
1198 
1199  /* Set the handle value */
1200  ExHandle.GenericHandleOverlay = Handle;
1201 
1202  /* Find the entry for this handle */
1203  HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, ExHandle);
1204 
1205  /* Make sure that we found an entry, and that it's valid */
1206  if (!(HandleTableEntry) ||
1207  !(HandleTableEntry->Object) ||
1208  (HandleTableEntry->NextFreeTableEntry == -2))
1209  {
1210  /* It isn't, fail */
1211  return FALSE;
1212  }
1213 
1214  /* Enter a critical region */
1216 
1217  /* Try locking the handle entry */
1218  if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
1219  {
1220  /* Call the change routine and unlock the entry */
1221  Result = ChangeRoutine(HandleTableEntry, Context);
1222  ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
1223  }
1224 
1225  /* Leave the critical region and return the callback result */
1227  return Result;
1228 }
PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle)
Definition: handle.c:43
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
VOID NTAPI ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:923
#define FALSE
Definition: types.h:117
Definition: extypes.h:595
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
HANDLE GenericHandleOverlay
Definition: ex.h:100
BOOLEAN NTAPI ExpLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:884
Definition: ex.h:84
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
LONG NextFreeTableEntry
Definition: extypes.h:612
_In_ HANDLE Handle
Definition: extypes.h:390
PVOID Object
Definition: extypes.h:599
#define PAGED_CODE()

Referenced by NtSetInformationObject(), and ObSetHandleAttributes().

◆ ExCreateHandle()

HANDLE NTAPI ExCreateHandle ( IN PHANDLE_TABLE  HandleTable,
IN PHANDLE_TABLE_ENTRY  HandleTableEntry 
)

Definition at line 827 of file handle.c.

829 {
831  PHANDLE_TABLE_ENTRY NewEntry;
832  PAGED_CODE();
833 
834  /* Start with a clean handle */
835  Handle.GenericHandleOverlay = NULL;
836 
837  /* Allocate a new entry */
839  if (NewEntry)
840  {
841  /* Enter a critical region */
843 
844  /* Write the entry */
845  *NewEntry = *HandleTableEntry;
846 
847  /* Unlock it and leave the critical region */
850  }
851 
852  /* Return the handle value */
853  return Handle.GenericHandleOverlay;
854 }
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
VOID NTAPI ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:923
Definition: extypes.h:595
PHANDLE_TABLE_ENTRY NTAPI ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable, OUT PEXHANDLE NewHandle)
Definition: handle.c:683
Definition: ex.h:84
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define NULL
Definition: types.h:112
_In_ HANDLE Handle
Definition: extypes.h:390
#define PAGED_CODE()

Referenced by ObDuplicateObject(), ObpCreateHandle(), ObpCreateUnnamedHandle(), PspCreateProcess(), PspCreateThread(), and RtlpCreateAtomHandle().

◆ ExCreateHandleTable()

PHANDLE_TABLE NTAPI ExCreateHandleTable ( IN PEPROCESS Process  OPTIONAL)

Definition at line 801 of file handle.c.

802 {
804  PAGED_CODE();
805 
806  /* Allocate the handle table */
808  if (!HandleTable) return NULL;
809 
810  /* Acquire the handle table lock */
813 
814  /* Insert it into the list */
815  InsertTailList(&HandleTableListHead, &HandleTable->HandleTableList);
816 
817  /* Release the lock */
820 
821  /* Return the handle table */
822  return HandleTable;
823 }
PHANDLE_TABLE NTAPI ExpAllocateHandleTable(IN PEPROCESS Process OPTIONAL, IN BOOLEAN NewTable)
Definition: handle.c:331
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1034
#define TRUE
Definition: types.h:120
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define InsertTailList(ListHead, Entry)
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1250
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
EX_PUSH_LOCK HandleTableListLock
Definition: handle.c:19
LIST_ENTRY HandleTableListHead
Definition: handle.c:18
#define PAGED_CODE()

Referenced by ObInitProcess(), ObInitSystem(), PspInitPhase0(), and RtlpCreateAtomHandleTable().

◆ ExDestroyHandle()

BOOLEAN NTAPI ExDestroyHandle ( IN PHANDLE_TABLE  HandleTable,
IN HANDLE  Handle,
IN PHANDLE_TABLE_ENTRY HandleTableEntry  OPTIONAL 
)

Definition at line 984 of file handle.c.

987 {
988  EXHANDLE ExHandle;
989  PVOID Object;
990  PAGED_CODE();
991 
992  /* Setup the actual handle value */
993  ExHandle.GenericHandleOverlay = Handle;
994 
995  /* Enter a critical region and check if we have to lookup the handle */
997  if (!HandleTableEntry)
998  {
999  /* Lookup the entry */
1000  HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, ExHandle);
1001 
1002  /* Make sure that we found an entry, and that it's valid */
1003  if (!(HandleTableEntry) ||
1004  !(HandleTableEntry->Object) ||
1005  (HandleTableEntry->NextFreeTableEntry == -2))
1006  {
1007  /* Invalid handle, fail */
1009  return FALSE;
1010  }
1011 
1012  /* Lock the entry */
1013  if (!ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
1014  {
1015  /* Couldn't lock, fail */
1017  return FALSE;
1018  }
1019  }
1020  else
1021  {
1022  /* Make sure the handle is locked */
1023  ASSERT((HandleTableEntry->Value & EXHANDLE_TABLE_ENTRY_LOCK_BIT) == 0);
1024  }
1025 
1026  /* Clear the handle */
1027  Object = InterlockedExchangePointer((PVOID*)&HandleTableEntry->Object, NULL);
1028 
1029  /* Sanity checks */
1030  ASSERT(Object != NULL);
1032 
1033  /* Unblock the pushlock */
1034  ExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL);
1035 
1036  /* Free the actual entry */
1037  ExpFreeHandleTableEntry(HandleTable, ExHandle, HandleTableEntry);
1038 
1039  /* If we got here, return success */
1041  return TRUE;
1042 }
PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle)
Definition: handle.c:43
#define TRUE
Definition: types.h:120
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define ASSERT(a)
Definition: mode.c:44
HANDLE GenericHandleOverlay
Definition: ex.h:100
BOOLEAN NTAPI ExpLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:884
Definition: ex.h:84
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define EXHANDLE_TABLE_ENTRY_LOCK_BIT
Definition: ex.h:144
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define NULL
Definition: types.h:112
VOID FASTCALL ExfUnblockPushLock(PEX_PUSH_LOCK PushLock, PVOID CurrentWaitBlock)
Definition: pushlock.c:1205
_In_ HANDLE Handle
Definition: extypes.h:390
VOID NTAPI ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:279
#define PAGED_CODE()

Referenced by ObpCloseHandleTableEntry(), PspDeleteProcess(), PspDeleteThread(), RtlpCloseHandleCallback(), RtlpCreateAtomHandle(), and RtlpFreeAtomHandle().

◆ ExDestroyHandleTable()

VOID NTAPI ExDestroyHandleTable ( IN PHANDLE_TABLE  HandleTable,
IN PVOID DestroyHandleProcedure  OPTIONAL 
)

Definition at line 963 of file handle.c.

965 {
966  PAGED_CODE();
967 
968  /* Remove the handle from the list */
970 
971  /* Check if we have a destroy callback */
972  if (DestroyHandleProcedure)
973  {
974  /* FIXME: */
975  ASSERT(FALSE);
976  }
977 
978  /* Free the handle table */
980 }
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
VOID NTAPI ExRemoveHandleTable(IN PHANDLE_TABLE HandleTable)
Definition: handle.c:944
VOID NTAPI ExpFreeHandleTable(IN PHANDLE_TABLE HandleTable)
Definition: handle.c:202
#define PAGED_CODE()

Referenced by ObKillProcess(), and RtlpDestroyAtomHandleTable().

◆ ExDupHandleTable()

PHANDLE_TABLE NTAPI ExDupHandleTable ( IN PEPROCESS  Process,
IN PHANDLE_TABLE  HandleTable,
IN PEX_DUPLICATE_HANDLE_CALLBACK  DupHandleProcedure,
IN ULONG_PTR  Mask 
)

Definition at line 1072 of file handle.c.

1076 {
1077  PHANDLE_TABLE NewTable;
1078  EXHANDLE Handle;
1079  PHANDLE_TABLE_ENTRY HandleTableEntry, NewEntry;
1080  BOOLEAN Failed = FALSE;
1081  PAGED_CODE();
1082 
1083  /* Allocate the duplicated copy */
1084  NewTable = ExpAllocateHandleTable(Process, FALSE);
1085  if (!NewTable) return NULL;
1086 
1087  /* Loop each entry */
1088  while (NewTable->NextHandleNeedingPool <
1089  HandleTable->NextHandleNeedingPool)
1090  {
1091  /* Insert it into the duplicated copy */
1092  if (!ExpAllocateHandleTableEntrySlow(NewTable, FALSE))
1093  {
1094  /* Insert failed, free the new copy and return */
1095  ExpFreeHandleTable(NewTable);
1096  return NULL;
1097  }
1098  }
1099 
1100  /* Setup the initial handle table data */
1101  NewTable->HandleCount = 0;
1102  NewTable->ExtraInfoPages = 0;
1103  NewTable->FirstFree = 0;
1104 
1105  /* Setup the first handle value */
1106  Handle.Value = INDEX_TO_HANDLE_VALUE(1);
1107 
1108  /* Enter a critical region and lookup the new entry */
1110  while ((NewEntry = ExpLookupHandleTableEntry(NewTable, Handle)))
1111  {
1112  /* Lookup the old entry */
1113  HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle);
1114 
1115  /* Loop each entry */
1116  do
1117  {
1118  /* Check if it doesn't match the audit mask */
1119  if (!(HandleTableEntry->Value & Mask))
1120  {
1121  /* Free it since we won't use it */
1122  Failed = TRUE;
1123  }
1124  else
1125  {
1126  /* Lock the entry */
1127  if (!ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
1128  {
1129  /* Free it since we can't lock it, so we won't use it */
1130  Failed = TRUE;
1131  }
1132  else
1133  {
1134  /* Copy the handle value */
1135  *NewEntry = *HandleTableEntry;
1136 
1137  /* Call the duplicate callback */
1138  if (DupHandleProcedure(Process,
1139  HandleTable,
1140  HandleTableEntry,
1141  NewEntry))
1142  {
1143  /* Clear failure flag */
1144  Failed = FALSE;
1145 
1146  /* Lock the entry, increase the handle count */
1147  NewEntry->Value |= EXHANDLE_TABLE_ENTRY_LOCK_BIT;
1148  NewTable->HandleCount++;
1149  }
1150  else
1151  {
1152  /* Duplication callback refused, fail */
1153  Failed = TRUE;
1154  }
1155  }
1156  }
1157 
1158  /* Check if we failed earlier and need to free */
1159  if (Failed)
1160  {
1161  /* Free this entry */
1162  NewEntry->Object = NULL;
1163  NewEntry->NextFreeTableEntry = NewTable->FirstFree;
1164  NewTable->FirstFree = (ULONG)Handle.Value;
1165  }
1166 
1167  /* Increase the handle value and move to the next entry */
1168  Handle.Value += INDEX_TO_HANDLE_VALUE(1);
1169  NewEntry++;
1170  HandleTableEntry++;
1171  } while (Handle.Value % INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES));
1172 
1173  /* We're done, skip the last entry */
1175  }
1176 
1177  /* Acquire the table lock and insert this new table into the list */
1181 
1182  /* Leave the critical region we entered previously and return the table */
1184  return NewTable;
1185 }
PHANDLE_TABLE NTAPI ExpAllocateHandleTable(IN PEPROCESS Process OPTIONAL, IN BOOLEAN NewTable)
Definition: handle.c:331
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1034
PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle)
Definition: handle.c:43
ULONG NextHandleNeedingPool
Definition: extypes.h:645
#define TRUE
Definition: types.h:120
LONG ExtraInfoPages
Definition: extypes.h:635
LIST_ENTRY HandleTableList
Definition: extypes.h:627
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define InsertTailList(ListHead, Entry)
#define FALSE
Definition: types.h:117
BOOLEAN NTAPI ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable, IN BOOLEAN DoInit)
Definition: handle.c:502
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1250
Definition: extypes.h:595
unsigned char BOOLEAN
LONG HandleCount
Definition: extypes.h:644
Definition: arc.h:79
BOOLEAN NTAPI ExpLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:884
#define INDEX_TO_HANDLE_VALUE(x)
Definition: handle.c:21
Definition: ex.h:84
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
processorSet Mask
#define EXHANDLE_TABLE_ENTRY_LOCK_BIT
Definition: ex.h:144
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
ULONG_PTR Value
Definition: extypes.h:602
#define LOW_LEVEL_ENTRIES
Definition: ex.h:150
VOID NTAPI ExpFreeHandleTable(IN PHANDLE_TABLE HandleTable)
Definition: handle.c:202
#define NULL
Definition: types.h:112
LONG NextFreeTableEntry
Definition: extypes.h:612
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
_In_ HANDLE Handle
Definition: extypes.h:390
EX_PUSH_LOCK HandleTableListLock
Definition: handle.c:19
unsigned int ULONG
Definition: retypes.h:1
PVOID Object
Definition: extypes.h:599
LIST_ENTRY HandleTableListHead
Definition: handle.c:18
#define PAGED_CODE()

Referenced by ObInitProcess().

◆ ExEnumHandleTable()

BOOLEAN NTAPI ExEnumHandleTable ( IN PHANDLE_TABLE  HandleTable,
IN PEX_ENUM_HANDLE_CALLBACK  EnumHandleProcedure,
IN OUT PVOID  Context,
OUT PHANDLE EnumHandle  OPTIONAL 
)

Definition at line 1271 of file handle.c.

1275 {
1276  EXHANDLE Handle;
1277  PHANDLE_TABLE_ENTRY HandleTableEntry;
1278  BOOLEAN Result = FALSE;
1279  PAGED_CODE();
1280 
1281  /* Enter a critical region */
1283 
1284  /* Set the initial value and loop the entries */
1285  Handle.Value = 0;
1286  while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
1287  {
1288  /* Validate the entry */
1289  if ((HandleTableEntry->Object) &&
1290  (HandleTableEntry->NextFreeTableEntry != -2))
1291  {
1292  /* Lock the entry */
1293  if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
1294  {
1295  /* Notify the callback routine */
1296  Result = EnumHandleProcedure(HandleTableEntry,
1297  Handle.GenericHandleOverlay,
1298  Context);
1299 
1300  /* Unlock it */
1301  ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
1302 
1303  /* Was this the one looked for? */
1304  if (Result)
1305  {
1306  /* If so, return it if requested */
1307  if (EnumHandle) *EnumHandle = Handle.GenericHandleOverlay;
1308  break;
1309  }
1310  }
1311  }
1312 
1313  /* Go to the next entry */
1314  Handle.Value += INDEX_TO_HANDLE_VALUE(1);
1315  }
1316 
1317  /* Leave the critical region and return callback result */
1319  return Result;
1320 }
PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle)
Definition: handle.c:43
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
VOID NTAPI ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:923
#define FALSE
Definition: types.h:117
Definition: extypes.h:595
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
BOOLEAN NTAPI ExpLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:884
#define INDEX_TO_HANDLE_VALUE(x)
Definition: handle.c:21
Definition: ex.h:84
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
LONG NextFreeTableEntry
Definition: extypes.h:612
_In_ HANDLE Handle
Definition: extypes.h:390
PVOID Object
Definition: extypes.h:599
#define PAGED_CODE()

Referenced by ObFindHandleForObject().

◆ ExMapHandleToPointer()

PHANDLE_TABLE_ENTRY NTAPI ExMapHandleToPointer ( IN PHANDLE_TABLE  HandleTable,
IN HANDLE  Handle 
)

Definition at line 1046 of file handle.c.

1048 {
1049  EXHANDLE ExHandle;
1050  PHANDLE_TABLE_ENTRY HandleTableEntry;
1051  PAGED_CODE();
1052 
1053  /* Set the handle value */
1054  ExHandle.GenericHandleOverlay = Handle;
1055 
1056  /* Fail if we got an invalid index */
1057  if (!(ExHandle.Index & (LOW_LEVEL_ENTRIES - 1))) return NULL;
1058 
1059  /* Do the lookup */
1060  HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, ExHandle);
1061  if (!HandleTableEntry) return NULL;
1062 
1063  /* Lock it */
1064  if (!ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) return NULL;
1065 
1066  /* Return the entry */
1067  return HandleTableEntry;
1068 }
PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle)
Definition: handle.c:43
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
ULONG_PTR Index
Definition: ex.h:89
Definition: extypes.h:595
HANDLE GenericHandleOverlay
Definition: ex.h:100
BOOLEAN NTAPI ExpLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:884
Definition: ex.h:84
#define LOW_LEVEL_ENTRIES
Definition: ex.h:150
#define NULL
Definition: types.h:112
_In_ HANDLE Handle
Definition: extypes.h:390
#define PAGED_CODE()

Referenced by NtWaitForMultipleObjects(), ObpCloseHandle(), ObpReferenceProcessObjectByHandle(), ObQueryObjectAuditingByHandle(), ObReferenceFileObjectForWrite(), ObReferenceObjectByHandle(), PsLookupProcessByProcessId(), PsLookupProcessThreadByCid(), PsLookupThreadByThreadId(), and RtlpGetAtomEntry().

◆ ExpAllocateHandleTable()

PHANDLE_TABLE NTAPI ExpAllocateHandleTable ( IN PEPROCESS Process  OPTIONAL,
IN BOOLEAN  NewTable 
)

Definition at line 331 of file handle.c.

333 {
335  PHANDLE_TABLE_ENTRY HandleTableTable, HandleEntry;
336  ULONG i;
338  PAGED_CODE();
339 
340  /* Allocate the table */
342  sizeof(HANDLE_TABLE),
344  if (!HandleTable) return NULL;
345 
346  /* Check if we have a process */
347  if (Process)
348  {
349  /* Charge quota */
351  if (!NT_SUCCESS(Status))
352  {
354  return NULL;
355  }
356  }
357 
358  /* Clear the table */
360 
361  /* Now allocate the first level structures */
363  if (!HandleTableTable)
364  {
365  /* Failed, free the table */
367 
368  /* Return the quota it was taking up */
369  if (Process)
370  {
372  }
373 
374  return NULL;
375  }
376 
377  /* Write the pointer to our first level structures */
378  HandleTable->TableCode = (ULONG_PTR)HandleTableTable;
379 
380  /* Initialize the first entry */
381  HandleEntry = &HandleTableTable[0];
382  HandleEntry->NextFreeTableEntry = -2;
383  HandleEntry->Value = 0;
384 
385  /* Check if this is a new table */
386  if (NewTable)
387  {
388  /* Go past the root entry */
389  HandleEntry++;
390 
391  /* Loop every low level entry */
392  for (i = 1; i < (LOW_LEVEL_ENTRIES - 1); i++)
393  {
394  /* Set up the free data */
395  HandleEntry->Value = 0;
396  HandleEntry->NextFreeTableEntry = INDEX_TO_HANDLE_VALUE(i + 1);
397 
398  /* Move to the next entry */
399  HandleEntry++;
400  }
401 
402  /* Terminate the last entry */
403  HandleEntry->Value = 0;
404  HandleEntry->NextFreeTableEntry = 0;
405  HandleTable->FirstFree = INDEX_TO_HANDLE_VALUE(1);
406  }
407 
408  /* Set the next handle needing pool after our allocated page from above */
409  HandleTable->NextHandleNeedingPool = INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES);
410 
411  /* Setup the rest of the handle table data */
412  HandleTable->QuotaProcess = Process;
413  HandleTable->UniqueProcessId = PsGetCurrentProcess()->UniqueProcessId;
414  HandleTable->Flags = 0;
415 
416  /* Loop all the handle table locks */
417  for (i = 0; i < 4; i++)
418  {
419  /* Initialize the handle table lock */
420  ExInitializePushLock(&HandleTable->HandleTableLock[i]);
421  }
422 
423  /* Initialize the contention event lock and return the lock */
424  ExInitializePushLock(&HandleTable->HandleContentionEvent);
425  return HandleTable;
426 }
LONG NTSTATUS
Definition: precomp.h:26
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define PsGetCurrentProcess
Definition: psfuncs.h:17
Definition: extypes.h:595
#define ExInitializePushLock
Definition: ex.h:1011
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define INDEX_TO_HANDLE_VALUE(x)
Definition: handle.c:21
VOID NTAPI PsReturnProcessPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the paged pool quota that the process was taking up.
Definition: quota.c:965
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TAG_OBJECT_TABLE
Definition: tag.h:26
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSTATUS NTAPI PsChargeProcessPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the paged pool quota of a given process.
Definition: quota.c:839
PVOID NTAPI ExpAllocateTablePagedPoolNoZero(IN PEPROCESS Process OPTIONAL, IN SIZE_T Size)
Definition: handle.c:139
ULONG_PTR Value
Definition: extypes.h:602
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define LOW_LEVEL_ENTRIES
Definition: ex.h:150
#define NULL
Definition: types.h:112
LONG NextFreeTableEntry
Definition: extypes.h:612
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by ExCreateHandleTable(), and ExDupHandleTable().

◆ ExpAllocateHandleTableEntry()

PHANDLE_TABLE_ENTRY NTAPI ExpAllocateHandleTableEntry ( IN PHANDLE_TABLE  HandleTable,
OUT PEXHANDLE  NewHandle 
)

Definition at line 683 of file handle.c.

685 {
686  ULONG OldValue, NewValue, NewValue1;
688  EXHANDLE Handle, OldHandle;
689  BOOLEAN Result;
690  ULONG i;
691 
692  /* Start allocation loop */
693  for (;;)
694  {
695  /* Get the current link */
696  OldValue = HandleTable->FirstFree;
697  while (!OldValue)
698  {
699  /* No free entries remain, lock the handle table */
701  ExAcquirePushLockExclusive(&HandleTable->HandleTableLock[0]);
702 
703  /* Check the value again */
704  OldValue = HandleTable->FirstFree;
705  if (OldValue)
706  {
707  /* Another thread has already created a new level, bail out */
708  ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]);
710  break;
711  }
712 
713  /* Now move any free handles */
714  OldValue = ExpMoveFreeHandles(HandleTable);
715  if (OldValue)
716  {
717  /* Another thread has already moved them, bail out */
718  ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]);
720  break;
721  }
722 
723  /* We're the first one through, so do the actual allocation */
725 
726  /* Unlock the table and get the value now */
727  ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]);
729  OldValue = HandleTable->FirstFree;
730 
731  /* Check if allocation failed */
732  if (!Result)
733  {
734  /* Check if nobody else went through here */
735  if (!OldValue)
736  {
737  /* We're still the only thread around, so fail */
738  NewHandle->GenericHandleOverlay = NULL;
739  return NULL;
740  }
741  }
742  }
743 
744  /* We made it, write the current value */
745  Handle.Value = (OldValue & FREE_HANDLE_MASK);
746 
747  /* Lookup the entry for this handle */
749 
750  /* Get an available lock and acquire it */
751  OldHandle.Value = OldValue;
752  i = OldHandle.Index % 4;
754  ExAcquirePushLockShared(&HandleTable->HandleTableLock[i]);
755 
756  /* Check if the value changed after acquiring the lock */
757  if (OldValue != *(volatile ULONG*)&HandleTable->FirstFree)
758  {
759  /* It did, so try again */
760  ExReleasePushLockShared(&HandleTable->HandleTableLock[i]);
762  continue;
763  }
764 
765  /* Now get the next value and do the compare */
766  NewValue = *(volatile ULONG*)&Entry->NextFreeTableEntry;
767  NewValue1 = InterlockedCompareExchange((PLONG) &HandleTable->FirstFree,
768  NewValue,
769  OldValue);
770 
771  /* The change was done, so release the lock */
772  ExReleasePushLockShared(&HandleTable->HandleTableLock[i]);
774 
775  /* Check if the compare was successful */
776  if (NewValue1 == OldValue)
777  {
778  /* Make sure that the new handle is in range, and break out */
779  ASSERT((NewValue & FREE_HANDLE_MASK) <
780  HandleTable->NextHandleNeedingPool);
781  break;
782  }
783  else
784  {
785  /* The compare failed, make sure we expected it */
786  ASSERT((NewValue1 & FREE_HANDLE_MASK) !=
787  (OldValue & FREE_HANDLE_MASK));
788  }
789  }
790 
791  /* Increase the number of handles */
792  InterlockedIncrement(&HandleTable->HandleCount);
793 
794  /* Return the handle and the entry */
795  *NewHandle = Handle;
796  return Entry;
797 }
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1034
PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle)
Definition: handle.c:43
struct _Entry Entry
Definition: kefuncs.h:629
#define TRUE
Definition: types.h:120
#define InterlockedCompareExchange
Definition: interlocked.h:104
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
ULONG_PTR Index
Definition: ex.h:89
BOOLEAN NTAPI ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable, IN BOOLEAN DoInit)
Definition: handle.c:502
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1250
Definition: extypes.h:595
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define ASSERT(a)
Definition: mode.c:44
#define FREE_HANDLE_MASK
Definition: ex.h:145
Definition: ex.h:84
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
ULONG NTAPI ExpMoveFreeHandles(IN PHANDLE_TABLE HandleTable)
Definition: handle.c:648
FORCEINLINE VOID ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1103
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define InterlockedIncrement
Definition: armddk.h:53
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
_In_ HANDLE Handle
Definition: extypes.h:390
FORCEINLINE VOID ExReleasePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1211
unsigned int ULONG
Definition: retypes.h:1
ULONG_PTR Value
Definition: ex.h:101
signed int * PLONG
Definition: retypes.h:5
base of all file and directory entries
Definition: entries.h:82

Referenced by ExCreateHandle().

◆ ExpAllocateHandleTableEntrySlow()

BOOLEAN NTAPI ExpAllocateHandleTableEntrySlow ( IN PHANDLE_TABLE  HandleTable,
IN BOOLEAN  DoInit 
)

Definition at line 502 of file handle.c.

504 {
505  ULONG i, j, Index;
506  PHANDLE_TABLE_ENTRY Low = NULL, *Mid, **High, *SecondLevel, **ThirdLevel;
507  ULONG NewFree, FirstFree;
508  PVOID Value;
509  ULONG_PTR TableCode = HandleTable->TableCode;
510  ULONG_PTR TableBase = TableCode & ~3;
511  ULONG TableLevel = (ULONG)(TableCode & 3);
512  PAGED_CODE();
513 
514  /* Check how many levels we already have */
515  if (TableLevel == 0)
516  {
517  /* Allocate a mid level, since we only have a low level */
518  Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low);
519  if (!Mid) return FALSE;
520 
521  /* Link up the tables */
522  Mid[1] = Mid[0];
523  Mid[0] = (PVOID)TableBase;
524 
525  /* Write the new level and attempt to change the table code */
526  TableBase = ((ULONG_PTR)Mid) | 1;
527  Value = InterlockedExchangePointer((PVOID*)&HandleTable->TableCode, (PVOID)TableBase);
528  }
529  else if (TableLevel == 1)
530  {
531  /* Setup the 2nd level table */
532  SecondLevel = (PVOID)TableBase;
533 
534  /* Get if the next index can fit in the table */
535  i = HandleTable->NextHandleNeedingPool /
537  if (i < MID_LEVEL_ENTRIES)
538  {
539  /* We need to allocate a new table */
541  if (!Low) return FALSE;
542 
543  /* Update the table */
544  Value = InterlockedExchangePointer((PVOID*)&SecondLevel[i], Low);
545  ASSERT(Value == NULL);
546  }
547  else
548  {
549  /* We need a new high level table */
552  if (!High) return FALSE;
553 
554  /* Allocate a new mid level table as well */
555  Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low);
556  if (!Mid)
557  {
558  /* We failed, free the high level table as well */
559  ExpFreeTablePagedPool(HandleTable->QuotaProcess,
560  High,
562  return FALSE;
563  }
564 
565  /* Link up the tables */
566  High[0] = (PVOID)TableBase;
567  High[1] = Mid;
568 
569  /* Write the new table and change the table code */
570  TableBase = ((ULONG_PTR)High) | 2;
572  (PVOID)TableBase);
573  }
574  }
575  else if (TableLevel == 2)
576  {
577  /* Setup the 3rd level table */
578  ThirdLevel = (PVOID)TableBase;
579 
580  /* Get the index and check if it can fit */
581  i = HandleTable->NextHandleNeedingPool / INDEX_TO_HANDLE_VALUE(MAX_MID_INDEX);
582  if (i >= HIGH_LEVEL_ENTRIES) return FALSE;
583 
584  /* Check if there's no mid-level table */
585  if (!ThirdLevel[i])
586  {
587  /* Allocate a new mid level table */
588  Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low);
589  if (!Mid) return FALSE;
590 
591  /* Update the table pointer */
592  Value = InterlockedExchangePointer((PVOID*)&ThirdLevel[i], Mid);
593  ASSERT(Value == NULL);
594  }
595  else
596  {
597  /* We have one, check at which index we should insert our entry */
598  Index = (HandleTable->NextHandleNeedingPool / INDEX_TO_HANDLE_VALUE(1)) -
599  i * MAX_MID_INDEX;
601 
602  /* Allocate a new low level */
604  if (!Low) return FALSE;
605 
606  /* Update the table pointer */
607  Value = InterlockedExchangePointer((PVOID*)&ThirdLevel[i][j], Low);
608  ASSERT(Value == NULL);
609  }
610  }
611  else
612  {
613  /* Something is really broken */
614  ASSERT(FALSE);
615  }
616 
617  /* Update the index of the next handle */
618  Index = InterlockedExchangeAdd((PLONG) &HandleTable->NextHandleNeedingPool,
620 
621  /* Check if need to initialize the table */
622  if (DoInit)
623  {
624  /* Create a new index number */
626 
627  /* Start free index change loop */
628  for (;;)
629  {
630  /* Setup the first free index */
631  FirstFree = HandleTable->FirstFree;
632  Low[LOW_LEVEL_ENTRIES - 1].NextFreeTableEntry = FirstFree;
633 
634  /* Change the index */
635  NewFree = InterlockedCompareExchange((PLONG) &HandleTable->FirstFree,
636  Index,
637  FirstFree);
638  if (NewFree == FirstFree) break;
639  }
640  }
641 
642  /* All done */
643  return TRUE;
644 }
#define TRUE
Definition: types.h:120
PHANDLE_TABLE_ENTRY NTAPI ExpAllocateLowLevelTable(IN PHANDLE_TABLE HandleTable, IN BOOLEAN DoInit)
Definition: handle.c:430
#define InterlockedCompareExchange
Definition: interlocked.h:104
PHANDLE_TABLE_ENTRY *NTAPI ExpAllocateMidLevelTable(IN PHANDLE_TABLE HandleTable, IN BOOLEAN DoInit, OUT PHANDLE_TABLE_ENTRY *LowTableEntry)
Definition: handle.c:475
Definition: strmini.h:380
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
#define SizeOfHandle(x)
Definition: handle.c:20
Definition: extypes.h:595
PVOID NTAPI ExpAllocateTablePagedPool(IN PEPROCESS Process OPTIONAL, IN SIZE_T Size)
Definition: handle.c:107
VOID NTAPI ExpFreeTablePagedPool(IN PEPROCESS Process OPTIONAL, IN PVOID Buffer, IN SIZE_T Size)
Definition: handle.c:168
void * PVOID
Definition: retypes.h:9
#define InterlockedExchangeAdd
Definition: interlocked.h:181
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define ASSERT(a)
Definition: mode.c:44
_In_ WDFCOLLECTION _In_ ULONG Index
#define INDEX_TO_HANDLE_VALUE(x)
Definition: handle.c:21
Definition: strmini.h:378
#define HIGH_LEVEL_ENTRIES
Definition: ex.h:152
#define MAX_MID_INDEX
Definition: ex.h:158
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define LOW_LEVEL_ENTRIES
Definition: ex.h:150
#define NULL
Definition: types.h:112
#define MID_LEVEL_ENTRIES
Definition: ex.h:151
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
signed int * PLONG
Definition: retypes.h:5
#define PAGED_CODE()

Referenced by ExDupHandleTable(), and ExpAllocateHandleTableEntry().

◆ ExpAllocateLowLevelTable()

PHANDLE_TABLE_ENTRY NTAPI ExpAllocateLowLevelTable ( IN PHANDLE_TABLE  HandleTable,
IN BOOLEAN  DoInit 
)

Definition at line 430 of file handle.c.

432 {
433  ULONG i, Base;
434  PHANDLE_TABLE_ENTRY Low, HandleEntry;
435 
436  /* Allocate the low level table */
438  PAGE_SIZE);
439  if (!Low) return NULL;
440 
441  /* Setup the initial entry */
442  HandleEntry = &Low[0];
443  HandleEntry->NextFreeTableEntry = -2;
444  HandleEntry->Value = 0;
445 
446  /* Check if we're initializing */
447  if (DoInit)
448  {
449  /* Go to the next entry and the base entry */
450  HandleEntry++;
451  Base = HandleTable->NextHandleNeedingPool + INDEX_TO_HANDLE_VALUE(2);
452 
453  /* Loop each entry */
454  for (i = Base;
456  i += INDEX_TO_HANDLE_VALUE(1))
457  {
458  /* Free this entry and move on to the next one */
459  HandleEntry->NextFreeTableEntry = i;
460  HandleEntry->Value = 0;
461  HandleEntry++;
462  }
463 
464  /* Terminate the last entry */
465  HandleEntry->NextFreeTableEntry = 0;
466  HandleEntry->Value = 0;
467  }
468 
469  /* Return the low level table */
470  return Low;
471 }
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2413
Definition: strmini.h:380
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
Definition: extypes.h:595
#define INDEX_TO_HANDLE_VALUE(x)
Definition: handle.c:21
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PVOID NTAPI ExpAllocateTablePagedPoolNoZero(IN PEPROCESS Process OPTIONAL, IN SIZE_T Size)
Definition: handle.c:139
ULONG_PTR Value
Definition: extypes.h:602
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define LOW_LEVEL_ENTRIES
Definition: ex.h:150
#define NULL
Definition: types.h:112
LONG NextFreeTableEntry
Definition: extypes.h:612
unsigned int ULONG
Definition: retypes.h:1

Referenced by ExpAllocateHandleTableEntrySlow(), and ExpAllocateMidLevelTable().

◆ ExpAllocateMidLevelTable()

PHANDLE_TABLE_ENTRY* NTAPI ExpAllocateMidLevelTable ( IN PHANDLE_TABLE  HandleTable,
IN BOOLEAN  DoInit,
OUT PHANDLE_TABLE_ENTRY LowTableEntry 
)

Definition at line 475 of file handle.c.

478 {
479  PHANDLE_TABLE_ENTRY *Mid, Low;
480 
481  /* Allocate the mid level table */
482  Mid = ExpAllocateTablePagedPool(HandleTable->QuotaProcess, PAGE_SIZE);
483  if (!Mid) return NULL;
484 
485  /* Allocate a new low level for it */
487  if (!Low)
488  {
489  /* We failed, free the mid table */
490  ExpFreeTablePagedPool(HandleTable->QuotaProcess, Mid, PAGE_SIZE);
491  return NULL;
492  }
493 
494  /* Link the tables and return the pointer */
495  Mid[0] = Low;
496  *LowTableEntry = Low;
497  return Mid;
498 }
PHANDLE_TABLE_ENTRY NTAPI ExpAllocateLowLevelTable(IN PHANDLE_TABLE HandleTable, IN BOOLEAN DoInit)
Definition: handle.c:430
Definition: strmini.h:380
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
Definition: extypes.h:595
PVOID NTAPI ExpAllocateTablePagedPool(IN PEPROCESS Process OPTIONAL, IN SIZE_T Size)
Definition: handle.c:107
VOID NTAPI ExpFreeTablePagedPool(IN PEPROCESS Process OPTIONAL, IN PVOID Buffer, IN SIZE_T Size)
Definition: handle.c:168
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NULL
Definition: types.h:112

Referenced by ExpAllocateHandleTableEntrySlow().

◆ ExpAllocateTablePagedPool()

PVOID NTAPI ExpAllocateTablePagedPool ( IN PEPROCESS Process  OPTIONAL,
IN SIZE_T  Size 
)

Definition at line 107 of file handle.c.

109 {
110  PVOID Buffer;
112 
113  /* Do the allocation */
115  if (Buffer)
116  {
117  /* Clear the memory */
119 
120  /* Check if we have a process to charge quota */
121  if (Process)
122  {
123  /* Charge quota */
125  if (!NT_SUCCESS(Status))
126  {
128  return NULL;
129  }
130  }
131  }
132 
133  /* Return the allocated memory */
134  return Buffer;
135 }
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
LONG NTSTATUS
Definition: precomp.h:26
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
Definition: bufpool.h:45
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TAG_OBJECT_TABLE
Definition: tag.h:26
NTSTATUS NTAPI PsChargeProcessPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the paged pool quota of a given process.
Definition: quota.c:839
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by ExpAllocateHandleTableEntrySlow(), and ExpAllocateMidLevelTable().

◆ ExpAllocateTablePagedPoolNoZero()

PVOID NTAPI ExpAllocateTablePagedPoolNoZero ( IN PEPROCESS Process  OPTIONAL,
IN SIZE_T  Size 
)

Definition at line 139 of file handle.c.

141 {
142  PVOID Buffer;
144 
145  /* Do the allocation */
147  if (Buffer)
148  {
149  /* Check if we have a process to charge quota */
150  if (Process)
151  {
152  /* Charge quota */
154  if (!NT_SUCCESS(Status))
155  {
157  return NULL;
158  }
159  }
160  }
161 
162  /* Return the allocated memory */
163  return Buffer;
164 }
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
LONG NTSTATUS
Definition: precomp.h:26
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
Definition: bufpool.h:45
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TAG_OBJECT_TABLE
Definition: tag.h:26
NTSTATUS NTAPI PsChargeProcessPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the paged pool quota of a given process.
Definition: quota.c:839
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by ExpAllocateHandleTable(), and ExpAllocateLowLevelTable().

◆ ExpBlockOnLockedHandleEntry()

VOID NTAPI ExpBlockOnLockedHandleEntry ( IN PHANDLE_TABLE  HandleTable,
IN PHANDLE_TABLE_ENTRY  HandleTableEntry 
)

Definition at line 858 of file handle.c.

860 {
861  LONG_PTR OldValue;
862  EX_PUSH_LOCK_WAIT_BLOCK WaitBlock;
863 
864  /* Block on the pushlock */
865  ExBlockPushLock(&HandleTable->HandleContentionEvent, &WaitBlock);
866 
867  /* Get the current value and check if it's been unlocked */
868  OldValue = HandleTableEntry->Value;
869  if (!(OldValue) || (OldValue & EXHANDLE_TABLE_ENTRY_LOCK_BIT))
870  {
871  /* Unblock the pushlock and return */
872  ExfUnblockPushLock(&HandleTable->HandleContentionEvent, &WaitBlock);
873  }
874  else
875  {
876  /* Wait for it to be unblocked */
877  ExWaitForUnblockPushLock(&HandleTable->HandleContentionEvent,
878  &WaitBlock);
879  }
880 }
EX_PUSH_LOCK_WAIT_BLOCK
Definition: extypes.h:501
VOID FASTCALL ExBlockPushLock(PEX_PUSH_LOCK PushLock, PVOID pWaitBlock)
Definition: pushlock.c:420
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
VOID FASTCALL ExWaitForUnblockPushLock(IN PEX_PUSH_LOCK PushLock, IN PVOID WaitBlock)
Definition: pushlock.c:395
#define EXHANDLE_TABLE_ENTRY_LOCK_BIT
Definition: ex.h:144
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
VOID FASTCALL ExfUnblockPushLock(PEX_PUSH_LOCK PushLock, PVOID CurrentWaitBlock)
Definition: pushlock.c:1205

Referenced by ExpLockHandleTableEntry().

◆ ExpFreeHandleTable()

VOID NTAPI ExpFreeHandleTable ( IN PHANDLE_TABLE  HandleTable)

Definition at line 202 of file handle.c.

203 {
204  PEPROCESS Process = HandleTable->QuotaProcess;
205  ULONG i, j;
206  ULONG_PTR TableCode = HandleTable->TableCode;
207  ULONG_PTR TableBase = TableCode & ~3;
208  ULONG TableLevel = (ULONG)(TableCode & 3);
209  PHANDLE_TABLE_ENTRY Level1, *Level2, **Level3;
210  PAGED_CODE();
211 
212  /* Check which level we're at */
213  if (TableLevel == 0)
214  {
215  /* Select the first level table base and just free it */
216  Level1 = (PVOID)TableBase;
217  ExpFreeLowLevelTable(Process, Level1);
218  }
219  else if (TableLevel == 1)
220  {
221  /* Select the second level table base */
222  Level2 = (PVOID)TableBase;
223 
224  /* Loop each mid level entry */
225  for (i = 0; i < MID_LEVEL_ENTRIES; i++)
226  {
227  /* Leave if we've reached the last entry */
228  if (!Level2[i]) break;
229 
230  /* Free the second level table */
231  ExpFreeLowLevelTable(Process, Level2[i]);
232  }
233 
234  /* Free the second level table */
236  }
237  else
238  {
239  /* Select the third level table base */
240  Level3 = (PVOID)TableBase;
241 
242  /* Loop each high level entry */
243  for (i = 0; i < HIGH_LEVEL_ENTRIES; i++)
244  {
245  /* Leave if we've reached the last entry */
246  if (!Level3[i]) break;
247 
248  /* Loop each mid level entry */
249  for (j = 0; j < MID_LEVEL_ENTRIES; j++)
250  {
251  /* Leave if we've reached the last entry */
252  if (!Level3[i][j]) break;
253 
254  /* Free the second level table */
255  ExpFreeLowLevelTable(Process, Level3[i][j]);
256  }
257 
258  /* Free the third level table entry */
260  }
261 
262  /* Free the third level table */
264  Level3,
266  }
267 
268  /* Free the actual table and check if we need to release quota */
270  if (Process)
271  {
272  /* Release the quota it was taking up */
274  }
275 }
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SizeOfHandle(x)
Definition: handle.c:20
Definition: extypes.h:595
VOID NTAPI ExpFreeTablePagedPool(IN PEPROCESS Process OPTIONAL, IN PVOID Buffer, IN SIZE_T Size)
Definition: handle.c:168
void * PVOID
Definition: retypes.h:9
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
VOID NTAPI PsReturnProcessPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the paged pool quota that the process was taking up.
Definition: quota.c:965
#define TAG_OBJECT_TABLE
Definition: tag.h:26
#define HIGH_LEVEL_ENTRIES
Definition: ex.h:152
#define PAGE_SIZE
Definition: env_spec_w32.h:49
VOID NTAPI ExpFreeLowLevelTable(IN PEPROCESS Process, IN PHANDLE_TABLE_ENTRY TableEntry)
Definition: handle.c:183
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MID_LEVEL_ENTRIES
Definition: ex.h:151
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by ExDestroyHandleTable(), and ExDupHandleTable().

◆ ExpFreeHandleTableEntry()

VOID NTAPI ExpFreeHandleTableEntry ( IN PHANDLE_TABLE  HandleTable,
IN EXHANDLE  Handle,
IN PHANDLE_TABLE_ENTRY  HandleTableEntry 
)

Definition at line 279 of file handle.c.

282 {
283  ULONG OldValue, *Free;
284  ULONG LockIndex;
285  PAGED_CODE();
286 
287  /* Sanity checks */
288  ASSERT(HandleTableEntry->Object == NULL);
289  ASSERT(HandleTableEntry == ExpLookupHandleTableEntry(HandleTable, Handle));
290 
291  /* Decrement the handle count */
292  InterlockedDecrement(&HandleTable->HandleCount);
293 
294  /* Mark the handle as free */
295  Handle.TagBits = 0;
296 
297  /* Check if we're FIFO */
298  if (!HandleTable->StrictFIFO)
299  {
300  /* Select a lock index */
301  LockIndex = Handle.Index % 4;
302 
303  /* Select which entry to use */
304  Free = (HandleTable->HandleTableLock[LockIndex].Locked) ?
305  &HandleTable->FirstFree : &HandleTable->LastFree;
306  }
307  else
308  {
309  /* No need to worry about locking, take the last entry */
310  Free = &HandleTable->LastFree;
311  }
312 
313  /* Start value change loop */
314  for (;;)
315  {
316  /* Get the current value and write */
317  OldValue = *Free;
318  HandleTableEntry->NextFreeTableEntry = OldValue;
319  if (InterlockedCompareExchange((PLONG)Free, Handle.AsULONG, OldValue) == OldValue)
320  {
321  /* Break out, we're done. Make sure the handle value makes sense */
322  ASSERT((OldValue & FREE_HANDLE_MASK) <
323  HandleTable->NextHandleNeedingPool);
324  break;
325  }
326  }
327 }
PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle)
Definition: handle.c:43
#define InterlockedCompareExchange
Definition: interlocked.h:104
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION Free
Definition: exfuncs.h:814
#define ASSERT(a)
Definition: mode.c:44
#define FREE_HANDLE_MASK
Definition: ex.h:145
#define InterlockedDecrement
Definition: armddk.h:52
#define NULL
Definition: types.h:112
_In_ HANDLE Handle
Definition: extypes.h:390
unsigned int ULONG
Definition: retypes.h:1
signed int * PLONG
Definition: retypes.h:5
#define PAGED_CODE()

Referenced by ExDestroyHandle().

◆ ExpFreeLowLevelTable()

VOID NTAPI ExpFreeLowLevelTable ( IN PEPROCESS  Process,
IN PHANDLE_TABLE_ENTRY  TableEntry 
)

Definition at line 183 of file handle.c.

185 {
186  /* Check if we have an entry */
187  if (TableEntry[0].Object)
188  {
189  /* Free the entry */
191  TableEntry[0].Object,
193  sizeof(HANDLE_TABLE_ENTRY_INFO));
194  }
195 
196  /* Free the table */
198 }
Definition: extypes.h:590
VOID NTAPI ExpFreeTablePagedPool(IN PEPROCESS Process OPTIONAL, IN PVOID Buffer, IN SIZE_T Size)
Definition: handle.c:168
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define LOW_LEVEL_ENTRIES
Definition: ex.h:150
_Must_inspect_result_ typedef _In_ ULONG TableEntry
Definition: iotypes.h:4303
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by ExpFreeHandleTable().

◆ ExpFreeTablePagedPool()

VOID NTAPI ExpFreeTablePagedPool ( IN PEPROCESS Process  OPTIONAL,
IN PVOID  Buffer,
IN SIZE_T  Size 
)

Definition at line 168 of file handle.c.

171 {
172  /* Free the buffer */
174  if (Process)
175  {
176  /* Release quota */
178  }
179 }
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
Definition: bufpool.h:45
VOID NTAPI PsReturnProcessPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the paged pool quota that the process was taking up.
Definition: quota.c:965
#define TAG_OBJECT_TABLE
Definition: tag.h:26
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by ExpAllocateHandleTableEntrySlow(), ExpAllocateMidLevelTable(), ExpFreeHandleTable(), and ExpFreeLowLevelTable().

◆ ExpInitializeHandleTables()

VOID NTAPI ExpInitializeHandleTables ( VOID  )

Definition at line 34 of file handle.c.

35 {
36  /* Initialize the list of handle tables and the lock */
39 }
#define ExInitializePushLock
Definition: ex.h:1011
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
EX_PUSH_LOCK HandleTableListLock
Definition: handle.c:19
LIST_ENTRY HandleTableListHead
Definition: handle.c:18

Referenced by ExpInitializeExecutive().

◆ ExpLockHandleTableEntry()

BOOLEAN NTAPI ExpLockHandleTableEntry ( IN PHANDLE_TABLE  HandleTable,
IN PHANDLE_TABLE_ENTRY  HandleTableEntry 
)

Definition at line 884 of file handle.c.

886 {
887  LONG_PTR NewValue, OldValue;
888 
889  /* Sanity check */
890  ASSERT((KeGetCurrentThread()->CombinedApcDisable != 0) ||
891  (KeGetCurrentIrql() == APC_LEVEL));
892 
893  /* Start lock loop */
894  for (;;)
895  {
896  /* Get the current value and check if it's locked */
897  OldValue = *(volatile LONG_PTR *)&HandleTableEntry->Object;
898  if (OldValue & EXHANDLE_TABLE_ENTRY_LOCK_BIT)
899  {
900  /* It's not locked, remove the lock bit to lock it */
901  NewValue = OldValue & ~EXHANDLE_TABLE_ENTRY_LOCK_BIT;
902  if (InterlockedCompareExchangePointer(&HandleTableEntry->Object,
903  (PVOID)NewValue,
904  (PVOID)OldValue) == (PVOID)OldValue)
905  {
906  /* We locked it, get out */
907  return TRUE;
908  }
909  }
910  else
911  {
912  /* We couldn't lock it, bail out if it's been freed */
913  if (!OldValue) return FALSE;
914  }
915 
916  /* It's locked, wait for it to be unlocked */
917  ExpBlockOnLockedHandleEntry(HandleTable, HandleTableEntry);
918  }
919 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define TRUE
Definition: types.h:120
VOID NTAPI ExpBlockOnLockedHandleEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:858
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define FALSE
Definition: types.h:117
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
void * PVOID
Definition: retypes.h:9
#define ASSERT(a)
Definition: mode.c:44
#define EXHANDLE_TABLE_ENTRY_LOCK_BIT
Definition: ex.h:144
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define KeGetCurrentThread
Definition: hal.h:55
#define APC_LEVEL
Definition: env_spec_w32.h:695

Referenced by ExChangeHandle(), ExDestroyHandle(), ExDupHandleTable(), ExEnumHandleTable(), ExMapHandleToPointer(), ExSweepHandleTable(), and QSI_DEF().

◆ ExpLookupHandleTableEntry()

PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry ( IN PHANDLE_TABLE  HandleTable,
IN EXHANDLE  Handle 
)

Definition at line 43 of file handle.c.

45 {
46  ULONG TableLevel;
47  ULONG_PTR TableBase;
48  PHANDLE_TABLE_ENTRY HandleArray, Entry;
49  PVOID *PointerArray;
50 
51  /* Clear the tag bits */
52  Handle.TagBits = 0;
53 
54  /* Check if the handle is in the allocated range */
55  if (Handle.Value >= HandleTable->NextHandleNeedingPool)
56  {
57  return NULL;
58  }
59 
60  /* Get the table code */
61  TableBase = HandleTable->TableCode;
62 
63  /* Extract the table level and actual table base */
64  TableLevel = (ULONG)(TableBase & 3);
65  TableBase &= ~3;
66 
67  PointerArray = (PVOID*)TableBase;
68  HandleArray = (PHANDLE_TABLE_ENTRY)TableBase;
69 
70  /* Check what level we're running at */
71  switch (TableLevel)
72  {
73  case 2:
74 
75  /* Get the mid level pointer array */
76  PointerArray = PointerArray[Handle.HighIndex];
77  ASSERT(PointerArray != NULL);
78 
79  /* Fall through */
80  case 1:
81 
82  /* Get the handle array */
83  HandleArray = PointerArray[Handle.MidIndex];
84  ASSERT(HandleArray != NULL);
85 
86  /* Fall through */
87  case 0:
88 
89  /* Get the entry using the low index */
90  Entry = &HandleArray[Handle.LowIndex];
91 
92  /* All done */
93  break;
94 
95  default:
96 
97  ASSERT(FALSE);
98  Entry = NULL;
99  }
100 
101  /* Return the handle entry */
102  return Entry;
103 }
struct _Entry Entry
Definition: kefuncs.h:629
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
Definition: extypes.h:595
struct _HANDLE_TABLE_ENTRY * PHANDLE_TABLE_ENTRY
#define ASSERT(a)
Definition: mode.c:44
#define NULL
Definition: types.h:112
_In_ HANDLE Handle
Definition: extypes.h:390
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82

Referenced by ExChangeHandle(), ExDestroyHandle(), ExDupHandleTable(), ExEnumHandleTable(), ExMapHandleToPointer(), ExpAllocateHandleTableEntry(), ExpFreeHandleTableEntry(), ExSweepHandleTable(), and QSI_DEF().

◆ ExpMoveFreeHandles()

ULONG NTAPI ExpMoveFreeHandles ( IN PHANDLE_TABLE  HandleTable)

Definition at line 648 of file handle.c.

649 {
650  ULONG LastFree, i;
651 
652  /* Clear the last free index */
653  LastFree = InterlockedExchange((PLONG) &HandleTable->LastFree, 0);
654 
655  /* Check if we had no index */
656  if (!LastFree) return LastFree;
657 
658  /* Acquire the locks we need */
659  for (i = 1; i < 4; i++)
660  {
661  /* Acquire this lock exclusively */
662  ExWaitOnPushLock(&HandleTable->HandleTableLock[i]);
663  }
664 
665  /* Check if we're not strict FIFO */
666  if (!HandleTable->StrictFIFO)
667  {
668  /* Update the first free index */
669  if (!InterlockedCompareExchange((PLONG) &HandleTable->FirstFree, LastFree, 0))
670  {
671  /* We're done, exit */
672  return LastFree;
673  }
674  }
675 
676  /* We are strict FIFO, we need to reverse the entries */
677  ASSERT(FALSE);
678  return LastFree;
679 }
FORCEINLINE VOID ExWaitOnPushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1176
#define InterlockedCompareExchange
Definition: interlocked.h:104
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
#define InterlockedExchange
Definition: armddk.h:54
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int ULONG
Definition: retypes.h:1
signed int * PLONG
Definition: retypes.h:5

Referenced by ExpAllocateHandleTableEntry().

◆ ExRemoveHandleTable()

VOID NTAPI ExRemoveHandleTable ( IN PHANDLE_TABLE  HandleTable)

Definition at line 944 of file handle.c.

945 {
946  PAGED_CODE();
947 
948  /* Acquire the table lock */
951 
952  /* Remove the table and reset the list */
953  RemoveEntryList(&HandleTable->HandleTableList);
954  InitializeListHead(&HandleTable->HandleTableList);
955 
956  /* Release the lock */
959 }
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1034
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1250
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
EX_PUSH_LOCK HandleTableListLock
Definition: handle.c:19
#define PAGED_CODE()

Referenced by ExDestroyHandleTable().

◆ ExSweepHandleTable()

VOID NTAPI ExSweepHandleTable ( IN PHANDLE_TABLE  HandleTable,
IN PEX_SWEEP_HANDLE_CALLBACK  EnumHandleProcedure,
IN PVOID  Context 
)

Definition at line 1232 of file handle.c.

1235 {
1236  EXHANDLE Handle;
1237  PHANDLE_TABLE_ENTRY HandleTableEntry;
1238  PAGED_CODE();
1239 
1240  /* Set the initial value and loop the entries */
1241  Handle.Value = INDEX_TO_HANDLE_VALUE(1);
1242  while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
1243  {
1244  /* Loop each handle */
1245  do
1246  {
1247  /* Lock the entry */
1248  if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
1249  {
1250  /* Notify the callback routine */
1251  EnumHandleProcedure(HandleTableEntry,
1252  Handle.GenericHandleOverlay,
1253  Context);
1254  }
1255 
1256  /* Go to the next handle and entry */
1257  Handle.Value += INDEX_TO_HANDLE_VALUE(1);
1258  HandleTableEntry++;
1259  } while (Handle.Value % INDEX_TO_HANDLE_VALUE(LOW_LEVEL_ENTRIES));
1260 
1261  /* Skip past the last entry */
1263  }
1264 }
PHANDLE_TABLE_ENTRY NTAPI ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN EXHANDLE Handle)
Definition: handle.c:43
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
Definition: extypes.h:595
BOOLEAN NTAPI ExpLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:884
#define INDEX_TO_HANDLE_VALUE(x)
Definition: handle.c:21
Definition: ex.h:84
ULONG_PTR Value
Definition: extypes.h:602
#define LOW_LEVEL_ENTRIES
Definition: ex.h:150
_In_ HANDLE Handle
Definition: extypes.h:390
#define PAGED_CODE()

Referenced by ObClearProcessHandleTable(), ObKillProcess(), and RtlpDestroyAtomHandleTable().

◆ ExUnlockHandleTableEntry()

VOID NTAPI ExUnlockHandleTableEntry ( IN PHANDLE_TABLE  HandleTable,
IN PHANDLE_TABLE_ENTRY  HandleTableEntry 
)

Definition at line 923 of file handle.c.

925 {
926  LONG_PTR OldValue;
927  PAGED_CODE();
928 
929  /* Sanity check */
930  ASSERT((KeGetCurrentThread()->CombinedApcDisable != 0) ||
931  (KeGetCurrentIrql() == APC_LEVEL));
932 
933  /* Set the lock bit and make sure it wasn't earlier */
934  OldValue = InterlockedOr((PLONG) &HandleTableEntry->Value,
936  ASSERT((OldValue & EXHANDLE_TABLE_ENTRY_LOCK_BIT) == 0);
937 
938  /* Unblock any waiters */
939  ExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL);
940 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define ASSERT(a)
Definition: mode.c:44
#define InterlockedOr
Definition: interlocked.h:224
#define EXHANDLE_TABLE_ENTRY_LOCK_BIT
Definition: ex.h:144
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define NULL
Definition: types.h:112
VOID FASTCALL ExfUnblockPushLock(PEX_PUSH_LOCK PushLock, PVOID CurrentWaitBlock)
Definition: pushlock.c:1205
#define KeGetCurrentThread
Definition: hal.h:55
signed int * PLONG
Definition: retypes.h:5
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PAGED_CODE()

Referenced by ExChangeHandle(), ExCreateHandle(), ExEnumHandleTable(), NtWaitForMultipleObjects(), ObpCloseHandleTableEntry(), ObpDuplicateHandleCallback(), ObpReferenceProcessObjectByHandle(), ObQueryObjectAuditingByHandle(), ObReferenceFileObjectForWrite(), ObReferenceObjectByHandle(), PsLookupProcessByProcessId(), PsLookupProcessThreadByCid(), PsLookupThreadByThreadId(), QSI_DEF(), and RtlpGetAtomEntry().

Variable Documentation

◆ HandleTableListHead

LIST_ENTRY HandleTableListHead

Definition at line 18 of file handle.c.

Referenced by ExCreateHandleTable(), ExDupHandleTable(), ExpInitializeHandleTables(), and QSI_DEF().

◆ HandleTableListLock

EX_PUSH_LOCK HandleTableListLock