ReactOS  0.4.14-dev-358-gbef841c
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  */
53 void 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  */
72 void destroy_handle_table(struct handle_table *lpTable)
73 {
74  TRACE("(lpTable=%p)\n", lpTable);
75 
76  HeapFree(GetProcessHeap(), 0, lpTable->paEntries);
77  lpTable->mutex.DebugInfo->Spare[0] = 0;
78  DeleteCriticalSection(&lpTable->mutex);
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;
118 exit:
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  */
138 static 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  */
183 static 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;
204 exit:
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;
245  {
246  TRACE("destroying handle %ld\n", handle);
247  if (pObject->destructor)
249  }
250 
251  lpTable->paEntries[index].pObject = NULL;
252  lpTable->paEntries[index].iNextFree = lpTable->iFirstFree;
253  lpTable->iFirstFree = index;
254 
255  ret = TRUE;
256 exit:
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  */
275 BOOL 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;
290 exit:
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  */
353 HCRYPTKEY 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 }
LONG refcount
Definition: handle.h:41
#define TRUE
Definition: types.h:120
static BOOL alloc_handle(struct handle_table *lpTable, OBJECTHDR *lpObject, HCRYPTKEY *lpHandle)
Definition: handle.c:183
#define DWORD_PTR
Definition: treelist.c:76
#define HANDLE2INDEX(h)
Definition: handle.c:38
#define INDEX2HANDLE(i)
Definition: handle.c:39
Definition: handle.h:45
unsigned int iNextFree
Definition: handle.h:48
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
CRITICAL_SECTION mutex
Definition: handle.h:56
void destroy_handle_table(struct handle_table *lpTable)
Definition: handle.c:72
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void(* DESTRUCTOR)(OBJECTHDR *object)
Definition: handle.h:37
DESTRUCTOR destructor
Definition: handle.h:42
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 BOOL
Definition: ntddk_ex.h:94
WINE_DEFAULT_DEBUG_CHANNEL(msi)
void init_handle_table(struct handle_table *lpTable)
Definition: handle.c:53
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
HCRYPTKEY new_object(struct handle_table *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, OBJECTHDR **ppObject)
Definition: handle.c:353
GLuint index
Definition: glext.h:6031
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL is_valid_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType)
Definition: handle.c:96
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
static BOOL grow_handle_table(struct handle_table *lpTable)
Definition: handle.c:138
unsigned long DWORD
Definition: ntddk_ex.h:95
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:866
int ret
BOOL copy_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy)
Definition: handle.c:310
#define index(s, c)
Definition: various.h:29
#define InterlockedDecrement
Definition: armddk.h:52
BOOL release_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType)
Definition: handle.c:230
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct handle_table_entry * paEntries
Definition: handle.h:55
#define TABLE_SIZE_INCREMENT
Definition: handle.h:33
OBJECTHDR * pObject
Definition: handle.h:47
#define InterlockedIncrement
Definition: armddk.h:53
unsigned int iEntries
Definition: handle.h:53
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
unsigned int iFirstFree
Definition: handle.h:54
ULONG_PTR HCRYPTKEY
Definition: wincrypt.h:49
BOOL lookup_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, OBJECTHDR **lplpObject)
Definition: handle.c:275
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void exit(int exitcode)
Definition: _exit.c:33
DWORD dwType
Definition: handle.h:40
#define HeapFree(x, y, z)
Definition: compat.h:402
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:859