1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS WIN32 subsystem 4 * PURPOSE: Support functions for GDI client objects 5 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) 6 */ 7 8 #include <precomp.h> 9 10 CRITICAL_SECTION gcsClientObjLinks; 11 ULONG gcClientObj; 12 13 typedef struct _CLIENTOBJLINK 14 { 15 struct _CLIENTOBJLINK *pcolNext; 16 HGDIOBJ hobj; 17 PVOID pvObj; 18 } CLIENTOBJLINK, *PCLIENTOBJLINK; 19 20 PCLIENTOBJLINK gapcolHashTable[127]; 21 22 BOOL 23 WINAPI 24 GdiCreateClientObjLink( 25 _In_ HGDIOBJ hobj, 26 _In_ PVOID pvObject) 27 { 28 PCLIENTOBJLINK pcol; 29 ULONG iHashIndex; 30 31 /* Allocate a link structure */ 32 pcol = HeapAlloc(GetProcessHeap(), 0, sizeof(*pcol)); 33 if (pcol == NULL) 34 { 35 return FALSE; 36 } 37 38 /* Setup the link structure */ 39 pcol->hobj = hobj; 40 pcol->pvObj = pvObject; 41 42 /* Calculate the hash index */ 43 iHashIndex = (ULONG_PTR)hobj % _countof(gapcolHashTable); 44 45 /* Enter the critical section */ 46 EnterCriticalSection(&gcsClientObjLinks); 47 48 /* Insert the link structure */ 49 pcol->pcolNext = gapcolHashTable[iHashIndex]; 50 gapcolHashTable[iHashIndex] = pcol; 51 gcClientObj++; 52 53 /* Leave the critical section */ 54 LeaveCriticalSection(&gcsClientObjLinks); 55 56 return TRUE; 57 } 58 59 PVOID 60 WINAPI 61 GdiGetClientObjLink( 62 _In_ HGDIOBJ hobj) 63 { 64 ULONG iHashIndex; 65 PCLIENTOBJLINK pcol; 66 PVOID pvObject = NULL; 67 68 /* Calculate the hash index */ 69 iHashIndex = (ULONG_PTR)hobj % _countof(gapcolHashTable); 70 71 /* Enter the critical section */ 72 EnterCriticalSection(&gcsClientObjLinks); 73 74 /* Loop the link entries in this hash bucket */ 75 pcol = gapcolHashTable[iHashIndex]; 76 while (pcol != NULL) 77 { 78 /* Check if this is the object we want */ 79 if (pcol->hobj == hobj) 80 { 81 /* Get the object pointer and bail out */ 82 pvObject = pcol->pvObj; 83 break; 84 } 85 86 /* Go to the next entry */ 87 pcol = pcol->pcolNext; 88 } 89 90 /* Leave the critical section */ 91 LeaveCriticalSection(&gcsClientObjLinks); 92 93 return pvObject; 94 } 95 96 PVOID 97 WINAPI 98 GdiRemoveClientObjLink( 99 _In_ HGDIOBJ hobj) 100 { 101 PCLIENTOBJLINK pcol, *ppcol; 102 ULONG iHashIndex; 103 PVOID pvObject = NULL; 104 105 /* Calculate the hash index */ 106 iHashIndex = (ULONG_PTR)hobj % _countof(gapcolHashTable); 107 108 /* Enter the critical section */ 109 EnterCriticalSection(&gcsClientObjLinks); 110 111 /* Loop the link entries in this hash bucket */ 112 ppcol = &gapcolHashTable[iHashIndex]; 113 while (*ppcol != NULL) 114 { 115 /* Get the current client object link */ 116 pcol = *ppcol; 117 118 /* Check if this is the one we want */ 119 if (pcol->hobj == hobj) 120 { 121 /* Update the link pointer, removing this link */ 122 *ppcol = pcol->pcolNext; 123 gcClientObj--; 124 125 /* Get the object pointer */ 126 pvObject = pcol->pvObj; 127 128 /* Free the link structure */ 129 HeapFree(GetProcessHeap(), 0, pcol); 130 131 /* We're done */ 132 break; 133 } 134 135 /* Go to the next link pointer */ 136 ppcol = &(pcol->pcolNext); 137 } 138 139 /* Leave the critical section */ 140 LeaveCriticalSection(&gcsClientObjLinks); 141 142 /* Return the object pointer, or NULL if we did not find it */ 143 return pvObject; 144 } 145 146 HGDIOBJ 147 WINAPI 148 GdiCreateClientObj( 149 _In_ PVOID pvObject, 150 _In_ GDILOOBJTYPE eObjType) 151 { 152 HGDIOBJ hobj; 153 154 /* Call win32k to create a client object handle */ 155 hobj = NtGdiCreateClientObj(eObjType); 156 if (hobj == NULL) 157 { 158 return NULL; 159 } 160 161 /* Create the client object link */ 162 if (!GdiCreateClientObjLink(hobj, pvObject)) 163 { 164 NtGdiDeleteClientObj(hobj); 165 return NULL; 166 } 167 168 return hobj; 169 } 170 171 PVOID 172 WINAPI 173 GdiDeleteClientObj( 174 _In_ HGDIOBJ hobj) 175 { 176 PVOID pvObject; 177 178 /* Remove the client object link */ 179 pvObject = GdiRemoveClientObjLink(hobj); 180 if (pvObject == NULL) 181 { 182 return NULL; 183 } 184 185 /* Call win32k to delete the handle */ 186 if (!NtGdiDeleteClientObj(hobj)) 187 { 188 ASSERT(FALSE); 189 } 190 191 return pvObject; 192 } 193