/*
 * Copyright (C) 2007 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.
 */

#define TRACE_TAG USB

#include "sysdeps.h"

#include <winsock2.h>  // winsock.h *must* be included before windows.h.
#include <adb_api.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <usb100.h>
#include <windows.h>
#include <winerror.h>

#include <android-base/errors.h>

#include "adb.h"
#include "transport.h"

/** Structure usb_handle describes our connection to the usb device via
  AdbWinApi.dll. This structure is returned from usb_open() routine and
  is expected in each subsequent call that is accessing the device.

  Most members are protected by usb_lock, except for adb_{read,write}_pipe which
  rely on AdbWinApi.dll's handle validation and AdbCloseHandle(endpoint)'s
  ability to break a thread out of pipe IO.
*/
struct usb_handle {
  /// Previous entry in the list of opened usb handles
  usb_handle *prev;

  /// Next entry in the list of opened usb handles
  usb_handle *next;

  /// Handle to USB interface
  ADBAPIHANDLE  adb_interface;

  /// Handle to USB read pipe (endpoint)
  ADBAPIHANDLE  adb_read_pipe;

  /// Handle to USB write pipe (endpoint)
  ADBAPIHANDLE  adb_write_pipe;

  /// Interface name
  wchar_t*      interface_name;

  /// Mask for determining when to use zero length packets
  unsigned zero_mask;
};

/// Class ID assigned to the device by androidusb.sys
static const GUID usb_class_id = ANDROID_USB_CLASS_ID;

/// List of opened usb handles
static usb_handle handle_list = {
  .prev = &handle_list,
  .next = &handle_list,
};

/// Locker for the list of opened usb handles
ADB_MUTEX_DEFINE( usb_lock );

/// Checks if there is opened usb handle in handle_list for this device.
int known_device(const wchar_t* dev_name);

/// Checks if there is opened usb handle in handle_list for this device.
/// usb_lock mutex must be held before calling this routine.
int known_device_locked(const wchar_t* dev_name);

/// Registers opened usb handle (adds it to handle_list).
int register_new_device(usb_handle* handle);

/// Checks if interface (device) matches certain criteria
int recognized_device(usb_handle* handle);

/// Enumerates present and available interfaces (devices), opens new ones and
/// registers usb transport for them.
void find_devices();

/// Kicks all USB devices
static void kick_devices();

/// Entry point for thread that polls (every second) for new usb interfaces.
/// This routine calls find_devices in infinite loop.
static void device_poll_thread(void*);

/// Initializes this module
void usb_init();

/// Opens usb interface (device) by interface (device) name.
usb_handle* do_usb_open(const wchar_t* interface_name);

/// Writes data to the opened usb handle
int usb_write(usb_handle* handle, const void* data, int len);

/// Reads data using the opened usb handle
int usb_read(usb_handle *handle, void* data, int len);

/// Cleans up opened usb handle
void usb_cleanup_handle(usb_handle* handle);

/// Cleans up (but don't close) opened usb handle
void usb_kick(usb_handle* handle);

/// Closes opened usb handle
int usb_close(usb_handle* handle);

int known_device_locked(const wchar_t* dev_name) {
  usb_handle* usb;

  if (NULL != dev_name) {
    // Iterate through the list looking for the name match.
    for(usb = handle_list.next; usb != &handle_list; usb = usb->next) {
      // In Windows names are not case sensetive!
      if((NULL != usb->interface_name) &&
         (0 == wcsicmp(usb->interface_name, dev_name))) {
        return 1;
      }
    }
  }

  return 0;
}

int known_device(const wchar_t* dev_name) {
  int ret = 0;

  if (NULL != dev_name) {
    adb_mutex_lock(&usb_lock);
    ret = known_device_locked(dev_name);
    adb_mutex_unlock(&usb_lock);
  }

  return ret;
}

int register_new_device(usb_handle* handle) {
  if (NULL == handle)
    return 0;

  adb_mutex_lock(&usb_lock);

  // Check if device is already in the list
  if (known_device_locked(handle->interface_name)) {
    adb_mutex_unlock(&usb_lock);
    return 0;
  }

  // Not in the list. Add this handle to the list.
  handle->next = &handle_list;
  handle->prev = handle_list.prev;
  handle->prev->next = handle;
  handle->next->prev = handle;

  adb_mutex_unlock(&usb_lock);

  return 1;
}

void device_poll_thread(void*) {
  adb_thread_setname("Device Poll");
  D("Created device thread");

  while(1) {
    find_devices();
    adb_sleep_ms(1000);
  }
}

static LRESULT CALLBACK _power_window_proc(HWND hwnd, UINT uMsg, WPARAM wParam,
                                           LPARAM lParam) {
  switch (uMsg) {
  case WM_POWERBROADCAST:
    switch (wParam) {
    case PBT_APMRESUMEAUTOMATIC:
      // Resuming from sleep or hibernation, so kick all existing USB devices
      // and then allow the device_poll_thread to redetect USB devices from
      // scratch. If we don't do this, existing USB devices will never respond
      // to us because they'll be waiting for the connect/auth handshake.
      D("Received (WM_POWERBROADCAST, PBT_APMRESUMEAUTOMATIC) notification, "
        "so kicking all USB devices\n");
      kick_devices();
      return TRUE;
    }
  }
  return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

static void _power_notification_thread(void*) {
  // This uses a thread with its own window message pump to get power
  // notifications. If adb runs from a non-interactive service account, this
  // might not work (not sure). If that happens to not work, we could use
  // heavyweight WMI APIs to get power notifications. But for the common case
  // of a developer's interactive session, a window message pump is more
  // appropriate.
  D("Created power notification thread");
  adb_thread_setname("Power Notifier");

  // Window class names are process specific.
  static const WCHAR kPowerNotificationWindowClassName[] =
    L"PowerNotificationWindow";

  // Get the HINSTANCE corresponding to the module that _power_window_proc
  // is in (the main module).
  const HINSTANCE instance = GetModuleHandleW(NULL);
  if (!instance) {
    // This is such a common API call that this should never fail.
    fatal("GetModuleHandleW failed: %s",
          android::base::SystemErrorCodeToString(GetLastError()).c_str());
  }

  WNDCLASSEXW wndclass;
  memset(&wndclass, 0, sizeof(wndclass));
  wndclass.cbSize = sizeof(wndclass);
  wndclass.lpfnWndProc = _power_window_proc;
  wndclass.hInstance = instance;
  wndclass.lpszClassName = kPowerNotificationWindowClassName;
  if (!RegisterClassExW(&wndclass)) {
    fatal("RegisterClassExW failed: %s",
          android::base::SystemErrorCodeToString(GetLastError()).c_str());
  }

  if (!CreateWindowExW(WS_EX_NOACTIVATE, kPowerNotificationWindowClassName,
                       L"ADB Power Notification Window", WS_POPUP, 0, 0, 0, 0,
                       NULL, NULL, instance, NULL)) {
    fatal("CreateWindowExW failed: %s",
          android::base::SystemErrorCodeToString(GetLastError()).c_str());
  }

  MSG msg;
  while (GetMessageW(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessageW(&msg);
  }

  // GetMessageW() will return false if a quit message is posted. We don't
  // do that, but it might be possible for that to occur when logging off or
  // shutting down. Not a big deal since the whole process will be going away
  // soon anyway.
  D("Power notification thread exiting");
}

void usb_init() {
  if (!adb_thread_create(device_poll_thread, nullptr)) {
    fatal_errno("cannot create device poll thread");
  }
  if (!adb_thread_create(_power_notification_thread, nullptr)) {
    fatal_errno("cannot create power notification thread");
  }
}

usb_handle* do_usb_open(const wchar_t* interface_name) {
  unsigned long name_len = 0;

  // Allocate our handle
  usb_handle* ret = (usb_handle*)calloc(1, sizeof(usb_handle));
  if (NULL == ret) {
    D("Could not allocate %u bytes for usb_handle: %s", sizeof(usb_handle),
      strerror(errno));
    goto fail;
  }

  // Set linkers back to the handle
  ret->next = ret;
  ret->prev = ret;

  // Create interface.
  ret->adb_interface = AdbCreateInterfaceByName(interface_name);
  if (NULL == ret->adb_interface) {
    D("AdbCreateInterfaceByName failed: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
    goto fail;
  }

  // Open read pipe (endpoint)
  ret->adb_read_pipe =
    AdbOpenDefaultBulkReadEndpoint(ret->adb_interface,
                                   AdbOpenAccessTypeReadWrite,
                                   AdbOpenSharingModeReadWrite);
  if (NULL == ret->adb_read_pipe) {
    D("AdbOpenDefaultBulkReadEndpoint failed: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
    goto fail;
  }

  // Open write pipe (endpoint)
  ret->adb_write_pipe =
    AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface,
                                    AdbOpenAccessTypeReadWrite,
                                    AdbOpenSharingModeReadWrite);
  if (NULL == ret->adb_write_pipe) {
    D("AdbOpenDefaultBulkWriteEndpoint failed: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
    goto fail;
  }

  // Save interface name
  // First get expected name length
  AdbGetInterfaceName(ret->adb_interface,
                      NULL,
                      &name_len,
                      false);
  if (0 == name_len) {
    D("AdbGetInterfaceName returned name length of zero: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
    goto fail;
  }

  ret->interface_name = (wchar_t*)malloc(name_len * sizeof(ret->interface_name[0]));
  if (NULL == ret->interface_name) {
    D("Could not allocate %lu characters for interface_name: %s", name_len, strerror(errno));
    goto fail;
  }

  // Now save the name
  if (!AdbGetInterfaceName(ret->adb_interface,
                           ret->interface_name,
                           &name_len,
                           false)) {
    D("AdbGetInterfaceName failed: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
    goto fail;
  }

  // We're done at this point
  return ret;

fail:
  if (NULL != ret) {
    usb_cleanup_handle(ret);
    free(ret);
  }

  return NULL;
}

int usb_write(usb_handle* handle, const void* data, int len) {
  unsigned long time_out = 5000;
  unsigned long written = 0;
  int err = 0;

  D("usb_write %d", len);
  if (NULL == handle) {
    D("usb_write was passed NULL handle");
    err = EINVAL;
    goto fail;
  }

  // Perform write
  if (!AdbWriteEndpointSync(handle->adb_write_pipe,
                            (void*)data,
                            (unsigned long)len,
                            &written,
                            time_out)) {
    D("AdbWriteEndpointSync failed: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
    err = EIO;
    goto fail;
  }

  // Make sure that we've written what we were asked to write
  D("usb_write got: %ld, expected: %d", written, len);
  if (written != (unsigned long)len) {
    // If this occurs, this code should be changed to repeatedly call
    // AdbWriteEndpointSync() until all bytes are written.
    D("AdbWriteEndpointSync was supposed to write %d, but only wrote %ld",
      len, written);
    err = EIO;
    goto fail;
  }

  if (handle->zero_mask && (len & handle->zero_mask) == 0) {
    // Send a zero length packet
    if (!AdbWriteEndpointSync(handle->adb_write_pipe,
                              (void*)data,
                              0,
                              &written,
                              time_out)) {
      D("AdbWriteEndpointSync of zero length packet failed: %s",
        android::base::SystemErrorCodeToString(GetLastError()).c_str());
      err = EIO;
      goto fail;
    }
  }

  return 0;

fail:
  // Any failure should cause us to kick the device instead of leaving it a
  // zombie state with potential to hang.
  if (NULL != handle) {
    D("Kicking device due to error in usb_write");
    usb_kick(handle);
  }

  D("usb_write failed");
  errno = err;
  return -1;
}

int usb_read(usb_handle *handle, void* data, int len) {
  unsigned long time_out = 0;
  unsigned long read = 0;
  int err = 0;

  D("usb_read %d", len);
  if (NULL == handle) {
    D("usb_read was passed NULL handle");
    err = EINVAL;
    goto fail;
  }

  while (len > 0) {
    if (!AdbReadEndpointSync(handle->adb_read_pipe, data, len, &read,
                             time_out)) {
      D("AdbReadEndpointSync failed: %s",
        android::base::SystemErrorCodeToString(GetLastError()).c_str());
      err = EIO;
      goto fail;
    }
    D("usb_read got: %ld, expected: %d", read, len);

    data = (char *)data + read;
    len -= read;
  }

  return 0;

fail:
  // Any failure should cause us to kick the device instead of leaving it a
  // zombie state with potential to hang.
  if (NULL != handle) {
    D("Kicking device due to error in usb_read");
    usb_kick(handle);
  }

  D("usb_read failed");
  errno = err;
  return -1;
}

// Wrapper around AdbCloseHandle() that logs diagnostics.
static void _adb_close_handle(ADBAPIHANDLE adb_handle) {
  if (!AdbCloseHandle(adb_handle)) {
    D("AdbCloseHandle(%p) failed: %s", adb_handle,
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
  }
}

void usb_cleanup_handle(usb_handle* handle) {
  D("usb_cleanup_handle");
  if (NULL != handle) {
    if (NULL != handle->interface_name)
      free(handle->interface_name);
    // AdbCloseHandle(pipe) will break any threads out of pending IO calls and
    // wait until the pipe no longer uses the interface. Then we can
    // AdbCloseHandle() the interface.
    if (NULL != handle->adb_write_pipe)
      _adb_close_handle(handle->adb_write_pipe);
    if (NULL != handle->adb_read_pipe)
      _adb_close_handle(handle->adb_read_pipe);
    if (NULL != handle->adb_interface)
      _adb_close_handle(handle->adb_interface);

    handle->interface_name = NULL;
    handle->adb_write_pipe = NULL;
    handle->adb_read_pipe = NULL;
    handle->adb_interface = NULL;
  }
}

static void usb_kick_locked(usb_handle* handle) {
  // The reason the lock must be acquired before calling this function is in
  // case multiple threads are trying to kick the same device at the same time.
  usb_cleanup_handle(handle);
}

void usb_kick(usb_handle* handle) {
  D("usb_kick");
  if (NULL != handle) {
    adb_mutex_lock(&usb_lock);

    usb_kick_locked(handle);

    adb_mutex_unlock(&usb_lock);
  } else {
    errno = EINVAL;
  }
}

int usb_close(usb_handle* handle) {
  D("usb_close");

  if (NULL != handle) {
    // Remove handle from the list
    adb_mutex_lock(&usb_lock);

    if ((handle->next != handle) && (handle->prev != handle)) {
      handle->next->prev = handle->prev;
      handle->prev->next = handle->next;
      handle->prev = handle;
      handle->next = handle;
    }

    adb_mutex_unlock(&usb_lock);

    // Cleanup handle
    usb_cleanup_handle(handle);
    free(handle);
  }

  return 0;
}

int recognized_device(usb_handle* handle) {
  if (NULL == handle)
    return 0;

  // Check vendor and product id first
  USB_DEVICE_DESCRIPTOR device_desc;

  if (!AdbGetUsbDeviceDescriptor(handle->adb_interface,
                                 &device_desc)) {
    D("AdbGetUsbDeviceDescriptor failed: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
    return 0;
  }

  // Then check interface properties
  USB_INTERFACE_DESCRIPTOR interf_desc;

  if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface,
                                    &interf_desc)) {
    D("AdbGetUsbInterfaceDescriptor failed: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
    return 0;
  }

  // Must have two endpoints
  if (2 != interf_desc.bNumEndpoints) {
    return 0;
  }

  if (is_adb_interface(device_desc.idVendor, device_desc.idProduct,
      interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass, interf_desc.bInterfaceProtocol)) {

    if(interf_desc.bInterfaceProtocol == 0x01) {
      AdbEndpointInformation endpoint_info;
      // assuming zero is a valid bulk endpoint ID
      if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) {
        handle->zero_mask = endpoint_info.max_packet_size - 1;
        D("device zero_mask: 0x%x", handle->zero_mask);
      } else {
        D("AdbGetEndpointInformation failed: %s",
          android::base::SystemErrorCodeToString(GetLastError()).c_str());
      }
    }

    return 1;
  }

  return 0;
}

void find_devices() {
  usb_handle* handle = NULL;
  char entry_buffer[2048];
  AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
  unsigned long entry_buffer_size = sizeof(entry_buffer);

  // Enumerate all present and active interfaces.
  ADBAPIHANDLE enum_handle =
    AdbEnumInterfaces(usb_class_id, true, true, true);

  if (NULL == enum_handle) {
    D("AdbEnumInterfaces failed: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
    return;
  }

  while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) {
    // Lets see if we already have this device in the list
    if (!known_device(next_interface->device_name)) {
      // This seems to be a new device. Open it!
      handle = do_usb_open(next_interface->device_name);
      if (NULL != handle) {
        // Lets see if this interface (device) belongs to us
        if (recognized_device(handle)) {
          D("adding a new device %ls", next_interface->device_name);

          // We don't request a wchar_t string from AdbGetSerialNumber() because of a bug in
          // adb_winusb_interface.cpp:CopyMemory(buffer, ser_num->bString, bytes_written) where the
          // last parameter should be (str_len * sizeof(wchar_t)). The bug reads 2 bytes past the
          // end of a stack buffer in the best case, and in the unlikely case of a long serial
          // number, it will read 2 bytes past the end of a heap allocation. This doesn't affect the
          // resulting string, but we should avoid the bad reads in the first place.
          char serial_number[512];
          unsigned long serial_number_len = sizeof(serial_number);
          if (AdbGetSerialNumber(handle->adb_interface,
                                serial_number,
                                &serial_number_len,
                                true)) {
            // Lets make sure that we don't duplicate this device
            if (register_new_device(handle)) {
              register_usb_transport(handle, serial_number, NULL, 1);
            } else {
              D("register_new_device failed for %ls", next_interface->device_name);
              usb_cleanup_handle(handle);
              free(handle);
            }
          } else {
            D("cannot get serial number: %s",
              android::base::SystemErrorCodeToString(GetLastError()).c_str());
            usb_cleanup_handle(handle);
            free(handle);
          }
        } else {
          usb_cleanup_handle(handle);
          free(handle);
        }
      }
    }

    entry_buffer_size = sizeof(entry_buffer);
  }

  if (GetLastError() != ERROR_NO_MORE_ITEMS) {
    // Only ERROR_NO_MORE_ITEMS is expected at the end of enumeration.
    D("AdbNextInterface failed: %s",
      android::base::SystemErrorCodeToString(GetLastError()).c_str());
  }

  _adb_close_handle(enum_handle);
}

static void kick_devices() {
  // Need to acquire lock to safely walk the list which might be modified
  // by another thread.
  adb_mutex_lock(&usb_lock);
  for (usb_handle* usb = handle_list.next; usb != &handle_list; usb = usb->next) {
    usb_kick_locked(usb);
  }
  adb_mutex_unlock(&usb_lock);
}
