Home | History | Annotate | Download | only in api
      1 /*
      2  * Copyright (C) 2009 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 AdbLegacyInterfaceObject
     19   that encapsulates an interface on our USB device that is accessible
     20 */
     21 
     22 #include "stdafx.h"
     23 #include "adb_api_legacy.h"
     24 #include "adb_legacy_interface.h"
     25 #include "adb_legacy_endpoint_object.h"
     26 
     27 AdbLegacyInterfaceObject::AdbLegacyInterfaceObject(const wchar_t* interf_name)
     28     : AdbInterfaceObject(interf_name),
     29       def_read_endpoint_(0xFF),
     30       read_endpoint_id_(0xFF),
     31       def_write_endpoint_(0xFF),
     32       write_endpoint_id_(0xFF) {
     33 }
     34 
     35 AdbLegacyInterfaceObject::~AdbLegacyInterfaceObject() {
     36 }
     37 
     38 ADBAPIHANDLE AdbLegacyInterfaceObject::CreateHandle() {
     39   // Open USB device for this intefface
     40   HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
     41                                         GENERIC_READ | GENERIC_WRITE,
     42                                         FILE_SHARE_READ | FILE_SHARE_WRITE,
     43                                         NULL,
     44                                         OPEN_EXISTING,
     45                                         0,
     46                                         NULL);
     47   if (INVALID_HANDLE_VALUE == usb_device_handle) {
     48     return NULL;
     49   }
     50 
     51   // Now, we ensured that our usb device / interface is up and running.
     52   // Lets collect device, interface and pipe information
     53   bool ok = true;
     54   if (!CacheUsbDeviceDescriptor(usb_device_handle) ||
     55       !CacheUsbConfigurationDescriptor(usb_device_handle) ||
     56       !CacheUsbInterfaceDescriptor(usb_device_handle)) {
     57     ok = false;
     58   }
     59 
     60   // Preserve error accross handle close
     61   ULONG error = ok ? NO_ERROR : GetLastError();
     62 
     63   ::CloseHandle(usb_device_handle);
     64 
     65   if (NO_ERROR != error) {
     66     SetLastError(error);
     67   }
     68 
     69   if (!ok) {
     70     return false;
     71   }
     72 
     73   // Save indexes and IDs for bulk read / write endpoints. We will use them to
     74   // convert ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX and
     75   // ADB_QUERY_BULK_READ_ENDPOINT_INDEX into actual endpoint indexes and IDs.
     76   for (UCHAR endpoint = 0; endpoint < usb_interface_descriptor_.bNumEndpoints;
     77        endpoint++) {
     78     // Get endpoint information
     79     AdbEndpointInformation pipe_info;
     80     if (!GetEndpointInformation(endpoint, &pipe_info)) {
     81       return false;
     82     }
     83 
     84     if (AdbEndpointTypeBulk == pipe_info.endpoint_type) {
     85       // This is a bulk endpoint. Cache its index and ID.
     86       if (0 != (pipe_info.endpoint_address & USB_ENDPOINT_DIRECTION_MASK)) {
     87         // Use this endpoint as default bulk read endpoint
     88         ATLASSERT(0xFF == def_read_endpoint_);
     89         def_read_endpoint_ = endpoint;
     90         read_endpoint_id_ = pipe_info.endpoint_address;
     91       } else {
     92         // Use this endpoint as default bulk write endpoint
     93         ATLASSERT(0xFF == def_write_endpoint_);
     94         def_write_endpoint_ = endpoint;
     95         write_endpoint_id_ = pipe_info.endpoint_address;
     96       }
     97     }
     98   }
     99 
    100   return AdbObjectHandle::CreateHandle();
    101 }
    102 
    103 bool AdbLegacyInterfaceObject::GetSerialNumber(void* buffer,
    104                                                unsigned long* buffer_char_size,
    105                                                bool ansi) {
    106   if (!IsOpened()) {
    107     SetLastError(ERROR_INVALID_HANDLE);
    108     return false;
    109   }
    110 
    111   // Open USB device for this intefface
    112   HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
    113                                         GENERIC_READ,
    114                                         FILE_SHARE_READ | FILE_SHARE_WRITE,
    115                                         NULL,
    116                                         OPEN_EXISTING,
    117                                         0,
    118                                         NULL);
    119   if (INVALID_HANDLE_VALUE == usb_device_handle) {
    120     return NULL;
    121   }
    122 
    123   WCHAR serial_number[512];
    124 
    125   // Send IOCTL
    126   DWORD ret_bytes = 0;
    127   BOOL ret = DeviceIoControl(usb_device_handle,
    128                              ADB_IOCTL_GET_SERIAL_NUMBER,
    129                              NULL, 0,
    130                              serial_number, sizeof(serial_number),
    131                              &ret_bytes,
    132                              NULL);
    133 
    134   // Preserve error accross CloseHandle
    135   ULONG error = ret ? NO_ERROR : GetLastError();
    136 
    137   ::CloseHandle(usb_device_handle);
    138 
    139   if (NO_ERROR != error) {
    140     SetLastError(error);
    141     return false;
    142   }
    143 
    144   unsigned long str_len =
    145     static_cast<unsigned long>(wcslen(serial_number) + 1);
    146 
    147   if ((NULL == buffer) || (*buffer_char_size < str_len)) {
    148     *buffer_char_size = str_len;
    149     SetLastError(ERROR_INSUFFICIENT_BUFFER);
    150     return false;
    151   }
    152 
    153   if (!ansi) {
    154     // If user asked for wide char name just return it
    155     wcscpy(reinterpret_cast<wchar_t*>(buffer), serial_number);
    156     return true;
    157   }
    158 
    159   // We need to convert name from wide char to ansi string
    160   int res = WideCharToMultiByte(CP_ACP,
    161                                 0,
    162                                 serial_number,
    163                                 static_cast<int>(str_len),
    164                                 reinterpret_cast<PSTR>(buffer),
    165                                 static_cast<int>(*buffer_char_size),
    166                                 NULL,
    167                                 NULL);
    168   return (res != 0);
    169 }
    170 
    171 bool AdbLegacyInterfaceObject::GetEndpointInformation(
    172     UCHAR endpoint_index,
    173     AdbEndpointInformation* info) {
    174   // Open USB device for this intefface
    175   HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
    176                                         GENERIC_READ,
    177                                         FILE_SHARE_READ | FILE_SHARE_WRITE,
    178                                         NULL,
    179                                         OPEN_EXISTING,
    180                                         0,
    181                                         NULL);
    182   if (INVALID_HANDLE_VALUE == usb_device_handle) {
    183     return NULL;
    184   }
    185 
    186   // Init ICTL param
    187   AdbQueryEndpointInformation param;
    188   param.endpoint_index = endpoint_index;
    189 
    190   // Send IOCTL
    191   DWORD ret_bytes = 0;
    192   BOOL ret = DeviceIoControl(usb_device_handle,
    193                              ADB_IOCTL_GET_ENDPOINT_INFORMATION,
    194                              &param, sizeof(param),
    195                              info, sizeof(AdbEndpointInformation),
    196                              &ret_bytes,
    197                              NULL);
    198   ATLASSERT(!ret || (sizeof(AdbEndpointInformation) == ret_bytes));
    199 
    200   // Preserve error accross CloseHandle
    201   ULONG error = ret ? NO_ERROR : GetLastError();
    202 
    203   ::CloseHandle(usb_device_handle);
    204 
    205   if (NO_ERROR != error) {
    206     SetLastError(error);
    207   }
    208 
    209   return ret ? true : false;
    210 }
    211 
    212 ADBAPIHANDLE AdbLegacyInterfaceObject::OpenEndpoint(
    213     UCHAR endpoint_index,
    214     AdbOpenAccessType access_type,
    215     AdbOpenSharingMode sharing_mode) {
    216   // Convert index into name and ID.
    217   std::wstring endpoint_name;
    218   UCHAR endpoint_id;
    219 
    220   try {
    221     if ((ADB_QUERY_BULK_READ_ENDPOINT_INDEX == endpoint_index) ||
    222         (def_read_endpoint_ == endpoint_index)) {
    223       endpoint_name = DEVICE_BULK_READ_PIPE_NAME;
    224       endpoint_id = read_endpoint_id_;
    225       endpoint_index = def_read_endpoint_;
    226     } else if ((ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX == endpoint_index) ||
    227                (def_write_endpoint_ == endpoint_index)) {
    228       endpoint_name = DEVICE_BULK_WRITE_PIPE_NAME;
    229       endpoint_id = write_endpoint_id_;
    230       endpoint_index = def_write_endpoint_;
    231     } else {
    232       SetLastError(ERROR_INVALID_PARAMETER);
    233       return false;
    234     }
    235   } catch (...) {
    236     // We don't expect exceptions other than OOM thrown here.
    237     SetLastError(ERROR_OUTOFMEMORY);
    238     return NULL;
    239   }
    240 
    241   return OpenEndpoint(endpoint_name.c_str(), endpoint_id, endpoint_index,
    242                       access_type, sharing_mode);
    243 }
    244 
    245 ADBAPIHANDLE AdbLegacyInterfaceObject::OpenEndpoint(
    246     const wchar_t* endpoint_name,
    247     UCHAR endpoint_id,
    248     UCHAR endpoint_index,
    249     AdbOpenAccessType access_type,
    250     AdbOpenSharingMode sharing_mode) {
    251   if (!IsOpened()) {
    252     SetLastError(ERROR_INVALID_HANDLE);
    253     return false;
    254   }
    255 
    256   AdbLegacyEndpointObject* adb_endpoint = NULL;
    257 
    258   try {
    259     adb_endpoint =
    260         new AdbLegacyEndpointObject(this, endpoint_id, endpoint_index);
    261   } catch (...) {
    262     // We don't expect exceptions other than OOM thrown here.
    263     SetLastError(ERROR_OUTOFMEMORY);
    264     return NULL;
    265   }
    266 
    267   // Build full path to the object
    268   std::wstring endpoint_path = interface_name();
    269   endpoint_path += L"\\";
    270   endpoint_path += endpoint_name;
    271 
    272   ADBAPIHANDLE ret = adb_endpoint->CreateHandle(endpoint_path.c_str(),
    273                                                 access_type,
    274                                                 sharing_mode);
    275 
    276   adb_endpoint->Release();
    277 
    278   return ret;
    279 }
    280 
    281 bool AdbLegacyInterfaceObject::CacheUsbDeviceDescriptor(
    282     HANDLE usb_device_handle) {
    283   DWORD ret_bytes = 0;
    284   BOOL ret = DeviceIoControl(usb_device_handle,
    285                              ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR,
    286                              NULL, 0,
    287                              &usb_device_descriptor_,
    288                              sizeof(usb_device_descriptor_),
    289                              &ret_bytes,
    290                              NULL);
    291   ATLASSERT(!ret || (sizeof(USB_DEVICE_DESCRIPTOR) == ret_bytes));
    292 
    293   return ret ? true : false;
    294 }
    295 
    296 bool AdbLegacyInterfaceObject::CacheUsbConfigurationDescriptor(
    297     HANDLE usb_device_handle) {
    298   DWORD ret_bytes = 0;
    299   BOOL ret = DeviceIoControl(usb_device_handle,
    300                              ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR,
    301                              NULL, 0,
    302                              &usb_config_descriptor_,
    303                              sizeof(usb_config_descriptor_),
    304                              &ret_bytes,
    305                              NULL);
    306   ATLASSERT(!ret || (sizeof(USB_CONFIGURATION_DESCRIPTOR) == ret_bytes));
    307 
    308   return ret ? true : false;
    309 }
    310 
    311 bool AdbLegacyInterfaceObject::CacheUsbInterfaceDescriptor(
    312     HANDLE usb_device_handle) {
    313   DWORD ret_bytes = 0;
    314   BOOL ret = DeviceIoControl(usb_device_handle,
    315                              ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR,
    316                              NULL, 0,
    317                              &usb_interface_descriptor_,
    318                              sizeof(usb_interface_descriptor_),
    319                              &ret_bytes,
    320                              NULL);
    321   ATLASSERT(!ret || (sizeof(USB_INTERFACE_DESCRIPTOR) == ret_bytes));
    322 
    323   return ret ? true : false;
    324 }
    325