• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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