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 /** \file 18 This file consists of implementation of a class AndroidUsbWdfObject that 19 encapsulates a basic extension to all KMDF objects. Currently, device and 20 file object extensions ared derived from it. 21 */ 22 #pragma data_seg() 23 #pragma code_seg() 24 25 #include "precomp.h" 26 #include "android_usb_wdf_object.h" 27 28 #pragma data_seg() 29 #pragma code_seg("PAGE") 30 31 AndroidUsbWdfObject::AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type) 32 : wdf_object_(NULL), 33 object_type_(obj_type) { 34 ASSERT_IRQL_LOW(); 35 ASSERT(obj_type < AndroidUsbWdfObjectTypeMax); 36 } 37 38 #pragma code_seg() 39 40 AndroidUsbWdfObject::~AndroidUsbWdfObject() { 41 ASSERT_IRQL_LOW_OR_DISPATCH(); 42 } 43 44 #pragma code_seg("PAGE") 45 46 NTSTATUS AndroidUsbWdfObject::InitObjectAttributes( 47 PWDF_OBJECT_ATTRIBUTES wdf_obj_attr, 48 WDFOBJECT parent) { 49 ASSERT_IRQL_LOW(); 50 51 // Enforce file object extension exception. 52 ASSERT(!Is(AndroidUsbWdfObjectTypeFile)); 53 if (Is(AndroidUsbWdfObjectTypeFile)) 54 return STATUS_INTERNAL_ERROR; 55 56 // Initialize attributes and set cleanup and destroy callbacks 57 WDF_OBJECT_ATTRIBUTES_INIT(wdf_obj_attr); 58 WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(wdf_obj_attr, 59 AndroidUsbWdfObjectContext); 60 wdf_obj_attr->EvtCleanupCallback = EvtCleanupCallbackEntry; 61 wdf_obj_attr->EvtDestroyCallback = EvtDestroyCallbackEntry; 62 wdf_obj_attr->ParentObject = parent; 63 wdf_obj_attr->SynchronizationScope = GetWdfSynchronizationScope(); 64 65 return STATUS_SUCCESS; 66 } 67 68 NTSTATUS AndroidUsbWdfObject::InitializeContext() { 69 ASSERT_IRQL_LOW(); 70 ASSERT(IsAttached()); 71 if (!IsAttached()) 72 return STATUS_INTERNAL_ERROR; 73 74 // Initialize our extension to that object 75 AndroidUsbWdfObjectContext* context = 76 GetAndroidUsbWdfObjectContext(wdf_object()); 77 ASSERT(NULL != context); 78 if (NULL == context) 79 return STATUS_INTERNAL_ERROR; 80 81 // Make sure that extension has not been initialized 82 ASSERT((0 == context->object_type) && (NULL == context->wdf_object_ext)); 83 if ((0 != context->object_type) || (NULL != context->wdf_object_ext)) 84 return STATUS_INTERNAL_ERROR; 85 86 context->object_type = object_type(); 87 context->wdf_object_ext = this; 88 ASSERT(this == GetAndroidUsbWdfObjectFromHandle(wdf_object())); 89 90 return STATUS_SUCCESS; 91 } 92 93 #pragma code_seg() 94 95 WDF_SYNCHRONIZATION_SCOPE AndroidUsbWdfObject::GetWdfSynchronizationScope() { 96 ASSERT_IRQL_LOW_OR_DISPATCH(); 97 98 // By default we don't want KMDF to synchronize access to our objects 99 return WdfSynchronizationScopeNone; 100 } 101 102 void AndroidUsbWdfObject::OnEvtCleanupCallback() { 103 ASSERT_IRQL_LOW_OR_DISPATCH(); 104 GoogleDbgPrint("\n----- Object %p of type %u is cleaned up", 105 this, object_type()); 106 } 107 108 void AndroidUsbWdfObject::OnEvtDestroyCallback() { 109 ASSERT_IRQL_LOW_OR_DISPATCH(); 110 GoogleDbgPrint("\n----- Object %p of type %u is destroyed", 111 this, object_type()); 112 } 113 114 void AndroidUsbWdfObject::EvtCleanupCallbackEntry(WDFOBJECT wdf_obj) { 115 ASSERT_IRQL_LOW_OR_DISPATCH(); 116 117 AndroidUsbWdfObjectContext* context = GetAndroidUsbWdfObjectContext(wdf_obj); 118 ASSERT(NULL != context); 119 if (NULL != context) { 120 // For file objects we will be always called here even though we didn't 121 // create any extension for them. In this case the context must not be 122 // initialized. 123 ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) || 124 ((0 != context->object_type) && (NULL != context->wdf_object_ext))); 125 if (NULL != context->wdf_object_ext) { 126 ASSERT(context->wdf_object_ext->Is(context->object_type)); 127 context->wdf_object_ext->OnEvtCleanupCallback(); 128 } 129 } 130 } 131 132 void AndroidUsbWdfObject::EvtDestroyCallbackEntry(WDFOBJECT wdf_obj) { 133 ASSERT_IRQL_LOW_OR_DISPATCH(); 134 135 AndroidUsbWdfObjectContext* context = 136 GetAndroidUsbWdfObjectContext(wdf_obj); 137 ASSERT(NULL != context); 138 if (NULL != context) { 139 // For file objects we will be always called here even though we didn't 140 // create any extension for them. In this case the context must not be 141 // initialized. 142 ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) || 143 ((0 != context->object_type) && (NULL != context->wdf_object_ext))); 144 if (NULL != context->wdf_object_ext) { 145 ASSERT(context->wdf_object_ext->Is(context->object_type)); 146 context->wdf_object_ext->OnEvtDestroyCallback(); 147 delete context->wdf_object_ext; 148 } 149 } 150 } 151 152 #pragma data_seg() 153 #pragma code_seg() 154