18267511c96e3226e45a0be773ee442b66261824dvchtchetkine/* 28267511c96e3226e45a0be773ee442b66261824dvchtchetkine * Copyright (C) 2009 The Android Open Source Project 38267511c96e3226e45a0be773ee442b66261824dvchtchetkine * 48267511c96e3226e45a0be773ee442b66261824dvchtchetkine * Licensed under the Apache License, Version 2.0 (the "License"); 58267511c96e3226e45a0be773ee442b66261824dvchtchetkine * you may not use this file except in compliance with the License. 68267511c96e3226e45a0be773ee442b66261824dvchtchetkine * You may obtain a copy of the License at 78267511c96e3226e45a0be773ee442b66261824dvchtchetkine * 88267511c96e3226e45a0be773ee442b66261824dvchtchetkine * http://www.apache.org/licenses/LICENSE-2.0 98267511c96e3226e45a0be773ee442b66261824dvchtchetkine * 108267511c96e3226e45a0be773ee442b66261824dvchtchetkine * Unless required by applicable law or agreed to in writing, software 118267511c96e3226e45a0be773ee442b66261824dvchtchetkine * distributed under the License is distributed on an "AS IS" BASIS, 128267511c96e3226e45a0be773ee442b66261824dvchtchetkine * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138267511c96e3226e45a0be773ee442b66261824dvchtchetkine * See the License for the specific language governing permissions and 148267511c96e3226e45a0be773ee442b66261824dvchtchetkine * limitations under the License. 158267511c96e3226e45a0be773ee442b66261824dvchtchetkine */ 168267511c96e3226e45a0be773ee442b66261824dvchtchetkine 178267511c96e3226e45a0be773ee442b66261824dvchtchetkine/** \file 188267511c96e3226e45a0be773ee442b66261824dvchtchetkine This file consists of implementation of class AdbWinUsbEndpointObject that 198267511c96e3226e45a0be773ee442b66261824dvchtchetkine encapsulates a handle opened to a WinUsb endpoint on our device. 208267511c96e3226e45a0be773ee442b66261824dvchtchetkine*/ 218267511c96e3226e45a0be773ee442b66261824dvchtchetkine 228267511c96e3226e45a0be773ee442b66261824dvchtchetkine#include "stdafx.h" 238267511c96e3226e45a0be773ee442b66261824dvchtchetkine#include "adb_winusb_endpoint_object.h" 248267511c96e3226e45a0be773ee442b66261824dvchtchetkine#include "adb_winusb_io_completion.h" 258267511c96e3226e45a0be773ee442b66261824dvchtchetkine 268267511c96e3226e45a0be773ee442b66261824dvchtchetkineAdbWinUsbEndpointObject::AdbWinUsbEndpointObject( 278267511c96e3226e45a0be773ee442b66261824dvchtchetkine AdbWinUsbInterfaceObject* parent_interf, 288267511c96e3226e45a0be773ee442b66261824dvchtchetkine UCHAR endpoint_id, 298267511c96e3226e45a0be773ee442b66261824dvchtchetkine UCHAR endpoint_index) 308267511c96e3226e45a0be773ee442b66261824dvchtchetkine : AdbEndpointObject(parent_interf, endpoint_id, endpoint_index) { 318267511c96e3226e45a0be773ee442b66261824dvchtchetkine} 328267511c96e3226e45a0be773ee442b66261824dvchtchetkine 338267511c96e3226e45a0be773ee442b66261824dvchtchetkineAdbWinUsbEndpointObject::~AdbWinUsbEndpointObject() { 348267511c96e3226e45a0be773ee442b66261824dvchtchetkine} 358267511c96e3226e45a0be773ee442b66261824dvchtchetkine 36acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkineLONG AdbWinUsbEndpointObject::Release() { 37acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine ATLASSERT(ref_count_ > 0); 38acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine LONG ret = InterlockedDecrement(&ref_count_); 39acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine ATLASSERT(ret >= 0); 40acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine if (0 == ret) { 41acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine LastReferenceReleased(); 42acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine delete this; 43acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine } 44acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine return ret; 45acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine} 46acc6f826433e639b1ba00c021ab5f9161eb56e59vchtchetkine 478267511c96e3226e45a0be773ee442b66261824dvchtchetkineADBAPIHANDLE AdbWinUsbEndpointObject::CommonAsyncReadWrite( 488267511c96e3226e45a0be773ee442b66261824dvchtchetkine bool is_read, 498267511c96e3226e45a0be773ee442b66261824dvchtchetkine void* buffer, 508267511c96e3226e45a0be773ee442b66261824dvchtchetkine ULONG bytes_to_transfer, 518267511c96e3226e45a0be773ee442b66261824dvchtchetkine ULONG* bytes_transferred, 528267511c96e3226e45a0be773ee442b66261824dvchtchetkine HANDLE event_handle, 538267511c96e3226e45a0be773ee442b66261824dvchtchetkine ULONG time_out) { 548267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (!SetTimeout(time_out)) 558267511c96e3226e45a0be773ee442b66261824dvchtchetkine return false; 568267511c96e3226e45a0be773ee442b66261824dvchtchetkine 578267511c96e3226e45a0be773ee442b66261824dvchtchetkine // Create completion i/o object 588267511c96e3226e45a0be773ee442b66261824dvchtchetkine AdbIOCompletion* adb_io_completion = NULL; 598267511c96e3226e45a0be773ee442b66261824dvchtchetkine 608267511c96e3226e45a0be773ee442b66261824dvchtchetkine try { 618267511c96e3226e45a0be773ee442b66261824dvchtchetkine adb_io_completion = new AdbWinUsbIOCompletion(this, 628267511c96e3226e45a0be773ee442b66261824dvchtchetkine bytes_to_transfer, 638267511c96e3226e45a0be773ee442b66261824dvchtchetkine event_handle); 648267511c96e3226e45a0be773ee442b66261824dvchtchetkine } catch (... ) { 658267511c96e3226e45a0be773ee442b66261824dvchtchetkine SetLastError(ERROR_OUTOFMEMORY); 668267511c96e3226e45a0be773ee442b66261824dvchtchetkine return NULL; 678267511c96e3226e45a0be773ee442b66261824dvchtchetkine } 688267511c96e3226e45a0be773ee442b66261824dvchtchetkine 698267511c96e3226e45a0be773ee442b66261824dvchtchetkine // Create a handle for it 708267511c96e3226e45a0be773ee442b66261824dvchtchetkine ADBAPIHANDLE ret = adb_io_completion->CreateHandle(); 718267511c96e3226e45a0be773ee442b66261824dvchtchetkine ULONG transferred = 0; 728267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (NULL != ret) { 738267511c96e3226e45a0be773ee442b66261824dvchtchetkine BOOL res = TRUE; 748267511c96e3226e45a0be773ee442b66261824dvchtchetkine // Go the read / write file way 758267511c96e3226e45a0be773ee442b66261824dvchtchetkine res = is_read ? 768267511c96e3226e45a0be773ee442b66261824dvchtchetkine WinUsb_ReadPipe(parent_winusb_interface()->winusb_handle(), 778267511c96e3226e45a0be773ee442b66261824dvchtchetkine endpoint_id(), 788267511c96e3226e45a0be773ee442b66261824dvchtchetkine reinterpret_cast<PUCHAR>(buffer), 798267511c96e3226e45a0be773ee442b66261824dvchtchetkine bytes_to_transfer, 808267511c96e3226e45a0be773ee442b66261824dvchtchetkine &transferred, 818267511c96e3226e45a0be773ee442b66261824dvchtchetkine adb_io_completion->overlapped()) : 828267511c96e3226e45a0be773ee442b66261824dvchtchetkine WinUsb_WritePipe(parent_winusb_interface()->winusb_handle(), 838267511c96e3226e45a0be773ee442b66261824dvchtchetkine endpoint_id(), 848267511c96e3226e45a0be773ee442b66261824dvchtchetkine reinterpret_cast<PUCHAR>(buffer), 858267511c96e3226e45a0be773ee442b66261824dvchtchetkine bytes_to_transfer, 868267511c96e3226e45a0be773ee442b66261824dvchtchetkine &transferred, 878267511c96e3226e45a0be773ee442b66261824dvchtchetkine adb_io_completion->overlapped()); 888267511c96e3226e45a0be773ee442b66261824dvchtchetkine 898267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (NULL != bytes_transferred) 908267511c96e3226e45a0be773ee442b66261824dvchtchetkine *bytes_transferred = transferred; 918267511c96e3226e45a0be773ee442b66261824dvchtchetkine 928267511c96e3226e45a0be773ee442b66261824dvchtchetkine ULONG error = GetLastError(); 938267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (!res && (ERROR_IO_PENDING != error)) { 948267511c96e3226e45a0be773ee442b66261824dvchtchetkine // I/O failed immediatelly. We need to close i/o completion object 958267511c96e3226e45a0be773ee442b66261824dvchtchetkine // before we return NULL to the caller. 968267511c96e3226e45a0be773ee442b66261824dvchtchetkine adb_io_completion->CloseHandle(); 978267511c96e3226e45a0be773ee442b66261824dvchtchetkine ret = NULL; 988267511c96e3226e45a0be773ee442b66261824dvchtchetkine SetLastError(error); 998267511c96e3226e45a0be773ee442b66261824dvchtchetkine } 1008267511c96e3226e45a0be773ee442b66261824dvchtchetkine } 1018267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1028267511c96e3226e45a0be773ee442b66261824dvchtchetkine // Offseting 'new' 1038267511c96e3226e45a0be773ee442b66261824dvchtchetkine adb_io_completion->Release(); 1048267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1058267511c96e3226e45a0be773ee442b66261824dvchtchetkine return ret; 1068267511c96e3226e45a0be773ee442b66261824dvchtchetkine} 1078267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1088267511c96e3226e45a0be773ee442b66261824dvchtchetkinebool AdbWinUsbEndpointObject::CommonSyncReadWrite(bool is_read, 1098267511c96e3226e45a0be773ee442b66261824dvchtchetkine void* buffer, 1108267511c96e3226e45a0be773ee442b66261824dvchtchetkine ULONG bytes_to_transfer, 1118267511c96e3226e45a0be773ee442b66261824dvchtchetkine ULONG* bytes_transferred, 1128267511c96e3226e45a0be773ee442b66261824dvchtchetkine ULONG time_out) { 1138267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (!SetTimeout(time_out)) 1148267511c96e3226e45a0be773ee442b66261824dvchtchetkine return false; 1158267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1168267511c96e3226e45a0be773ee442b66261824dvchtchetkine // This is synchronous I/O. Since we always open I/O items for 1178267511c96e3226e45a0be773ee442b66261824dvchtchetkine // overlapped I/O we're obligated to always provide OVERLAPPED 1188267511c96e3226e45a0be773ee442b66261824dvchtchetkine // structure to read / write routines. Prepare it now. 1198267511c96e3226e45a0be773ee442b66261824dvchtchetkine OVERLAPPED overlapped; 1208267511c96e3226e45a0be773ee442b66261824dvchtchetkine ZeroMemory(&overlapped, sizeof(overlapped)); 1218267511c96e3226e45a0be773ee442b66261824dvchtchetkine overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1228267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1238267511c96e3226e45a0be773ee442b66261824dvchtchetkine BOOL ret = TRUE; 1248267511c96e3226e45a0be773ee442b66261824dvchtchetkine ULONG transferred = 0; 1258267511c96e3226e45a0be773ee442b66261824dvchtchetkine // Go the read / write file way 1268267511c96e3226e45a0be773ee442b66261824dvchtchetkine ret = is_read ? 1278267511c96e3226e45a0be773ee442b66261824dvchtchetkine WinUsb_ReadPipe(parent_winusb_interface()->winusb_handle(), 1288267511c96e3226e45a0be773ee442b66261824dvchtchetkine endpoint_id(), 1298267511c96e3226e45a0be773ee442b66261824dvchtchetkine reinterpret_cast<PUCHAR>(buffer), 1308267511c96e3226e45a0be773ee442b66261824dvchtchetkine bytes_to_transfer, 1318267511c96e3226e45a0be773ee442b66261824dvchtchetkine &transferred, 1328267511c96e3226e45a0be773ee442b66261824dvchtchetkine &overlapped) : 1338267511c96e3226e45a0be773ee442b66261824dvchtchetkine WinUsb_WritePipe(parent_winusb_interface()->winusb_handle(), 1348267511c96e3226e45a0be773ee442b66261824dvchtchetkine endpoint_id(), 1358267511c96e3226e45a0be773ee442b66261824dvchtchetkine reinterpret_cast<PUCHAR>(buffer), 1368267511c96e3226e45a0be773ee442b66261824dvchtchetkine bytes_to_transfer, 1378267511c96e3226e45a0be773ee442b66261824dvchtchetkine &transferred, 1388267511c96e3226e45a0be773ee442b66261824dvchtchetkine &overlapped); 1398267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1408267511c96e3226e45a0be773ee442b66261824dvchtchetkine // Lets see the result 1418267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (!ret && (ERROR_IO_PENDING != GetLastError())) { 1428267511c96e3226e45a0be773ee442b66261824dvchtchetkine // I/O failed. 1438267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (NULL != overlapped.hEvent) 1448267511c96e3226e45a0be773ee442b66261824dvchtchetkine ::CloseHandle(overlapped.hEvent); 1458267511c96e3226e45a0be773ee442b66261824dvchtchetkine return false; 1468267511c96e3226e45a0be773ee442b66261824dvchtchetkine } 1478267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1488267511c96e3226e45a0be773ee442b66261824dvchtchetkine // Lets wait till I/O completes 1498267511c96e3226e45a0be773ee442b66261824dvchtchetkine ret = WinUsb_GetOverlappedResult(parent_winusb_interface()->winusb_handle(), &overlapped, 1508267511c96e3226e45a0be773ee442b66261824dvchtchetkine &transferred, TRUE); 1518267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (ret && (NULL != bytes_transferred)) { 1528267511c96e3226e45a0be773ee442b66261824dvchtchetkine *bytes_transferred = transferred; 1538267511c96e3226e45a0be773ee442b66261824dvchtchetkine } 1548267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1558267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (NULL != overlapped.hEvent) 1568267511c96e3226e45a0be773ee442b66261824dvchtchetkine ::CloseHandle(overlapped.hEvent); 1578267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1588267511c96e3226e45a0be773ee442b66261824dvchtchetkine return ret ? true : false; 1598267511c96e3226e45a0be773ee442b66261824dvchtchetkine} 1608267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1618267511c96e3226e45a0be773ee442b66261824dvchtchetkinebool AdbWinUsbEndpointObject::SetTimeout(ULONG timeout) { 1628267511c96e3226e45a0be773ee442b66261824dvchtchetkine if (!WinUsb_SetPipePolicy(parent_winusb_interface()->winusb_handle(), 1638267511c96e3226e45a0be773ee442b66261824dvchtchetkine endpoint_id(), PIPE_TRANSFER_TIMEOUT, 1648267511c96e3226e45a0be773ee442b66261824dvchtchetkine sizeof(ULONG), &timeout)) { 1658267511c96e3226e45a0be773ee442b66261824dvchtchetkine return false; 1668267511c96e3226e45a0be773ee442b66261824dvchtchetkine } 1678267511c96e3226e45a0be773ee442b66261824dvchtchetkine 1688267511c96e3226e45a0be773ee442b66261824dvchtchetkine return true; 1698267511c96e3226e45a0be773ee442b66261824dvchtchetkine} 170