xref: /reactos/win32ss/reactx/dxg/ddhmg.c (revision 2a5e2a2a)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * COPYRIGHT:        See COPYING in the top level directory
3c2c66affSColin Finck  * PROJECT:          ReactOS kernel
4c2c66affSColin Finck  * PURPOSE:          Native driver for dxg implementation
5c2c66affSColin Finck  * FILE:             win32ss/reactx/dxg/ddhmg.c
6c2c66affSColin Finck  * PROGRAMER:        Magnus olsen (magnus@greatlord.com)
7c2c66affSColin Finck  *                   Sebastian Gasiorek (sebastian.gasiorek@reactos.org)
8c2c66affSColin Finck  * REVISION HISTORY:
9c2c66affSColin Finck  *       30/12-2007   Magnus Olsen
10c2c66affSColin Finck  */
11c2c66affSColin Finck 
12c2c66affSColin Finck #include <dxg_int.h>
13c2c66affSColin Finck 
14c2c66affSColin Finck /* The DdHmgr manger stuff */
15c2c66affSColin Finck ULONG gcSizeDdHmgr =  1024;
16c2c66affSColin Finck PDD_ENTRY gpentDdHmgr = NULL;
17c2c66affSColin Finck 
18c2c66affSColin Finck ULONG gcMaxDdHmgr = 0;
19c2c66affSColin Finck PDD_ENTRY gpentDdHmgrLast = NULL;
20c2c66affSColin Finck 
21c2c66affSColin Finck /* next free ddhmg handle number available to reuse */
22c2c66affSColin Finck ULONG ghFreeDdHmgr = 0;
23c2c66affSColin Finck HSEMAPHORE ghsemHmgr = NULL;
24c2c66affSColin Finck 
25c2c66affSColin Finck BOOL
26c2c66affSColin Finck FASTCALL
VerifyObjectOwner(PDD_ENTRY pEntry)27c2c66affSColin Finck VerifyObjectOwner(PDD_ENTRY pEntry)
28c2c66affSColin Finck {
29c2c66affSColin Finck     DWORD Pid = (DWORD)(DWORD_PTR)PsGetCurrentProcessId() & 0xFFFFFFFC;
30*2a5e2a2aSTimo Kreuzer     DWORD check = (DWORD_PTR)pEntry->Pid & 0xFFFFFFFE;
31c2c66affSColin Finck     return ( (check == Pid) || (!check));
32c2c66affSColin Finck }
33c2c66affSColin Finck 
34c2c66affSColin Finck /*++
35c2c66affSColin Finck * @name DdHmgCreate
36c2c66affSColin Finck * @implemented
37c2c66affSColin Finck *
38c2c66affSColin Finck * The function DdHmgCreate is used internally in dxg.sys
39c2c66affSColin Finck * It creates all DX kernel objects that are need it for creation of DX objects.
40c2c66affSColin Finck *
41c2c66affSColin Finck * @return
42c2c66affSColin Finck * Return FALSE for failure and TRUE for success in creating the DX object
43c2c66affSColin Finck *
44c2c66affSColin Finck * @remarks.
45c2c66affSColin Finck * Only used internally in dxg.sys
46c2c66affSColin Finck *--*/
47c2c66affSColin Finck BOOL
48c2c66affSColin Finck FASTCALL
DdHmgCreate(VOID)49c2c66affSColin Finck DdHmgCreate(VOID)
50c2c66affSColin Finck {
51c2c66affSColin Finck     gpentDdHmgr = EngAllocMem(FL_ZERO_MEMORY, gcSizeDdHmgr * sizeof(DD_ENTRY), TAG_THDD);
52c2c66affSColin Finck     ghFreeDdHmgr = 0;
53c2c66affSColin Finck     gcMaxDdHmgr = 1;
54c2c66affSColin Finck 
55c2c66affSColin Finck     if (gpentDdHmgr)
56c2c66affSColin Finck     {
57c2c66affSColin Finck         ghsemHmgr = EngCreateSemaphore();
58c2c66affSColin Finck 
59c2c66affSColin Finck         if (ghsemHmgr)
60c2c66affSColin Finck         {
61c2c66affSColin Finck             gpLockShortDelay = EngAllocMem(FL_ZERO_MEMORY | FL_NONPAGED_MEMORY, sizeof(LARGE_INTEGER), TAG_GINI);
62c2c66affSColin Finck 
63c2c66affSColin Finck             if (gpLockShortDelay)
64c2c66affSColin Finck             {
65c2c66affSColin Finck                 gpLockShortDelay->HighPart = -1;
66c2c66affSColin Finck                 return TRUE;
67c2c66affSColin Finck             }
68c2c66affSColin Finck 
69c2c66affSColin Finck             EngDeleteSemaphore(ghsemHmgr);
70c2c66affSColin Finck             ghsemHmgr = NULL;
71c2c66affSColin Finck         }
72c2c66affSColin Finck 
73c2c66affSColin Finck         EngFreeMem(gpentDdHmgr);
74c2c66affSColin Finck         gpentDdHmgr = NULL;
75c2c66affSColin Finck     }
76c2c66affSColin Finck 
77c2c66affSColin Finck     return FALSE;
78c2c66affSColin Finck }
79c2c66affSColin Finck 
80c2c66affSColin Finck /*++
81c2c66affSColin Finck * @name DdHmgDestroy
82c2c66affSColin Finck * @implemented
83c2c66affSColin Finck *
84c2c66affSColin Finck * The function DdHmgDestroy is used internally in dxg.sys
85c2c66affSColin Finck * It destroys all DX kernel objects
86c2c66affSColin Finck *
87c2c66affSColin Finck * @return
88c2c66affSColin Finck * Always returns true, as a failure here would result in a BSOD.
89c2c66affSColin Finck *
90c2c66affSColin Finck * @remarks.
91c2c66affSColin Finck * Only used internally in dxg.sys
92c2c66affSColin Finck *--*/
93c2c66affSColin Finck BOOL
94c2c66affSColin Finck FASTCALL
DdHmgDestroy(VOID)95c2c66affSColin Finck DdHmgDestroy(VOID)
96c2c66affSColin Finck {
97c2c66affSColin Finck     gcMaxDdHmgr = 0;
98c2c66affSColin Finck     gcSizeDdHmgr = 0;
99c2c66affSColin Finck     ghFreeDdHmgr = 0;
100c2c66affSColin Finck     gpentDdHmgrLast = NULL;
101c2c66affSColin Finck 
102c2c66affSColin Finck     if (gpentDdHmgr)
103c2c66affSColin Finck     {
104c2c66affSColin Finck         EngFreeMem(gpentDdHmgr);
105c2c66affSColin Finck         gpentDdHmgr = NULL;
106c2c66affSColin Finck     }
107c2c66affSColin Finck 
108c2c66affSColin Finck     if (ghsemHmgr)
109c2c66affSColin Finck     {
110c2c66affSColin Finck         EngDeleteSemaphore(ghsemHmgr);
111c2c66affSColin Finck         ghsemHmgr = NULL;
112c2c66affSColin Finck     }
113c2c66affSColin Finck 
114c2c66affSColin Finck     return TRUE;
115c2c66affSColin Finck }
116c2c66affSColin Finck 
117c2c66affSColin Finck /*++
118c2c66affSColin Finck * @name DdHmgLock
119c2c66affSColin Finck * @implemented
120c2c66affSColin Finck *
121c2c66affSColin Finck * The function DdHmgLock is used internally in dxg.sys
122c2c66affSColin Finck * It locks a DX kernel object
123c2c66affSColin Finck *
124c2c66affSColin Finck * @param HANDLE DdHandle
125c2c66affSColin Finck * The handle we want locked
126c2c66affSColin Finck *
127c2c66affSColin Finck * @param UCHAR ObjectType
128c2c66affSColin Finck * The type of the object we expected the handle to contain
129c2c66affSColin Finck * value 0 is for ?
130c2c66affSColin Finck * value 1 is for EDD_DIRECTDRAW_LOCAL
131c2c66affSColin Finck * value 2 is for EDD_SURFACE
132c2c66affSColin Finck * value 3 is for ?
133c2c66affSColin Finck * value 4 is for EDD_VIDEOPORT
134c2c66affSColin Finck * value 5 is for EDD_MOTIONCOMP
135c2c66affSColin Finck 
136c2c66affSColin Finck * @param BOOLEAN LockOwned
137c2c66affSColin Finck * If it needs to call EngAcquireSemaphore or not
138c2c66affSColin Finck *
139c2c66affSColin Finck * @return
140c2c66affSColin Finck * Returns an EDD_* object, or NULL if it fails
141c2c66affSColin Finck *
142c2c66affSColin Finck * @remarks.
143c2c66affSColin Finck * Only used internally in dxg.sys
144c2c66affSColin Finck *--*/
145c2c66affSColin Finck PVOID
146c2c66affSColin Finck FASTCALL
DdHmgLock(HANDLE DdHandle,UCHAR ObjectType,BOOLEAN LockOwned)147c2c66affSColin Finck DdHmgLock(HANDLE DdHandle, UCHAR ObjectType, BOOLEAN LockOwned)
148c2c66affSColin Finck {
149c2c66affSColin Finck     DWORD Index = DDHMG_HTOI(DdHandle);
150c2c66affSColin Finck 
151c2c66affSColin Finck     PDD_ENTRY pEntry = NULL;
152c2c66affSColin Finck     PVOID Object = NULL;
153c2c66affSColin Finck 
154c2c66affSColin Finck     if ( !LockOwned )
155c2c66affSColin Finck     {
156c2c66affSColin Finck         EngAcquireSemaphore(ghsemHmgr);
157c2c66affSColin Finck     }
158c2c66affSColin Finck 
159c2c66affSColin Finck     if ( Index < gcMaxDdHmgr )
160c2c66affSColin Finck     {
161c2c66affSColin Finck         pEntry = (PDD_ENTRY)((PBYTE)gpentDdHmgr + (sizeof(DD_ENTRY) * Index));
162c2c66affSColin Finck 
163c2c66affSColin Finck         if ( VerifyObjectOwner(pEntry) )
164c2c66affSColin Finck         {
165c2c66affSColin Finck             if ( ( pEntry->Objt == ObjectType ) &&
166*2a5e2a2aSTimo Kreuzer                  ( pEntry->FullUnique == (((ULONG_PTR)DdHandle >> 21) & 0x7FF) ) &&
167c2c66affSColin Finck                  ( !pEntry->pobj->cExclusiveLock ) )
168c2c66affSColin Finck             {
169c2c66affSColin Finck                 InterlockedIncrement((VOID*)&pEntry->pobj->cExclusiveLock);
170c2c66affSColin Finck                 pEntry->pobj->Tid = KeGetCurrentThread();
171c2c66affSColin Finck                 Object = pEntry->pobj;
172c2c66affSColin Finck             }
173c2c66affSColin Finck         }
174c2c66affSColin Finck     }
175c2c66affSColin Finck 
176c2c66affSColin Finck     if ( !LockOwned )
177c2c66affSColin Finck     {
178c2c66affSColin Finck         EngReleaseSemaphore(ghsemHmgr);
179c2c66affSColin Finck     }
180c2c66affSColin Finck 
181c2c66affSColin Finck     return Object;
182c2c66affSColin Finck }
183c2c66affSColin Finck 
184c2c66affSColin Finck /*++
185c2c66affSColin Finck * @name DdAllocateObject
186c2c66affSColin Finck * @implemented
187c2c66affSColin Finck *
188c2c66affSColin Finck * The function DdAllocateObject is used internally in dxg.sys
189c2c66affSColin Finck * It allocates memory for a DX kernel object
190c2c66affSColin Finck *
191c2c66affSColin Finck * @param UINT32 oSize
192c2c66affSColin Finck * Size of memory to be allocated
193c2c66affSColin Finck * @param UCHAR oType
194c2c66affSColin Finck * Object type
195c2c66affSColin Finck * @param BOOLEAN oZeroMemory
196c2c66affSColin Finck * Zero memory
197c2c66affSColin Finck *
198c2c66affSColin Finck * @remarks.
199c2c66affSColin Finck * Only used internally in dxg.sys
200c2c66affSColin Finck */
201c2c66affSColin Finck PVOID
202c2c66affSColin Finck FASTCALL
DdAllocateObject(ULONG objSize,UCHAR objType,BOOLEAN objZeroMemory)203c2c66affSColin Finck DdAllocateObject(ULONG objSize, UCHAR objType, BOOLEAN objZeroMemory)
204c2c66affSColin Finck {
205c2c66affSColin Finck     PVOID pObject = NULL;
206c2c66affSColin Finck 
207c2c66affSColin Finck     if (objZeroMemory)
208c2c66affSColin Finck         pObject = EngAllocMem(FL_ZERO_MEMORY, objSize, ((ULONG)objType << 24) + TAG_DH_0);
209c2c66affSColin Finck     else
210c2c66affSColin Finck         pObject = EngAllocMem(0, objSize, ((ULONG)objType << 24) + TAG_DH_0);
211c2c66affSColin Finck 
212c2c66affSColin Finck     if (!pObject)
213c2c66affSColin Finck     {
214c2c66affSColin Finck         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
215c2c66affSColin Finck     }
216c2c66affSColin Finck 
217c2c66affSColin Finck     return pObject;
218c2c66affSColin Finck }
219c2c66affSColin Finck 
220c2c66affSColin Finck /*++
221c2c66affSColin Finck * @name DdFreeObject
222c2c66affSColin Finck * @implemented
223c2c66affSColin Finck *
224c2c66affSColin Finck * The function DdFreeObject is used internally in dxg.sys
225c2c66affSColin Finck * It frees memory of DX kernel object
226c2c66affSColin Finck *
227c2c66affSColin Finck * @param PVOID pObject
228c2c66affSColin Finck * Object memory to be freed
229c2c66affSColin Finck *
230c2c66affSColin Finck * @remarks.
231c2c66affSColin Finck * Only used internally in dxg.sys
232c2c66affSColin Finck */
233c2c66affSColin Finck VOID
234c2c66affSColin Finck FASTCALL
DdFreeObject(PVOID pObject)235c2c66affSColin Finck DdFreeObject(PVOID pObject)
236c2c66affSColin Finck {
237c2c66affSColin Finck     EngFreeMem(pObject);
238c2c66affSColin Finck }
239c2c66affSColin Finck 
240c2c66affSColin Finck 
241c2c66affSColin Finck /*++
242c2c66affSColin Finck * @name DdGetFreeHandle
243c2c66affSColin Finck * @implemented
244c2c66affSColin Finck *
245c2c66affSColin Finck * The function DdGetFreeHandle is used internally in dxg.sys
246c2c66affSColin Finck * It allocates new handle for specified object type
247c2c66affSColin Finck *
248c2c66affSColin Finck * @param UCHAR oType
249c2c66affSColin Finck * Object type
250c2c66affSColin Finck *
251c2c66affSColin Finck * @return
252c2c66affSColin Finck * Returns handle or 0 if it fails.
253c2c66affSColin Finck *
254c2c66affSColin Finck * @remarks.
255c2c66affSColin Finck * Only used internally in dxg.sys
256c2c66affSColin Finck *--*/
257c2c66affSColin Finck HANDLE
258c2c66affSColin Finck FASTCALL
DdGetFreeHandle(UCHAR objType)259c2c66affSColin Finck DdGetFreeHandle(UCHAR objType)
260c2c66affSColin Finck {
261c2c66affSColin Finck     PVOID mAllocMem = NULL;
262c2c66affSColin Finck     ULONG mAllocEntries = 0;
263c2c66affSColin Finck     PDD_ENTRY pEntry = NULL;
264*2a5e2a2aSTimo Kreuzer     ULONG_PTR retVal;
265c2c66affSColin Finck     ULONG index;
266c2c66affSColin Finck 
267c2c66affSColin Finck     // check if memory is allocated
268c2c66affSColin Finck     if (!gpentDdHmgr)
269c2c66affSColin Finck         return 0;
270c2c66affSColin Finck 
271c2c66affSColin Finck     // check if we reached maximum handle index
272c2c66affSColin Finck     if (gcMaxDdHmgr == DDHMG_HANDLE_LIMIT)
273c2c66affSColin Finck         return 0;
274c2c66affSColin Finck 
275c2c66affSColin Finck     // check if we have free handle to reuse
276c2c66affSColin Finck     if (ghFreeDdHmgr)
277c2c66affSColin Finck     {
278c2c66affSColin Finck        index = ghFreeDdHmgr;
279c2c66affSColin Finck        pEntry = (PDD_ENTRY)((PBYTE)gpentDdHmgr + (sizeof(DD_ENTRY) * index));
280c2c66affSColin Finck 
281c2c66affSColin Finck        // put next free index to our global variable
282c2c66affSColin Finck        ghFreeDdHmgr = pEntry->NextFree;
283c2c66affSColin Finck 
284c2c66affSColin Finck        // build handle
285c2c66affSColin Finck        pEntry->FullUnique = objType | 8;
286c2c66affSColin Finck        retVal = (pEntry->FullUnique << 21) | index;
287c2c66affSColin Finck        return (HANDLE)retVal;
288c2c66affSColin Finck     }
289c2c66affSColin Finck 
290c2c66affSColin Finck     // if all pre-allocated memory is already used then allocate more
291c2c66affSColin Finck     if (gcSizeDdHmgr == gcMaxDdHmgr)
292c2c66affSColin Finck     {
293c2c66affSColin Finck         // allocate buffer for next 1024 handles
294c2c66affSColin Finck         mAllocEntries = gcSizeDdHmgr + 1024;
295c2c66affSColin Finck         mAllocMem = EngAllocMem(FL_ZERO_MEMORY, sizeof(DD_ENTRY) * (mAllocEntries), TAG_THDD);
296c2c66affSColin Finck         if (!mAllocMem)
297c2c66affSColin Finck             return 0;
298c2c66affSColin Finck 
299c2c66affSColin Finck         memmove(&mAllocMem, gpentDdHmgr, sizeof(DD_ENTRY) * gcSizeDdHmgr);
300c2c66affSColin Finck         gcSizeDdHmgr = mAllocEntries;
301c2c66affSColin Finck         gpentDdHmgrLast = gpentDdHmgr;
302c2c66affSColin Finck         EngFreeMem(gpentDdHmgr);
303c2c66affSColin Finck         gpentDdHmgr = mAllocMem;
304c2c66affSColin Finck     }
305c2c66affSColin Finck 
306c2c66affSColin Finck     pEntry = (PDD_ENTRY)((PBYTE)gpentDdHmgr + (sizeof(DD_ENTRY) * gcMaxDdHmgr));
307c2c66affSColin Finck 
308c2c66affSColin Finck     // build handle
309c2c66affSColin Finck     pEntry->FullUnique = objType | 8;
310c2c66affSColin Finck     retVal = (pEntry->FullUnique << 21) | gcMaxDdHmgr;
311c2c66affSColin Finck     gcMaxDdHmgr = gcMaxDdHmgr + 1;
312c2c66affSColin Finck 
313c2c66affSColin Finck     return (HANDLE)retVal;
314c2c66affSColin Finck }
315c2c66affSColin Finck 
316c2c66affSColin Finck /*++
317c2c66affSColin Finck * @name DdHmgAlloc
318c2c66affSColin Finck * @implemented
319c2c66affSColin Finck *
320c2c66affSColin Finck * The function DdHmgAlloc is used internally in dxg.sys
321c2c66affSColin Finck * It allocates object
322c2c66affSColin Finck *
323c2c66affSColin Finck * @param ULONG objSize
324c2c66affSColin Finck * Size of memory to be allocated
325c2c66affSColin Finck * @param CHAR objType
326c2c66affSColin Finck * Object type
327c2c66affSColin Finck * @param UINT objLock
328c2c66affSColin Finck * Object lock flag
329c2c66affSColin Finck *
330c2c66affSColin Finck * @return
331c2c66affSColin Finck * Handle if object is not locked by objLock
332c2c66affSColin Finck * Object if lock is set in objLock
333c2c66affSColin Finck * 0 if it fails.
334c2c66affSColin Finck *
335c2c66affSColin Finck * @remarks.
336c2c66affSColin Finck * Only used internally in dxg.sys
337c2c66affSColin Finck *--*/
338c2c66affSColin Finck HANDLE
339c2c66affSColin Finck FASTCALL
DdHmgAlloc(ULONG objSize,CHAR objType,BOOLEAN objLock)340c2c66affSColin Finck DdHmgAlloc(ULONG objSize, CHAR objType, BOOLEAN objLock)
341c2c66affSColin Finck {
342c2c66affSColin Finck     PVOID pObject = NULL;
343c2c66affSColin Finck     HANDLE DdHandle = NULL;
344c2c66affSColin Finck     PDD_ENTRY pEntry = NULL;
345c2c66affSColin Finck     DWORD Index;
346c2c66affSColin Finck 
347c2c66affSColin Finck     pObject = DdAllocateObject(objSize, objType, TRUE);
348c2c66affSColin Finck     if (!pObject)
349c2c66affSColin Finck         return 0;
350c2c66affSColin Finck 
351c2c66affSColin Finck     EngAcquireSemaphore(ghsemHmgr);
352c2c66affSColin Finck 
353c2c66affSColin Finck     /* Get next free handle */
354c2c66affSColin Finck     DdHandle = DdGetFreeHandle(objType);
355c2c66affSColin Finck 
356c2c66affSColin Finck     if (DdHandle)
357c2c66affSColin Finck     {
358c2c66affSColin Finck         Index = DDHMG_HTOI(DdHandle);
359c2c66affSColin Finck 
360c2c66affSColin Finck         pEntry = (PDD_ENTRY)((PBYTE)gpentDdHmgr + (sizeof(DD_ENTRY) * Index));
361c2c66affSColin Finck 
362c2c66affSColin Finck         pEntry->pobj = pObject;
363c2c66affSColin Finck         pEntry->Objt = objType;
364c2c66affSColin Finck 
365*2a5e2a2aSTimo Kreuzer         pEntry->Pid = (HANDLE)(((ULONG_PTR)PsGetCurrentProcessId() & 0xFFFFFFFC) | ((ULONG_PTR)(pEntry->Pid) & 1));
366c2c66affSColin Finck 
367c2c66affSColin Finck         if (objLock)
368c2c66affSColin Finck         {
369c2c66affSColin Finck             InterlockedIncrement((VOID*)&pEntry->pobj->cExclusiveLock);
370c2c66affSColin Finck             pEntry->pobj->Tid = KeGetCurrentThread();
371c2c66affSColin Finck         }
372c2c66affSColin Finck         pEntry->pobj->hHmgr = DdHandle;
373c2c66affSColin Finck 
374c2c66affSColin Finck         EngReleaseSemaphore(ghsemHmgr);
375c2c66affSColin Finck 
376c2c66affSColin Finck         /* Return handle if object not locked */
377c2c66affSColin Finck         if (!objLock)
378c2c66affSColin Finck            return DdHandle;
379c2c66affSColin Finck 
380c2c66affSColin Finck         return (HANDLE)pEntry;
381c2c66affSColin Finck     }
382c2c66affSColin Finck 
383c2c66affSColin Finck     EngReleaseSemaphore(ghsemHmgr);
384c2c66affSColin Finck     DdFreeObject(pObject);
385c2c66affSColin Finck     return 0;
386c2c66affSColin Finck }
387c2c66affSColin Finck 
388c2c66affSColin Finck /*++
389c2c66affSColin Finck * @name DdHmgFree
390c2c66affSColin Finck * @implemented
391c2c66affSColin Finck *
392c2c66affSColin Finck * The function DdHmgFree is used internally in dxg.sys
393c2c66affSColin Finck * It frees DX object and memory allocated to it
394c2c66affSColin Finck *
395c2c66affSColin Finck * @param HANDLE DdHandle
396c2c66affSColin Finck * DX object handle
397c2c66affSColin Finck *
398c2c66affSColin Finck * @remarks.
399c2c66affSColin Finck * Only used internally in dxg.sys
400c2c66affSColin Finck *--*/
401c2c66affSColin Finck VOID
402c2c66affSColin Finck FASTCALL
DdHmgFree(HANDLE DdHandle)403c2c66affSColin Finck DdHmgFree(HANDLE DdHandle)
404c2c66affSColin Finck {
405c2c66affSColin Finck     PDD_ENTRY pEntry = NULL;
406c2c66affSColin Finck 
407c2c66affSColin Finck     DWORD Index = DDHMG_HTOI(DdHandle);
408c2c66affSColin Finck 
409c2c66affSColin Finck     EngAcquireSemaphore(ghsemHmgr);
410c2c66affSColin Finck 
411c2c66affSColin Finck     pEntry = (PDD_ENTRY)((PBYTE)gpentDdHmgr + (sizeof(DD_ENTRY) * Index));
412c2c66affSColin Finck 
413c2c66affSColin Finck     // check if we have object that should be freed
414c2c66affSColin Finck     if (pEntry->pobj)
415c2c66affSColin Finck         DdFreeObject(pEntry->pobj);
416c2c66affSColin Finck 
417c2c66affSColin Finck     pEntry->NextFree = ghFreeDdHmgr;
418c2c66affSColin Finck 
419c2c66affSColin Finck     // reset process ID
420*2a5e2a2aSTimo Kreuzer     pEntry->Pid = (HANDLE)((DWORD_PTR)pEntry->Pid & 1);
421c2c66affSColin Finck     ghFreeDdHmgr = Index;
422c2c66affSColin Finck 
423c2c66affSColin Finck     EngReleaseSemaphore(ghsemHmgr);
424c2c66affSColin Finck }
425