/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** \file
  This file consists of implementation of rotines that are exported
  from this DLL.
*/

#include "stdafx.h"
#include "adb_api.h"
#include "adb_object_handle.h"
#include "adb_interface_enum.h"
#include "adb_interface.h"
#include "adb_legacy_interface.h"
#include "adb_endpoint_object.h"
#include "adb_io_completion.h"
#include "adb_helper_routines.h"

/** \brief Points to InstantiateWinUsbInterface exported from AdbWinUsbApi.dll.

  This variable is initialized with the actual address in DllMain routine for
  this DLL on DLL_PROCESS_ATTACH event.
  @see PFN_INSTWINUSBINTERFACE for more information.
*/
PFN_INSTWINUSBINTERFACE InstantiateWinUsbInterface = NULL;

ADBAPIHANDLE __cdecl AdbEnumInterfaces(GUID class_id,
                               bool exclude_not_present,
                               bool exclude_removed,
                               bool active_only) {
  AdbInterfaceEnumObject* enum_obj = NULL;
  ADBAPIHANDLE ret = NULL;

  try {
    // Instantiate and initialize enum object
    enum_obj = new AdbInterfaceEnumObject();

    if (enum_obj->InitializeEnum(class_id,
                                 exclude_not_present,
                                 exclude_removed,
                                 active_only)) {
      // After successful initialization we can create handle.
      ret = enum_obj->CreateHandle();
    }
  } catch (...) {
    SetLastError(ERROR_OUTOFMEMORY);
  }

  if (NULL != enum_obj)
    enum_obj->Release();

  return ret;
}

bool __cdecl AdbNextInterface(ADBAPIHANDLE adb_handle,
                      AdbInterfaceInfo* info,
                      unsigned long* size) {
  if (NULL == size) {
    SetLastError(ERROR_INVALID_PARAMETER);
    return false;
  }

  // Lookup AdbInterfaceEnumObject object for the handle
  AdbInterfaceEnumObject* adb_ienum_object =
    LookupObject<AdbInterfaceEnumObject>(adb_handle);
  if (NULL == adb_ienum_object)
    return false;

  // Everything is verified. Pass it down to the object
  bool ret = adb_ienum_object->Next(info, size);

  adb_ienum_object->Release();

  return ret;
}

bool __cdecl AdbResetInterfaceEnum(ADBAPIHANDLE adb_handle) {
  // Lookup AdbInterfaceEnumObject object for the handle
  AdbInterfaceEnumObject* adb_ienum_object =
    LookupObject<AdbInterfaceEnumObject>(adb_handle);
  if (NULL == adb_ienum_object)
    return false;

  // Everything is verified. Pass it down to the object
  bool ret = adb_ienum_object->Reset();

  adb_ienum_object->Release();

  return ret;
}

ADBAPIHANDLE __cdecl AdbCreateInterfaceByName(
    const wchar_t* interface_name) {
  AdbInterfaceObject* obj = NULL;
  ADBAPIHANDLE ret = NULL;

  try {
    // Instantiate interface object, depending on the USB driver type.
    if (IsLegacyInterface(interface_name)) {
      // We have legacy USB driver underneath us.
      obj = new AdbLegacyInterfaceObject(interface_name);
    } else {
      // We have WinUsb driver underneath us. Make sure that AdbWinUsbApi.dll
      // is loaded and its InstantiateWinUsbInterface routine address has
      // been cached.
      if (NULL != InstantiateWinUsbInterface) {
        obj = InstantiateWinUsbInterface(interface_name);
        if (NULL == obj) {
          return NULL;
        }
      } else {
        return NULL;
      }
    }

    // Create handle for it
    ret = obj->CreateHandle();
  } catch (...) {
    SetLastError(ERROR_OUTOFMEMORY);
  }

  if (NULL != obj)
    obj->Release();

  return ret;
}

ADBAPIHANDLE __cdecl AdbCreateInterface(GUID class_id,
                                unsigned short vendor_id,
                                unsigned short product_id,
                                unsigned char interface_id) {
  // Enumerate all active interfaces for the given class
  AdbEnumInterfaceArray interfaces;

  if (!EnumerateDeviceInterfaces(class_id,
                                 DIGCF_DEVICEINTERFACE | DIGCF_PRESENT,
                                 true,
                                 true,
                                 &interfaces)) {
    return NULL;
  }

  if (interfaces.empty()) {
    SetLastError(ERROR_DEVICE_NOT_AVAILABLE);
    return NULL;
  }

  // Now iterate over active interfaces looking for the name match.
  // The name is formatted as such:
  // "\\\\?\\usb#vid_xxxx&pid_xxxx&mi_xx#123456789abcdef#{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
  // where
  //    vid_xxxx is for the vendor id (xxxx are hex for the given vendor id),
  //    pid_xxxx is for the product id (xxxx are hex for the given product id)
  //    mi_xx is for the interface id  (xx are hex for the given interface id)
  // EnumerateDeviceInterfaces will guarantee that returned interface names
  // will have our class id at the end of the name (those last XXXes in the
  // format). So, we only need to match the beginning of the name
  wchar_t match_name[64];
  if (0xFF == interface_id) {
    // No interface id for the name.
    swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x#",
             vendor_id, product_id);
  } else {
    // With interface id for the name.
    swprintf(match_name, L"\\\\?\\usb#vid_%04x&pid_%04x&mi_%02x#",
             vendor_id, product_id, interface_id);
  }
  size_t match_len = wcslen(match_name);

  for (AdbEnumInterfaceArray::iterator it = interfaces.begin();
       it != interfaces.end(); it++) {
    const AdbInstanceEnumEntry& next_interface = *it;
    if (0 == _wcsnicmp(match_name,
                      next_interface.device_name().c_str(),
                      match_len)) {
      // Found requested interface among active interfaces.
      return AdbCreateInterfaceByName(next_interface.device_name().c_str());
    }
  }

  SetLastError(ERROR_DEVICE_NOT_AVAILABLE);
  return NULL;
}

bool __cdecl AdbGetInterfaceName(ADBAPIHANDLE adb_interface,
                         void* buffer,
                         unsigned long* buffer_char_size,
                         bool ansi) {
  // Lookup interface object for the handle
  AdbInterfaceObject* adb_object =
    LookupObject<AdbInterfaceObject>(adb_interface);

  if (NULL != adb_object) {
    // Dispatch call to the found object
    bool ret = adb_object->GetInterfaceName(buffer, buffer_char_size, ansi);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

bool __cdecl AdbGetSerialNumber(ADBAPIHANDLE adb_interface,
                        void* buffer,
                        unsigned long* buffer_char_size,
                        bool ansi) {
  // Lookup interface object for the handle
  AdbInterfaceObject* adb_object =
    LookupObject<AdbInterfaceObject>(adb_interface);

  if (NULL != adb_object) {
    // Dispatch call to the found object
    bool ret = adb_object->GetSerialNumber(buffer, buffer_char_size, ansi);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

bool __cdecl AdbGetUsbDeviceDescriptor(ADBAPIHANDLE adb_interface,
                               USB_DEVICE_DESCRIPTOR* desc) {
  // Lookup interface object for the handle
  AdbInterfaceObject* adb_object =
    LookupObject<AdbInterfaceObject>(adb_interface);

  if (NULL != adb_object) {
    // Dispatch close to the found object
    bool ret = adb_object->GetUsbDeviceDescriptor(desc);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

bool __cdecl AdbGetUsbConfigurationDescriptor(ADBAPIHANDLE adb_interface,
                                      USB_CONFIGURATION_DESCRIPTOR* desc) {
  // Lookup interface object for the handle
  AdbInterfaceObject* adb_object =
    LookupObject<AdbInterfaceObject>(adb_interface);

  if (NULL != adb_object) {
    // Dispatch close to the found object
    bool ret = adb_object->GetUsbConfigurationDescriptor(desc);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

bool __cdecl AdbGetUsbInterfaceDescriptor(ADBAPIHANDLE adb_interface,
                                  USB_INTERFACE_DESCRIPTOR* desc) {
  // Lookup interface object for the handle
  AdbInterfaceObject* adb_object =
    LookupObject<AdbInterfaceObject>(adb_interface);

  if (NULL != adb_object) {
    // Dispatch close to the found object
    bool ret = adb_object->GetUsbInterfaceDescriptor(desc);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

bool __cdecl AdbGetEndpointInformation(ADBAPIHANDLE adb_interface,
                               UCHAR endpoint_index,
                               AdbEndpointInformation* info) {
  // Lookup interface object for the handle
  AdbInterfaceObject* adb_object =
    LookupObject<AdbInterfaceObject>(adb_interface);

  if (NULL != adb_object) {
    // Dispatch close to the found object
    bool ret = adb_object->GetEndpointInformation(endpoint_index, info);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

bool __cdecl AdbGetDefaultBulkReadEndpointInformation(ADBAPIHANDLE adb_interface,
                                              AdbEndpointInformation* info) {
  return AdbGetEndpointInformation(adb_interface,
                                   ADB_QUERY_BULK_READ_ENDPOINT_INDEX,
                                   info);
}

bool __cdecl AdbGetDefaultBulkWriteEndpointInformation(ADBAPIHANDLE adb_interface,
                                               AdbEndpointInformation* info) {
  return AdbGetEndpointInformation(adb_interface,
                                   ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX,
                                   info);
}

ADBAPIHANDLE __cdecl AdbOpenEndpoint(ADBAPIHANDLE adb_interface,
                             unsigned char endpoint_index,
                             AdbOpenAccessType access_type,
                             AdbOpenSharingMode sharing_mode) {
  // Lookup interface object for the handle
  AdbInterfaceObject* adb_object =
    LookupObject<AdbInterfaceObject>(adb_interface);

  if (NULL != adb_object) {
    // Dispatch close to the found object
    ADBAPIHANDLE ret =
      adb_object->OpenEndpoint(endpoint_index, access_type, sharing_mode);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return NULL;
  }
}

ADBAPIHANDLE __cdecl AdbOpenDefaultBulkReadEndpoint(ADBAPIHANDLE adb_interface,
                                            AdbOpenAccessType access_type,
                                            AdbOpenSharingMode sharing_mode) {
  return AdbOpenEndpoint(adb_interface,
                         ADB_QUERY_BULK_READ_ENDPOINT_INDEX,
                         access_type,
                         sharing_mode);
}

ADBAPIHANDLE __cdecl AdbOpenDefaultBulkWriteEndpoint(ADBAPIHANDLE adb_interface,
                                             AdbOpenAccessType access_type,
                                             AdbOpenSharingMode sharing_mode) {
  return AdbOpenEndpoint(adb_interface,
                         ADB_QUERY_BULK_WRITE_ENDPOINT_INDEX,
                         access_type,
                         sharing_mode);
}

ADBAPIHANDLE __cdecl AdbGetEndpointInterface(ADBAPIHANDLE adb_endpoint) {
  // Lookup endpoint object for the handle
  AdbEndpointObject* adb_object =
    LookupObject<AdbEndpointObject>(adb_endpoint);

  if (NULL != adb_object) {
    // Dispatch the call to the found object
    ADBAPIHANDLE ret = adb_object->GetParentInterfaceHandle();
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return NULL;
  }
}

bool __cdecl AdbQueryInformationEndpoint(ADBAPIHANDLE adb_endpoint,
                                 AdbEndpointInformation* info) {
  // Lookup endpoint object for the handle
  AdbEndpointObject* adb_object =
    LookupObject<AdbEndpointObject>(adb_endpoint);

  if (NULL != adb_object) {
    // Dispatch the call to the found object
    bool ret = adb_object->GetEndpointInformation(info);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

ADBAPIHANDLE __cdecl AdbReadEndpointAsync(ADBAPIHANDLE adb_endpoint,
                                  void* buffer,
                                  unsigned long bytes_to_read,
                                  unsigned long* bytes_read,
                                  unsigned long time_out,
                                  HANDLE event_handle) {
  // Lookup endpoint object for the handle
  AdbEndpointObject* adb_object =
    LookupObject<AdbEndpointObject>(adb_endpoint);

  if (NULL != adb_object) {
    // Dispatch the call to the found object
    ADBAPIHANDLE ret = adb_object->AsyncRead(buffer,
                                             bytes_to_read,
                                             bytes_read,
                                             event_handle,
                                             time_out);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return NULL;
  }
}

ADBAPIHANDLE __cdecl AdbWriteEndpointAsync(ADBAPIHANDLE adb_endpoint,
                                   void* buffer,
                                   unsigned long bytes_to_write,
                                   unsigned long* bytes_written,
                                   unsigned long time_out,
                                   HANDLE event_handle) {
  // Lookup endpoint object for the handle
  AdbEndpointObject* adb_object =
    LookupObject<AdbEndpointObject>(adb_endpoint);

  if (NULL != adb_object) {
    // Dispatch the call to the found object
    ADBAPIHANDLE ret = adb_object->AsyncWrite(buffer,
                                              bytes_to_write,
                                              bytes_written,
                                              event_handle,
                                              time_out);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

bool __cdecl AdbReadEndpointSync(ADBAPIHANDLE adb_endpoint,
                         void* buffer,
                         unsigned long bytes_to_read,
                         unsigned long* bytes_read,
                         unsigned long time_out) {
  // Lookup endpoint object for the handle
  AdbEndpointObject* adb_object =
    LookupObject<AdbEndpointObject>(adb_endpoint);

  if (NULL != adb_object) {
    // Dispatch the call to the found object
    bool ret =
      adb_object->SyncRead(buffer, bytes_to_read, bytes_read, time_out);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return NULL;
  }
}

bool __cdecl AdbWriteEndpointSync(ADBAPIHANDLE adb_endpoint,
                          void* buffer,
                          unsigned long bytes_to_write,
                          unsigned long* bytes_written,
                          unsigned long time_out) {
  // Lookup endpoint object for the handle
  AdbEndpointObject* adb_object =
    LookupObject<AdbEndpointObject>(adb_endpoint);

  if (NULL != adb_object) {
    // Dispatch the call to the found object
    bool ret =
      adb_object->SyncWrite(buffer, bytes_to_write, bytes_written, time_out);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

bool __cdecl AdbGetOvelappedIoResult(ADBAPIHANDLE adb_io_completion,
                             LPOVERLAPPED overlapped,
                             unsigned long* bytes_transferred,
                             bool wait) {
  // Lookup endpoint object for the handle
  AdbIOCompletion* adb_object =
    LookupObject<AdbIOCompletion>(adb_io_completion);

  if (NULL != adb_object) {
    // Dispatch the call to the found object
    bool ret =
      adb_object->GetOvelappedIoResult(overlapped, bytes_transferred, wait);
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}

bool __cdecl AdbHasOvelappedIoComplated(ADBAPIHANDLE adb_io_completion) {
  // Lookup endpoint object for the handle
  AdbIOCompletion* adb_object =
    LookupObject<AdbIOCompletion>(adb_io_completion);

  if (NULL != adb_object) {
    // Dispatch the call to the found object
    bool ret =
      adb_object->IsCompleted();
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return true;
  }
}

bool __cdecl AdbCloseHandle(ADBAPIHANDLE adb_handle) {
  // Lookup object for the handle
  AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle);

  if (NULL != adb_object) {
    // Dispatch close to the found object
    bool ret = adb_object->CloseHandle();
    adb_object->Release();
    return ret;
  } else {
    SetLastError(ERROR_INVALID_HANDLE);
    return false;
  }
}
