139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine/*
239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine * Copyright (C) 2009 The Android Open Source Project
339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine *
439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine * Licensed under the Apache License, Version 2.0 (the "License");
539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine * you may not use this file except in compliance with the License.
639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine * You may obtain a copy of the License at
739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine *
839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine *      http://www.apache.org/licenses/LICENSE-2.0
939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine *
1039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine * Unless required by applicable law or agreed to in writing, software
1139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine * distributed under the License is distributed on an "AS IS" BASIS,
1239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine * See the License for the specific language governing permissions and
1439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine * limitations under the License.
1539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine */
1639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
1739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine/** \file
1839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  This file consists of implementation of class AdbLegacyEndpointObject that
1939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  encapsulates a handle opened to an endpoint on our device controlled by
2039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  a custom (legacy) USB driver.
2139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine*/
2239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
2339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine#include "stdafx.h"
2439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine#include "adb_api_legacy.h"
2539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine#include "adb_legacy_endpoint_object.h"
2639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine#include "adb_legacy_io_completion.h"
2739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine#include "adb_helper_routines.h"
2839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
2939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkineAdbLegacyEndpointObject::AdbLegacyEndpointObject(
3039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    AdbLegacyInterfaceObject* parent_interf,
3139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    UCHAR endpoint_id,
3239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    UCHAR endpoint_index)
3339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    : AdbEndpointObject(parent_interf, endpoint_id, endpoint_index),
3439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      usb_handle_(INVALID_HANDLE_VALUE) {
3539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine}
3639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
3739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkineAdbLegacyEndpointObject::~AdbLegacyEndpointObject() {
3839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (INVALID_HANDLE_VALUE != usb_handle_) {
3939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ::CloseHandle(usb_handle_);
4039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
4139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine}
4239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
4339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkineADBAPIHANDLE AdbLegacyEndpointObject::CommonAsyncReadWrite(
4439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    bool is_read,
4539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    void* buffer,
4639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ULONG bytes_to_transfer,
4739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ULONG* bytes_transferred,
4839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    HANDLE event_handle,
4939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ULONG time_out) {
5039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (NULL != bytes_transferred) {
5139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    *bytes_transferred = 0;
5239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
5339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
5439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (!IsOpened()) {
5539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    SetLastError(ERROR_INVALID_HANDLE);
5639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    return false;
5739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
5839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
5939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  bool is_ioctl_write = is_read ? false : (0 != time_out);
6039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
6139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // Create completion i/o object
6239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  AdbLegacyIOCompletion* adb_io_completion = NULL;
6339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
6439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  try {
6539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    adb_io_completion = new AdbLegacyIOCompletion(this,
6639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                                  bytes_to_transfer,
6739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                                  event_handle,
6839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                                  is_ioctl_write);
6939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  } catch (... ) {
7039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    // We don't expect exceptions other than OOM thrown here.
7139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    SetLastError(ERROR_OUTOFMEMORY);
7239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    return NULL;
7339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
7439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
7539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // Create a handle for it
7639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  ADBAPIHANDLE ret = adb_io_completion->CreateHandle();
7739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  ULONG transferred = 0;
7839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (NULL != ret) {
7939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    BOOL res = TRUE;
8039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    if (0 == time_out) {
8139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      // Go the read / write file way
8239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      res = is_read ? ReadFile(usb_handle(),
8339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                               buffer,
8439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                               bytes_to_transfer,
8539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                               &transferred,
8639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                               adb_io_completion->overlapped()) :
8739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                      WriteFile(usb_handle(),
8839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                buffer,
8939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                bytes_to_transfer,
9039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                &transferred,
9139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                adb_io_completion->overlapped());
9239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    } else {
9339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      // Go IOCTL way
9439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      AdbBulkTransfer transfer_param;
9539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      transfer_param.time_out = time_out;
9639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      transfer_param.transfer_size = is_read ? 0 : bytes_to_transfer;
9739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      transfer_param.SetWriteBuffer(is_read ? NULL : buffer);
9839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
9939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      res = DeviceIoControl(usb_handle(),
10039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine        is_read ? ADB_IOCTL_BULK_READ : ADB_IOCTL_BULK_WRITE,
10139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine        &transfer_param, sizeof(transfer_param),
10239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine        is_read ? buffer : adb_io_completion->transferred_bytes_ptr(),
10339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine        is_read ? bytes_to_transfer : sizeof(ULONG),
10439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine        &transferred,
10539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine        adb_io_completion->overlapped());
10639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    }
10739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
10839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    if (NULL != bytes_transferred) {
10939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      *bytes_transferred = transferred;
11039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    }
11139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
11239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ULONG error = GetLastError();
11339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    if (!res && (ERROR_IO_PENDING != error)) {
11439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      // I/O failed immediatelly. We need to close i/o completion object
11539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      // before we return NULL to the caller.
11639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      adb_io_completion->CloseHandle();
11739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      ret = NULL;
11839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      SetLastError(error);
11939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    }
12039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
12139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
12239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // Offseting 'new'
12339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  adb_io_completion->Release();
12439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
12539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  return ret;
12639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine}
12739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
12839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkinebool AdbLegacyEndpointObject::CommonSyncReadWrite(bool is_read,
12939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                                  void* buffer,
13039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                                  ULONG bytes_to_transfer,
13139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                                  ULONG* bytes_transferred,
13239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                                  ULONG time_out) {
13339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (NULL != bytes_transferred) {
13439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    *bytes_transferred = 0;
13539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
13639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
13739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (!IsOpened()) {
13839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    SetLastError(ERROR_INVALID_HANDLE);
13939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    return false;
14039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
14139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
14239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  bool is_ioctl_write = is_read ? false : (0 != time_out);
14339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
14439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // This is synchronous I/O. Since we always open I/O items for
14539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // overlapped I/O we're obligated to always provide OVERLAPPED
14639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // structure to read / write routines. Prepare it now.
14739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  OVERLAPPED overlapped;
14839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  ZeroMemory(&overlapped, sizeof(overlapped));
14939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
15039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  BOOL ret = TRUE;
15139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  ULONG ioctl_write_transferred = 0;
15239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (0 == time_out) {
15339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    // Go the read / write file way
15439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ret = is_read ?
15539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      ReadFile(usb_handle(), buffer, bytes_to_transfer, bytes_transferred, &overlapped) :
15639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      WriteFile(usb_handle(), buffer, bytes_to_transfer, bytes_transferred, &overlapped);
15739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  } else {
15839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    // Go IOCTL way
15939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    AdbBulkTransfer transfer_param;
16039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    transfer_param.time_out = time_out;
16139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    transfer_param.transfer_size = is_read ? 0 : bytes_to_transfer;
16239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    transfer_param.SetWriteBuffer(is_read ? NULL : buffer);
16339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
16439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ULONG tmp;
16539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ret = DeviceIoControl(usb_handle(),
16639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      is_read ? ADB_IOCTL_BULK_READ : ADB_IOCTL_BULK_WRITE,
16739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      &transfer_param, sizeof(transfer_param),
16839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      is_read ? buffer : &ioctl_write_transferred,
16939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      is_read ? bytes_to_transfer : sizeof(ULONG),
17039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      &tmp,
17139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine      &overlapped);
17239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
17339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
17439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // Lets see the result
17539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (!ret && (ERROR_IO_PENDING != GetLastError())) {
17639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    // I/O failed.
17739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    return false;
17839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
17939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
18039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // Lets wait till I/O completes
18139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  ULONG transferred = 0;
18239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  ret = GetOverlappedResult(usb_handle(), &overlapped, &transferred, TRUE);
18339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (ret && (NULL != bytes_transferred)) {
18439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    *bytes_transferred = is_ioctl_write ? ioctl_write_transferred :
18539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                                          transferred;
18639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
18739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
18839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  return ret ? true : false;
18939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine}
19039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
19139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkineADBAPIHANDLE AdbLegacyEndpointObject::CreateHandle(
19239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    const wchar_t* item_path,
19339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    AdbOpenAccessType access_type,
19439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    AdbOpenSharingMode share_mode) {
19539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // Convert access / share parameters into CreateFile - compatible
19639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  ULONG desired_access;
19739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  ULONG desired_sharing;
19839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
19939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (!GetSDKComplientParam(access_type, share_mode,
20039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                            &desired_access, &desired_sharing)) {
20139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    return NULL;
20239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
20339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
20439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // Open USB handle
20539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  usb_handle_ = CreateFile(item_path,
20639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                           desired_access,
20739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                           share_mode,
20839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                           NULL,
20939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                           OPEN_EXISTING,
21039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                           FILE_FLAG_OVERLAPPED,  // Always overlapped!
21139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine                           NULL);
21239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (INVALID_HANDLE_VALUE == usb_handle_) {
21339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    return NULL;
21439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
21539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
21639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  // Create ADB handle
21739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  ADBAPIHANDLE ret = AdbObjectHandle::CreateHandle();
21839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
21939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (NULL == ret) {
22039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    // If creation of ADB handle failed we have to close USB handle too.
22139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ULONG error = GetLastError();
22239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ::CloseHandle(usb_handle());
22339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    usb_handle_ = INVALID_HANDLE_VALUE;
22439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    SetLastError(error);
22539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
22639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
22739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  return ret;
22839164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine}
22939164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
23039164844f16c2c63d52a71652d53b233c5f28e14vchtchetkinebool AdbLegacyEndpointObject::CloseHandle() {
23139164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  if (INVALID_HANDLE_VALUE != usb_handle_) {
23239164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    ::CloseHandle(usb_handle_);
23339164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine    usb_handle_ = INVALID_HANDLE_VALUE;
23439164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  }
23539164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine
23639164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine  return AdbEndpointObject::CloseHandle();
23739164844f16c2c63d52a71652d53b233c5f28e14vchtchetkine}
238