*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
-int usedHandles=0;
+//int usedHandles=0;
PUSER_HANDLE_TABLE gHandleTable = NULL;
{
PUSER_HANDLE_ENTRY entry;
- DPRINT("handles used %i\n",usedHandles);
+ DPRINT("handles used %i\n",gpsi->cHandleEntries);
if (ht->freelist)
{
entry = ht->freelist;
ht->freelist = entry->ptr;
- usedHandles++;
+ gpsi->cHandleEntries++;
return entry;
}
if (ht->nb_handles >= ht->allocated_handles) /* need to grow the array */
{
- DPRINT1("Out of user handles!\n");
+/**/
+ int i, iFree = 0, iWindow = 0, iMenu = 0, iCursorIcon = 0,
+ iHook = 0, iCallProc = 0, iAccel = 0, iMonitor = 0, iTimer = 0;
+ /**/
+ DPRINT1("Out of user handles! Used -> %i, NM_Handle -> %d\n", gpsi->cHandleEntries, ht->nb_handles);
+//#if 0
+ for(i = 0; i < ht->nb_handles; i++)
+ {
+ switch (ht->handles[i].type)
+ {
+ case otFree: // Should be zero.
+ iFree++;
+ break;
+ case otWindow:
+ iWindow++;
+ break;
+ case otMenu:
+ iMenu++;
+ break;
+ case otCursorIcon:
+ iCursorIcon++;
+ break;
+ case otHook:
+ iHook++;
+ break;
+ case otCallProc:
+ iCallProc++;
+ break;
+ case otAccel:
+ iAccel++;
+ break;
+ case otMonitor:
+ iMonitor++;
+ break;
+ case otTimer:
+ iTimer++;
+ break;
+ default:
+ break;
+ }
+ }
+ DPRINT1("Handle Count by Type:\n Free = %d Window = %d Menu = %d CursorIcon = %d Hook = %d\n CallProc = %d Accel = %d Monitor = %d Timer = %d\n",
+ iFree, iWindow, iMenu, iCursorIcon, iHook, iCallProc, iAccel, iMonitor, iTimer );
+//#endif
return NULL;
#if 0
PUSER_HANDLE_ENTRY new_handles;
entry->generation = 1;
- usedHandles++;
+ gpsi->cHandleEntries++;
return entry;
}
ret = entry->ptr;
entry->ptr = ht->freelist;
entry->type = 0;
- entry->pti = 0;
+ entry->flags = 0;
+ entry->pi = NULL;
ht->freelist = entry;
- usedHandles--;
+ gpsi->cHandleEntries--;
return ret;
}
+static __inline PVOID
+UserHandleOwnerByType(USER_OBJECT_TYPE type)
+{
+ PVOID pi;
+
+ switch (type)
+ {
+ case otWindow:
+ case otInputContext:
+ pi = GetW32ThreadInfo();
+ break;
+
+ case otMenu:
+ case otCursorIcon:
+ case otHook:
+ case otCallProc:
+ case otAccel:
+ pi = GetW32ProcessInfo();
+ break;
+
+ case otMonitor:
+ pi = NULL; /* System */
+ break;
+
+ default:
+ pi = NULL;
+ break;
+ }
+
+ return pi;
+}
+
/* allocate a user handle for a given object */
HANDLE UserAllocHandle(PUSER_HANDLE_TABLE ht, PVOID object, USER_OBJECT_TYPE type )
{
return 0;
entry->ptr = object;
entry->type = type;
- entry->pti = GetW32ThreadInfo();
- if (entry->pti->pi->UserHandleTable == NULL) GetW32ProcessInfo();
+ entry->flags = 0;
+ entry->pi = UserHandleOwnerByType(type);
if (++entry->generation >= 0xffff)
entry->generation = 1;
+
+ /* We have created a handle, which is a reference! */
+ UserReferenceObject(object);
+
return entry_to_handle(ht, entry );
}
return entry->ptr;
}
-/* free a user handle and return a pointer to the object */
-PVOID UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle )
-{
- PUSER_HANDLE_ENTRY entry;
-
- if (!(entry = handle_to_entry( ht, handle )))
- {
- SetLastNtError( STATUS_INVALID_HANDLE );
- return NULL;
- }
-
- return free_user_entry(ht, entry );
-}
-
/* return the next user handle after 'handle' that is of a given type */
PVOID UserGetNextHandle(PUSER_HANDLE_TABLE ht, HANDLE* handle, USER_OBJECT_TYPE type )
{
return NULL;
}
-
-
-PVOID FASTCALL
-ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG size)
+BOOL FASTCALL UserCreateHandleTable(VOID)
{
- HANDLE hi;
- PUSER_OBJECT_HEADER hdr = UserHeapAlloc(size + sizeof(USER_OBJECT_HEADER));//ExAllocatePool(PagedPool, size + sizeof(USER_OBJECT_HEADER));
- if (!hdr)
- return NULL;
+ PVOID mem;
+ //FIXME: dont alloc all at once! must be mapped into umode also...
+ mem = UserHeapAlloc(sizeof(USER_HANDLE_ENTRY) * 1024*2);
+ if (!mem)
+ {
+ DPRINT1("Failed creating handle table\n");
+ return FALSE;
+ }
- hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type );
- if (!hi)
+ gHandleTable = UserHeapAlloc(sizeof(USER_HANDLE_TABLE));
+ if (gHandleTable == NULL)
{
- //ExFreePool(hdr);
- UserHeapFree(hdr);
- return NULL;
+ UserHeapFree(mem);
+ DPRINT1("Failed creating handle table\n");
+ return FALSE;
}
- RtlZeroMemory(hdr, size + sizeof(USER_OBJECT_HEADER));
- hdr->hSelf = hi;
- hdr->RefCount++; //temp hack!
+ //FIXME: make auto growable
+ UserInitHandleTable(gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024*2);
- if (h)
- *h = hi;
- return USER_HEADER_TO_BODY(hdr);
+ return TRUE;
}
-BOOL FASTCALL
-ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
+//
+// New
+//
+PVOID
+FASTCALL
+UserCreateObject( PUSER_HANDLE_TABLE ht,
+ PDESKTOP pDesktop,
+ HANDLE* h,
+ USER_OBJECT_TYPE type,
+ ULONG size)
{
- PUSER_OBJECT_HEADER hdr;
- PVOID body = UserGetObject(gHandleTable, h, type);
- if (!body)
- return FALSE;
+ HANDLE hi;
+ PVOID Object;
+ PTHREADINFO pti;
+ PPROCESSINFO ppi;
+ BOOL dt;
+ PDESKTOP rpdesk = pDesktop;
- hdr = USER_BODY_TO_HEADER(body);
- ASSERT(hdr->RefCount >= 0);
+ pti = GetW32ThreadInfo();
+ ppi = pti->ppi;
+ if (!pDesktop) rpdesk = pti->rpdesk;
- hdr->destroyed = TRUE;
- if (hdr->RefCount == 0)
+ switch (type)
{
- UserFreeHandle(gHandleTable, h);
-
- memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
-
- UserHeapFree(hdr);
- //ExFreePool(hdr);
- return TRUE;
+// case otWindow:
+// case otMenu:
+// case otHook:
+// case otCallProc:
+ case otInputContext:
+ Object = DesktopHeapAlloc(rpdesk, size);
+ dt = TRUE;
+ break;
+
+ default:
+ Object = UserHeapAlloc(size);
+ dt = FALSE;
+ break;
}
-// DPRINT1("info: something not destroyed bcause refs still left, inuse %i\n",usedHandles);
- return FALSE;
-}
+ if (!Object)
+ return NULL;
-VOID FASTCALL ObmReferenceObject(PVOID obj)
-{
- PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
+ hi = UserAllocHandle(ht, Object, type );
+ if (!hi)
+ {
+ if (dt)
+ DesktopHeapFree(rpdesk, Object);
+ else
+ UserHeapFree(Object);
+ return NULL;
+ }
- ASSERT(hdr->RefCount >= 0);
+ RtlZeroMemory(Object, size);
- hdr->RefCount++;
-}
+ switch (type)
+ {
+ case otWindow:
+ case otHook:
+ case otInputContext:
+ ((PTHRDESKHEAD)Object)->rpdesk = rpdesk;
+ ((PTHRDESKHEAD)Object)->pSelf = Object;
+ case otEvent:
+ ((PTHROBJHEAD)Object)->pti = pti;
+ break;
+
+ case otMenu:
+ case otCallProc:
+ ((PPROCDESKHEAD)Object)->rpdesk = rpdesk;
+ ((PPROCDESKHEAD)Object)->pSelf = Object;
+ break;
+
+ case otCursorIcon:
+ ((PPROCMARKHEAD)Object)->ppi = ppi;
+ break;
+
+ default:
+ break;
+ }
+ /* Now set default headers. */
+ ((PHEAD)Object)->h = hi;
+ ((PHEAD)Object)->cLockObj = 2; // we need this, because we create 2 refs: handle and pointer!
-HANDLE FASTCALL ObmObjectToHandle(PVOID obj)
-{
- PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
- return hdr->hSelf;
+ if (h)
+ *h = hi;
+ return Object;
}
-BOOL FASTCALL ObmDereferenceObject2(PVOID obj)
+BOOL
+FASTCALL
+UserDereferenceObject(PVOID object)
{
- PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
+ PUSER_HANDLE_ENTRY entry;
+ USER_OBJECT_TYPE type;
- ASSERT(hdr->RefCount >= 1);
+ ASSERT(((PHEAD)object)->cLockObj >= 1);
- hdr->RefCount--;
+ if ((INT)--((PHEAD)object)->cLockObj <= 0)
+ {
+ entry = handle_to_entry(gHandleTable, ((PHEAD)object)->h );
- // You can not have a zero here!
- if (!hdr->destroyed && hdr->RefCount == 0) hdr->RefCount++; // BOUNCE!!!!!
+ DPRINT("warning! Dereference to zero! Obj -> 0x%x\n", object);
- if (hdr->RefCount == 0 && hdr->destroyed)
- {
-// DPRINT1("info: something destroyed bcaise of deref, in use=%i\n",usedHandles);
-
- UserFreeHandle(gHandleTable, hdr->hSelf);
+ ((PHEAD)object)->cLockObj = 0;
- memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
+ if (!(entry->flags & HANDLEENTRY_INDESTROY))
+ return TRUE;
- UserHeapFree(hdr);
- //ExFreePool(hdr);
+ type = entry->type;
+ free_user_entry(gHandleTable, entry );
- return TRUE;
- }
+ switch (type)
+ {
+// case otWindow:
+// case otMenu:
+// case otHook:
+// case otCallProc:
+ case otInputContext:
+ return DesktopHeapFree(((PTHRDESKHEAD)object)->rpdesk, object);
- return FALSE;
+ default:
+ return UserHeapFree(object);
+ }
+ }
+ return FALSE;
}
+BOOL
+FASTCALL
+UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle )
+{
+ PUSER_HANDLE_ENTRY entry;
+
+ if (!(entry = handle_to_entry( ht, handle )))
+ {
+ SetLastNtError( STATUS_INVALID_HANDLE );
+ return FALSE;
+ }
+ entry->flags = HANDLEENTRY_INDESTROY;
-BOOL FASTCALL ObmCreateHandleTable()
+ return UserDereferenceObject(entry->ptr);
+}
+
+BOOL
+FASTCALL
+UserDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
{
+ PVOID body = UserGetObject(gHandleTable, h, type);
+
+ if (!body) return FALSE;
- PVOID mem;
+ ASSERT( ((PHEAD)body)->cLockObj >= 1);
- //FIXME: dont alloc all at once! must be mapped into umode also...
- //mem = ExAllocatePool(PagedPool, sizeof(USER_HANDLE_ENTRY) * 1024*2);
- mem = UserHeapAlloc(sizeof(USER_HANDLE_ENTRY) * 1024*2);
- if (!mem)
- {
- DPRINT1("Failed creating handle table\n");
- return FALSE;
- }
+ return UserFreeHandle(gHandleTable, h);
+}
- gHandleTable = UserHeapAlloc(sizeof(USER_HANDLE_TABLE));
- if (gHandleTable == NULL)
- {
- UserHeapFree(mem);
- DPRINT1("Failed creating handle table\n");
- return FALSE;
- }
+VOID
+FASTCALL
+UserReferenceObject(PVOID obj)
+{
+ ASSERT(((PHEAD)obj)->cLockObj >= 0);
- //FIXME: make auto growable
- UserInitHandleTable(gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024*2);
+ ((PHEAD)obj)->cLockObj++;
+}
- return TRUE;
+PVOID
+FASTCALL
+UserReferenceObjectByHandle(HANDLE handle, USER_OBJECT_TYPE type)
+{
+ PVOID object;
+
+ object = UserGetObject(gHandleTable, handle, type);
+ if (object)
+ {
+ UserReferenceObject(object);
+ }
+ return object;
}