ReactOS 0.4.17-dev-1190-g4c812f4
handle.c
Go to the documentation of this file.
1/*
2 * dlls/rsaenh/handle.c
3 * Support code to manage HANDLE tables.
4 *
5 * Copyright 1998 Alexandre Julliard
6 * Copyright 2002-2004 Mike McCormack for CodeWeavers
7 * Copyright 2004 Michael Jung
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <string.h>
25#include <stdarg.h>
26#include <stdlib.h>
27
28#include "windef.h"
29#include "winbase.h"
30#include "handle.h"
31
32#include "wine/debug.h"
33
35
36#define HANDLE2INDEX(h) ((h)-1)
37#define INDEX2HANDLE(i) ((i)+1)
38
39/******************************************************************************
40 * init_handle_table
41 *
42 * Initializes the HANDLETABLE structure pointed to by lpTable
43 *
44 * PARAMS
45 * lpTable [I] Pointer to the HANDLETABLE structure, which is to be initialized.
46 *
47 * NOTES
48 * You have to call destroy_handle_table when you don't need the table
49 * any more.
50 */
51void init_handle_table(struct handle_table *lpTable)
52{
53 TRACE("(lpTable=%p)\n", lpTable);
54
55 lpTable->paEntries = NULL;
56 lpTable->iEntries = 0;
57 lpTable->iFirstFree = 0;
59 lpTable->mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": HANDLETABLE.mutex");
60}
61
62/******************************************************************************
63 * destroy_handle_table
64 *
65 * Destroys the handle table.
66 *
67 * PARAMS
68 * lpTable [I] Pointer to the handle table, which is to be destroyed.
69 */
71{
72 TRACE("(lpTable=%p)\n", lpTable);
73
74 free(lpTable->paEntries);
75 lpTable->mutex.DebugInfo->Spare[0] = 0;
77}
78
79/******************************************************************************
80 * is_valid_handle
81 *
82 * Tests if handle is valid given the specified handle table
83 *
84 * PARAMS
85 * lpTable [I] Pointer to the handle table, with respect to which the handle's
86 * validness is tested.
87 * handle [I] The handle tested for validness.
88 * dwType [I] A magic value that identifies the referenced object's type.
89 *
90 * RETURNS
91 * TRUE, if handle is valid.
92 * FALSE, if handle is not valid.
93 */
95{
96 unsigned int index = HANDLE2INDEX(handle);
97 BOOL ret = FALSE;
98
99 TRACE("(lpTable=%p, handle=%Id)\n", lpTable, handle);
100
101 EnterCriticalSection(&lpTable->mutex);
102
103 /* We don't use zero handle values */
104 if (!handle) goto exit;
105
106 /* Check for index out of table bounds */
107 if (index >= lpTable->iEntries) goto exit;
108
109 /* Check if this handle is currently allocated */
110 if (!lpTable->paEntries[index].pObject) goto exit;
111
112 /* Check if this handle references an object of the correct type. */
113 if (lpTable->paEntries[index].pObject->dwType != dwType) goto exit;
114
115 ret = TRUE;
116exit:
117 LeaveCriticalSection(&lpTable->mutex);
118 return ret;
119}
120
121/******************************************************************************
122 * grow_handle_table [Internal]
123 *
124 * Grows the number of entries in the given table by TABLE_SIZE_INCREMENT
125 *
126 * PARAMS
127 * lpTable [I] Pointer to the table, which is to be grown
128 *
129 * RETURNS
130 * TRUE, if successful
131 * FALSE, if not successful (out of memory on process heap)
132 *
133 * NOTES
134 * This is a support function for alloc_handle. Do not call!
135 */
136static BOOL grow_handle_table(struct handle_table *lpTable)
137{
138 struct handle_table_entry *newEntries;
139 unsigned int i, newIEntries;
140
141 newIEntries = lpTable->iEntries + TABLE_SIZE_INCREMENT;
142
143 newEntries = malloc(sizeof(struct handle_table_entry)*newIEntries);
144 if (!newEntries)
145 return FALSE;
146
147 if (lpTable->paEntries)
148 {
149 memcpy(newEntries, lpTable->paEntries, sizeof(struct handle_table_entry)*lpTable->iEntries);
150 free(lpTable->paEntries);
151 }
152
153 for (i=lpTable->iEntries; i<newIEntries; i++)
154 {
155 newEntries[i].pObject = NULL;
156 newEntries[i].iNextFree = i+1;
157 }
158
159 lpTable->paEntries = newEntries;
160 lpTable->iEntries = newIEntries;
161
162 return TRUE;
163}
164
165/******************************************************************************
166 * alloc_handle
167 *
168 * Allocates a new handle to the specified object in a given handle table.
169 *
170 * PARAMS
171 * lpTable [I] Pointer to the handle table, from which the new handle is
172 * allocated.
173 * lpObject [I] Pointer to the object, for which a handle shall be allocated.
174 * lpHandle [O] Pointer to a handle variable, into which the handle value will
175 * be stored. If not successful, this will be
176 * INVALID_HANDLE_VALUE
177 * RETURNS
178 * TRUE, if successful
179 * FALSE, if not successful (no free handle)
180 */
181static BOOL alloc_handle(struct handle_table *lpTable, OBJECTHDR *lpObject, HCRYPTKEY *lpHandle)
182{
183 BOOL ret = FALSE;
184
185 TRACE("(lpTable=%p, lpObject=%p, lpHandle=%p)\n", lpTable, lpObject, lpHandle);
186
187 EnterCriticalSection(&lpTable->mutex);
188 if (lpTable->iFirstFree >= lpTable->iEntries)
189 if (!grow_handle_table(lpTable))
190 {
191 *lpHandle = (HCRYPTKEY)INVALID_HANDLE_VALUE;
192 goto exit;
193 }
194
195 *lpHandle = INDEX2HANDLE(lpTable->iFirstFree);
196
197 lpTable->paEntries[lpTable->iFirstFree].pObject = lpObject;
198 lpTable->iFirstFree = lpTable->paEntries[lpTable->iFirstFree].iNextFree;
199 InterlockedIncrement(&lpObject->refcount);
200
201 ret = TRUE;
202exit:
203 LeaveCriticalSection(&lpTable->mutex);
204 return ret;
205}
206
207/******************************************************************************
208 * release_handle
209 *
210 * Releases resources occupied by the specified handle in the given table.
211 * The reference count of the handled object is decremented. If it becomes
212 * zero and if the 'destructor' function pointer member is non NULL, the
213 * destructor function will be called. Note that release_handle does not
214 * release resources other than the handle itself. If this is wanted, do it
215 * in the destructor function.
216 *
217 * PARAMS
218 * lpTable [I] Pointer to the handle table, from which a handle is to be
219 * released.
220 * handle [I] The handle, which is to be released
221 * dwType [I] Identifier for the type of the object, for which a handle is
222 * to be released.
223 *
224 * RETURNS
225 * TRUE, if successful
226 * FALSE, if not successful (invalid handle)
227 */
229{
230 unsigned int index = HANDLE2INDEX(handle);
232 BOOL ret = FALSE;
233
234 TRACE("(lpTable=%p, handle=%Id)\n", lpTable, handle);
235
236 EnterCriticalSection(&lpTable->mutex);
237
238 if (!is_valid_handle(lpTable, handle, dwType))
239 goto exit;
240
241 pObject = lpTable->paEntries[index].pObject;
242 if (InterlockedDecrement(&pObject->refcount) == 0)
243 {
244 TRACE("destroying handle %Id\n", handle);
245 if (pObject->destructor)
246 pObject->destructor(pObject);
247 }
248
249 lpTable->paEntries[index].pObject = NULL;
250 lpTable->paEntries[index].iNextFree = lpTable->iFirstFree;
251 lpTable->iFirstFree = index;
252
253 ret = TRUE;
254exit:
255 LeaveCriticalSection(&lpTable->mutex);
256 return ret;
257}
258
259/******************************************************************************
260 * lookup_handle
261 *
262 * Returns the object identified by the handle in the given handle table
263 *
264 * PARAMS
265 * lpTable [I] Pointer to the handle table, in which the handle is looked up.
266 * handle [I] The handle, which is to be looked up
267 * lplpObject [O] Pointer to the variable, into which the pointer to the
268 * object looked up is copied.
269 * RETURNS
270 * TRUE, if successful
271 * FALSE, if not successful (invalid handle)
272 */
273BOOL lookup_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject)
274{
275 BOOL ret = FALSE;
276
277 TRACE("(lpTable=%p, handle=%Id, lplpObject=%p)\n", lpTable, handle, lplpObject);
278
279 EnterCriticalSection(&lpTable->mutex);
280 if (!is_valid_handle(lpTable, handle, dwType))
281 {
282 *lplpObject = NULL;
283 goto exit;
284 }
285 *lplpObject = lpTable->paEntries[HANDLE2INDEX(handle)].pObject;
286
287 ret = TRUE;
288exit:
289 LeaveCriticalSection(&lpTable->mutex);
290 return ret;
291}
292
293/******************************************************************************
294 * copy_handle
295 *
296 * Copies a handle. Increments the reference count of the object referenced
297 * by the handle.
298 *
299 * PARAMS
300 * lpTable [I] Pointer to the handle table, which holds the handle to be copied.
301 * handle [I] The handle to be copied.
302 * copy [O] Pointer to a handle variable, where the copied handle is put.
303 *
304 * RETURNS
305 * TRUE, if successful
306 * FALSE, if not successful (invalid handle or out of memory)
307 */
309{
311 BOOL ret;
312
313 TRACE("(lpTable=%p, handle=%Id, copy=%p)\n", lpTable, handle, copy);
314
315 EnterCriticalSection(&lpTable->mutex);
316 if (!lookup_handle(lpTable, handle, dwType, &pObject))
317 {
319 LeaveCriticalSection(&lpTable->mutex);
320 return FALSE;
321 }
322
323 ret = alloc_handle(lpTable, pObject, copy);
324 LeaveCriticalSection(&lpTable->mutex);
325 return ret;
326}
327
328/******************************************************************************
329 * new_object
330 *
331 * Allocates a new object of size cbSize on the current process's heap.
332 * Initializes the object header using the destructor and dwType params.
333 * Allocates a handle to the object in the handle table pointed to by lpTable.
334 * Returns a pointer to the created object in ppObject.
335 * Returns a handle to the created object.
336 *
337 * PARAMS
338 * lpTable [I] Pointer to the handle table, from which a handle is to be
339 * allocated.
340 * cbSize [I] Size of the object to be allocated in bytes.
341 * dwType [I] Object type; will be copied to the object header.
342 * destructor [I] Function pointer to a destructor function. Will be called
343 * once the object's reference count gets zero.
344 * ppObject [O] Pointer to a pointer variable, where a pointer to the newly
345 * created object will be stored. You may set this to NULL.
346 *
347 * RETURNS
348 * INVALID_HANDLE_VALUE, if something went wrong.
349 * a handle to the new object, if successful.
350 */
351HCRYPTKEY new_object(struct handle_table *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor,
352 OBJECTHDR **ppObject)
353{
355 HCRYPTKEY hObject;
356
357 if (ppObject)
358 *ppObject = NULL;
359
361 if (!pObject)
363
364 pObject->dwType = dwType;
365 pObject->refcount = 0;
366 pObject->destructor = destructor;
367
368 if (!alloc_handle(lpTable, pObject, &hObject))
369 free(pObject);
370 else
371 if (ppObject)
372 *ppObject = pObject;
373
374 return hObject;
375}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
BOOL lookup_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject)
Definition: handle.c:273
static BOOL alloc_handle(struct handle_table *lpTable, OBJECTHDR *lpObject, HCRYPTKEY *lpHandle)
Definition: handle.c:181
#define HANDLE2INDEX(h)
Definition: handle.c:36
#define INDEX2HANDLE(i)
Definition: handle.c:37
static BOOL grow_handle_table(struct handle_table *lpTable)
Definition: handle.c:136
BOOL release_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType)
Definition: handle.c:228
void destroy_handle_table(struct handle_table *lpTable)
Definition: handle.c:70
void init_handle_table(struct handle_table *lpTable)
Definition: handle.c:51
BOOL is_valid_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType)
Definition: handle.c:94
HCRYPTKEY new_object(struct handle_table *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, OBJECTHDR **ppObject)
Definition: handle.c:351
BOOL copy_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy)
Definition: handle.c:308
#define TABLE_SIZE_INCREMENT
Definition: handle.h:33
void(* DESTRUCTOR)(OBJECTHDR *object)
Definition: handle.h:37
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxObject * pObject
GLuint index
Definition: glext.h:6031
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 memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define exit(n)
Definition: config.h:202
#define TRACE(s)
Definition: solgame.cpp:4
PRTL_CRITICAL_SECTION_DEBUG DebugInfo
Definition: rtltypes.h:1478
Definition: handle.h:46
OBJECTHDR * pObject
Definition: handle.h:47
unsigned int iNextFree
Definition: handle.h:48
CRITICAL_SECTION mutex
Definition: handle.h:56
unsigned int iFirstFree
Definition: handle.h:54
struct handle_table_entry * paEntries
Definition: handle.h:55
unsigned int iEntries
Definition: handle.h:53
LONG refcount
Definition: handle.h:41
UINT32 cbSize
#define DWORD_PTR
Definition: treelist.c:76
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
ULONG_PTR HCRYPTKEY
Definition: wincrypt.h:58
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1160