diff options
Diffstat (limited to 'host/windows/usb/api/adb_winusb_endpoint_object.cpp')
| -rwxr-xr-x | host/windows/usb/api/adb_winusb_endpoint_object.cpp | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/host/windows/usb/api/adb_winusb_endpoint_object.cpp b/host/windows/usb/api/adb_winusb_endpoint_object.cpp new file mode 100755 index 000000000..236de3b49 --- /dev/null +++ b/host/windows/usb/api/adb_winusb_endpoint_object.cpp @@ -0,0 +1,159 @@ +/*
+ * Copyright (C) 2009 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 class AdbWinUsbEndpointObject that
+ encapsulates a handle opened to a WinUsb endpoint on our device.
+*/
+
+#include "stdafx.h"
+#include "adb_winusb_endpoint_object.h"
+#include "adb_winusb_io_completion.h"
+#include "adb_helper_routines.h"
+
+AdbWinUsbEndpointObject::AdbWinUsbEndpointObject(
+ AdbWinUsbInterfaceObject* parent_interf,
+ UCHAR endpoint_id,
+ UCHAR endpoint_index)
+ : AdbEndpointObject(parent_interf, endpoint_id, endpoint_index) {
+}
+
+AdbWinUsbEndpointObject::~AdbWinUsbEndpointObject() {
+}
+
+ADBAPIHANDLE AdbWinUsbEndpointObject::CommonAsyncReadWrite(
+ bool is_read,
+ void* buffer,
+ ULONG bytes_to_transfer,
+ ULONG* bytes_transferred,
+ HANDLE event_handle,
+ ULONG time_out) {
+ if (!SetTimeout(time_out))
+ return false;
+
+ // Create completion i/o object
+ AdbIOCompletion* adb_io_completion = NULL;
+
+ try {
+ adb_io_completion = new AdbWinUsbIOCompletion(this,
+ bytes_to_transfer,
+ event_handle);
+ } catch (... ) {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return NULL;
+ }
+
+ // Create a handle for it
+ ADBAPIHANDLE ret = adb_io_completion->CreateHandle();
+ ULONG transferred = 0;
+ if (NULL != ret) {
+ BOOL res = TRUE;
+ // Go the read / write file way
+ res = is_read ?
+ WinUsb_ReadPipe(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(),
+ reinterpret_cast<PUCHAR>(buffer),
+ bytes_to_transfer,
+ &transferred,
+ adb_io_completion->overlapped()) :
+ WinUsb_WritePipe(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(),
+ reinterpret_cast<PUCHAR>(buffer),
+ bytes_to_transfer,
+ &transferred,
+ adb_io_completion->overlapped());
+
+ if (NULL != bytes_transferred)
+ *bytes_transferred = transferred;
+
+ ULONG error = GetLastError();
+ if (!res && (ERROR_IO_PENDING != error)) {
+ // I/O failed immediatelly. We need to close i/o completion object
+ // before we return NULL to the caller.
+ adb_io_completion->CloseHandle();
+ ret = NULL;
+ SetLastError(error);
+ }
+ }
+
+ // Offseting 'new'
+ adb_io_completion->Release();
+
+ return ret;
+}
+
+bool AdbWinUsbEndpointObject::CommonSyncReadWrite(bool is_read,
+ void* buffer,
+ ULONG bytes_to_transfer,
+ ULONG* bytes_transferred,
+ ULONG time_out) {
+ if (!SetTimeout(time_out))
+ return false;
+
+ // This is synchronous I/O. Since we always open I/O items for
+ // overlapped I/O we're obligated to always provide OVERLAPPED
+ // structure to read / write routines. Prepare it now.
+ OVERLAPPED overlapped;
+ ZeroMemory(&overlapped, sizeof(overlapped));
+ overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ BOOL ret = TRUE;
+ ULONG transferred = 0;
+ // Go the read / write file way
+ ret = is_read ?
+ WinUsb_ReadPipe(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(),
+ reinterpret_cast<PUCHAR>(buffer),
+ bytes_to_transfer,
+ &transferred,
+ &overlapped) :
+ WinUsb_WritePipe(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(),
+ reinterpret_cast<PUCHAR>(buffer),
+ bytes_to_transfer,
+ &transferred,
+ &overlapped);
+
+ // Lets see the result
+ if (!ret && (ERROR_IO_PENDING != GetLastError())) {
+ // I/O failed.
+ if (NULL != overlapped.hEvent)
+ ::CloseHandle(overlapped.hEvent);
+ return false;
+ }
+
+ // Lets wait till I/O completes
+ ret = WinUsb_GetOverlappedResult(parent_winusb_interface()->winusb_handle(), &overlapped,
+ &transferred, TRUE);
+ if (ret && (NULL != bytes_transferred)) {
+ *bytes_transferred = transferred;
+ }
+
+ if (NULL != overlapped.hEvent)
+ ::CloseHandle(overlapped.hEvent);
+
+ return ret ? true : false;
+}
+
+bool AdbWinUsbEndpointObject::SetTimeout(ULONG timeout) {
+ if (!WinUsb_SetPipePolicy(parent_winusb_interface()->winusb_handle(),
+ endpoint_id(), PIPE_TRANSFER_TIMEOUT,
+ sizeof(ULONG), &timeout)) {
+ return false;
+ }
+
+ return true;
+}
|
