xref: /reactos/win32ss/gdi/eng/driverobj.c (revision 53221834)
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:              win32ss/gdi/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));
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))
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 ? &pedo->drvobj : NULL;
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 
161