/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
ret = entry->ptr;
entry->ptr = ht->freelist;
entry->type = 0;
+ entry->flags = 0;
entry->pi = NULL;
ht->freelist = entry;
switch (type)
{
case otWindow:
+ case otInputContext:
pi = GetW32ThreadInfo();
break;
case otHook:
case otCallProc:
case otAccel:
+ case otSMWP:
pi = GetW32ProcessInfo();
break;
return 0;
entry->ptr = object;
entry->type = type;
+ entry->flags = 0;
entry->pi = UserHandleOwnerByType(type);
if (++entry->generation >= 0xffff)
entry->generation = 1;
if (!(entry = handle_to_entry(ht, handle )) || entry->type != type)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
return entry->ptr;
return entry->ptr;
}
-/* free a user handle */
-BOOL UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle )
-{
- PUSER_HANDLE_ENTRY entry;
- PVOID object;
-
- if (!(entry = handle_to_entry( ht, handle )))
- {
- SetLastNtError( STATUS_INVALID_HANDLE );
- return FALSE;
- }
-
- object = free_user_entry(ht, entry );
-
- /* We removed the handle, which was a reference! */
- return UserDereferenceObject(object);
-
- return TRUE;
-}
-
/* 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
-UserCreateObject(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 = 2; // we need this, because we create 2 refs: handle and pointer!
+ //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
-UserDeleteObject(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 >= 1);
-
- hdr->destroyed = TRUE;
- return UserFreeHandle(gHandleTable, h);
-}
+ pti = GetW32ThreadInfo();
+ ppi = pti->ppi;
+ if (!pDesktop) rpdesk = pti->rpdesk;
+ switch (type)
+ {
+ case otWindow:
+// case otMenu:
+ case otHook:
+ case otCallProc:
+ case otInputContext:
+ Object = DesktopHeapAlloc(rpdesk, size);
+ dt = TRUE;
+ break;
+
+ default:
+ Object = UserHeapAlloc(size);
+ dt = FALSE;
+ break;
+ }
-VOID FASTCALL UserReferenceObject(PVOID obj)
-{
- PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
+ if (!Object)
+ return NULL;
- ASSERT(hdr->RefCount >= 0);
- hdr->RefCount++;
-}
+ hi = UserAllocHandle(ht, Object, type );
+ if (!hi)
+ {
+ if (dt)
+ DesktopHeapFree(rpdesk, Object);
+ else
+ UserHeapFree(Object);
+ return NULL;
+ }
+ RtlZeroMemory(Object, size);
-PVOID FASTCALL UserReferenceObjectByHandle(HANDLE handle, USER_OBJECT_TYPE type)
-{
- PVOID object;
+ switch (type)
+ {
+ case otWindow:
+ case otHook:
+ case otInputContext:
+ ((PTHRDESKHEAD)Object)->rpdesk = rpdesk;
+ ((PTHRDESKHEAD)Object)->pSelf = Object;
+ case otEvent:
+ ((PTHROBJHEAD)Object)->pti = pti;
+ break;
- object = UserGetObject(gHandleTable, handle, type);
- if(object)
- {
- UserReferenceObject(object);
- }
+ case otMenu:
+ case otCallProc:
+ ((PPROCDESKHEAD)Object)->rpdesk = rpdesk;
+ ((PPROCDESKHEAD)Object)->pSelf = Object;
+ break;
- return object;
-}
+ 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 UserObjectToHandle(PVOID obj)
-{
- PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
- return hdr->hSelf;
+ if (h)
+ *h = hi;
+ return Object;
}
-BOOL FASTCALL UserDereferenceObject(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!!!!!
- DPRINT1("warning! Dereference to zero without deleting! Obj -> 0x%x\n", obj);
- }
+ 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",gpsi->cHandleEntries);
+ ((PHEAD)object)->cLockObj = 0;
- memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
+ if (!(entry->flags & HANDLEENTRY_INDESTROY))
+ return TRUE;
- return 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;
+ }
-BOOL FASTCALL UserCreateHandleTable(VOID)
+ entry->flags = HANDLEENTRY_INDESTROY;
+
+ 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;
}