[WIN32K]
[reactos.git] / reactos / win32ss / gdi / eng / driverobj.c
1 /*
2 * COPYRIGHT: GPL, see COPYING in the top level directory
3 * PROJECT: ReactOS win32 kernel mode sunsystem
4 * PURPOSE: GDI DRIVEROBJ Functions
5 * FILE: subsystems/win32k/eng/driverobj.c
6 * PROGRAMER: Timo Kreuzer
7 */
8
9 /** Includes ******************************************************************/
10
11 #include <win32k.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16
17 /** Internal interface ********************************************************/
18
19 /*!
20 * \brief DRIVEROBJ cleanup function
21 */
22 VOID
23 NTAPI
24 DRIVEROBJ_vCleanup(PVOID pObject)
25 {
26 PEDRIVEROBJ pedo = pObject;
27 FREEOBJPROC pFreeProc;
28
29 pFreeProc = pedo->drvobj.pFreeProc;
30 if (pFreeProc)
31 {
32 NT_VERIFY(pFreeProc(pedo->drvobj.pvObj));
33 }
34 }
35
36 /** Public interface **********************************************************/
37
38 _Must_inspect_result_
39 HDRVOBJ
40 APIENTRY
41 EngCreateDriverObj(
42 _In_ PVOID pvObj,
43 _In_opt_ FREEOBJPROC pFreeObjProc,
44 _In_ HDEV hdev)
45 {
46 PEDRIVEROBJ pedo;
47 HDRVOBJ hdo;
48 PDEVOBJ *ppdev = (PDEVOBJ*)hdev;
49
50 /* Allocate a new DRIVEROBJ */
51 pedo = DRIVEROBJ_AllocObjectWithHandle();
52 if (!pedo)
53 {
54 return NULL;
55 }
56 hdo = pedo->baseobj.hHmgr;
57
58 /* Fill in fields */
59 pedo->drvobj.pvObj = pvObj;
60 pedo->drvobj.pFreeProc = pFreeObjProc;
61 pedo->drvobj.hdev = hdev;
62 pedo->drvobj.dhpdev = ppdev->dhpdev;
63
64 /* Unlock the object */
65 DRIVEROBJ_UnlockObject(pedo);
66
67 /* Return the handle */
68 return hdo;
69 }
70
71
72 BOOL
73 APIENTRY
74 EngDeleteDriverObj(
75 _In_ _Post_ptr_invalid_ HDRVOBJ hdo,
76 _In_ BOOL bCallBack,
77 _In_ BOOL bLocked)
78 {
79 PEDRIVEROBJ pedo;
80
81 /* Lock the object */
82 pedo = DRIVEROBJ_TryLockObject(hdo);
83 if (!pedo)
84 {
85 return FALSE;
86 }
87
88 /* Manually call cleanup callback */
89 if (bCallBack)
90 {
91 if (!pedo->drvobj.pFreeProc(pedo->drvobj.pvObj))
92 {
93 /* Callback failed */
94 DRIVEROBJ_UnlockObject(pedo);
95 return FALSE;
96 }
97 }
98
99 /* Prevent cleanup callback from being called again */
100 pedo->drvobj.pFreeProc = NULL;
101
102 /* Unlock if the caller indicates it is locked */
103 if (bLocked)
104 DRIVEROBJ_UnlockObject(pedo);
105
106 /* Now delete the object */
107 GDIOBJ_vDeleteObject(&pedo->baseobj);
108 return TRUE;
109 }
110
111
112 PDRIVEROBJ
113 APIENTRY
114 EngLockDriverObj(
115 _In_ HDRVOBJ hdo)
116 {
117 PEDRIVEROBJ pedo;
118
119 /* Lock the object */
120 pedo = DRIVEROBJ_TryLockObject(hdo);
121
122 /* Return pointer to the DRIVEROBJ structure */
123 return &pedo->drvobj;
124 }
125
126
127 BOOL
128 APIENTRY
129 EngUnlockDriverObj(
130 _In_ _Post_ptr_invalid_ HDRVOBJ hdo)
131 {
132 PEDRIVEROBJ pedo;
133 ULONG cLocks;
134
135 /* First lock to get a pointer to the object */
136 pedo = DRIVEROBJ_TryLockObject(hdo);
137 if(!pedo)
138 {
139 /* Object could not be locked, fail. */
140 return FALSE;
141 }
142
143 /* Unlock object */
144 cLocks = pedo->baseobj.cExclusiveLock;
145 DRIVEROBJ_UnlockObject(pedo);
146
147 /* Check if we still hold a lock */
148 if (cLocks < 2)
149 {
150 /* Object wasn't locked before, fail. */
151 return FALSE;
152 }
153
154 /* Unlock again */
155 DRIVEROBJ_UnlockObject(pedo);
156
157 /* Success */
158 return TRUE;
159 }
160