ReactOS  0.4.15-dev-5459-gb85f005
object.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * PURPOSE: User handle manager
5  * FILE: win32ss/user/ntuser/object.c
6  * PROGRAMER: Copyright (C) 2001 Alexandre Julliard
7  */
8 
9 #include <win32k.h>
10 DBG_DEFAULT_CHANNEL(UserObj);
11 
12 //int usedHandles=0;
14 
15 /* Forward declarations */
16 _Success_(return!=NULL)
17 static PVOID AllocThreadObject(
18  _In_ PDESKTOP pDesk,
19  _In_ PTHREADINFO pti,
21  _Out_ PVOID* HandleOwner)
22 {
23  PTHROBJHEAD ObjHead;
24 
26 
27  ASSERT(Size > sizeof(*ObjHead));
28  ASSERT(pti != NULL);
29 
30  ObjHead = UserHeapAlloc(Size);
31  if (!ObjHead)
32  return NULL;
33 
34  RtlZeroMemory(ObjHead, Size);
35 
36  ObjHead->pti = pti;
38  *HandleOwner = pti;
39  /* It's a thread object, but it still count as one for the process */
40  pti->ppi->UserHandleCount++;
41 
42  return ObjHead;
43 }
44 
45 static void FreeThreadObject(
47 {
48  PTHROBJHEAD ObjHead = (PTHROBJHEAD)Object;
49  PTHREADINFO pti = ObjHead->pti;
50 
51  UserHeapFree(ObjHead);
52 
53  pti->ppi->UserHandleCount--;
55 }
56 
57 _Success_(return!=NULL)
58 static PVOID AllocDeskThreadObject(
59  _In_ PDESKTOP pDesk,
60  _In_ PTHREADINFO pti,
62  _Out_ PVOID* HandleOwner)
63 {
64  PTHRDESKHEAD ObjHead;
65 
66  ASSERT(Size > sizeof(*ObjHead));
67  ASSERT(pti != NULL);
68 
69  if (!pDesk)
70  pDesk = pti->rpdesk;
71 
72  ObjHead = DesktopHeapAlloc(pDesk, Size);
73  if (!ObjHead)
74  return NULL;
75 
76  RtlZeroMemory(ObjHead, Size);
77 
78  ObjHead->pSelf = ObjHead;
79  ObjHead->rpdesk = pDesk;
80  ObjHead->pti = pti;
82  *HandleOwner = pti;
83  /* It's a thread object, but it still count as one for the process */
84  pti->ppi->UserHandleCount++;
85 
86  return ObjHead;
87 }
88 
91 {
92  PTHRDESKHEAD ObjHead = (PTHRDESKHEAD)Object;
93  PDESKTOP pDesk = ObjHead->rpdesk;
94  PTHREADINFO pti = ObjHead->pti;
95 
96  DesktopHeapFree(pDesk, Object);
97 
98  pti->ppi->UserHandleCount--;
100 }
101 
102 _Success_(return!=NULL)
103 static PVOID AllocDeskProcObject(
104  _In_ PDESKTOP pDesk,
105  _In_ PTHREADINFO pti,
106  _In_ SIZE_T Size,
107  _Out_ PVOID* HandleOwner)
108 {
109  PPROCDESKHEAD ObjHead;
110  PPROCESSINFO ppi;
111 
112  ASSERT(Size > sizeof(*ObjHead));
113  ASSERT(pDesk != NULL);
114  ASSERT(pti != NULL);
115 
116  ObjHead = DesktopHeapAlloc(pDesk, Size);
117  if (!ObjHead)
118  return NULL;
119 
120  RtlZeroMemory(ObjHead, Size);
121 
122  ppi = pti->ppi;
123 
124  ObjHead->pSelf = ObjHead;
125  ObjHead->rpdesk = pDesk;
126  ObjHead->hTaskWow = (DWORD_PTR)ppi;
127  ppi->UserHandleCount++;
129  *HandleOwner = ppi;
130 
131  return ObjHead;
132 }
133 
134 static void FreeDeskProcObject(
135  _In_ PVOID Object)
136 {
138  PDESKTOP pDesk = ObjHead->rpdesk;
139  PPROCESSINFO ppi = (PPROCESSINFO)ObjHead->hTaskWow;
140 
141  ppi->UserHandleCount--;
143 
144  DesktopHeapFree(pDesk, Object);
145 }
146 
147 _Success_(return!=NULL)
148 static PVOID AllocProcMarkObject(
149  _In_ PDESKTOP pDesk,
150  _In_ PTHREADINFO pti,
151  _In_ SIZE_T Size,
152  _Out_ PVOID* HandleOwner)
153 {
154  PPROCMARKHEAD ObjHead;
155  PPROCESSINFO ppi = pti->ppi;
156 
157  UNREFERENCED_PARAMETER(pDesk);
158 
159  ASSERT(Size > sizeof(*ObjHead));
160 
161  ObjHead = UserHeapAlloc(Size);
162  if (!ObjHead)
163  return NULL;
164 
165  RtlZeroMemory(ObjHead, Size);
166 
167  ObjHead->ppi = ppi;
169  *HandleOwner = ppi;
170  ppi->UserHandleCount++;
171 
172  return ObjHead;
173 }
174 
176  _In_ PVOID Object)
177 {
178  PPROCESSINFO ppi = ((PPROCMARKHEAD)Object)->ppi;
179 
181 
182  ppi->UserHandleCount--;
184 }
185 
186 _Success_(return!=NULL)
187 static PVOID AllocSysObject(
188  _In_ PDESKTOP pDesk,
189  _In_ PTHREADINFO pti,
190  _In_ SIZE_T Size,
191  _Out_ PVOID* ObjectOwner)
192 {
193  PVOID Object;
194 
195  UNREFERENCED_PARAMETER(pDesk);
197 
198  ASSERT(Size > sizeof(HEAD));
199 
201  if (!Object)
202  return NULL;
203 
204  *ObjectOwner = NULL;
205 
207  return Object;
208 }
209 
210 _Success_(return!=NULL)
211 static PVOID AllocSysObjectCB(
212  _In_ PDESKTOP pDesk,
213  _In_ PTHREADINFO pti,
214  _In_ SIZE_T Size,
215  _Out_ PVOID* ObjectOwner)
216 {
217  PVOID Object;
218 
219  UNREFERENCED_PARAMETER(pDesk);
221  ASSERT(Size > sizeof(HEAD));
222 
223  /* Allocate the clipboard data */
224  // FIXME: This allocation should be done on the current session pool;
225  // however ReactOS' MM doesn't support session pool yet.
226  Object = ExAllocatePoolZero(/* SESSION_POOL_MASK | */ PagedPool, Size, USERTAG_CLIPBOARD);
227  if (!Object)
228  {
229  ERR("ExAllocatePoolZero failed. No object created.\n");
230  return NULL;
231  }
232 
233  *ObjectOwner = NULL;
234  return Object;
235 }
236 
237 static void FreeSysObject(
238  _In_ PVOID Object)
239 {
241 }
242 
243 static void FreeSysObjectCB(
244  _In_ PVOID Object)
245 {
247 }
248 
249 static const struct
250 {
255 {
256  { NULL, NULL, NULL }, /* TYPE_FREE */
257  { AllocDeskThreadObject, co_UserDestroyWindow, FreeDeskThreadObject }, /* TYPE_WINDOW */
258  { AllocDeskProcObject, UserDestroyMenuObject, FreeDeskProcObject }, /* TYPE_MENU */
259  { AllocProcMarkObject, IntDestroyCurIconObject, FreeCurIconObject }, /* TYPE_CURSOR */
260  { AllocSysObject, /*UserSetWindowPosCleanup*/NULL, FreeSysObject }, /* TYPE_SETWINDOWPOS */
261  { AllocDeskThreadObject, IntRemoveHook, FreeDeskThreadObject }, /* TYPE_HOOK */
262  { AllocSysObjectCB, /*UserClipDataCleanup*/NULL,FreeSysObjectCB }, /* TYPE_CLIPDATA */
263  { AllocDeskProcObject, DestroyCallProc, FreeDeskProcObject }, /* TYPE_CALLPROC */
264  { AllocProcMarkObject, UserDestroyAccelTable, FreeProcMarkObject }, /* TYPE_ACCELTABLE */
265  { NULL, NULL, NULL }, /* TYPE_DDEACCESS */
266  { NULL, NULL, NULL }, /* TYPE_DDECONV */
267  { NULL, NULL, NULL }, /* TYPE_DDEXACT */
268  { AllocSysObject, /*UserMonitorCleanup*/NULL, FreeSysObject }, /* TYPE_MONITOR */
269  { AllocSysObject, /*UserKbdLayoutCleanup*/NULL,FreeSysObject }, /* TYPE_KBDLAYOUT */
270  { AllocSysObject, /*UserKbdFileCleanup*/NULL, FreeSysObject }, /* TYPE_KBDFILE */
271  { AllocThreadObject, IntRemoveEvent, FreeThreadObject }, /* TYPE_WINEVENTHOOK */
272  { AllocSysObject, /*UserTimerCleanup*/NULL, FreeSysObject }, /* TYPE_TIMER */
274  { NULL, NULL, NULL }, /* TYPE_HIDDATA */
275  { NULL, NULL, NULL }, /* TYPE_DEVICEINFO */
276  { NULL, NULL, NULL }, /* TYPE_TOUCHINPUTINFO */
277  { NULL, NULL, NULL }, /* TYPE_GESTUREINFOOBJ */
278 };
279 
280 #if DBG
281 
283 {
284  int HandleCounts[TYPE_CTYPES];
285  PPROCESSINFO ppiList;
286  int i;
287  PWCHAR TypeNames[] = {L"Free",L"Window",L"Menu", L"CursorIcon", L"SMWP", L"Hook", L"ClipBoardData", L"CallProc",
288  L"Accel", L"DDEaccess", L"DDEconv", L"DDExact", L"Monitor", L"KBDlayout", L"KBDfile",
289  L"Event", L"Timer", L"InputContext", L"HidData", L"DeviceInfo", L"TouchInput",L"GestureInfo"};
290 
291  ERR("Total handles count: %lu\n", gpsi->cHandleEntries);
292 
293  memset(HandleCounts, 0, sizeof(HandleCounts));
294 
295  /* First of all count the number of handles per type */
296  ppiList = gppiList;
297  while (ppiList)
298  {
299  ERR("Process %s (%p) handles count: %d\n\t", ppiList->peProcess->ImageFileName, ppiList->peProcess->UniqueProcessId, ppiList->UserHandleCount);
300 
301  for (i = 1 ;i < TYPE_CTYPES; i++)
302  {
303  HandleCounts[i] += ppiList->DbgHandleCount[i];
304 
305  DbgPrint("%S: %lu, ", TypeNames[i], ppiList->DbgHandleCount[i]);
306  if (i % 6 == 0)
307  DbgPrint("\n\t");
308  }
309  DbgPrint("\n");
310 
311  ppiList = ppiList->ppiNext;
312  }
313 
314  /* Print total type counts */
315  ERR("Total handles of the running processes: \n\t");
316  for (i = 1 ;i < TYPE_CTYPES; i++)
317  {
318  DbgPrint("%S: %d, ", TypeNames[i], HandleCounts[i]);
319  if (i % 6 == 0)
320  DbgPrint("\n\t");
321  }
322  DbgPrint("\n");
323 
324  /* Now count the handle counts that are allocated from the handle table */
325  memset(HandleCounts, 0, sizeof(HandleCounts));
326  for (i = 0; i < gHandleTable->nb_handles; i++)
327  HandleCounts[gHandleTable->handles[i].type]++;
328 
329  ERR("Total handles count allocated: \n\t");
330  for (i = 1 ;i < TYPE_CTYPES; i++)
331  {
332  DbgPrint("%S: %d, ", TypeNames[i], HandleCounts[i]);
333  if (i % 6 == 0)
334  DbgPrint("\n\t");
335  }
336  DbgPrint("\n");
337 }
338 
339 #endif
340 
342 {
343  unsigned short generation;
344  int index = (LOWORD(handle) - FIRST_USER_HANDLE) >> 1;
345  if (index < 0 || index >= ht->nb_handles)
346  return NULL;
347  if (!ht->handles[index].type)
348  return NULL;
350  if (generation == ht->handles[index].generation || !generation || generation == 0xffff)
351  return &ht->handles[index];
352  return NULL;
353 }
354 
356 {
357  int index = ptr - ht->handles;
358  return (HANDLE)((((INT_PTR)index << 1) + FIRST_USER_HANDLE) + (ptr->generation << 16));
359 }
360 
362 {
364  TRACE("handles used %lu\n", gpsi->cHandleEntries);
365 
366  if (ht->freelist)
367  {
368  entry = ht->freelist;
369  ht->freelist = entry->ptr;
370 
371  gpsi->cHandleEntries++;
372  return entry;
373  }
374 
375  if (ht->nb_handles >= ht->allocated_handles) /* Need to grow the array */
376  {
377  ERR("Out of user handles! Used -> %lu, NM_Handle -> %d\n", gpsi->cHandleEntries, ht->nb_handles);
378 
379 #if DBG
381 #endif
382 
383  return NULL;
384 #if 0
385  PUSER_HANDLE_ENTRY new_handles;
386  /* Grow array by 50% (but at minimum 32 entries) */
387  int growth = max( 32, ht->allocated_handles / 2 );
388  int new_size = min( ht->allocated_handles + growth, (LAST_USER_HANDLE-FIRST_USER_HANDLE+1) >> 1 );
389  if (new_size <= ht->allocated_handles)
390  return NULL;
391  if (!(new_handles = UserHeapReAlloc( ht->handles, new_size * sizeof(*ht->handles) )))
392  return NULL;
393  ht->handles = new_handles;
394  ht->allocated_handles = new_size;
395 #endif
396  }
397 
398  entry = &ht->handles[ht->nb_handles++];
399 
400  entry->generation = 1;
401 
402  gpsi->cHandleEntries++;
403 
404  return entry;
405 }
406 
408 {
409  ht->freelist = NULL;
410  ht->handles = mem;
411 
412  ht->nb_handles = 0;
413  ht->allocated_handles = bytes / sizeof(USER_HANDLE_ENTRY);
414 }
415 
416 
418 {
419  void *ret;
420 
421 #if DBG
422  {
423  PPROCESSINFO ppi;
424  switch (entry->type)
425  {
426  case TYPE_WINDOW:
427  case TYPE_HOOK:
428  case TYPE_WINEVENTHOOK:
429  ppi = ((PTHREADINFO)entry->pi)->ppi;
430  break;
431  case TYPE_MENU:
432  case TYPE_CURSOR:
433  case TYPE_CALLPROC:
434  case TYPE_ACCELTABLE:
435  ppi = entry->pi;
436  break;
437  default:
438  ppi = NULL;
439  }
440  if (ppi)
441  ppi->DbgHandleCount[entry->type]--;
442  }
443 #endif
444 
445  ret = entry->ptr;
446  entry->ptr = ht->freelist;
447  entry->type = 0;
448  entry->flags = 0;
449  entry->pi = NULL;
450  ht->freelist = entry;
451 
452  gpsi->cHandleEntries--;
453 
454  return ret;
455 }
456 
457 /* allocate a user handle for a given object */
460  _In_ PVOID object,
462  _In_ PVOID HandleOwner)
463 {
465  if (!entry)
466  return 0;
467  entry->ptr = object;
468  entry->type = type;
469  entry->flags = 0;
470  entry->pi = HandleOwner;
471  if (++entry->generation >= 0xffff)
472  entry->generation = 1;
473 
474  /* We have created a handle, which is a reference! */
475  UserReferenceObject(object);
476 
477  return entry_to_handle(ht, entry );
478 }
479 
480 /* return a pointer to a user object from its handle without setting an error */
482 {
484 
485  ASSERT(ht);
486 
487  if (!(entry = handle_to_entry(ht, handle )) || entry->type != type)
488  {
489  return NULL;
490  }
491  return entry->ptr;
492 }
493 
494 /* return a pointer to a user object from its handle */
496 {
498 
499  ASSERT(ht);
500 
501  if (!(entry = handle_to_entry(ht, handle )) || entry->type != type)
502  {
504  return NULL;
505  }
506  return entry->ptr;
507 }
508 
509 
510 /* Get the full handle (32bit) for a possibly truncated (16bit) handle */
512 {
514 
515  if ((ULONG_PTR)handle >> 16)
516  return handle;
517  if (!(entry = handle_to_entry(ht, handle )))
518  return handle;
519  return entry_to_handle( ht, entry );
520 }
521 
522 
523 /* Same as get_user_object plus set the handle to the full 32-bit value */
525 {
527 
528  if (!(entry = handle_to_entry(ht, *handle )) || entry->type != type)
529  return NULL;
531  return entry->ptr;
532 }
533 
534 
535 
537 {
538  PVOID mem;
539  INT HandleCount = 1024 * 4;
540 
541  // FIXME: Don't alloc all at once! Must be mapped into umode also...
542  mem = UserHeapAlloc(sizeof(USER_HANDLE_ENTRY) * HandleCount);
543  if (!mem)
544  {
545  ERR("Failed creating handle table\n");
546  return FALSE;
547  }
548 
550  if (gHandleTable == NULL)
551  {
552  UserHeapFree(mem);
553  ERR("Failed creating handle table\n");
554  return FALSE;
555  }
556 
557  // FIXME: Make auto growable
558  UserInitHandleTable(gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * HandleCount);
559 
560  return TRUE;
561 }
562 
563 //
564 // New
565 //
566 PVOID
567 FASTCALL
569  PDESKTOP pDesktop,
570  PTHREADINFO pti,
571  HANDLE* h,
573  ULONG size)
574 {
575  HANDLE hi;
576  PVOID Object;
577  PVOID ObjectOwner;
578 
579  /* Some sanity checks. Other checks will be made in the allocator */
581  ASSERT(type != TYPE_FREE);
582  ASSERT(ht != NULL);
583 
584  /* Allocate the object */
586  Object = ObjectCallbacks[type].ObjectAlloc(pDesktop, pti, size, &ObjectOwner);
587  if (!Object)
588  {
589  ERR("User object allocation failed. Out of memory!\n");
590  return NULL;
591  }
592 
593  hi = UserAllocHandle(ht, Object, type, ObjectOwner);
594  if (hi == NULL)
595  {
596  ERR("Out of user handles!\n");
597  ObjectCallbacks[type].ObjectFree(Object);
598  return NULL;
599  }
600 
601 #if DBG
602  if (pti)
603  pti->ppi->DbgHandleCount[type]++;
604 #endif
605 
606  /* Give this object its identity. */
607  ((PHEAD)Object)->h = hi;
608 
609  /* The caller will get a locked object.
610  * Note: with the reference from the handle, that makes two */
612 
613  if (h)
614  *h = hi;
615  return Object;
616 }
617 
618 // Win: HMMarkObjectDestroy
619 BOOL
620 FASTCALL
622 {
624  PHEAD ObjHead = Object;
625 
626  entry = handle_to_entry(gHandleTable, ObjHead->h);
627 
628  ASSERT(entry != NULL);
629 
630  entry->flags |= HANDLEENTRY_DESTROY;
631 
632  if (ObjHead->cLockObj > 1)
633  {
634  entry->flags &= ~HANDLEENTRY_INDESTROY;
635  TRACE("Count %d\n",ObjHead->cLockObj);
636  return FALSE;
637  }
638 
639  return TRUE;
640 }
641 
642 BOOL
643 FASTCALL
645 {
646  PHEAD ObjHead = Object;
647 
648  ASSERT(ObjHead->cLockObj >= 1);
649  ASSERT(ObjHead->cLockObj < 0x10000);
650 
651  if (--ObjHead->cLockObj == 0)
652  {
655 
656  entry = handle_to_entry(gHandleTable, ObjHead->h);
657 
658  ASSERT(entry != NULL);
659  /* The entry should be marked as in deletion */
661 
662  type = entry->type;
663  ASSERT(type != TYPE_FREE);
665 
666  /* We can now get rid of everything */
668 
669 #if 0
670  /* Call the object destructor */
671  ASSERT(ObjectCallbacks[type].ObjectCleanup != NULL);
672  ObjectCallbacks[type].ObjectCleanup(Object);
673 #endif
674 
675  /* And free it */
677  ObjectCallbacks[type].ObjectFree(Object);
678 
679  return TRUE;
680  }
681  return FALSE;
682 }
683 
684 BOOL
685 FASTCALL
687 {
689 
690  if (!(entry = handle_to_entry( ht, handle )))
691  {
693  return FALSE;
694  }
695 
696  entry->flags = HANDLEENTRY_INDESTROY;
697 
698  return UserDereferenceObject(entry->ptr);
699 }
700 
701 BOOL
702 FASTCALL
704 {
706 
707  if (!(entry = handle_to_entry( gHandleTable, h )))
708  {
710  return TRUE;
711  }
712  return (entry->flags & HANDLEENTRY_INDESTROY);
713 }
714 
715 BOOL
716 FASTCALL
718 {
720 
721  if (!body) return FALSE;
722 
723  ASSERT( ((PHEAD)body)->cLockObj >= 1);
724  ASSERT( ((PHEAD)body)->cLockObj < 0x10000);
725 
726  return UserFreeHandle(gHandleTable, h);
727 }
728 
729 VOID
730 FASTCALL
732 {
733  PHEAD ObjHead = obj;
734  ASSERT(ObjHead->cLockObj < 0x10000);
735 
736  ObjHead->cLockObj++;
737 }
738 
739 PVOID
740 FASTCALL
742 {
743  PVOID object;
744 
746  if (object)
747  {
748  UserReferenceObject(object);
749  }
750  return object;
751 }
752 
753 BOOLEAN
755 {
756  int i;
758  BOOLEAN Ret = TRUE;
759 
760  /* Sweep the whole handle table */
761  for (i = 0; i < Table->allocated_handles; i++)
762  {
763  Entry = &Table->handles[i];
764 
765  if (Entry->pi != Owner)
766  continue;
767 
768  /* Do not destroy if it's already been done */
769  if (Entry->flags & HANDLEENTRY_INDESTROY)
770  continue;
771 
772  /* Call destructor */
773  if (!ObjectCallbacks[Entry->type].ObjectDestroy(Entry->ptr))
774  {
775  ERR("Failed destructing object %p, type %u.\n", Entry->ptr, Entry->type);
776  /* Don't return immediately, we must continue destroying the other objects */
777  Ret = FALSE;
778  }
779  }
780 
781  return Ret;
782 }
783 
784 /*
785  *
786  * Status
787  * @implemented
788  */
789 
790 BOOL
791 APIENTRY
793  HANDLE handle)
794 {
795  UINT uType;
796  PPROCESSINFO ppi;
798 
801 
803  {
805  RETURN( FALSE);
806  }
807  uType = entry->type;
808  switch (uType)
809  {
810  case TYPE_WINDOW:
811  case TYPE_INPUTCONTEXT:
812  ppi = ((PTHREADINFO)entry->pi)->ppi;
813  break;
814  case TYPE_MENU:
815  case TYPE_ACCELTABLE:
816  case TYPE_CURSOR:
817  case TYPE_HOOK:
818  case TYPE_CALLPROC:
819  case TYPE_SETWINDOWPOS:
820  ppi = entry->pi;
821  break;
822  default:
823  ppi = NULL;
824  break;
825  }
826 
827  if (!ppi) RETURN( FALSE);
828 
829  // Same process job returns TRUE.
830  if (gptiCurrent->ppi->pW32Job == ppi->pW32Job) RETURN( TRUE);
831 
832  RETURN( FALSE);
833 
834 CLEANUP:
835  UserLeave();
836  END_CLEANUP;
837 }
838 
839 // Win: HMAssignmentLock
841 {
842  PVOID pvOld = *ppvObj;
843  *ppvObj = pvNew;
844 
845  if (pvOld && pvOld == pvNew)
846  return pvOld;
847 
848  if (pvNew)
849  UserReferenceObject(pvNew);
850 
851  if (pvOld)
852  {
853  if (UserDereferenceObject(pvOld))
854  pvOld = NULL;
855  }
856 
857  return pvOld;
858 }
859 
860 // Win: HMAssignmentUnlock
862 {
863  PVOID pvOld = *ppvObj;
864  *ppvObj = NULL;
865 
866  if (pvOld)
867  {
868  if (UserDereferenceObject(pvOld))
869  pvOld = NULL;
870  }
871 
872  return pvOld;
873 }
BOOLEAN IntRemoveHook(PVOID Object)
Definition: hook.c:1037
ULONG_PTR cHandleEntries
Definition: ntuser.h:1047
PVOID FASTCALL UserReferenceObjectByHandle(HANDLE handle, HANDLE_TYPE type)
Definition: object.c:741
#define max(a, b)
Definition: svc.c:63
PVOID pSelf
Definition: ntuser.h:195
ASMGENDATA Table[]
Definition: genincdata.c:61
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:717
#define CLEANUP
Definition: ntuser.h:5
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
struct _DESKTOP * rpdesk
Definition: ntuser.h:194
#define _Inout_
Definition: ms_sal.h:378
#define DWORD_PTR
Definition: treelist.c:76
#define DbgPrint
Definition: hal.h:12
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle)
Definition: object.c:341
coclass MSXML2::XSLTemplate40 object
struct _Entry Entry
Definition: kefuncs.h:629
PPROCESSINFO ppiNext
Definition: win32.h:261
PVOID UserGetObjectNoErr(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:481
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
Definition: object.c:840
#define _Out_
Definition: ms_sal.h:345
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
static __inline void * free_user_entry(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY entry)
Definition: object.c:417
unsigned char type
Definition: ntuser.h:25
HANDLE h
Definition: ntuser.h:181
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
struct _DESKTOP * PDESKTOP
BOOLEAN UserDestroyMenuObject(PVOID Object)
Definition: menu.c:313
PSERVERINFO gpsi
Definition: imm.c:18
void * get_user_object_handle(PUSER_HANDLE_TABLE ht, HANDLE *handle, HANDLE_TYPE type)
Definition: object.c:524
struct _PROCESSINFO * PPROCESSINFO
Definition: ntwin32.h:5
static __inline BOOL UserHeapFree(PVOID lpMem)
Definition: usrheap.h:44
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
_Success_(return!=NULL)
Definition: object.c:16
#define FIRST_USER_HANDLE
Definition: ntuser.h:10
uint16_t * PWCHAR
Definition: typedefs.h:56
int32_t INT_PTR
Definition: typedefs.h:64
static __inline PVOID UserHeapAlloc(SIZE_T Bytes)
Definition: usrheap.h:34
#define FASTCALL
Definition: nt_native.h:50
int32_t INT
Definition: typedefs.h:58
struct _PROCDESKHEAD * PPROCDESKHEAD
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define RETURN(x)
BOOLEAN UserDestroyAccelTable(PVOID Object)
Definition: accelerator.c:328
#define USERTAG_CLIPBOARD
Definition: tags.h:200
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:568
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
PPROCESSINFO ppi
Definition: win32.h:88
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define L(x)
Definition: ntvdm.h:50
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:204
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
struct _THRDESKHEAD * PTHRDESKHEAD
BOOLEAN co_UserDestroyWindow(PVOID Object)
Definition: window.c:2845
PVOID pSelf
Definition: ntuser.h:220
void(* ObjectFree)(PVOID)
Definition: object.c:253
#define LAST_USER_HANDLE
Definition: ntuser.h:11
BOOLEAN DestroyCallProc(_Inout_ PVOID Object)
Definition: callproc.c:22
static PVOID ptr
Definition: dispmode.c:27
static __inline PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht)
Definition: object.c:361
PPROCESSINFO gppiList
Definition: main.c:31
unsigned char BOOLEAN
#define IntReferenceProcessInfo(ppi)
Definition: win32.h:181
#define _In_
Definition: ms_sal.h:308
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
GLuint index
Definition: glext.h:6031
void * PVOID
Definition: retypes.h:9
BOOL FASTCALL UserObjectInDestroy(HANDLE h)
Definition: object.c:703
VOID UserFreeInputContext(PVOID Object)
Definition: ime.c:1464
#define IntReferenceThreadInfo(pti)
Definition: win32.h:166
Definition: ntuser.h:179
BOOLEAN UserDestroyInputContext(PVOID Object)
Definition: ime.c:1491
void FreeProcMarkObject(_In_ PVOID Object)
Definition: object.c:175
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
Definition: ntuser.h:16
static __inline PVOID UserHeapReAlloc(PVOID lpMem, SIZE_T Bytes)
Definition: usrheap.h:54
static void FreeDeskProcObject(_In_ PVOID Object)
Definition: object.c:134
BOOLEAN IntRemoveEvent(PVOID Object)
Definition: event.c:127
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
struct _THREADINFO * PTHREADINFO
Definition: ntwin32.h:6
static void FreeDeskThreadObject(_In_ PVOID Object)
Definition: object.c:89
#define ASSERT(a)
Definition: mode.c:44
struct _USER_HANDLE_ENTRY USER_HANDLE_ENTRY
static __inline HANDLE entry_to_handle(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY ptr)
Definition: object.c:355
#define DECLARE_RETURN(type)
Definition: ntuser.h:3
static void FreeSysObjectCB(_In_ PVOID Object)
Definition: object.c:243
struct _THROBJHEAD * PTHROBJHEAD
int ret
static void FreeSysObject(_In_ PVOID Object)
Definition: object.c:237
#define index(s, c)
Definition: various.h:29
struct _THREADINFO * pti
Definition: ntuser.h:188
struct _PROCESSINFO * ppi
Definition: ntuser.h:227
uint32_t entry
Definition: isohybrid.c:63
PVOID AllocInputContextObject(PDESKTOP pDesk, PTHREADINFO pti, SIZE_T Size, PVOID *HandleOwner)
Definition: ime.c:1435
DWORD cLockObj
Definition: ntuser.h:182
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:37
PVOID pW32Job
Definition: win32.h:275
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define ERR(fmt,...)
Definition: debug.h:110
enum _HANDLE_TYPE HANDLE_TYPE
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:254
PVOID(* ObjectAlloc)(PDESKTOP, PTHREADINFO, SIZE_T, PVOID *)
Definition: object.c:251
ULONG_PTR SIZE_T
Definition: typedefs.h:80
HANDLE get_user_full_handle(PUSER_HANDLE_TABLE ht, HANDLE handle)
Definition: object.c:511
VOID FreeCurIconObject(_In_ PVOID Object)
Definition: cursoricon.c:332
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
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:495
BOOL FASTCALL UserCreateHandleTable(VOID)
Definition: object.c:536
#define HANDLEENTRY_DESTROY
Definition: ntuser.h:13
BOOLEAN(* ObjectDestroy)(PVOID)
Definition: object.c:252
PUSER_HANDLE_ENTRY handles
Definition: ntuser.h:32
_In_ uint64_t _In_ uint64_t _In_ uint64_t generation
Definition: btrfs.c:2995
BOOLEAN IntDestroyCurIconObject(_In_ PVOID Object)
Definition: cursoricon.c:313
static const struct @4917 ObjectCallbacks[TYPE_CTYPES]
static void FreeThreadObject(_In_ PVOID Object)
Definition: object.c:45
static const struct newhuff ht[]
Definition: huffman.h:296
static const void * body(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:100
#define min(a, b)
Definition: monoChain.cc:55
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1597
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
VOID UserInitHandleTable(PUSER_HANDLE_TABLE ht, PVOID mem, ULONG bytes)
Definition: object.c:407
DWORD_PTR hTaskWow
Definition: ntuser.h:218
BOOLEAN UserDestroyObjectsForOwner(PUSER_HANDLE_TABLE Table, PVOID Owner)
Definition: object.c:754
Definition: mem.c:156
void DbgUserDumpHandleTable()
PVOID FASTCALL UserAssignmentUnlock(PVOID *ppvObj)
Definition: object.c:861
#define BOOLEAN
Definition: pedump.c:73
#define HIWORD(l)
Definition: typedefs.h:247
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct _HEAD * PHEAD
BOOL APIENTRY NtUserValidateHandleSecure(HANDLE handle)
Definition: object.c:792
#define HANDLEENTRY_INDESTROY
Definition: ntuser.h:14
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:215
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
BOOL FASTCALL UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle)
Definition: object.c:686
struct _DESKTOP * rpdesk
Definition: ntuser.h:219
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
#define memset(x, y, z)
Definition: compat.h:39
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define IntDereferenceProcessInfo(ppi)
Definition: win32.h:186
HANDLE UserAllocHandle(_Inout_ PUSER_HANDLE_TABLE ht, _In_ PVOID object, _In_ HANDLE_TYPE type, _In_ PVOID HandleOwner)
Definition: object.c:458
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:171
#define LOWORD(l)
Definition: pedump.c:82
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
base of all file and directory entries
Definition: entries.h:82
#define APIENTRY
Definition: api.h:79
#define END_CLEANUP
Definition: ntuser.h:6
struct _PROCMARKHEAD * PPROCMARKHEAD
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:731
DBG_DEFAULT_CHANNEL(UserObj)
BOOL FASTCALL UserMarkObjectDestroy(PVOID Object)
Definition: object.c:621