• 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 /** \file
18   This file consists of implementation of class AndroidUsbDriverObject that
19   encapsulates our driver object
20 */
21 #pragma data_seg()
22 #pragma code_seg()
23 
24 #include "precomp.h"
25 #include "android_usb_device_object.h"
26 #include "android_usb_driver_object.h"
27 
28 #pragma data_seg()
29 
30 /** Globally accessible instance of the AndroidUsbDriverObject.
31   NT OS design allows us using of a global pointer to our driver object
32   instance since it can't be created or destroyed concurently and its value
33   is not going to change between creation and destruction.
34 */
35 AndroidUsbDriverObject* global_driver_object = NULL;
36 
37 #pragma code_seg("INIT")
38 
39 extern "C" {
40 
41 /// Main entry point to the driver
DriverEntry(PDRIVER_OBJECT drv_object,PUNICODE_STRING reg_path)42 NTSTATUS DriverEntry(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path) {
43   // Just pass it down inside the class
44   return AndroidUsbDriverObject::DriverEntry(drv_object, reg_path);
45 }
46 
47 }  // extern "C"
48 
DriverEntry(PDRIVER_OBJECT drv_object,PUNICODE_STRING reg_path)49 NTSTATUS AndroidUsbDriverObject::DriverEntry(PDRIVER_OBJECT drv_object,
50                                              PUNICODE_STRING reg_path) {
51   ASSERT_IRQL_PASSIVE();
52   ASSERT(NULL != drv_object);
53   ASSERT((NULL != reg_path) &&
54          (NULL != reg_path->Buffer) &&
55          (0 != reg_path->Length));
56 
57   // Instantiate driver object
58   global_driver_object = new(NonPagedPool, GANDR_POOL_TAG_DRIVER_OBJECT)
59     AndroidUsbDriverObject(drv_object, reg_path);
60   ASSERT(NULL != global_driver_object);
61   if (NULL == global_driver_object)
62     return STATUS_INSUFFICIENT_RESOURCES;
63 
64   // Initialize driver object
65   NTSTATUS status = global_driver_object->OnDriverEntry(drv_object, reg_path);
66 
67   if (!NT_SUCCESS(status)) {
68     // Something went wrong. Delete our driver object and get out of here.
69     delete global_driver_object;
70   }
71 
72   return status;
73 }
74 
AndroidUsbDriverObject(PDRIVER_OBJECT drv_object,PUNICODE_STRING reg_path)75 AndroidUsbDriverObject::AndroidUsbDriverObject(PDRIVER_OBJECT drv_object,
76                                                PUNICODE_STRING reg_path)
77     : driver_object_(drv_object),
78       wdf_driver_(NULL) {
79   ASSERT_IRQL_PASSIVE();
80   ASSERT(NULL != driver_object());
81 }
82 
OnDriverEntry(PDRIVER_OBJECT drv_object,PUNICODE_STRING reg_path)83 NTSTATUS AndroidUsbDriverObject::OnDriverEntry(PDRIVER_OBJECT drv_object,
84                                                PUNICODE_STRING reg_path) {
85   ASSERT_IRQL_PASSIVE();
86   ASSERT(driver_object() == drv_object);
87 
88   // Initiialize driver config, specifying our unload callback and default
89   // pool tag for memory allocations that KMDF does on our behalf.
90   WDF_DRIVER_CONFIG config;
91   WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAddEntry);
92   config.EvtDriverUnload = EvtDriverUnloadEntry;
93   config.DriverPoolTag = GANDR_POOL_TAG_DEFAULT;
94 
95   // Create a framework driver object to represent our driver.
96   NTSTATUS status = WdfDriverCreate(drv_object,
97                                     reg_path,
98                                     WDF_NO_OBJECT_ATTRIBUTES,
99                                     &config,
100                                     &wdf_driver_);
101   ASSERT(NT_SUCCESS(status));
102   if (!NT_SUCCESS(status))
103     return status;
104 
105   GoogleDbgPrint("\n>>>>>>>>>> Android USB driver has started >>>>>>>>>>");
106 
107   return STATUS_SUCCESS;
108 }
109 
110 #pragma code_seg("PAGE")
111 
~AndroidUsbDriverObject()112 AndroidUsbDriverObject::~AndroidUsbDriverObject() {
113   ASSERT_IRQL_PASSIVE();
114 }
115 
OnAddDevice(PWDFDEVICE_INIT device_init)116 NTSTATUS AndroidUsbDriverObject::OnAddDevice(PWDFDEVICE_INIT device_init) {
117   ASSERT_IRQL_PASSIVE();
118   GoogleDbgPrint("\n++++++++++ AndroidUsbDriverObject::OnAddDevice ++++++++++");
119   // Instantiate our device object extension for this device
120   AndroidUsbDeviceObject* wdf_device_ext =
121     new(NonPagedPool, GANDR_POOL_TAG_KMDF_DEVICE) AndroidUsbDeviceObject();
122   ASSERT(NULL != wdf_device_ext);
123   if (NULL == wdf_device_ext)
124     return STATUS_INSUFFICIENT_RESOURCES;
125 
126   // Create and initialize FDO device
127   NTSTATUS status = wdf_device_ext->CreateFDODevice(device_init);
128   ASSERT(NT_SUCCESS(status));
129   if (!NT_SUCCESS(status))
130     delete wdf_device_ext;
131 
132   return status;
133 }
134 
OnDriverUnload()135 void AndroidUsbDriverObject::OnDriverUnload() {
136   ASSERT_IRQL_PASSIVE();
137   GoogleDbgPrint("\n<<<<<<<<<< Android USB driver is unloaded <<<<<<<<<<");
138 }
139 
EvtDeviceAddEntry(WDFDRIVER wdf_drv,PWDFDEVICE_INIT device_init)140 NTSTATUS AndroidUsbDriverObject::EvtDeviceAddEntry(
141     WDFDRIVER wdf_drv,
142     PWDFDEVICE_INIT device_init) {
143   ASSERT_IRQL_PASSIVE();
144   ASSERT((NULL != global_driver_object) && (global_driver_object->wdf_driver() == wdf_drv));
145 
146   // Pass it down to our driver object
147   if ((NULL == global_driver_object) ||
148       (global_driver_object->wdf_driver() != wdf_drv)) {
149     return STATUS_INTERNAL_ERROR;
150   }
151 
152   return global_driver_object->OnAddDevice(device_init);
153 }
154 
EvtDriverUnloadEntry(WDFDRIVER wdf_drv)155 VOID AndroidUsbDriverObject::EvtDriverUnloadEntry(WDFDRIVER wdf_drv) {
156   ASSERT_IRQL_PASSIVE();
157   ASSERT((NULL != global_driver_object) &&
158          (global_driver_object->wdf_driver() == wdf_drv));
159 
160   // Pass it down to our driver object
161   if ((NULL != global_driver_object) &&
162       (global_driver_object->wdf_driver() == wdf_drv)) {
163     global_driver_object->OnDriverUnload();
164     // Now we can (and have to) delete our driver object
165     delete global_driver_object;
166   }
167 }
168 
169 #if DBG
170 
171 #pragma code_seg()
172 
GoogleDbgPrint(char * format,...)173 ULONG __cdecl GoogleDbgPrint(char* format, ...) {
174   va_list arg_list;
175   va_start(arg_list, format);
176   ULONG ret =
177     vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, arg_list);
178   va_end(arg_list);
179 
180   return ret;
181 }
182 
183 #endif  // DBG
184 
185 #pragma data_seg()
186 #pragma code_seg()
187