ReactOS  0.4.14-dev-552-g2fad488
handle.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * PURPOSE: Handle table
5  * FILE: lib/rtl/handle.c
6  * PROGRAMMER: Eric Kohl
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include <rtl.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* GLOBALS ******************************************************************/
17 
18 VOID
19 NTAPI
22  ULONG HandleSize,
24 {
25  /* Initialize handle table */
26  memset(HandleTable, 0, sizeof(RTL_HANDLE_TABLE));
27  HandleTable->MaximumNumberOfHandles = TableSize;
28  HandleTable->SizeOfHandleTableEntry = HandleSize;
29 }
30 
31 
32 /*
33  * @implemented
34  */
35 VOID
36 NTAPI
39 {
40  PVOID ArrayPointer;
41  SIZE_T ArraySize = 0;
42 
43  /* free handle array */
44  if (HandleTable->CommittedHandles)
45  {
46  ArrayPointer = (PVOID)HandleTable->CommittedHandles;
48  &ArrayPointer,
49  &ArraySize,
50  MEM_RELEASE);
51  }
52 }
53 
54 
55 /*
56  * @implemented
57  */
59 NTAPI
62  PULONG Index)
63 {
64  PRTL_HANDLE_TABLE_ENTRY CurrentEntry, NextEntry;
66  PRTL_HANDLE_TABLE_ENTRY HandleEntry;
67  PVOID ArrayPointer;
68  SIZE_T ArraySize;
69  ULONG i, NumberOfEntries;
70 
71  /* Check if we are out of free handles entries */
72  if (HandleTable->FreeHandles == NULL)
73  {
74  /* Check if we don't have uncomitted handle entries yet */
75  if (HandleTable->UnCommittedHandles == NULL)
76  {
77  /* Use the maximum number of handle entries */
78  ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles;
79  ArrayPointer = NULL;
80 
81  /* Reserve memory */
82  Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
83  &ArrayPointer,
84  0,
85  &ArraySize,
88  if (!NT_SUCCESS(Status))
89  return NULL;
90 
91  /* Update handle array pointers */
92  HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
93  HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
94  HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
95  }
96 
97  /* Commit one reserved handle entry page */
98  ArraySize = PAGE_SIZE;
99  ArrayPointer = HandleTable->UnCommittedHandles;
100  Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
101  &ArrayPointer,
102  0,
103  &ArraySize,
104  MEM_COMMIT,
106  if (!NT_SUCCESS(Status))
107  return NULL;
108 
109  /* Update handle array pointers */
110  HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer;
111  HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize);
112 
113  /* Calculate the number of entries we can store in the array */
114  NumberOfEntries = ArraySize / HandleTable->SizeOfHandleTableEntry;
115 
116  /* Loop all entries, except the last one */
117  CurrentEntry = HandleTable->FreeHandles;
118  for (i = 0; i < NumberOfEntries - 1; i++)
119  {
120  /* Calculate the address of the next handle entry */
121  NextEntry = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)CurrentEntry +
122  HandleTable->SizeOfHandleTableEntry);
123 
124  /* Link the next entry */
125  CurrentEntry->NextFree = NextEntry;
126 
127  /* Continue with the next entry */
128  CurrentEntry = NextEntry;
129  }
130 
131  /* CurrentEntry now points to the last entry, terminate the list here */
132  CurrentEntry->NextFree = NULL;
133  }
134 
135  /* remove handle from free list */
136  HandleEntry = HandleTable->FreeHandles;
137  HandleTable->FreeHandles = HandleEntry->NextFree;
138  HandleEntry->NextFree = NULL;
139 
140  if (Index)
141  {
142  *Index = ((ULONG)((ULONG_PTR)HandleEntry - (ULONG_PTR)HandleTable->CommittedHandles) /
143  HandleTable->SizeOfHandleTableEntry);
144  }
145 
146  return HandleEntry;
147 }
148 
149 
150 /*
151  * @implemented
152  */
153 BOOLEAN
154 NTAPI
158 {
159 #if DBG
160  /* check if handle is valid */
162  {
163  DPRINT1("Invalid Handle! HandleTable=0x%p, Handle=0x%p, Handle->Flags=0x%x\n",
164  HandleTable, Handle, Handle ? Handle->Flags : 0);
165  return FALSE;
166  }
167 #endif
168 
169  /* clear handle */
170  memset(Handle, 0, HandleTable->SizeOfHandleTableEntry);
171 
172  /* add handle to free list */
173  Handle->NextFree = HandleTable->FreeHandles;
174  HandleTable->FreeHandles = Handle;
175 
176  return TRUE;
177 }
178 
179 
180 /*
181  * @implemented
182  */
183 BOOLEAN
184 NTAPI
188 {
189  if ((HandleTable != NULL)
190  && (Handle >= HandleTable->CommittedHandles)
191  && (Handle < HandleTable->MaxReservedHandles)
192  && (Handle->Flags & RTL_HANDLE_VALID))
193  {
194  return TRUE;
195  }
196  return FALSE;
197 }
198 
199 
200 /*
201  * @implemented
202  */
203 BOOLEAN
204 NTAPI
207  IN ULONG Index,
209 {
210  PRTL_HANDLE_TABLE_ENTRY InternalHandle;
211 
212  DPRINT("RtlIsValidIndexHandle(HandleTable %p Index 0x%lx Handle %p)\n", HandleTable, Index, Handle);
213 
214  if (HandleTable == NULL)
215  return FALSE;
216 
217  DPRINT("Handles %p HandleSize 0x%lx\n",
218  HandleTable->CommittedHandles, HandleTable->SizeOfHandleTableEntry);
219 
220  InternalHandle = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)HandleTable->CommittedHandles +
221  (HandleTable->SizeOfHandleTableEntry * Index));
222  if (!RtlIsValidHandle(HandleTable, InternalHandle))
223  return FALSE;
224 
225  DPRINT("InternalHandle %p\n", InternalHandle);
226 
227  if (Handle != NULL)
228  *Handle = InternalHandle;
229 
230  return TRUE;
231 }
232 
233 /* EOF */
#define RTL_HANDLE_VALID
Definition: rtltypes.h:372
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
BOOLEAN NTAPI RtlIsValidHandle(PRTL_HANDLE_TABLE HandleTable, PRTL_HANDLE_TABLE_ENTRY Handle)
Definition: handle.c:185
#define MEM_COMMIT
Definition: nt_native.h:1313
BOOLEAN NTAPI RtlIsValidIndexHandle(IN PRTL_HANDLE_TABLE HandleTable, IN ULONG Index, OUT PRTL_HANDLE_TABLE_ENTRY *Handle)
Definition: handle.c:205
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOLEAN NTAPI RtlFreeHandle(PRTL_HANDLE_TABLE HandleTable, PRTL_HANDLE_TABLE_ENTRY Handle)
Definition: handle.c:155
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define MEM_RESERVE
Definition: nt_native.h:1314
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
#define NtCurrentProcess()
Definition: nt_native.h:1657
_In_ HANDLE Handle
Definition: extypes.h:390
VOID NTAPI RtlInitializeHandleTable(ULONG TableSize, ULONG HandleSize, PRTL_HANDLE_TABLE HandleTable)
Definition: handle.c:20
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _RTL_HANDLE_TABLE_ENTRY * PRTL_HANDLE_TABLE_ENTRY
static const UCHAR Index[8]
Definition: usbohci.c:18
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
struct _RTL_HANDLE_TABLE_ENTRY * NextFree
Definition: rtltypes.h:1245
unsigned int * PULONG
Definition: retypes.h:1
#define DPRINT1
Definition: precomp.h:8
PRTL_HANDLE_TABLE_ENTRY NTAPI RtlAllocateHandle(PRTL_HANDLE_TABLE HandleTable, PULONG Index)
Definition: handle.c:60
#define MEM_RELEASE
Definition: nt_native.h:1316
#define OUT
Definition: typedefs.h:39
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:3971
unsigned int ULONG
Definition: retypes.h:1
Definition: rtltypes.h:1240
#define ULONG_PTR
Definition: config.h:101
VOID NTAPI RtlDestroyHandleTable(PRTL_HANDLE_TABLE HandleTable)
Definition: handle.c:37
#define memset(x, y, z)
Definition: compat.h:39
#define PAGE_READWRITE
Definition: nt_native.h:1304
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5090