/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_USB_WDF_OBJECT_H__ #define ANDROID_USB_WDF_OBJECT_H__ /** \file This file consists of declaration of a class AndroidUsbWdfObject that encapsulates a basic extension to all KMDF objects. Currently, device and file object extensions ared derived from it. */ /** AndroidUsbWdfObject class encapsulates a basic extension to all KMDF objects. Currently, device and file object extensions ared derived from it. Instances of this and derived classes must be allocated from NonPagedPool. */ class AndroidUsbWdfObject { public: /** \brief Constructs the object. @param obj_type[in] Type of the object that this wrapper represents. This method must be called at low IRQL. */ AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type); /** \brief Destructs the object. This method can be called at any IRQL. */ virtual ~AndroidUsbWdfObject(); /** \brief Initializes object attributes for new KMDF object. Each KMDF extension object must perform attribute initializations in order to register an extension with KMDF framework. Since all our extensions are derived from the base AndroidUsbWdfObject we use a single WDF object extension context for all KMDF objects that we extend. So we can initialize and register our context extension structure here. Note that object attributes for file object wrappers are initialized globaly, when device object is created. So file object extensions must not call this method. This method must be called at low IRQL. @param wdf_obj_attr[out] Object attributes to initialize. @param parent[in] Parent object for this object. Can be NULL. @return STATUS_SUCCESS on success or an appropriate error code. */ virtual NTSTATUS InitObjectAttributes(PWDF_OBJECT_ATTRIBUTES wdf_obj_attr, WDFOBJECT parent); /** \brief Initializes context for this extension This method initializes AndroidUsbWdfObjectContext structure that KMDF allocated for the object that is being extended with this class. InitObjectAttributes method must be called prior to the call to this method. Besides, before calling this method, instance of this class must be already attached to the KMDF object it represents. Otherwise this method will fail with STATUS_INTERNAL_ERROR. This method must be called at low IRQL. @return STATUS_SUCCESS on success or an appropriate error code */ virtual NTSTATUS InitializeContext(); protected: /** \brief Returns syncronisation scope for this extension type. This method is called from InitObjectAttributes method to specify what type of synchronization is required for instances of this type. By default we return WdfSynchronizationScopeNone which makes KMDF not to synchronize access to this type of object. This method can be called at IRQL <= DISPATCH_LEVEL. */ virtual WDF_SYNCHRONIZATION_SCOPE GetWdfSynchronizationScope(); /** \brief Handler for cleanup event fired for associated KMDF object. The framework calls this callback function when either the framework or a driver attempts to delete the object. This method can be called at IRQL <= DISPATCH_LEVEL. */ virtual void OnEvtCleanupCallback(); /** \brief Handler for destroy callback The framework calls the EvtDestroyCallback callback function after the object's reference count has been decremented to zero. The framework deletes the object immediately after the EvtDestroyCallback callback function returns. This callback can be called at IRQL <= DISPATCH_LEVEL. */ virtual void OnEvtDestroyCallback(); /** \brief Removes driver's references on an object so it can be deleted. The framework calls the callback function when either the framework or a driver attempts to delete the object. This callback can be called at IRQL <= DISPATCH_LEVEL. @param wdf_obj[in] A handle to a framework object this class wraps. */ static void EvtCleanupCallbackEntry(WDFOBJECT wdf_obj); /** \brief Called when framework object is being deleted The framework calls the EvtDestroyCallback callback function after the object's reference count has been decremented to zero. The framework deletes the object immediately after the EvtDestroyCallback callback function returns. This callback can be called at IRQL <= DISPATCH_LEVEL. @param wdf_obj[in] A handle to a framework object this class wraps. */ static void EvtDestroyCallbackEntry(WDFOBJECT wdf_obj); public: /// Gets KMDF object extended with this instance __forceinline WDFOBJECT wdf_object() const { return wdf_object_; } /// Sets KMDF object associated with this extension __forceinline void set_wdf_object(WDFOBJECT wdf_obj) { ASSERT(NULL == wdf_object_); wdf_object_ = wdf_obj; } /// Gets KMDF object type for this extension __forceinline AndroidUsbWdfObjectType object_type() const { return object_type_; } /** \brief Checks if this extension represends KMDF object of the given type @param obj_type[in] Object type to check @return true if this wrapper represents object of that type and false otherwise. */ __forceinline Is(AndroidUsbWdfObjectType obj_type) const { return (obj_type == object_type()); } /// Checks if extension is attached to a KMDF object __forceinline bool IsAttached() const { return (NULL != wdf_object()); } protected: /// KMDF object that is extended with this instance WDFOBJECT wdf_object_; /// KMDF object type for this extension AndroidUsbWdfObjectType object_type_; }; /** \brief Gets our extension for the given KMDF object This method can be called at any IRQL @param wdf_obj[in] KMDF handle describing an object @return Instance of AndroidUsbWdfObject associated with this object or NULL if association is not found. */ __forceinline AndroidUsbWdfObject* GetAndroidUsbWdfObjectFromHandle( WDFOBJECT wdf_obj) { ASSERT(NULL != wdf_obj); if (NULL != wdf_obj) { AndroidUsbWdfObjectContext* context = GetAndroidUsbWdfObjectContext(wdf_obj); ASSERT((NULL != context) && (NULL != context->wdf_object_ext) && (context->wdf_object_ext->Is(context->object_type))); if ((NULL != context) && (NULL != context->wdf_object_ext) && context->wdf_object_ext->Is(context->object_type)) { return context->wdf_object_ext; } } return NULL; } #endif // ANDROID_USB_WDF_OBJECT_H__