Home | History | Annotate | Download | only in driver
      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