| /* |
| * 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. |
| */ |
| |
| /** \file |
| This file consists of implementation of a class AndroidUsbWdfObject that |
| encapsulates a basic extension to all KMDF objects. Currently, device and |
| file object extensions ared derived from it. |
| */ |
| #pragma data_seg() |
| #pragma code_seg() |
| |
| #include "precomp.h" |
| #include "android_usb_wdf_object.h" |
| |
| #pragma data_seg() |
| #pragma code_seg("PAGE") |
| |
| AndroidUsbWdfObject::AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type) |
| : wdf_object_(NULL), |
| object_type_(obj_type) { |
| ASSERT_IRQL_LOW(); |
| ASSERT(obj_type < AndroidUsbWdfObjectTypeMax); |
| } |
| |
| #pragma code_seg() |
| |
| AndroidUsbWdfObject::~AndroidUsbWdfObject() { |
| ASSERT_IRQL_LOW_OR_DISPATCH(); |
| } |
| |
| #pragma code_seg("PAGE") |
| |
| NTSTATUS AndroidUsbWdfObject::InitObjectAttributes( |
| PWDF_OBJECT_ATTRIBUTES wdf_obj_attr, |
| WDFOBJECT parent) { |
| ASSERT_IRQL_LOW(); |
| |
| // Enforce file object extension exception. |
| ASSERT(!Is(AndroidUsbWdfObjectTypeFile)); |
| if (Is(AndroidUsbWdfObjectTypeFile)) |
| return STATUS_INTERNAL_ERROR; |
| |
| // Initialize attributes and set cleanup and destroy callbacks |
| WDF_OBJECT_ATTRIBUTES_INIT(wdf_obj_attr); |
| WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(wdf_obj_attr, |
| AndroidUsbWdfObjectContext); |
| wdf_obj_attr->EvtCleanupCallback = EvtCleanupCallbackEntry; |
| wdf_obj_attr->EvtDestroyCallback = EvtDestroyCallbackEntry; |
| wdf_obj_attr->ParentObject = parent; |
| wdf_obj_attr->SynchronizationScope = GetWdfSynchronizationScope(); |
| |
| return STATUS_SUCCESS; |
| } |
| |
| NTSTATUS AndroidUsbWdfObject::InitializeContext() { |
| ASSERT_IRQL_LOW(); |
| ASSERT(IsAttached()); |
| if (!IsAttached()) |
| return STATUS_INTERNAL_ERROR; |
| |
| // Initialize our extension to that object |
| AndroidUsbWdfObjectContext* context = |
| GetAndroidUsbWdfObjectContext(wdf_object()); |
| ASSERT(NULL != context); |
| if (NULL == context) |
| return STATUS_INTERNAL_ERROR; |
| |
| // Make sure that extension has not been initialized |
| ASSERT((0 == context->object_type) && (NULL == context->wdf_object_ext)); |
| if ((0 != context->object_type) || (NULL != context->wdf_object_ext)) |
| return STATUS_INTERNAL_ERROR; |
| |
| context->object_type = object_type(); |
| context->wdf_object_ext = this; |
| ASSERT(this == GetAndroidUsbWdfObjectFromHandle(wdf_object())); |
| |
| return STATUS_SUCCESS; |
| } |
| |
| #pragma code_seg() |
| |
| WDF_SYNCHRONIZATION_SCOPE AndroidUsbWdfObject::GetWdfSynchronizationScope() { |
| ASSERT_IRQL_LOW_OR_DISPATCH(); |
| |
| // By default we don't want KMDF to synchronize access to our objects |
| return WdfSynchronizationScopeNone; |
| } |
| |
| void AndroidUsbWdfObject::OnEvtCleanupCallback() { |
| ASSERT_IRQL_LOW_OR_DISPATCH(); |
| GoogleDbgPrint("\n----- Object %p of type %u is cleaned up", |
| this, object_type()); |
| } |
| |
| void AndroidUsbWdfObject::OnEvtDestroyCallback() { |
| ASSERT_IRQL_LOW_OR_DISPATCH(); |
| GoogleDbgPrint("\n----- Object %p of type %u is destroyed", |
| this, object_type()); |
| } |
| |
| void AndroidUsbWdfObject::EvtCleanupCallbackEntry(WDFOBJECT wdf_obj) { |
| ASSERT_IRQL_LOW_OR_DISPATCH(); |
| |
| AndroidUsbWdfObjectContext* context = GetAndroidUsbWdfObjectContext(wdf_obj); |
| ASSERT(NULL != context); |
| if (NULL != context) { |
| // For file objects we will be always called here even though we didn't |
| // create any extension for them. In this case the context must not be |
| // initialized. |
| ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) || |
| ((0 != context->object_type) && (NULL != context->wdf_object_ext))); |
| if (NULL != context->wdf_object_ext) { |
| ASSERT(context->wdf_object_ext->Is(context->object_type)); |
| context->wdf_object_ext->OnEvtCleanupCallback(); |
| } |
| } |
| } |
| |
| void AndroidUsbWdfObject::EvtDestroyCallbackEntry(WDFOBJECT wdf_obj) { |
| ASSERT_IRQL_LOW_OR_DISPATCH(); |
| |
| AndroidUsbWdfObjectContext* context = |
| GetAndroidUsbWdfObjectContext(wdf_obj); |
| ASSERT(NULL != context); |
| if (NULL != context) { |
| // For file objects we will be always called here even though we didn't |
| // create any extension for them. In this case the context must not be |
| // initialized. |
| ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) || |
| ((0 != context->object_type) && (NULL != context->wdf_object_ext))); |
| if (NULL != context->wdf_object_ext) { |
| ASSERT(context->wdf_object_ext->Is(context->object_type)); |
| context->wdf_object_ext->OnEvtDestroyCallback(); |
| delete context->wdf_object_ext; |
| } |
| } |
| } |
| |
| #pragma data_seg() |
| #pragma code_seg() |