ReactOS 0.4.15-dev-7924-g5949c20
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#define WIN32_NO_STATUS
25#define WIN32_LEAN_AND_MEAN
26
27//#include <string.h>
28#include <stdarg.h>
29
30#include <windef.h>
31#include <winbase.h>
32#include "handle.h"
33
34#include <wine/debug.h>
35
37
38#define HANDLE2INDEX(h) ((h)-1)
39#define INDEX2HANDLE(i) ((i)+1)
40
41/******************************************************************************
42 * init_handle_table
43 *
44 * Initializes the HANDLETABLE structure pointed to by lpTable
45 *
46 * PARAMS
47 * lpTable [I] Pointer to the HANDLETABLE structure, which is to be initialized.
48 *
49 * NOTES
50 * You have to call destroy_handle_table when you don't need the table
51 * any more.
52 */
53void init_handle_table(struct handle_table *lpTable)
54{
55 TRACE("(lpTable=%p)\n", lpTable);
56
57 lpTable->paEntries = NULL;
58 lpTable->iEntries = 0;
59 lpTable->iFirstFree = 0;
61 lpTable->mutex.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": HANDLETABLE.mutex");
62}
63
64/******************************************************************************
65 * destroy_handle_table
66 *
67 * Destroys the handle table.
68 *
69 * PARAMS
70 * lpTable [I] Pointer to the handle table, which is to be destroyed.
71 */
73{
74 TRACE("(lpTable=%p)\n", lpTable);
75
76 HeapFree(GetProcessHeap(), 0, lpTable->paEntries);
77 lpTable->mutex.DebugInfo->Spare[0] = 0;
79}
80
81/******************************************************************************
82 * is_valid_handle
83 *
84 * Tests if handle is valid given the specified handle table
85 *
86 * PARAMS
87 * lpTable [I] Pointer to the handle table, with respect to which the handle's
88 * validness is tested.
89 * handle [I] The handle tested for validness.
90 * dwType [I] A magic value that identifies the referenced object's type.
91 *
92 * RETURNS
93 * TRUE, if handle is valid.
94 * FALSE, if handle is not valid.
95 */
97{
98 unsigned int index = HANDLE2INDEX(handle);
99 BOOL ret = FALSE;
100
101 TRACE("(lpTable=%p, handle=%ld)\n", lpTable, handle);
102
103 EnterCriticalSection(&lpTable->mutex);
104
105 /* We don't use zero handle values */
106 if (!handle) goto exit;
107
108 /* Check for index out of table bounds */
109 if (index >= lpTable->iEntries) goto exit;
110
111 /* Check if this handle is currently allocated */
112 if (!lpTable->paEntries[index].pObject) goto exit;
113
114 /* Check if this handle references an object of the correct type. */
115 if (lpTable->paEntries[index].pObject->dwType != dwType) goto exit;
116
117 ret = TRUE;
118exit:
119 LeaveCriticalSection(&lpTable->mutex);
120 return ret;
121}
122
123/******************************************************************************
124 * grow_handle_table [Internal]
125 *
126 * Grows the number of entries in the given table by TABLE_SIZE_INCREMENT
127 *
128 * PARAMS
129 * lpTable [I] Pointer to the table, which is to be grown
130 *
131 * RETURNS
132 * TRUE, if successful
133 * FALSE, if not successful (out of memory on process heap)
134 *
135 * NOTES
136 * This is a support function for alloc_handle. Do not call!
137 */
138static BOOL grow_handle_table(struct handle_table *lpTable)
139{
140 struct handle_table_entry *newEntries;
141 unsigned int i, newIEntries;
142
143 newIEntries = lpTable->iEntries + TABLE_SIZE_INCREMENT;
144
145 newEntries = HeapAlloc(GetProcessHeap(), 0, sizeof(struct handle_table_entry)*newIEntries);
146 if (!newEntries)
147 return FALSE;
148
149 if (lpTable->paEntries)
150 {
151 memcpy(newEntries, lpTable->paEntries, sizeof(struct handle_table_entry)*lpTable->iEntries);
152 HeapFree(GetProcessHeap(), 0, lpTable->paEntries);
153 }
154
155 for (i=lpTable->iEntries; i<newIEntries; i++)
156 {
157 newEntries[i].pObject = NULL;
158 newEntries[i].iNextFree = i+1;
159 }
160
161 lpTable->paEntries = newEntries;
162 lpTable->iEntries = newIEntries;
163
164 return TRUE;
165}
166
167/******************************************************************************
168 * alloc_handle
169 *
170 * Allocates a new handle to the specified object in a given handle table.
171 *
172 * PARAMS
173 * lpTable [I] Pointer to the handle table, from which the new handle is
174 * allocated.
175 * lpObject [I] Pointer to the object, for which a handle shall be allocated.
176 * lpHandle [O] Pointer to a handle variable, into which the handle value will
177 * be stored. If not successful, this will be
178 * INVALID_HANDLE_VALUE
179 * RETURNS
180 * TRUE, if successful
181 * FALSE, if not successful (no free handle)
182 */
183static BOOL alloc_handle(struct handle_table *lpTable, OBJECTHDR *lpObject, HCRYPTKEY *lpHandle)
184{
185 BOOL ret = FALSE;
186
187 TRACE("(lpTable=%p, lpObject=%p, lpHandle=%p)\n", lpTable, lpObject, lpHandle);
188
189 EnterCriticalSection(&lpTable->mutex);
190 if (lpTable->iFirstFree >= lpTable->iEntries)
191 if (!grow_handle_table(lpTable))
192 {
193 *lpHandle = (HCRYPTKEY)INVALID_HANDLE_VALUE;
194 goto exit;
195 }
196
197 *lpHandle = INDEX2HANDLE(lpTable->iFirstFree);
198
199 lpTable->paEntries[lpTable->iFirstFree].pObject = lpObject;
200 lpTable->iFirstFree = lpTable->paEntries[lpTable->iFirstFree].iNextFree;
201 InterlockedIncrement(&lpObject->refcount);
202
203 ret = TRUE;
204exit:
205 LeaveCriticalSection(&lpTable->mutex);
206 return ret;
207}
208
209/******************************************************************************
210 * release_handle
211 *
212 * Releases resources occupied by the specified handle in the given table.
213 * The reference count of the handled object is decremented. If it becomes
214 * zero and if the 'destructor' function pointer member is non NULL, the
215 * destructor function will be called. Note that release_handle does not
216 * release resources other than the handle itself. If this is wanted, do it
217 * in the destructor function.
218 *
219 * PARAMS
220 * lpTable [I] Pointer to the handle table, from which a handle is to be
221 * released.
222 * handle [I] The handle, which is to be released
223 * dwType [I] Identifier for the type of the object, for which a handle is
224 * to be released.
225 *
226 * RETURNS
227 * TRUE, if successful
228 * FALSE, if not successful (invalid handle)
229 */
231{
232 unsigned int index = HANDLE2INDEX(handle);
234 BOOL ret = FALSE;
235
236 TRACE("(lpTable=%p, handle=%ld)\n", lpTable, handle);
237
238 EnterCriticalSection(&lpTable->mutex);
239
240 if (!is_valid_handle(lpTable, handle, dwType))
241 goto exit;
242
243 pObject = lpTable->paEntries[index].pObject;
244 if (InterlockedDecrement(&pObject->refcount) == 0)
245 {
246 TRACE("destroying handle %ld\n", handle);
247 if (pObject->destructor)
248 pObject->destructor(pObject);
249 }
250
251 lpTable->paEntries[index].pObject = NULL;
252 lpTable->paEntries[index].iNextFree = lpTable->iFirstFree;
253 lpTable->iFirstFree = index;
254
255 ret = TRUE;
256exit:
257 LeaveCriticalSection(&lpTable->mutex);
258 return ret;
259}
260
261/******************************************************************************
262 * lookup_handle
263 *
264 * Returns the object identified by the handle in the given handle table
265 *
266 * PARAMS
267 * lpTable [I] Pointer to the handle table, in which the handle is looked up.
268 * handle [I] The handle, which is to be looked up
269 * lplpObject [O] Pointer to the variable, into which the pointer to the
270 * object looked up is copied.
271 * RETURNS
272 * TRUE, if successful
273 * FALSE, if not successful (invalid handle)
274 */
275BOOL lookup_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject)
276{
277 BOOL ret = FALSE;
278
279 TRACE("(lpTable=%p, handle=%ld, lplpObject=%p)\n", lpTable, handle, lplpObject);
280
281 EnterCriticalSection(&lpTable->mutex);
282 if (!is_valid_handle(lpTable, handle, dwType))
283 {
284 *lplpObject = NULL;
285 goto exit;
286 }
287 *lplpObject = lpTable->paEntries[HANDLE2INDEX(handle)].pObject;
288
289 ret = TRUE;
290exit:
291 LeaveCriticalSection(&lpTable->mutex);
292 return ret;
293}
294
295/******************************************************************************
296 * copy_handle
297 *
298 * Copies a handle. Increments the reference count of the object referenced
299 * by the handle.
300 *
301 * PARAMS
302 * lpTable [I] Pointer to the handle table, which holds the handle to be copied.
303 * handle [I] The handle to be copied.
304 * copy [O] Pointer to a handle variable, where the copied handle is put.
305 *
306 * RETURNS
307 * TRUE, if successful
308 * FALSE, if not successful (invalid handle or out of memory)
309 */
311{
313 BOOL ret;
314
315 TRACE("(lpTable=%p, handle=%ld, copy=%p)\n", lpTable, handle, copy);
316
317 EnterCriticalSection(&lpTable->mutex);
318 if (!lookup_handle(lpTable, handle, dwType, &pObject))
319 {
321 LeaveCriticalSection(&lpTable->mutex);
322 return FALSE;
323 }
324
325 ret = alloc_handle(lpTable, pObject, copy);
326 LeaveCriticalSection(&lpTable->mutex);
327 return ret;
328}
329
330/******************************************************************************
331 * new_object
332 *
333 * Allocates a new object of size cbSize on the current process's heap.
334 * Initializes the object header using the destructor and dwType params.
335 * Allocates a handle to the object in the handle table pointed to by lpTable.
336 * Returns a pointer to the created object in ppObject.
337 * Returns a handle to the created object.
338 *
339 * PARAMS
340 * lpTable [I] Pointer to the handle table, from which a handle is to be
341 * allocated.
342 * cbSize [I] Size of the object to be allocated in bytes.
343 * dwType [I] Object type; will be copied to the object header.
344 * destructor [I] Function pointer to a destructor function. Will be called
345 * once the object's reference count gets zero.
346 * ppObject [O] Pointer to a pointer variable, where a pointer to the newly
347 * created object will be stored. You may set this to NULL.
348 *
349 * RETURNS
350 * INVALID_HANDLE_VALUE, if something went wrong.
351 * a handle to the new object, if successful.
352 */
353HCRYPTKEY new_object(struct handle_table *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor,
354 OBJECTHDR **ppObject)
355{
357 HCRYPTKEY hObject;
358
359 if (ppObject)
360 *ppObject = NULL;
361
362 pObject = HeapAlloc(GetProcessHeap(), 0, cbSize);
363 if (!pObject)
365
366 pObject->dwType = dwType;
367 pObject->refcount = 0;
368 pObject->destructor = destructor;
369
370 if (!alloc_handle(lpTable, pObject, &hObject))
372 else
373 if (ppObject)
374 *ppObject = pObject;
375
376 return hObject;
377}
#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 NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
BOOL lookup_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject)
Definition: handle.c:275
static BOOL alloc_handle(struct handle_table *lpTable, OBJECTHDR *lpObject, HCRYPTKEY *lpHandle)
Definition: handle.c:183
#define HANDLE2INDEX(h)
Definition: handle.c:38
#define INDEX2HANDLE(i)
Definition: handle.c:39
static BOOL grow_handle_table(struct handle_table *lpTable)
Definition: handle.c:138
BOOL release_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType)
Definition: handle.c:230
void destroy_handle_table(struct handle_table *lpTable)
Definition: handle.c:72
void init_handle_table(struct handle_table *lpTable)
Definition: handle.c:53
BOOL is_valid_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType)
Definition: handle.c:96
HCRYPTKEY new_object(struct handle_table *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, OBJECTHDR **ppObject)
Definition: handle.c:353
BOOL copy_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy)
Definition: handle.c:310
#define TABLE_SIZE_INCREMENT
Definition: handle.h:33
void(* DESTRUCTOR)(OBJECTHDR *object)
Definition: handle.h:37
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
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:887
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:894
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
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define DWORD_PTR
Definition: treelist.c:76
int ret
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
ULONG_PTR HCRYPTKEY
Definition: wincrypt.h:49