1 /*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ANDROID_USB_WDF_OBJECT_H__
18 #define ANDROID_USB_WDF_OBJECT_H__
19 /** \file
20 This file consists of declaration of a class AndroidUsbWdfObject that
21 encapsulates a basic extension to all KMDF objects. Currently, device and
22 file object extensions ared derived from it.
23 */
24
25 /** AndroidUsbWdfObject class encapsulates a basic extension to all KMDF
26 objects. Currently, device and file object extensions ared derived from it.
27 Instances of this and derived classes must be allocated from NonPagedPool.
28 */
29 class AndroidUsbWdfObject {
30 public:
31 /** \brief Constructs the object.
32
33 @param obj_type[in] Type of the object that this wrapper represents.
34 This method must be called at low IRQL.
35 */
36 AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type);
37
38 /** \brief Destructs the object.
39
40 This method can be called at any IRQL.
41 */
42 virtual ~AndroidUsbWdfObject();
43
44 /** \brief Initializes object attributes for new KMDF object.
45
46 Each KMDF extension object must perform attribute initializations in order
47 to register an extension with KMDF framework. Since all our extensions are
48 derived from the base AndroidUsbWdfObject we use a single WDF object
49 extension context for all KMDF objects that we extend. So we can initialize
50 and register our context extension structure here. Note that object
51 attributes for file object wrappers are initialized globaly, when device
52 object is created. So file object extensions must not call this method.
53 This method must be called at low IRQL.
54 @param wdf_obj_attr[out] Object attributes to initialize.
55 @param parent[in] Parent object for this object. Can be NULL.
56 @return STATUS_SUCCESS on success or an appropriate error code.
57 */
58 virtual NTSTATUS InitObjectAttributes(PWDF_OBJECT_ATTRIBUTES wdf_obj_attr,
59 WDFOBJECT parent);
60
61 /** \brief Initializes context for this extension
62
63 This method initializes AndroidUsbWdfObjectContext structure that KMDF
64 allocated for the object that is being extended with this class.
65 InitObjectAttributes method must be called prior to the call to this
66 method. Besides, before calling this method, instance of this class must
67 be already attached to the KMDF object it represents. Otherwise this
68 method will fail with STATUS_INTERNAL_ERROR.
69 This method must be called at low IRQL.
70 @return STATUS_SUCCESS on success or an appropriate error code
71 */
72 virtual NTSTATUS InitializeContext();
73
74
75 protected:
76 /** \brief Returns syncronisation scope for this extension type.
77
78 This method is called from InitObjectAttributes method to specify what
79 type of synchronization is required for instances of this type. By
80 default we return WdfSynchronizationScopeNone which makes KMDF not
81 to synchronize access to this type of object.
82 This method can be called at IRQL <= DISPATCH_LEVEL.
83 */
84 virtual WDF_SYNCHRONIZATION_SCOPE GetWdfSynchronizationScope();
85
86 /** \brief Handler for cleanup event fired for associated KMDF object.
87
88 The framework calls this callback function when either the framework or a
89 driver attempts to delete the object.
90 This method can be called at IRQL <= DISPATCH_LEVEL.
91 */
92 virtual void OnEvtCleanupCallback();
93
94 /** \brief Handler for destroy callback
95
96 The framework calls the EvtDestroyCallback callback function after the
97 object's reference count has been decremented to zero. The framework
98 deletes the object immediately after the EvtDestroyCallback callback
99 function returns.
100 This callback can be called at IRQL <= DISPATCH_LEVEL.
101 */
102 virtual void OnEvtDestroyCallback();
103
104 /** \brief Removes driver's references on an object so it can be deleted.
105
106 The framework calls the callback function when either the framework or a
107 driver attempts to delete the object.
108 This callback can be called at IRQL <= DISPATCH_LEVEL.
109 @param wdf_obj[in] A handle to a framework object this class wraps.
110 */
111 static void EvtCleanupCallbackEntry(WDFOBJECT wdf_obj);
112
113 /** \brief Called when framework object is being deleted
114
115 The framework calls the EvtDestroyCallback callback function after the
116 object's reference count has been decremented to zero. The framework
117 deletes the object immediately after the EvtDestroyCallback callback
118 function returns.
119 This callback can be called at IRQL <= DISPATCH_LEVEL.
120 @param wdf_obj[in] A handle to a framework object this class wraps.
121 */
122 static void EvtDestroyCallbackEntry(WDFOBJECT wdf_obj);
123
124 public:
125
126 /// Gets KMDF object extended with this instance
wdf_object()127 __forceinline WDFOBJECT wdf_object() const {
128 return wdf_object_;
129 }
130
131 /// Sets KMDF object associated with this extension
set_wdf_object(WDFOBJECT wdf_obj)132 __forceinline void set_wdf_object(WDFOBJECT wdf_obj) {
133 ASSERT(NULL == wdf_object_);
134 wdf_object_ = wdf_obj;
135 }
136
137 /// Gets KMDF object type for this extension
object_type()138 __forceinline AndroidUsbWdfObjectType object_type() const {
139 return object_type_;
140 }
141
142 /** \brief Checks if this extension represends KMDF object of the given type
143
144 @param obj_type[in] Object type to check
145 @return true if this wrapper represents object of that type and
146 false otherwise.
147 */
Is(AndroidUsbWdfObjectType obj_type)148 __forceinline Is(AndroidUsbWdfObjectType obj_type) const {
149 return (obj_type == object_type());
150 }
151
152 /// Checks if extension is attached to a KMDF object
IsAttached()153 __forceinline bool IsAttached() const {
154 return (NULL != wdf_object());
155 }
156
157 protected:
158 /// KMDF object that is extended with this instance
159 WDFOBJECT wdf_object_;
160
161 /// KMDF object type for this extension
162 AndroidUsbWdfObjectType object_type_;
163 };
164
165 /** \brief Gets our extension for the given KMDF object
166
167 This method can be called at any IRQL
168 @param wdf_obj[in] KMDF handle describing an object
169 @return Instance of AndroidUsbWdfObject associated with this object or NULL
170 if association is not found.
171 */
GetAndroidUsbWdfObjectFromHandle(WDFOBJECT wdf_obj)172 __forceinline AndroidUsbWdfObject* GetAndroidUsbWdfObjectFromHandle(
173 WDFOBJECT wdf_obj) {
174 ASSERT(NULL != wdf_obj);
175 if (NULL != wdf_obj) {
176 AndroidUsbWdfObjectContext* context =
177 GetAndroidUsbWdfObjectContext(wdf_obj);
178 ASSERT((NULL != context) && (NULL != context->wdf_object_ext) &&
179 (context->wdf_object_ext->Is(context->object_type)));
180 if ((NULL != context) && (NULL != context->wdf_object_ext) &&
181 context->wdf_object_ext->Is(context->object_type)) {
182 return context->wdf_object_ext;
183 }
184 }
185 return NULL;
186 }
187
188 #endif // ANDROID_USB_WDF_OBJECT_H__
189