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