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
AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type)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
~AndroidUsbWdfObject()40 AndroidUsbWdfObject::~AndroidUsbWdfObject() {
41 ASSERT_IRQL_LOW_OR_DISPATCH();
42 }
43
44 #pragma code_seg("PAGE")
45
InitObjectAttributes(PWDF_OBJECT_ATTRIBUTES wdf_obj_attr,WDFOBJECT parent)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
InitializeContext()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
GetWdfSynchronizationScope()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
OnEvtCleanupCallback()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
OnEvtDestroyCallback()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
EvtCleanupCallbackEntry(WDFOBJECT wdf_obj)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
EvtDestroyCallbackEntry(WDFOBJECT wdf_obj)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