/****************************************************************************** * alloc_handle * * Allocates a new handle to the specified object in a given handle table. * * PARAMS * lpTable [I] Pointer to the handle table, from which the new handle is * allocated. * lpObject [I] Pointer to the object, for which a handle shall be allocated. * lpHandle [O] Pointer to a handle variable, into which the handle value will * be stored. If not successful, this will be * INVALID_HANDLE_VALUE * RETURNS * non zero, if successful * zero, if not successful (no free handle) */ int alloc_handle(HANDLETABLE *lpTable, OBJECTHDR *lpObject, unsigned int *lpHandle) { int ret = 0; TRACE("(lpTable=%p, lpObject=%p, lpHandle=%p)\n", lpTable, lpObject, lpHandle); EnterCriticalSection(&lpTable->mutex); if (lpTable->iFirstFree >= lpTable->iEntries) if (!grow_handle_table(lpTable)) { *lpHandle = (unsigned int)INVALID_HANDLE_VALUE; goto exit; } *lpHandle = INDEX2HANDLE(lpTable->iFirstFree); lpTable->paEntries[lpTable->iFirstFree].pObject = lpObject; lpTable->iFirstFree = lpTable->paEntries[lpTable->iFirstFree].iNextFree; InterlockedIncrement(&lpObject->refcount); ret = 1; exit: LeaveCriticalSection(&lpTable->mutex); return ret; }
/* allocate the first free entry in the handle table */ static obj_handle_t alloc_entry( struct handle_table *table, void *obj, unsigned int access ) { struct handle_entry *entry = table->entries + table->free; int i; for (i = table->free; i <= table->last; i++, entry++) if (!entry->ptr) goto found; if (i >= table->count) { if (!grow_handle_table( table )) return 0; entry = table->entries + i; /* the entries may have moved */ } table->last = i; found: table->free = i + 1; entry->ptr = grab_object_for_handle( obj ); entry->access = access; return index_to_handle(i); }