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 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 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 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 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 112 AndroidUsbDriverObject::~AndroidUsbDriverObject() { 113 ASSERT_IRQL_PASSIVE(); 114 } 115 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 135 void AndroidUsbDriverObject::OnDriverUnload() { 136 ASSERT_IRQL_PASSIVE(); 137 GoogleDbgPrint("\n<<<<<<<<<< Android USB driver is unloaded <<<<<<<<<<"); 138 } 139 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 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 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