Delete files irrelevant for the new driver model
:x
This commit is contained in:
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_COMMON_DEFINES_H__
|
||||
#define ANDROID_USB_COMMON_DEFINES_H__
|
||||
/** \file
|
||||
This file consists of declarations common for both, User and Kernel mode
|
||||
parts of the system.
|
||||
*/
|
||||
|
||||
/// Name for the default bulk read pipe
|
||||
#define DEVICE_BULK_READ_PIPE_NAME L"BulkRead"
|
||||
|
||||
/// Name for the default bulk write pipe
|
||||
#define DEVICE_BULK_WRITE_PIPE_NAME L"BulkWrite"
|
||||
|
||||
/// Prefix for an index-based pipe name
|
||||
#define DEVICE_PIPE_NAME_PREFIX L"PIPE_"
|
||||
|
||||
/** \name IOCTL codes for the driver
|
||||
*/
|
||||
///@{
|
||||
|
||||
/// Control code for IOCTL that gets USB_DEVICE_DESCRIPTOR
|
||||
#define ADB_CTL_GET_USB_DEVICE_DESCRIPTOR 10
|
||||
|
||||
/// Control code for IOCTL that gets USB_CONFIGURATION_DESCRIPTOR
|
||||
#define ADB_CTL_GET_USB_CONFIGURATION_DESCRIPTOR 11
|
||||
|
||||
/// Control code for IOCTL that gets USB_INTERFACE_DESCRIPTOR
|
||||
#define ADB_CTL_GET_USB_INTERFACE_DESCRIPTOR 12
|
||||
|
||||
/// Control code for IOCTL that gets endpoint information
|
||||
#define ADB_CTL_GET_ENDPOINT_INFORMATION 13
|
||||
|
||||
/// Control code for bulk read IOCTL
|
||||
#define ADB_CTL_BULK_READ 14
|
||||
|
||||
/// Control code for bulk write IOCTL
|
||||
#define ADB_CTL_BULK_WRITE 15
|
||||
|
||||
/// Control code for IOCTL that gets device serial number
|
||||
#define ADB_CTL_GET_SERIAL_NUMBER 16
|
||||
|
||||
/// IOCTL that gets USB_DEVICE_DESCRIPTOR
|
||||
#define ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
||||
ADB_CTL_GET_USB_DEVICE_DESCRIPTOR, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_READ_ACCESS)
|
||||
|
||||
/// IOCTL that gets USB_CONFIGURATION_DESCRIPTOR
|
||||
#define ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
||||
ADB_CTL_GET_USB_CONFIGURATION_DESCRIPTOR, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_READ_ACCESS)
|
||||
|
||||
/// IOCTL that gets USB_INTERFACE_DESCRIPTOR
|
||||
#define ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
||||
ADB_CTL_GET_USB_INTERFACE_DESCRIPTOR, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_READ_ACCESS)
|
||||
|
||||
/// IOCTL that gets endpoint information
|
||||
#define ADB_IOCTL_GET_ENDPOINT_INFORMATION \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
||||
ADB_CTL_GET_ENDPOINT_INFORMATION, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_READ_ACCESS)
|
||||
|
||||
/// Bulk read IOCTL
|
||||
#define ADB_IOCTL_BULK_READ \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
||||
ADB_CTL_BULK_READ, \
|
||||
METHOD_OUT_DIRECT, \
|
||||
FILE_READ_ACCESS)
|
||||
|
||||
// For bulk write IOCTL we send request data in the form of AdbBulkTransfer
|
||||
// structure and output buffer is just ULONG that receives number of bytes
|
||||
// actually written. Since both of these are tiny we can use buffered I/O
|
||||
// for this IOCTL.
|
||||
/// Bulk write IOCTL
|
||||
#define ADB_IOCTL_BULK_WRITE \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
||||
ADB_CTL_BULK_WRITE, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_WRITE_ACCESS)
|
||||
|
||||
/// IOCTL that gets device serial number
|
||||
#define ADB_IOCTL_GET_SERIAL_NUMBER \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
||||
ADB_CTL_GET_SERIAL_NUMBER, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_READ_ACCESS)
|
||||
|
||||
///@}
|
||||
|
||||
/** Structure AdbQueryEndpointInformation formats input for
|
||||
ADB_IOCTL_GET_ENDPOINT_INFORMATION IOCTL request
|
||||
*/
|
||||
struct AdbQueryEndpointInformation {
|
||||
/// Zero-based endpoint index for which information is queried.
|
||||
/// See ADB_QUERY_BULK_xxx_ENDPOINT_INDEX for shortcuts.
|
||||
UCHAR endpoint_index;
|
||||
};
|
||||
|
||||
/** Structure AdbBulkTransfer formats parameters for ADB_CTL_BULK_READ and
|
||||
ADB_CTL_BULK_WRITE IOCTL requests.
|
||||
*/
|
||||
struct AdbBulkTransfer {
|
||||
/// Time in milliseconds to complete this request
|
||||
ULONG time_out;
|
||||
|
||||
/// Size of the data to transfer. This parameter is used only for
|
||||
/// ADB_CTL_BULK_WRITE request. For ADB_CTL_BULK_READ requests transfer
|
||||
/// size is defined by the output buffer size.
|
||||
ULONG transfer_size;
|
||||
|
||||
/// Initializes statically allocated structure
|
||||
__forceinline AdbBulkTransfer() {
|
||||
time_out = 0;
|
||||
transfer_size = 0;
|
||||
for_x64 = 0;
|
||||
}
|
||||
|
||||
/// Provides access to protected write_buffer field
|
||||
void* GetWriteBuffer() {
|
||||
return write_buffer;
|
||||
}
|
||||
|
||||
/// Provides access to protected write_buffer field
|
||||
const void* GetWriteBuffer() const {
|
||||
return write_buffer;
|
||||
}
|
||||
|
||||
/// Sets write_buffer field.
|
||||
void SetWriteBuffer(void* buffer) {
|
||||
// For 32-bit we must zero out high 32 bit of the address, so 64-bit
|
||||
// driver will see valid address when accessing 64-bit write_buffer.
|
||||
for_x64 = 0;
|
||||
write_buffer = buffer;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Pointer to the actual buffer for ADB_CTL_BULK_WRITE request. This field
|
||||
/// is not used in ADB_CTL_BULK_READ request. Note that in order to support
|
||||
/// compatibility between 32-bit and 64-bit versions of both, driver and
|
||||
/// application we must sizeof this field to the max pointer sizeof (which
|
||||
/// is 64 bit in our case). The idea is that if IOCTL was issued by a 64-bit
|
||||
/// process to a 64-bit driver, write_buffer will be valid 64-bit pointer to
|
||||
/// the write buffer. Same is true for 32-bit app talking to 32-bit driver.
|
||||
/// If, however, a 32-bit app is talking to 64-bit driver, then write_buffer
|
||||
/// initialized by 32-bit app will contain 32-bit address, which will be
|
||||
/// correctly picked up ("extended") by 64-bit driver. Since when setting
|
||||
/// this field by a 32-bit app requires some extra work (see SetWriteBuffer)
|
||||
/// we hide this field, making it accessible only throug the accessor
|
||||
/// methods (Get/SetWriteBuffer).
|
||||
union {
|
||||
void* write_buffer;
|
||||
__int64 for_x64;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // ANDROID_USB_COMMON_DEFINES_H__
|
||||
@@ -1,126 +0,0 @@
|
||||
;/*++
|
||||
;
|
||||
;Abstract:
|
||||
; Installation inf for the Android USB Bulk device
|
||||
;
|
||||
;--*/
|
||||
|
||||
[Version]
|
||||
Signature="$WINDOWS NT$"
|
||||
Class=USB
|
||||
ClassGuid={F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}
|
||||
Provider=%GOOG%
|
||||
DriverVer=1/29/2009,1.0.0010.00000
|
||||
CatalogFile.NTx86=androidusb86.cat
|
||||
CatalogFile.NTamd64=androidusba64.cat
|
||||
|
||||
; ================= Class section =====================
|
||||
|
||||
[ClassInstall32]
|
||||
Addreg=AndroidUsbClassReg
|
||||
|
||||
[AndroidUsbClassReg]
|
||||
HKR,,,0,%ClassName%
|
||||
HKR,,Icon,,-5
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir = 12
|
||||
|
||||
; ================= Device section =====================
|
||||
|
||||
[Manufacturer]
|
||||
%MfgName%=Google,NTx86,NTamd64
|
||||
|
||||
; For Win2K
|
||||
[Google]
|
||||
; For loopback testing
|
||||
%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
|
||||
; HTC Dream
|
||||
%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
|
||||
%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
|
||||
%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
|
||||
|
||||
; For XP and later
|
||||
[Google.NTx86]
|
||||
; For loopback testing
|
||||
%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
|
||||
; HTC Dream
|
||||
%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
|
||||
%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
|
||||
%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
|
||||
|
||||
; For AMD64 and later
|
||||
[Google.NTamd64]
|
||||
; For loopback testing
|
||||
%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
|
||||
; HTC Dream
|
||||
%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
|
||||
%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
|
||||
%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
|
||||
|
||||
[androidusb.Dev.NT]
|
||||
CopyFiles=androidusb.Files.Ext
|
||||
|
||||
[androidusb.Dev.NT.Services]
|
||||
Addservice = androidusb, 0x00000002, androidusb.AddService
|
||||
|
||||
[androidusb.AddService]
|
||||
DisplayName = %androidusb.SvcDesc%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 3 ; SERVICE_DEMAND_START
|
||||
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
|
||||
ServiceBinary = %10%\System32\Drivers\androidusb.sys
|
||||
AddReg = androidusb.AddReg
|
||||
LoadOrderGroup = Base
|
||||
|
||||
[androidusb.AddReg]
|
||||
HKR,"Parameters","MaximumTransferSize",0x10001,4096
|
||||
HKR,"Parameters","DebugLevel",0x10001,2
|
||||
HKR, Parameters\Wdf, VerboseOn, 0x00010001, 1
|
||||
HKR, Parameters\Wdf, VerifierOn, 0x00010001, 1
|
||||
HKR, Parameters\Wdf, DbgBreakOnError, 0x00010001, 1
|
||||
|
||||
[androidusb.Files.Ext]
|
||||
androidusb.sys
|
||||
|
||||
[SourceDisksNames]
|
||||
1=%Disk_Description%,,,
|
||||
|
||||
[SourceDisksFiles]
|
||||
androidusb.sys = 1
|
||||
|
||||
;-------------- WDF Coinstaller installation
|
||||
[DestinationDirs]
|
||||
CoInstaller_CopyFiles = 11
|
||||
|
||||
[androidusb.Dev.NT.CoInstallers]
|
||||
AddReg=CoInstaller_AddReg
|
||||
CopyFiles=CoInstaller_CopyFiles
|
||||
|
||||
[CoInstaller_CopyFiles]
|
||||
wdfcoinstaller01005.dll
|
||||
|
||||
[SourceDisksFiles]
|
||||
wdfcoinstaller01005.dll=1 ; make sure the number matches with SourceDisksNames
|
||||
|
||||
[CoInstaller_AddReg]
|
||||
HKR,,CoInstallers32,0x00010000, "wdfcoinstaller01005.dll,WdfCoInstaller"
|
||||
|
||||
[androidusb.Dev.NT.Wdf]
|
||||
KmdfService = androidusb, androidusb_wdfsect
|
||||
|
||||
[androidusb_wdfsect]
|
||||
KmdfLibraryVersion = 1.5
|
||||
|
||||
;---------------------------------------------------------------;
|
||||
|
||||
[Strings]
|
||||
GOOG = "Google, Inc"
|
||||
MfgName = "Google, Inc"
|
||||
Disk_Description= "ADB Interface Installation Disk"
|
||||
androidusb.SvcDesc = "ADB Interface Driver"
|
||||
ClassName = "ADB Interface"
|
||||
USB\VID_18D1&PID_DDDD.DeviceDescTest="ADB Testing Interface"
|
||||
USB\VID_0BB4&PID_0C01.DeviceDescRelease="HTC Dream"
|
||||
USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease="HTC Dream Composite ADB Interface"
|
||||
USB\VID_0BB4&PID_0FFF.DeviceDescRelease="HTC Bootloader"
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// Don't let the resource editor in here
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#error this file is not editable by Visual C++
|
||||
#endif //APSTUDIO_INVOKED
|
||||
|
||||
|
||||
#define VER_FILETYPE VFT_DRV
|
||||
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
|
||||
#define VER_FILEDESCRIPTION_STR "ADB Interface"
|
||||
#define VER_INTERNALNAME_STR "androidusb.sys"
|
||||
#define VER_ORIGINALFILENAME_STR "androidusb.sys"
|
||||
#define VER_FILEOS VOS_NT
|
||||
#define VER_FILEFLAGSMASK (VS_FF_DEBUG | VS_FF_PRERELEASE)
|
||||
|
||||
#if DBG
|
||||
#define VER_FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE
|
||||
#else // DBG
|
||||
#define VER_FILEFLAGS VS_FF_PRERELEASE
|
||||
#endif // DBG
|
||||
|
||||
#include "common.ver"
|
||||
@@ -1,27 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "android_usb", "android_usb.vcproj", "{D980BE56-A7AB-4E05-919B-677FB7716307}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Debug-64 = Debug-64
|
||||
Release = Release
|
||||
Release-64 = Release-64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{D980BE56-A7AB-4E05-919B-677FB7716307}.Debug.ActiveCfg = Debug|Win32
|
||||
{D980BE56-A7AB-4E05-919B-677FB7716307}.Debug.Build.0 = Debug|Win32
|
||||
{D980BE56-A7AB-4E05-919B-677FB7716307}.Debug-64.ActiveCfg = Debug-64|Win32
|
||||
{D980BE56-A7AB-4E05-919B-677FB7716307}.Debug-64.Build.0 = Debug-64|Win32
|
||||
{D980BE56-A7AB-4E05-919B-677FB7716307}.Release.ActiveCfg = Release|Win32
|
||||
{D980BE56-A7AB-4E05-919B-677FB7716307}.Release.Build.0 = Release|Win32
|
||||
{D980BE56-A7AB-4E05-919B-677FB7716307}.Release-64.ActiveCfg = Release-64|Win32
|
||||
{D980BE56-A7AB-4E05-919B-677FB7716307}.Release-64.Build.0 = Release-64|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 AndroidUsbBulkPipeFileObject
|
||||
that encapsulates extension to a bulk pipe file objects.
|
||||
*/
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
|
||||
#include "precomp.h"
|
||||
#include "android_usb_bulk_file_object.h"
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
AndroidUsbBulkPipeFileObject::AndroidUsbBulkPipeFileObject(
|
||||
AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo,
|
||||
WDFUSBPIPE wdf_pipe_obj)
|
||||
: AndroidUsbPipeFileObject(dev_obj, wdf_fo, wdf_pipe_obj) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
|
||||
#if DBG
|
||||
WDF_USB_PIPE_INFORMATION pipe_info;
|
||||
WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
|
||||
WdfUsbTargetPipeGetInformation(wdf_pipe_obj, &pipe_info);
|
||||
ASSERT(WdfUsbPipeTypeBulk == pipe_info.PipeType);
|
||||
#endif // DBG
|
||||
}
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
AndroidUsbBulkPipeFileObject::~AndroidUsbBulkPipeFileObject() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
}
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_BULK_PIPE_FILE_OBJECT_H__
|
||||
#define ANDROID_USB_BULK_PIPE_FILE_OBJECT_H__
|
||||
/** \file
|
||||
This file consists of declaration of class AndroidUsbBulkPipeFileObject
|
||||
that encapsulates extension to a bulk pipe file objects.
|
||||
*/
|
||||
|
||||
#include "android_usb_pipe_file_object.h"
|
||||
|
||||
/** AndroidUsbBulkPipeFileObject class encapsulates extension to a KMDF file
|
||||
object that represent opened bulk pipe. Instances of this class must be
|
||||
allocated from NonPagedPool.
|
||||
*/
|
||||
class AndroidUsbBulkPipeFileObject : public AndroidUsbPipeFileObject {
|
||||
public:
|
||||
/** \brief Constructs the object.
|
||||
|
||||
This method must be called at low IRQL.
|
||||
@param dev_obj[in] Our device object for which this file has been created
|
||||
@param wdf_fo[in] KMDF file object this extension wraps
|
||||
@param wdf_pipe_obj[in] KMDF pipe for this file
|
||||
*/
|
||||
AndroidUsbBulkPipeFileObject(AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo,
|
||||
WDFUSBPIPE wdf_pipe_obj);
|
||||
|
||||
/** \brief Destructs the object.
|
||||
|
||||
This method can be called at any IRQL.
|
||||
*/
|
||||
virtual ~AndroidUsbBulkPipeFileObject();
|
||||
};
|
||||
|
||||
#endif // ANDROID_USB_BULK_PIPE_FILE_OBJECT_H__
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 AndroidUsbDeviceFileObject
|
||||
that encapsulates an extension for a KMDF file object that represent
|
||||
opened device.
|
||||
*/
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
|
||||
#include "precomp.h"
|
||||
#include "android_usb_device_file_object.h"
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
AndroidUsbDeviceFileObject::AndroidUsbDeviceFileObject(
|
||||
AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo)
|
||||
: AndroidUsbFileObject(AndroidUsbFileObjectTypeDevice, dev_obj, wdf_fo) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
}
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
AndroidUsbDeviceFileObject::~AndroidUsbDeviceFileObject() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
}
|
||||
|
||||
void AndroidUsbDeviceFileObject::OnEvtIoDeviceControl(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len,
|
||||
ULONG ioctl_code) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
switch (ioctl_code) {
|
||||
case ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR:
|
||||
device_object()->OnGetUsbDeviceDescriptorCtl(request, output_buf_len);
|
||||
break;
|
||||
|
||||
case ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR:
|
||||
device_object()->OnGetUsbConfigDescriptorCtl(request, output_buf_len);
|
||||
break;
|
||||
|
||||
case ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR:
|
||||
device_object()->OnGetUsbInterfaceDescriptorCtl(request, output_buf_len);
|
||||
break;
|
||||
|
||||
case ADB_IOCTL_GET_ENDPOINT_INFORMATION:
|
||||
device_object()->OnGetEndpointInformationCtl(request,
|
||||
input_buf_len,
|
||||
output_buf_len);
|
||||
break;
|
||||
|
||||
case ADB_IOCTL_GET_SERIAL_NUMBER:
|
||||
device_object()->OnGetSerialNumberCtl(request, output_buf_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
AndroidUsbFileObject::OnEvtIoDeviceControl(request,
|
||||
output_buf_len,
|
||||
input_buf_len,
|
||||
ioctl_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_DEVICE_FILE_OBJECT_H__
|
||||
#define ANDROID_USB_DEVICE_FILE_OBJECT_H__
|
||||
/** \file
|
||||
This file consists of declaration of class AndroidUsbDeviceFileObject that
|
||||
encapsulates an extension for a KMDF file object that represent opened
|
||||
device.
|
||||
*/
|
||||
|
||||
#include "android_usb_file_object.h"
|
||||
|
||||
/** AndroidUsbDeviceFileObject class encapsulates an extension for a KMDF
|
||||
file object that represent opened device. Instances of this class must be
|
||||
allocated from NonPagedPool.
|
||||
*/
|
||||
class AndroidUsbDeviceFileObject : public AndroidUsbFileObject {
|
||||
public:
|
||||
/** \brief Constructs the object.
|
||||
|
||||
This method must be called at low IRQL.
|
||||
@param dev_obj[in] Our device object for which this file has been created
|
||||
@param wdf_fo[in] KMDF file object this extension wraps
|
||||
*/
|
||||
AndroidUsbDeviceFileObject(AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo);
|
||||
|
||||
/** \brief Destructs the object.
|
||||
|
||||
This method can be called at any IRQL.
|
||||
*/
|
||||
virtual ~AndroidUsbDeviceFileObject();
|
||||
|
||||
/** \brief IOCTL event handler
|
||||
|
||||
This method is called when a device control request comes to the file
|
||||
object this extension wraps. We override this method to handle the
|
||||
following IOCTL requests:
|
||||
1. ADB_CTL_GET_USB_DEVICE_DESCRIPTOR
|
||||
2. ADB_CTL_GET_USB_CONFIGURATION_DESCRIPTOR
|
||||
3. ADB_CTL_GET_USB_INTERFACE_DESCRIPTOR
|
||||
4. ADB_CTL_GET_ENDPOINT_INFORMATION
|
||||
This callback can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
@param input_buf_len[in] The length, in bytes, of the request's input
|
||||
buffer, if an input buffer is available.
|
||||
@param ioctl_code[in] The driver-defined or system-defined I/O control code
|
||||
that is associated with the request.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
virtual void OnEvtIoDeviceControl(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len,
|
||||
ULONG ioctl_code);
|
||||
};
|
||||
|
||||
#endif // ANDROID_USB_DEVICE_FILE_OBJECT_H__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,603 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_DEVICE_OBJECT_H__
|
||||
#define ANDROID_USB_DEVICE_OBJECT_H__
|
||||
/** \file
|
||||
This file consists of declaration of class AndroidUsbDeviceObject that
|
||||
encapsulates an extension for KMDF device (FDO) object.
|
||||
*/
|
||||
|
||||
#include "android_usb_wdf_object.h"
|
||||
|
||||
// Forward declaration for file object extension
|
||||
class AndroidUsbFileObject;
|
||||
|
||||
/** AndroidUsbDeviceObject class encapsulates an extension for KMDF FDO device
|
||||
object. Instances of this class must be allocated from NonPagedPool.
|
||||
*/
|
||||
class AndroidUsbDeviceObject : public AndroidUsbWdfObject {
|
||||
public:
|
||||
/** \brief Constructs the object.
|
||||
|
||||
This method must be called at low IRQL.
|
||||
*/
|
||||
AndroidUsbDeviceObject();
|
||||
|
||||
/** \brief Destructs the object.
|
||||
|
||||
This method can be called at any IRQL.
|
||||
*/
|
||||
~AndroidUsbDeviceObject();
|
||||
|
||||
public:
|
||||
/** \brief Creates and initializes FDO device object extension
|
||||
|
||||
This method is called from driver's OnAddDevice method in response to
|
||||
AddDevice call from the PnP manager
|
||||
@param device_init[in] A pointer to a framework-allocated WDFDEVICE_INIT
|
||||
structure.
|
||||
@return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise,
|
||||
it returns one of the error status values defined in ntstatus.h.
|
||||
*/
|
||||
NTSTATUS CreateFDODevice(PWDFDEVICE_INIT device_init);
|
||||
|
||||
/** \brief Resets target device
|
||||
|
||||
When executing this method instance of this class may be deleted!
|
||||
This method must be called at PASSIVE IRQL.
|
||||
@return STATUS_SUCCESS or an appropriate error code
|
||||
*/
|
||||
NTSTATUS ResetDevice();
|
||||
|
||||
private:
|
||||
/** \name Device event handlers and callbacks
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** \brief Handler for PnP prepare hardware event
|
||||
|
||||
This method performs any operations that are needed to make a device
|
||||
accessible to the driver. The framework calls this callback after the PnP
|
||||
manager has assigned hardware resources to the device and after the device
|
||||
has entered its uninitialized D0 state. This callback is called before
|
||||
calling the driver's EvtDeviceD0Entry callback function.
|
||||
This method is called at PASSIVE IRQL.
|
||||
@param resources_raw[in] A handle to a framework resource-list object that
|
||||
identifies the raw hardware resources that the PnP manager has
|
||||
assigned to the device.
|
||||
@param resources_translated[in] A handle to a framework resource-list
|
||||
object that identifies the translated hardware resources that the
|
||||
PnP manager has assigned to the device.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
NTSTATUS OnEvtDevicePrepareHardware(WDFCMRESLIST resources_raw,
|
||||
WDFCMRESLIST resources_translated);
|
||||
|
||||
/** \brief Handler for PnP release hardware event
|
||||
|
||||
This method performs operations that that are needed when a device is no
|
||||
longer accessible. Framework calls the callback function if the device is
|
||||
being removed, or if the PnP manager is attempting to redistribute hardware
|
||||
resources. The framework calls the EvtDeviceReleaseHardware callback
|
||||
function after the driver's device has been shut off, the PnP manager has
|
||||
reclaimed the hardware resources that it assigned to the device, and the
|
||||
device is no longer accessible. (The PCI configuration state is still
|
||||
accessible.) Typically, a EvtDeviceReleaseHardware callback function unmaps
|
||||
memory that the driver's EvtDevicePrepareHardware callback function mapped.
|
||||
Usually, all other hardware shutdown operations should take place in the
|
||||
driver's EvtDeviceD0Exit callback function.
|
||||
This method is called at PASSIVE IRQL.
|
||||
@param wdf_device[in] A handle to a framework device object.
|
||||
@param resources_translated[in] A handle to a framework resource-list
|
||||
object that identifies the translated hardware resources that the
|
||||
PnP manager has assigned to the device.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
NTSTATUS OnEvtDeviceReleaseHardware(WDFCMRESLIST resources_translated);
|
||||
|
||||
/** \brief Handler for create file event (request)
|
||||
|
||||
This method performs operations that are needed when an application
|
||||
requests access to an item within this device path (including device
|
||||
itself). This method is called synchronously, in the context of the
|
||||
user thread that opens the item.
|
||||
This method is called at PASSIVE IRQL.
|
||||
@param request[in] A handle to a framework request object that represents
|
||||
a file creation request.
|
||||
@param wdf_fo[in] A handle to a framework file object that describes a
|
||||
file that is being created with this request.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
void OnEvtDeviceFileCreate(WDFREQUEST request, WDFFILEOBJECT wdf_fo);
|
||||
|
||||
/** \brief Entry point for PnP prepare hardware event
|
||||
|
||||
This callback performs any operations that are needed to make a device
|
||||
accessible to the driver. The framework calls this callback after the PnP
|
||||
manager has assigned hardware resources to the device and after the device
|
||||
has entered its uninitialized D0 state. This callback is called before
|
||||
calling the driver's EvtDeviceD0Entry callback function.
|
||||
This callback is called at PASSIVE IRQL.
|
||||
@param wdf_dev[in] A handle to a framework device object.
|
||||
@param resources_raw[in] A handle to a framework resource-list object that
|
||||
identifies the raw hardware resources that the PnP manager has
|
||||
assigned to the device.
|
||||
@param resources_translated[in] A handle to a framework resource-list
|
||||
object that identifies the translated hardware resources that the
|
||||
PnP manager has assigned to the device.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
static NTSTATUS EvtDevicePrepareHardwareEntry(WDFDEVICE wdf_dev,
|
||||
WDFCMRESLIST resources_raw,
|
||||
WDFCMRESLIST resources_translated);
|
||||
|
||||
/** \brief Entry point for PnP release hardware event
|
||||
|
||||
This callback performs operations that that are needed when a device is no
|
||||
longer accessible. Framework calls the callback function if the device is
|
||||
being removed, or if the PnP manager is attempting to redistribute hardware
|
||||
resources. The framework calls the EvtDeviceReleaseHardware callback
|
||||
function after the driver's device has been shut off, the PnP manager has
|
||||
reclaimed the hardware resources that it assigned to the device, and the
|
||||
device is no longer accessible. (The PCI configuration state is still
|
||||
accessible.) Typically, a EvtDeviceReleaseHardware callback function unmaps
|
||||
memory that the driver's EvtDevicePrepareHardware callback function mapped.
|
||||
Usually, all other hardware shutdown operations should take place in the
|
||||
driver's EvtDeviceD0Exit callback function.
|
||||
This callback is called at PASSIVE IRQL.
|
||||
@param wdf_dev[in] A handle to a framework device object.
|
||||
@param resources_translated[in] A handle to a framework resource-list
|
||||
object that identifies the translated hardware resources that the
|
||||
PnP manager has assigned to the device.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
static NTSTATUS EvtDeviceReleaseHardwareEntry(WDFDEVICE wdf_dev,
|
||||
WDFCMRESLIST resources_translated);
|
||||
|
||||
/** \brief Entry point for create file event (request)
|
||||
|
||||
This callback performs operations that that are needed when an application
|
||||
requests access to a device. The framework calls a driver's
|
||||
EvtDeviceFileCreate callback function when a user application or another
|
||||
driver opens the device (or file on this device) to perform an I/O
|
||||
operation, such as reading or writing a file. This callback function is
|
||||
called synchronously, in the context of the user thread that opens the
|
||||
device.
|
||||
This callback is called at PASSIVE IRQL.
|
||||
@param wdf_dev[in] A handle to a framework device object.
|
||||
@param request[in] A handle to a framework request object that represents
|
||||
a file creation request.
|
||||
@param wdf_fo[in] A handle to a framework file object that describes a
|
||||
file that is being created with this request.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
static void EvtDeviceFileCreateEntry(WDFDEVICE wdf_dev,
|
||||
WDFREQUEST request,
|
||||
WDFFILEOBJECT wdf_fo);
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
/** \name I/O request event handlers and callbacks
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** \brief Read event handler
|
||||
|
||||
This method is called when a read request comes to a file object opened
|
||||
on this device.
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param length[in] The number of bytes to be read.
|
||||
*/
|
||||
void OnEvtIoRead(WDFREQUEST request, size_t length);
|
||||
|
||||
/** \brief Write event handler
|
||||
|
||||
This method is called when a write request comes to a file object opened
|
||||
on this device.
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param length[in] The number of bytes to be written.
|
||||
*/
|
||||
void OnEvtIoWrite(WDFREQUEST request, size_t length);
|
||||
|
||||
/** \brief IOCTL event handler
|
||||
|
||||
This method is called when a device control request comes to a file object
|
||||
opened on this device.
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
@param input_buf_len[in] The length, in bytes, of the request's input
|
||||
buffer, if an input buffer is available.
|
||||
@param ioctl_code[in] The driver-defined or system-defined I/O control code
|
||||
that is associated with the request.
|
||||
*/
|
||||
void OnEvtIoDeviceControl(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len,
|
||||
ULONG ioctl_code);
|
||||
|
||||
/** \brief Entry point for read event
|
||||
|
||||
This callback is called when a read request comes to a file object opened
|
||||
on this device.
|
||||
This callback can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param queue[in] A handle to the framework queue object that is associated
|
||||
with the I/O request.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param length[in] The number of bytes to be read.
|
||||
*/
|
||||
static void EvtIoReadEntry(WDFQUEUE queue,
|
||||
WDFREQUEST request,
|
||||
size_t length);
|
||||
|
||||
/** \brief Entry point for write event
|
||||
|
||||
This callback is called when a write request comes to a file object opened
|
||||
on this device.
|
||||
This callback can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param queue[in] A handle to the framework queue object that is associated
|
||||
with the I/O request.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param length[in] The number of bytes to be written.
|
||||
*/
|
||||
static void EvtIoWriteEntry(WDFQUEUE queue,
|
||||
WDFREQUEST request,
|
||||
size_t length);
|
||||
|
||||
/** \brief Entry point for device IOCTL event
|
||||
|
||||
This callback is called when a device control request comes to a file
|
||||
object opened on this device.
|
||||
This callback can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param queue[in] A handle to the framework queue object that is associated
|
||||
with the I/O request.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
@param input_buf_len[in] The length, in bytes, of the request's input
|
||||
buffer, if an input buffer is available.
|
||||
@param ioctl_code[in] The driver-defined or system-defined I/O control code
|
||||
that is associated with the request.
|
||||
*/
|
||||
static void EvtIoDeviceControlEntry(WDFQUEUE queue,
|
||||
WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len,
|
||||
ULONG ioctl_code);
|
||||
|
||||
///@}
|
||||
|
||||
public:
|
||||
/** \name Device level I/O request handlers
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** \brief Gets USB device descriptor
|
||||
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL
|
||||
@param request[in] A handle to a framework request object for this IOCTL.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
*/
|
||||
void OnGetUsbDeviceDescriptorCtl(WDFREQUEST request, size_t output_buf_len);
|
||||
|
||||
/** \brief Gets USB configuration descriptor for the selected configuration.
|
||||
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL
|
||||
@param request[in] A handle to a framework request object for this IOCTL.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
*/
|
||||
void OnGetUsbConfigDescriptorCtl(WDFREQUEST request, size_t output_buf_len);
|
||||
|
||||
/** \brief Gets USB configuration descriptor for the selected interface.
|
||||
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL
|
||||
@param request[in] A handle to a framework request object for this IOCTL.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
*/
|
||||
void OnGetUsbInterfaceDescriptorCtl(WDFREQUEST request, size_t output_buf_len);
|
||||
|
||||
/** \brief Gets information about an endpoint.
|
||||
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL
|
||||
@param request[in] A handle to a framework request object for this IOCTL.
|
||||
@param input_buf_len[in] The length, in bytes, of the request's input
|
||||
buffer, if an input buffer is available.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
*/
|
||||
void OnGetEndpointInformationCtl(WDFREQUEST request,
|
||||
size_t input_buf_len,
|
||||
size_t output_buf_len);
|
||||
|
||||
/** \brief Gets device serial number.
|
||||
|
||||
Serial number is returned in form of zero-terminated string that in the
|
||||
output buffer. This method must be called at low IRQL.
|
||||
@param request[in] A handle to a framework request object for this IOCTL.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
*/
|
||||
void OnGetSerialNumberCtl(WDFREQUEST request, size_t output_buf_len);
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
/** \name Internal methods
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** \brief Creates default request queue for this device.
|
||||
|
||||
In KMDF all I/O requests are coming through the queue object. So, in order
|
||||
to enable our device to receive I/O requests we must create a queue for it.
|
||||
This method is called at PASSIVE IRQL.
|
||||
@return STATUS_SUCCESS or an appropriate error code.
|
||||
*/
|
||||
NTSTATUS CreateDefaultQueue();
|
||||
|
||||
/** \brief Configures our device.
|
||||
|
||||
This method is called from the prepare hardware handler after underlying
|
||||
FDO device has been created.
|
||||
This method is called at PASSSIVE IRQL.
|
||||
@return STATUS_SUCCESS or an appropriate error code.
|
||||
*/
|
||||
NTSTATUS ConfigureDevice();
|
||||
|
||||
/** \brief Selects interfaces on our device.
|
||||
|
||||
This method is called from the prepare hardware handler after underlying
|
||||
FDO device has been created and configured.
|
||||
This method is called at PASSSIVE IRQL.
|
||||
@return STATUS_SUCCESS or an appropriate error code.
|
||||
*/
|
||||
NTSTATUS SelectInterfaces();
|
||||
|
||||
/** \brief Gets pipe index from a file name
|
||||
|
||||
This method is called from OnEvtDeviceFileCreate to determine index of
|
||||
the pipe this file is addressing.
|
||||
This method is called at PASSIVE IRQL.
|
||||
@param file_path[in] Path to the file that being opened.
|
||||
@return Pipe index or INVALID_UCHAR if index cannot be calculated.
|
||||
*/
|
||||
UCHAR GetPipeIndexFromFileName(PUNICODE_STRING file_path);
|
||||
|
||||
/** \brief Creates file object extension for a pipe
|
||||
|
||||
This method is called from OnEvtDeviceFileCreate to create an appropriate
|
||||
file object extension for a particular pipe type.
|
||||
This method is called at PASSIVE IRQL.
|
||||
@param wdf_fo[in] KMDF file to extend.
|
||||
@param wdf_pipe_obj[in] KMDF pipe for this extension
|
||||
@param pipe_info[in] Pipe information
|
||||
@param wdf_file_ext[out] Upon successfull completion will receive instance
|
||||
of the extension.
|
||||
@return STATUS_SUCCESS or an appropriate error code
|
||||
*/
|
||||
NTSTATUS CreatePipeFileObjectExt(WDFFILEOBJECT wdf_fo,
|
||||
WDFUSBPIPE wdf_pipe_obj,
|
||||
const WDF_USB_PIPE_INFORMATION* pipe_info,
|
||||
AndroidUsbFileObject** wdf_file_ext);
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
/** \name Debugging support
|
||||
*/
|
||||
///@{
|
||||
|
||||
#if DBG
|
||||
/// Prints USB_DEVICE_DESCRIPTOR to debug output
|
||||
void PrintUsbDeviceDescriptor(const USB_DEVICE_DESCRIPTOR* desc);
|
||||
|
||||
/// Prints WDF_USB_DEVICE_INFORMATION to debug output
|
||||
void PrintUsbTargedDeviceInformation(const WDF_USB_DEVICE_INFORMATION* info);
|
||||
|
||||
/// Prints USB_CONFIGURATION_DESCRIPTOR to debug output
|
||||
void PrintConfigDescriptor(const USB_CONFIGURATION_DESCRIPTOR* desc,
|
||||
ULONG size);
|
||||
|
||||
/// Prints WDF_USB_DEVICE_SELECT_CONFIG_PARAMS to debug output
|
||||
void PrintSelectedConfig(const WDF_USB_DEVICE_SELECT_CONFIG_PARAMS* config);
|
||||
|
||||
/// Prints USB_INTERFACE_DESCRIPTOR to debug output
|
||||
void PrintInterfaceDescriptor(const USB_INTERFACE_DESCRIPTOR* desc);
|
||||
|
||||
/// Prints WDF_USB_PIPE_INFORMATION to debug output
|
||||
void PrintPipeInformation(const WDF_USB_PIPE_INFORMATION* info,
|
||||
UCHAR pipe_index);
|
||||
|
||||
#endif // DBG
|
||||
|
||||
///@}
|
||||
|
||||
public:
|
||||
/// Gets WDF device handle for this device
|
||||
__forceinline WDFDEVICE wdf_device() const {
|
||||
return reinterpret_cast<WDFDEVICE>(wdf_object());
|
||||
}
|
||||
|
||||
/// Gets target USB device descriptor
|
||||
__forceinline const USB_DEVICE_DESCRIPTOR* usb_device_descriptor() const {
|
||||
return &usb_device_descriptor_;
|
||||
}
|
||||
|
||||
/// Gets target USB device information
|
||||
__forceinline const WDF_USB_DEVICE_INFORMATION* usb_device_info() const {
|
||||
return &usb_device_info_;
|
||||
}
|
||||
|
||||
/// Gets selected interface descriptor
|
||||
__forceinline const USB_INTERFACE_DESCRIPTOR* interface_descriptor() const {
|
||||
return &interface_descriptor_;
|
||||
}
|
||||
|
||||
/// Gets target (PDO) device handle
|
||||
__forceinline WDFUSBDEVICE wdf_target_device() const {
|
||||
return wdf_target_device_;
|
||||
}
|
||||
|
||||
/// Checks if target device has been created
|
||||
__forceinline bool IsTaretDeviceCreated() const {
|
||||
return (NULL != wdf_target_device());
|
||||
}
|
||||
|
||||
/// Gets USB configuration descriptor
|
||||
__forceinline const USB_CONFIGURATION_DESCRIPTOR* configuration_descriptor() const {
|
||||
return configuration_descriptor_;
|
||||
}
|
||||
|
||||
/// Checks if device has been configured
|
||||
__forceinline bool IsDeviceConfigured() const {
|
||||
return (NULL != configuration_descriptor());
|
||||
}
|
||||
|
||||
/// Gets number of interfaces for this device
|
||||
__forceinline UCHAR GetInterfaceCount() const {
|
||||
ASSERT(IsDeviceConfigured());
|
||||
return IsDeviceConfigured() ? configuration_descriptor()->bNumInterfaces : 0;
|
||||
}
|
||||
|
||||
/// Checks if this is "single interface" device
|
||||
__forceinline bool IsSingleInterfaceDevice() const {
|
||||
return (1 == GetInterfaceCount());
|
||||
}
|
||||
|
||||
/// Gets USB interface selected on this device
|
||||
__forceinline WDFUSBINTERFACE wdf_usb_interface() const {
|
||||
return wdf_usb_interface_;
|
||||
}
|
||||
|
||||
/// Checks if an interface has been selected on this device
|
||||
__forceinline bool IsInterfaceSelected() const {
|
||||
return (NULL != wdf_usb_interface());
|
||||
}
|
||||
|
||||
/// Gets number of pipes configured on this device
|
||||
__forceinline UCHAR configured_pipes_num() const {
|
||||
return configured_pipes_num_;
|
||||
}
|
||||
|
||||
/// Gets index of the bulk read pipe
|
||||
__forceinline UCHAR bulk_read_pipe_index() const {
|
||||
return bulk_read_pipe_index_;
|
||||
}
|
||||
|
||||
/// Gets index of the bulk write pipe
|
||||
__forceinline UCHAR bulk_write_pipe_index() const {
|
||||
return bulk_write_pipe_index_;
|
||||
}
|
||||
|
||||
/// Checks if this is a high speed device
|
||||
__forceinline bool IsHighSpeed() const {
|
||||
return (0 != (usb_device_info()->Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED));
|
||||
}
|
||||
|
||||
/// Checks if bulk read pipe index is known
|
||||
__forceinline bool IsBulkReadPipeKnown() const {
|
||||
return (INVALID_UCHAR != bulk_read_pipe_index());
|
||||
}
|
||||
|
||||
/// Checks if bulk write pipe index is known
|
||||
__forceinline bool IsBulkWritePipeKnown() const {
|
||||
return (INVALID_UCHAR != bulk_write_pipe_index());
|
||||
}
|
||||
|
||||
/// Gets device serial number string. Note that string may be
|
||||
/// not zero-terminated. Use serial_number_len() to get actual
|
||||
/// length of this string.
|
||||
__forceinline const WCHAR* serial_number() const {
|
||||
ASSERT(NULL != serial_number_handle_);
|
||||
return (NULL != serial_number_handle_) ?
|
||||
reinterpret_cast<const WCHAR*>
|
||||
(WdfMemoryGetBuffer(serial_number_handle_, NULL)) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
/// Gets length (in bytes) of device serial number string
|
||||
__forceinline USHORT serial_number_char_len() const {
|
||||
return serial_number_char_len_;
|
||||
}
|
||||
|
||||
/// Gets length (in bytes) of device serial number string
|
||||
__forceinline USHORT serial_number_byte_len() const {
|
||||
return serial_number_char_len() * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Target USB device descriptor
|
||||
USB_DEVICE_DESCRIPTOR usb_device_descriptor_;
|
||||
|
||||
/// Target USB device information
|
||||
WDF_USB_DEVICE_INFORMATION usb_device_info_;
|
||||
|
||||
/// Selected interface descriptor
|
||||
USB_INTERFACE_DESCRIPTOR interface_descriptor_;
|
||||
|
||||
/// USB configuration descriptor
|
||||
PUSB_CONFIGURATION_DESCRIPTOR configuration_descriptor_;
|
||||
|
||||
/// Target (PDO?) device handle
|
||||
WDFUSBDEVICE wdf_target_device_;
|
||||
|
||||
/// USB interface selected on this device
|
||||
WDFUSBINTERFACE wdf_usb_interface_;
|
||||
|
||||
/// Device serial number
|
||||
WDFMEMORY serial_number_handle_;
|
||||
|
||||
/// Device serial number string length
|
||||
USHORT serial_number_char_len_;
|
||||
|
||||
/// Number of pipes configured on this device
|
||||
UCHAR configured_pipes_num_;
|
||||
|
||||
/// Index of the bulk read pipe
|
||||
UCHAR bulk_read_pipe_index_;
|
||||
|
||||
/// Index of the bulk write pipe
|
||||
UCHAR bulk_write_pipe_index_;
|
||||
};
|
||||
|
||||
/** \brief Gets device KMDF object extension for the given KMDF object
|
||||
|
||||
@param wdf_dev[in] KMDF handle describing device object
|
||||
@return Instance of AndroidUsbDeviceObject associated with KMDF object or
|
||||
NULL if association is not found.
|
||||
*/
|
||||
__forceinline AndroidUsbDeviceObject* GetAndroidUsbDeviceObjectFromHandle(
|
||||
WDFDEVICE wdf_dev) {
|
||||
AndroidUsbWdfObject* wdf_object_ext =
|
||||
GetAndroidUsbWdfObjectFromHandle(wdf_dev);
|
||||
ASSERT((NULL != wdf_object_ext) &&
|
||||
wdf_object_ext->Is(AndroidUsbWdfObjectTypeDevice));
|
||||
if ((NULL != wdf_object_ext) &&
|
||||
wdf_object_ext->Is(AndroidUsbWdfObjectTypeDevice)) {
|
||||
return reinterpret_cast<AndroidUsbDeviceObject*>(wdf_object_ext);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // ANDROID_USB_DEVICE_OBJECT_H__
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_DRIVER_DEFINES_H__
|
||||
#define ANDROID_USB_DRIVER_DEFINES_H__
|
||||
/** \file
|
||||
This file consists of constants, types and macros used (and useful) in driver
|
||||
development.
|
||||
*/
|
||||
|
||||
/** \name IRQL assertions
|
||||
These assertions help to verify that code is running at expected IRQL
|
||||
*/
|
||||
///@{
|
||||
|
||||
/// Asserts that current IRQL is less than provided level
|
||||
#define ASSERT_IRQL_LESS(irql_level) ASSERT(KeGetCurrentIrql() < irql_level)
|
||||
/// Asserts that current IRQL is less or equal than provided level
|
||||
#define ASSERT_IRQL_LESS_OR_EQUAL(irql_level) ASSERT(KeGetCurrentIrql() <= irql_level)
|
||||
/// Asserts that current IRQL is the same as provided level
|
||||
#define ASSERT_IRQL_IS(irql_level) ASSERT(irql_level == KeGetCurrentIrql())
|
||||
/// Asserts that current IRQL is less than DISPATCH_LEVEL
|
||||
#define ASSERT_IRQL_LOW() ASSERT_IRQL_LESS(DISPATCH_LEVEL)
|
||||
/// Asserts that current IRQL is above APC_LEVEL
|
||||
#define ASSERT_IRQL_HIGH() ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL)
|
||||
/// Asserts that current IRQL is at PASSIVE_LEVEL
|
||||
#define ASSERT_IRQL_PASSIVE() ASSERT_IRQL_IS(PASSIVE_LEVEL)
|
||||
/// Asserts that current IRQL is at APC_LEVEL
|
||||
#define ASSERT_IRQL_APC() ASSERT_IRQL_IS(APC_LEVEL)
|
||||
/// Asserts that current IRQL is at DISPATCH_LEVEL
|
||||
#define ASSERT_IRQL_DISPATCH() ASSERT_IRQL_IS(DISPATCH_LEVEL)
|
||||
/// Asserts that current IRQL is at APC or DISPATCH_LEVEL
|
||||
#define ASSERT_IRQL_APC_OR_DISPATCH() \
|
||||
ASSERT((KeGetCurrentIrql() == APC_LEVEL) || (KeGetCurrentIrql() == DISPATCH_LEVEL))
|
||||
/// Asserts that current IRQL is less or equal DISPATCH_LEVEL
|
||||
#define ASSERT_IRQL_LOW_OR_DISPATCH() \
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL)
|
||||
|
||||
///@}
|
||||
|
||||
#if DBG
|
||||
/** \brief Overrides DbgPrint to make sure that nothing gets printed
|
||||
to debug output in release build.
|
||||
*/
|
||||
ULONG __cdecl GoogleDbgPrint(char* format, ...);
|
||||
#else
|
||||
#define GoogleDbgPrint(Arg) NOTHING
|
||||
#endif
|
||||
|
||||
/// Invalid UCHAR value
|
||||
#define INVALID_UCHAR (static_cast<UCHAR>(0xFF))
|
||||
|
||||
/// Invalid ULONG value
|
||||
#define INVALID_ULONG (static_cast<ULONG>(-1))
|
||||
|
||||
/** Enum AndroidUsbWdfObjectType enumerates types of KMDF objects that
|
||||
we extend in our driver.
|
||||
*/
|
||||
enum AndroidUsbWdfObjectType {
|
||||
// We start enum with 1 insetead of 0 to protect orselves from a dangling
|
||||
// or uninitialized context structures because KMDF will zero our extension
|
||||
// when it gets created.
|
||||
|
||||
/// Device object context
|
||||
AndroidUsbWdfObjectTypeDevice = 1,
|
||||
|
||||
/// File object context
|
||||
AndroidUsbWdfObjectTypeFile,
|
||||
|
||||
/// Request object context
|
||||
AndroidUsbWdfObjectTypeRequest,
|
||||
|
||||
/// Workitem object context
|
||||
AndroidUsbWdfObjectTypeWorkitem,
|
||||
|
||||
/// Illegal (maximum) context id
|
||||
AndroidUsbWdfObjectTypeMax
|
||||
};
|
||||
|
||||
/** Structure AndroidUsbWdfObjectContext represents our context that extends
|
||||
every KMDF object (device, file, pipe, etc).
|
||||
*/
|
||||
typedef struct TagAndroidUsbWdfObjectContext {
|
||||
/// KMDF object type that is extended with this context
|
||||
AndroidUsbWdfObjectType object_type;
|
||||
|
||||
/// Instance of the class that extends KMDF object with this context
|
||||
class AndroidUsbWdfObject* wdf_object_ext;
|
||||
} AndroidUsbWdfObjectContext;
|
||||
|
||||
// KMDF woodoo to register our extension and implement accessor method
|
||||
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWdfObjectContext,
|
||||
GetAndroidUsbWdfObjectContext)
|
||||
|
||||
/** Structure AndroidUsbWdfRequestContext represents our context that is
|
||||
associated with every request recevied by the driver.
|
||||
*/
|
||||
typedef struct TagAndroidUsbWdfRequestContext {
|
||||
/// KMDF object type that is extended with this context
|
||||
/// (must be AndroidUsbWdfObjectTypeRequest)
|
||||
AndroidUsbWdfObjectType object_type;
|
||||
|
||||
/// System time request has been first scheduled
|
||||
// (time of the first WdfRequestSend is called for it)
|
||||
LARGE_INTEGER sent_at;
|
||||
|
||||
/// KMDF descriptor for the memory allocated for URB
|
||||
WDFMEMORY urb_mem;
|
||||
|
||||
/// MDL describing the transfer buffer
|
||||
PMDL transfer_mdl;
|
||||
|
||||
/// Private MDL that we build in order to perform the transfer
|
||||
PMDL mdl;
|
||||
|
||||
// Virtual address for the current segment of transfer.
|
||||
void* virtual_address;
|
||||
|
||||
/// Number of bytes remaining to transfer
|
||||
ULONG length;
|
||||
|
||||
/// Number of bytes requested to transfer
|
||||
ULONG transfer_size;
|
||||
|
||||
/// Accummulated number of bytes transferred
|
||||
ULONG num_xfer;
|
||||
|
||||
/// Initial timeout (in millisec) set for this request
|
||||
ULONG initial_time_out;
|
||||
|
||||
// Read / Write selector
|
||||
bool is_read;
|
||||
|
||||
// IOCTL selector
|
||||
bool is_ioctl;
|
||||
} AndroidUsbWdfRequestContext;
|
||||
|
||||
// KMDF woodoo to register our extension and implement accessor method
|
||||
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWdfRequestContext,
|
||||
GetAndroidUsbWdfRequestContext)
|
||||
|
||||
/** Structure AndroidUsbWorkitemContext represents our context that is
|
||||
associated with workitems created by our driver.
|
||||
*/
|
||||
typedef struct TagAndroidUsbWorkitemContext {
|
||||
/// KMDF object type that is extended with this context
|
||||
/// (must be AndroidUsbWdfObjectTypeWorkitem)
|
||||
AndroidUsbWdfObjectType object_type;
|
||||
|
||||
/// Pipe file object extension that enqueued this work item
|
||||
class AndroidUsbPipeFileObject* pipe_file_ext;
|
||||
} AndroidUsbWorkitemContext;
|
||||
|
||||
// KMDF woodoo to register our extension and implement accessor method
|
||||
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWorkitemContext,
|
||||
GetAndroidUsbWorkitemContext)
|
||||
|
||||
#endif // ANDROID_USB_DRIVER_DEFINES_H__
|
||||
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 AndroidUsbDriverObject that
|
||||
encapsulates our driver object
|
||||
*/
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
|
||||
#include "precomp.h"
|
||||
#include "android_usb_device_object.h"
|
||||
#include "android_usb_driver_object.h"
|
||||
|
||||
#pragma data_seg()
|
||||
|
||||
/** Globally accessible instance of the AndroidUsbDriverObject.
|
||||
NT OS design allows us using of a global pointer to our driver object
|
||||
instance since it can't be created or destroyed concurently and its value
|
||||
is not going to change between creation and destruction.
|
||||
*/
|
||||
AndroidUsbDriverObject* global_driver_object = NULL;
|
||||
|
||||
#pragma code_seg("INIT")
|
||||
|
||||
extern "C" {
|
||||
|
||||
/// Main entry point to the driver
|
||||
NTSTATUS DriverEntry(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path) {
|
||||
// Just pass it down inside the class
|
||||
return AndroidUsbDriverObject::DriverEntry(drv_object, reg_path);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
NTSTATUS AndroidUsbDriverObject::DriverEntry(PDRIVER_OBJECT drv_object,
|
||||
PUNICODE_STRING reg_path) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
ASSERT(NULL != drv_object);
|
||||
ASSERT((NULL != reg_path) &&
|
||||
(NULL != reg_path->Buffer) &&
|
||||
(0 != reg_path->Length));
|
||||
|
||||
// Instantiate driver object
|
||||
global_driver_object = new(NonPagedPool, GANDR_POOL_TAG_DRIVER_OBJECT)
|
||||
AndroidUsbDriverObject(drv_object, reg_path);
|
||||
ASSERT(NULL != global_driver_object);
|
||||
if (NULL == global_driver_object)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
// Initialize driver object
|
||||
NTSTATUS status = global_driver_object->OnDriverEntry(drv_object, reg_path);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
// Something went wrong. Delete our driver object and get out of here.
|
||||
delete global_driver_object;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
AndroidUsbDriverObject::AndroidUsbDriverObject(PDRIVER_OBJECT drv_object,
|
||||
PUNICODE_STRING reg_path)
|
||||
: driver_object_(drv_object),
|
||||
wdf_driver_(NULL) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
ASSERT(NULL != driver_object());
|
||||
}
|
||||
|
||||
NTSTATUS AndroidUsbDriverObject::OnDriverEntry(PDRIVER_OBJECT drv_object,
|
||||
PUNICODE_STRING reg_path) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
ASSERT(driver_object() == drv_object);
|
||||
|
||||
// Initiialize driver config, specifying our unload callback and default
|
||||
// pool tag for memory allocations that KMDF does on our behalf.
|
||||
WDF_DRIVER_CONFIG config;
|
||||
WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAddEntry);
|
||||
config.EvtDriverUnload = EvtDriverUnloadEntry;
|
||||
config.DriverPoolTag = GANDR_POOL_TAG_DEFAULT;
|
||||
|
||||
// Create a framework driver object to represent our driver.
|
||||
NTSTATUS status = WdfDriverCreate(drv_object,
|
||||
reg_path,
|
||||
WDF_NO_OBJECT_ATTRIBUTES,
|
||||
&config,
|
||||
&wdf_driver_);
|
||||
ASSERT(NT_SUCCESS(status));
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
GoogleDbgPrint("\n>>>>>>>>>> Android USB driver has started >>>>>>>>>>");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
AndroidUsbDriverObject::~AndroidUsbDriverObject() {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
}
|
||||
|
||||
NTSTATUS AndroidUsbDriverObject::OnAddDevice(PWDFDEVICE_INIT device_init) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
GoogleDbgPrint("\n++++++++++ AndroidUsbDriverObject::OnAddDevice ++++++++++");
|
||||
// Instantiate our device object extension for this device
|
||||
AndroidUsbDeviceObject* wdf_device_ext =
|
||||
new(NonPagedPool, GANDR_POOL_TAG_KMDF_DEVICE) AndroidUsbDeviceObject();
|
||||
ASSERT(NULL != wdf_device_ext);
|
||||
if (NULL == wdf_device_ext)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
// Create and initialize FDO device
|
||||
NTSTATUS status = wdf_device_ext->CreateFDODevice(device_init);
|
||||
ASSERT(NT_SUCCESS(status));
|
||||
if (!NT_SUCCESS(status))
|
||||
delete wdf_device_ext;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void AndroidUsbDriverObject::OnDriverUnload() {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
GoogleDbgPrint("\n<<<<<<<<<< Android USB driver is unloaded <<<<<<<<<<");
|
||||
}
|
||||
|
||||
NTSTATUS AndroidUsbDriverObject::EvtDeviceAddEntry(
|
||||
WDFDRIVER wdf_drv,
|
||||
PWDFDEVICE_INIT device_init) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
ASSERT((NULL != global_driver_object) && (global_driver_object->wdf_driver() == wdf_drv));
|
||||
|
||||
// Pass it down to our driver object
|
||||
if ((NULL == global_driver_object) ||
|
||||
(global_driver_object->wdf_driver() != wdf_drv)) {
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
return global_driver_object->OnAddDevice(device_init);
|
||||
}
|
||||
|
||||
VOID AndroidUsbDriverObject::EvtDriverUnloadEntry(WDFDRIVER wdf_drv) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
ASSERT((NULL != global_driver_object) &&
|
||||
(global_driver_object->wdf_driver() == wdf_drv));
|
||||
|
||||
// Pass it down to our driver object
|
||||
if ((NULL != global_driver_object) &&
|
||||
(global_driver_object->wdf_driver() == wdf_drv)) {
|
||||
global_driver_object->OnDriverUnload();
|
||||
// Now we can (and have to) delete our driver object
|
||||
delete global_driver_object;
|
||||
}
|
||||
}
|
||||
|
||||
#if DBG
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
ULONG __cdecl GoogleDbgPrint(char* format, ...) {
|
||||
va_list arg_list;
|
||||
va_start(arg_list, format);
|
||||
ULONG ret =
|
||||
vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, arg_list);
|
||||
va_end(arg_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // DBG
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_DRIVER_OBJECT_H__
|
||||
#define ANDROID_USB_DRIVER_OBJECT_H__
|
||||
/** \file
|
||||
This file consists of declaration of class AndroidUsbDriverObject that
|
||||
encapsulates our driver object.
|
||||
*/
|
||||
|
||||
/// Globally accessible pointer to the driver object
|
||||
extern class AndroidUsbDriverObject* global_driver_object;
|
||||
|
||||
/** AndroidUsbDriverObject class encapsulates driver object and provides
|
||||
overall initialization / cleanup as well as management of globally used
|
||||
resources. We use KMDF framework for this driver because it takes care of
|
||||
most of the USB related "things" (like PnP, power management and other
|
||||
stuff) so we can concentrate more on real functionality. This driver is
|
||||
based on KMDF's usbsamp driver sample available at DDK's src\kmdf\usbsamp
|
||||
directory. Instance of this class (always one) must be allocated from
|
||||
NonPagedPool.
|
||||
*/
|
||||
class AndroidUsbDriverObject {
|
||||
|
||||
public:
|
||||
/** \brief Driver initialization entry point.
|
||||
|
||||
This method is a "gate" to our driver class from main DriverEntry routine.
|
||||
Since this method is called from within DriverEntry only it is placed in
|
||||
"INIT" code segment.
|
||||
This method is called at IRQL PASSIVE_LEVEL.
|
||||
@param drv_object[in] Driver object passed to DriverEntry routine
|
||||
@param reg_path[in] Path to the driver's Registry passed to DriverEntry
|
||||
routine
|
||||
@returns STATUS_SUCCESS on success or an appropriate error code.
|
||||
*/
|
||||
static NTSTATUS DriverEntry(PDRIVER_OBJECT drv_object,
|
||||
PUNICODE_STRING reg_path);
|
||||
|
||||
private:
|
||||
/** \brief Constructs driver object.
|
||||
|
||||
Constructor for driver class must be as light as possible. All
|
||||
initialization that may fail must be deferred to OnDriverEntry method.
|
||||
Since this method is called from within DriverEntry only it is placed in
|
||||
"INIT" code segment.
|
||||
This method is called at IRQL PASSIVE_LEVEL.
|
||||
@param drv_object[in] Driver object passed to DriverEntry routine
|
||||
@param reg_path[in] Path to the driver's Registry passed to DriverEntry
|
||||
routine
|
||||
*/
|
||||
AndroidUsbDriverObject(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path);
|
||||
|
||||
/** \brief Destructs driver object.
|
||||
|
||||
Destructor for driver class must be as light as possible. All
|
||||
uninitialization must be done in OnDriverUnload method.
|
||||
This method must be called at PASSIVE IRQL.
|
||||
*/
|
||||
~AndroidUsbDriverObject();
|
||||
|
||||
/** \brief Initializes instance of the driver object.
|
||||
|
||||
This method is called immediatelly after driver object has been
|
||||
instantiated to perform actual initialization of the driver. Since this
|
||||
method is called from within DriverEntry only it is placed in
|
||||
"INIT" code segment.
|
||||
This method is called at IRQL PASSIVE_LEVEL.
|
||||
@param drv_object[in] Driver object passed to DriverEntry routine
|
||||
@param reg_path[in] Path to the driver's Registry passed to DriverEntry
|
||||
routine
|
||||
@returns STATUS_SUCCESS on success or an appropriate error code.
|
||||
*/
|
||||
NTSTATUS OnDriverEntry(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path);
|
||||
|
||||
/** \brief Actual handler for KMDF's AddDevice event
|
||||
|
||||
This method is called by the framework in response to AddDevice call from
|
||||
the PnP manager. We create and initialize a device object to represent a
|
||||
new instance of the device.
|
||||
This method is called at IRQL PASSIVE_LEVEL.
|
||||
@param device_init[in] A pointer to a framework-allocated WDFDEVICE_INIT
|
||||
structure.
|
||||
@return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise,
|
||||
it returns one of the error status values defined in ntstatus.h.
|
||||
*/
|
||||
NTSTATUS OnAddDevice(PWDFDEVICE_INIT device_init);
|
||||
|
||||
/** \brief Actual driver unload event handler.
|
||||
|
||||
This method is called when driver is being unloaded.
|
||||
This method is called at IRQL PASSIVE_LEVEL.
|
||||
*/
|
||||
void OnDriverUnload();
|
||||
|
||||
/** \brief KMDF's DeviceAdd event entry point
|
||||
|
||||
This callback is called by the framework in response to AddDevice call from
|
||||
the PnP manager. We create and initialize a device object to represent a
|
||||
new instance of the device. All the software resources should be allocated
|
||||
in this callback.
|
||||
This method is called at IRQL PASSIVE_LEVEL.
|
||||
@param wdf_drv[in] WDF driver handle.
|
||||
@param device_init[in] A pointer to a framework-allocated WDFDEVICE_INIT
|
||||
structure.
|
||||
@return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise,
|
||||
it returns one of the error status values defined in ntstatus.h.
|
||||
*/
|
||||
static NTSTATUS EvtDeviceAddEntry(WDFDRIVER wdf_drv,
|
||||
PWDFDEVICE_INIT device_init);
|
||||
|
||||
/** \brief Driver unload event entry point.
|
||||
|
||||
Framework calls this callback when driver is being unloaded.
|
||||
This method is called at IRQL PASSIVE_LEVEL.
|
||||
*/
|
||||
static VOID EvtDriverUnloadEntry(WDFDRIVER wdf_drv);
|
||||
|
||||
public:
|
||||
|
||||
/// Gets this driver's DRIVER_OBJECT
|
||||
__forceinline PDRIVER_OBJECT driver_object() const {
|
||||
return driver_object_;
|
||||
}
|
||||
|
||||
/// Gets KMDF driver handle
|
||||
__forceinline WDFDRIVER wdf_driver() const {
|
||||
return wdf_driver_;
|
||||
}
|
||||
|
||||
private:
|
||||
/// This driver's driver object
|
||||
PDRIVER_OBJECT driver_object_;
|
||||
|
||||
/// KMDF driver handle
|
||||
WDFDRIVER wdf_driver_;
|
||||
};
|
||||
|
||||
#endif // ANDROID_USB_DRIVER_OBJECT_H__
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 AndroidUsbFileObject that
|
||||
encapsulates a common extension for all KMDF file object types.
|
||||
*/
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
|
||||
#include "precomp.h"
|
||||
#include "android_usb_file_object.h"
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
AndroidUsbFileObject::AndroidUsbFileObject(AndroidUsbFileObjectType fo_type,
|
||||
AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo)
|
||||
: AndroidUsbWdfObject(AndroidUsbWdfObjectTypeFile),
|
||||
file_type_(fo_type),
|
||||
device_object_(dev_obj) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
ASSERT(NULL != dev_obj);
|
||||
ASSERT(fo_type < AndroidUsbFileObjectTypeMax);
|
||||
ASSERT(NULL != wdf_fo);
|
||||
set_wdf_object(wdf_fo);
|
||||
}
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
AndroidUsbFileObject::~AndroidUsbFileObject() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
}
|
||||
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
NTSTATUS AndroidUsbFileObject::Initialize() {
|
||||
ASSERT_IRQL_LOW();
|
||||
ASSERT(NULL != wdf_file());
|
||||
if (NULL == wdf_file())
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
||||
// Register context for this file object
|
||||
return InitializeContext();
|
||||
}
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
void AndroidUsbFileObject::OnEvtIoRead(WDFREQUEST request,
|
||||
size_t length) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
ASSERT(WdfRequestGetFileObject(request) == wdf_file());
|
||||
// Complete zero reads with success
|
||||
if (0 == length) {
|
||||
WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
|
||||
}
|
||||
|
||||
void AndroidUsbFileObject::OnEvtIoWrite(WDFREQUEST request,
|
||||
size_t length) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
ASSERT(WdfRequestGetFileObject(request) == wdf_file());
|
||||
// Complete zero writes with success
|
||||
if (0 == length) {
|
||||
WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
|
||||
}
|
||||
|
||||
void AndroidUsbFileObject::OnEvtIoDeviceControl(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len,
|
||||
ULONG ioctl_code) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
ASSERT(WdfRequestGetFileObject(request) == wdf_file());
|
||||
|
||||
WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
|
||||
}
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_FILE_OBJECT_H__
|
||||
#define ANDROID_USB_FILE_OBJECT_H__
|
||||
/** \file
|
||||
This file consists of declaration of class AndroidUsbFileObject that
|
||||
encapsulates a common extension for all KMDF file object types.
|
||||
*/
|
||||
|
||||
#include "android_usb_wdf_object.h"
|
||||
#include "android_usb_device_object.h"
|
||||
|
||||
/** Enumerator AndroidUsbFileObjectType defines possible types for our file
|
||||
object extension.
|
||||
*/
|
||||
enum AndroidUsbFileObjectType {
|
||||
/// File extends device FO
|
||||
AndroidUsbFileObjectTypeDevice,
|
||||
|
||||
// File extends a pipe FO
|
||||
AndroidUsbFileObjectTypePipe,
|
||||
|
||||
AndroidUsbFileObjectTypeMax,
|
||||
};
|
||||
|
||||
/** AndroidUsbFileObject class encapsulates a common extension for all KMDF
|
||||
file object types. Instances of this class must be allocated from
|
||||
NonPagedPool.
|
||||
*/
|
||||
class AndroidUsbFileObject : public AndroidUsbWdfObject {
|
||||
public:
|
||||
/** \brief Constructs the object.
|
||||
|
||||
This method must be called at low IRQL.
|
||||
@param fo_type[in] Type of the file object that this object extends
|
||||
@param dev_obj[in] Our device object for which this file has been created
|
||||
@param wdf_fo[in] KMDF file object for this extension
|
||||
*/
|
||||
AndroidUsbFileObject(AndroidUsbFileObjectType fo_type,
|
||||
AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo);
|
||||
|
||||
/** \brief Destructs the object.
|
||||
|
||||
This method can be called at any IRQL.
|
||||
*/
|
||||
virtual ~AndroidUsbFileObject();
|
||||
|
||||
/** \brief Initializes the object
|
||||
|
||||
This method verifies that instance has been created and calls base class's
|
||||
InitializeContext method to register itself with the wrapped FO. All
|
||||
derived classes must call this method when initializing.
|
||||
This method must be called at low IRQL.
|
||||
@return STATUS_SUCCESS on success or an appropriate error code
|
||||
*/
|
||||
virtual NTSTATUS Initialize();
|
||||
|
||||
/** \brief Read event handler
|
||||
|
||||
This method is called when a read request comes to the file object this
|
||||
class extends.
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param length[in] The number of bytes to be read.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
virtual void OnEvtIoRead(WDFREQUEST request, size_t length);
|
||||
|
||||
/** \brief Write event handler
|
||||
|
||||
This method is called when a write request comes to the file object this
|
||||
class extends.
|
||||
This callback can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param length[in] The number of bytes to be written.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
virtual void OnEvtIoWrite(WDFREQUEST request, size_t length);
|
||||
|
||||
/** \brief IOCTL event handler
|
||||
|
||||
This method is called when a device control request comes to the file
|
||||
object this class extends.
|
||||
This callback can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
@param input_buf_len[in] The length, in bytes, of the request's input
|
||||
buffer, if an input buffer is available.
|
||||
@param ioctl_code[in] The driver-defined or system-defined I/O control code
|
||||
that is associated with the request.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
virtual void OnEvtIoDeviceControl(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len,
|
||||
ULONG ioctl_code);
|
||||
|
||||
public:
|
||||
/// Gets KMDF file handle for this extension
|
||||
__forceinline WDFFILEOBJECT wdf_file() const {
|
||||
return reinterpret_cast<WDFFILEOBJECT>(wdf_object());
|
||||
}
|
||||
|
||||
/// Gets device object that owns this file
|
||||
__forceinline AndroidUsbDeviceObject* device_object() const {
|
||||
return device_object_;
|
||||
}
|
||||
|
||||
/// Gets type of the file object that this extension wraps
|
||||
__forceinline AndroidUsbFileObjectType file_type() const {
|
||||
return file_type_;
|
||||
}
|
||||
|
||||
/// Gets WDF device handle for device that owns this file
|
||||
__forceinline WDFDEVICE wdf_device() const {
|
||||
ASSERT(NULL != device_object());
|
||||
return (NULL != device_object()) ? device_object()->wdf_device() :
|
||||
NULL;
|
||||
}
|
||||
|
||||
/// Gets target (PDO) device handle for the device that owns this file
|
||||
__forceinline WDFUSBDEVICE wdf_target_device() const {
|
||||
ASSERT(NULL != device_object());
|
||||
return (NULL != device_object()) ? device_object()->wdf_target_device() :
|
||||
NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Device object that owns this file
|
||||
AndroidUsbDeviceObject* device_object_;
|
||||
|
||||
/// Type of the file object that this extension wraps
|
||||
AndroidUsbFileObjectType file_type_;
|
||||
};
|
||||
|
||||
/** \brief Gets file KMDF object extension for the given KMDF file object
|
||||
|
||||
This method can be called at any IRQL
|
||||
@param wdf_fo[in] KMDF file handle describing file object
|
||||
@return Instance of AndroidUsbFileObject associated with this object or NULL
|
||||
if association is not found.
|
||||
*/
|
||||
__forceinline AndroidUsbFileObject* GetAndroidUsbFileObjectFromHandle(
|
||||
WDFFILEOBJECT wdf_fo) {
|
||||
AndroidUsbWdfObject* wdf_object_ext =
|
||||
GetAndroidUsbWdfObjectFromHandle(wdf_fo);
|
||||
ASSERT(NULL != wdf_object_ext);
|
||||
if (NULL != wdf_object_ext) {
|
||||
ASSERT(wdf_object_ext->Is(AndroidUsbWdfObjectTypeFile));
|
||||
if (wdf_object_ext->Is(AndroidUsbWdfObjectTypeFile))
|
||||
return reinterpret_cast<AndroidUsbFileObject*>(wdf_object_ext);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief Gets file KMDF file object extension for the given request
|
||||
|
||||
This method can be called at any IRQL
|
||||
@param request[in] KMDF request object
|
||||
@return Instance of AndroidUsbFileObject associated with this request or NULL
|
||||
if association is not found.
|
||||
*/
|
||||
__forceinline AndroidUsbFileObject* GetAndroidUsbFileObjectForRequest(
|
||||
WDFREQUEST request) {
|
||||
return GetAndroidUsbFileObjectFromHandle(WdfRequestGetFileObject(request));
|
||||
}
|
||||
|
||||
#endif // ANDROID_USB_FILE_OBJECT_H__
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_INL_H__
|
||||
#define ANDROID_USB_INL_H__
|
||||
/** \file
|
||||
This file consists of inline routines for the driver.
|
||||
*/
|
||||
|
||||
/// Gets control code out of the entire IOCTL code packet
|
||||
__forceinline ULONG GetCtlCode(ULONG ioctl_code) {
|
||||
return (ioctl_code >> 2) & 0x0FFF;
|
||||
}
|
||||
|
||||
/** \brief
|
||||
Converts string length from number of wide characters into number of bytes.
|
||||
*/
|
||||
__forceinline USHORT ByteLen(USHORT wchar_len) {
|
||||
return static_cast<USHORT>(wchar_len * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
/** \brief Gets byte length of a zero-terminated string not including
|
||||
zero terminator. Must be called at low IRQL.
|
||||
*/
|
||||
__forceinline USHORT ByteLen(const WCHAR* str) {
|
||||
ASSERT_IRQL_LOW();
|
||||
return (NULL != str) ? ByteLen(static_cast<USHORT>(wcslen(str))) : 0;
|
||||
}
|
||||
|
||||
/** \brief
|
||||
Converts string length from number of bytes into number of wide characters.
|
||||
Can be called at any IRQL.
|
||||
*/
|
||||
__forceinline USHORT WcharLen(USHORT byte_len) {
|
||||
return byte_len / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/** \brief Retrieves pointer out of the WDFMEMORY handle
|
||||
*/
|
||||
__forceinline void* GetAddress(WDFMEMORY wdf_mem) {
|
||||
ASSERT(NULL != wdf_mem);
|
||||
return (NULL != wdf_mem) ? WdfMemoryGetBuffer(wdf_mem, NULL) : NULL;
|
||||
}
|
||||
|
||||
/** \brief Retrieves output memory address for WDFREQUEST
|
||||
|
||||
@param request[in] A handle to KMDF request object
|
||||
@param status[out] Receives status of the call. Can be NULL.
|
||||
*/
|
||||
__forceinline void* OutAddress(WDFREQUEST request, NTSTATUS* status) {
|
||||
ASSERT(NULL != request);
|
||||
WDFMEMORY wdf_mem = NULL;
|
||||
NTSTATUS stat = WdfRequestRetrieveOutputMemory(request, &wdf_mem);
|
||||
ASSERT((NULL != wdf_mem) || (!NT_SUCCESS(stat)));
|
||||
if (NULL != status)
|
||||
*status = stat;
|
||||
return NT_SUCCESS(stat) ? GetAddress(wdf_mem) : NULL;
|
||||
}
|
||||
|
||||
/** \brief Retrieves input memory address for WDFREQUEST
|
||||
|
||||
@param request[in] A handle to KMDF request object
|
||||
@param status[out] Receives status of the call. Can be NULL.
|
||||
*/
|
||||
__forceinline void* InAddress(WDFREQUEST request, NTSTATUS* status) {
|
||||
ASSERT(NULL != request);
|
||||
WDFMEMORY wdf_mem = NULL;
|
||||
NTSTATUS stat = WdfRequestRetrieveInputMemory(request, &wdf_mem);
|
||||
ASSERT((NULL != wdf_mem) || (!NT_SUCCESS(stat)));
|
||||
if (NULL != status)
|
||||
*status = stat;
|
||||
return NT_SUCCESS(stat) ? GetAddress(wdf_mem) : NULL;
|
||||
}
|
||||
|
||||
#endif // ANDROID_USB_INL_H__
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 AndroidUsbInterruptPipeFileObject
|
||||
that encapsulates extension to an interrupt pipe file objects.
|
||||
*/
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
|
||||
#include "precomp.h"
|
||||
#include "android_usb_interrupt_file_object.h"
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
AndroidUsbInterruptPipeFileObject::AndroidUsbInterruptPipeFileObject(
|
||||
AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo,
|
||||
WDFUSBPIPE wdf_pipe_obj)
|
||||
: AndroidUsbPipeFileObject(dev_obj, wdf_fo, wdf_pipe_obj) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
|
||||
#if DBG
|
||||
WDF_USB_PIPE_INFORMATION pipe_info;
|
||||
WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
|
||||
WdfUsbTargetPipeGetInformation(wdf_pipe_obj, &pipe_info);
|
||||
ASSERT(WdfUsbPipeTypeInterrupt == pipe_info.PipeType);
|
||||
#endif // DBG
|
||||
|
||||
}
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
AndroidUsbInterruptPipeFileObject::~AndroidUsbInterruptPipeFileObject() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
}
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_INTERRUPT_PIPE_FILE_OBJECT_H__
|
||||
#define ANDROID_USB_INTERRUPT_PIPE_FILE_OBJECT_H__
|
||||
/** \file
|
||||
This file consists of declaration of class AndroidUsbInterruptPipeFileObject
|
||||
that encapsulates extension to an interrupt pipe file objects.
|
||||
*/
|
||||
|
||||
#include "android_usb_pipe_file_object.h"
|
||||
|
||||
/** AndroidUsbInterruptPipeFileObject class encapsulates extension for a KMDF
|
||||
file object that represent opened interrupt pipe. Instances of this class
|
||||
must be allocated from NonPagedPool.
|
||||
*/
|
||||
class AndroidUsbInterruptPipeFileObject : public AndroidUsbPipeFileObject {
|
||||
public:
|
||||
/** \brief Constructs the object.
|
||||
|
||||
This method must be called at low IRQL.
|
||||
@param dev_obj[in] Our device object for which this file has been created
|
||||
@param wdf_fo[in] KMDF file object this extension wraps
|
||||
@param wdf_pipe_obj[in] KMDF pipe for this file
|
||||
*/
|
||||
AndroidUsbInterruptPipeFileObject(AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo,
|
||||
WDFUSBPIPE wdf_pipe_obj);
|
||||
|
||||
/** \brief Destructs the object.
|
||||
|
||||
This method can be called at any IRQL.
|
||||
*/
|
||||
virtual ~AndroidUsbInterruptPipeFileObject();
|
||||
};
|
||||
|
||||
#endif // ANDROID_USB_INTERRUPT_PIPE_FILE_OBJECT_H__
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_NEW_DELETE_H__
|
||||
#define ANDROID_USB_NEW_DELETE_H__
|
||||
/** \file
|
||||
This file consists implementations of our 'new' and 'delete' operators
|
||||
*/
|
||||
|
||||
#include "android_usb_pool_tags.h"
|
||||
|
||||
/** \brief Checks if given pool type is one of NonPaged pool kinds.
|
||||
|
||||
All numeric values for all NonPaged pool types are even numbers while all
|
||||
numeric values for all PagedPool types are odd numbers (see definition of
|
||||
POOL_TYPE enum). So this routine utilizes this to see whether given pool
|
||||
type is one of NonPaged pool kinds. This routine can be called at any IRQL.
|
||||
@param pool_type[in] Pool type
|
||||
@return True if pool type is one of NonPaged pool types, false otherwise
|
||||
*/
|
||||
__forceinline bool IsPoolNonPaged(POOL_TYPE pool_type) {
|
||||
return (0 == (pool_type & 0x1));
|
||||
}
|
||||
|
||||
/** @name Operators new and delete
|
||||
|
||||
In Kernel Mode development each memory allocation must specify type of the
|
||||
pool from which memory should be allocated, usualy PagedPool or NonPagedPool.
|
||||
Because of that "traditional" operator 'new' that takes only one parameter
|
||||
(memory size) is not good so we modify that operator by adding two more
|
||||
parameters: pool type and memory tag (last one is optional but highly
|
||||
encouraged). To prevent from mistakes, traditional operator 'new' is also
|
||||
defined. It will allocate requested number of bytes from NonPagedPool with
|
||||
default memory tag but it will always assert on checked (debug) builds.
|
||||
Since there is no infrastructure for C++ exceptions in Kernel Mode we are
|
||||
not using them to report memory allocation error. So, on failure operators
|
||||
'new' are returning NULL instead of throwing an exception.
|
||||
*/
|
||||
///@{
|
||||
|
||||
/** \brief Main operator new
|
||||
|
||||
This is the main operator new that allocates specified number of bytes from
|
||||
the specified pool and assigns a custom tag to the allocated memory.
|
||||
Inherits IRQL restrictions for ExAllocatePoolWithTag (see the DDK doc).
|
||||
@param size[in] Number of bytes to allocate.
|
||||
@param pool_type[in] Type of the pool to allocate from.
|
||||
@param pool_tag[in] A tag to attach to the allocated memory. Since utilities
|
||||
that display tags use their ASCII representations it's advisable to
|
||||
use tag values that are ASCII symbols, f.i. 'ATag'. Note that due to
|
||||
inversion of bytes in stored ULONG value, to read 'ATag' in the tag
|
||||
displaying utility, the actual value passed to operator 'new' must be
|
||||
'gaTA'
|
||||
@return Pointer to allocated memory on success, NULL on error.
|
||||
*/
|
||||
__forceinline void* __cdecl operator new(size_t size,
|
||||
POOL_TYPE pool_type,
|
||||
ULONG pool_tag) {
|
||||
ASSERT((pool_type < MaxPoolType) && (0 != size));
|
||||
// Enforce IRQL restriction check.
|
||||
ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
|
||||
return size ? ExAllocatePoolWithTag(pool_type,
|
||||
static_cast<ULONG>(size),
|
||||
pool_tag) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
/** \brief
|
||||
Short operator new that attaches a default tag to the allocated memory.
|
||||
|
||||
This version of operator new allocates specified number of bytes from the
|
||||
specified pool and assigns a default tag (GANDR_POOL_TAG_DEFAULT) to the
|
||||
allocated memory. Inherits IRQL restrictions for ExAllocatePoolWithTag.
|
||||
@param size[in] Number of bytes to allocate.
|
||||
@param pool_type[in] Type of the pool to allocate from.
|
||||
@return Pointer to allocated memory on success, NULL on error.
|
||||
*/
|
||||
__forceinline void* __cdecl operator new(size_t size, POOL_TYPE pool_type) {
|
||||
ASSERT((pool_type < MaxPoolType) && (0 != size));
|
||||
// Enforce IRQL restriction check.
|
||||
ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
|
||||
return size ? ExAllocatePoolWithTag(pool_type,
|
||||
static_cast<ULONG>(size),
|
||||
GANDR_POOL_TAG_DEFAULT) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
/** \brief Traditional operator new that should never be used.
|
||||
|
||||
Using of this version of operator 'new' is prohibited in Kernel Mode
|
||||
development. For the sake of safety it is implemented though to allocate
|
||||
requested number of bytes from the NonPagedPool and attach default tag
|
||||
to the allocated memory. It will assert on checked (debug) builds.
|
||||
Inherits IRQL restrictions for ExAllocatePoolWithTag.
|
||||
@param size[in] Number of bytes to allocate.
|
||||
@return Pointer to memory allocated from NonPagedPool on success or NULL on
|
||||
error.
|
||||
*/
|
||||
__forceinline void* __cdecl operator new(size_t size) {
|
||||
ASSERTMSG("\n!!! Using of operator new(size_t size) is detected!\n"
|
||||
"This is illegal in our driver C++ development environment to use "
|
||||
"this version of operator 'new'. Please switch to\n"
|
||||
"new(size_t size, POOL_TYPE pool_type) or "
|
||||
"new(size_t size, POOL_TYPE pool_type, ULONG pool_tag) ASAP!!!\n",
|
||||
false);
|
||||
ASSERT(0 != size);
|
||||
return size ? ExAllocatePoolWithTag(NonPagedPool,
|
||||
static_cast<ULONG>(size),
|
||||
GANDR_POOL_TAG_DEFAULT) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
/** \brief Operator delete.
|
||||
|
||||
Frees memory allocated by 'new' operator.
|
||||
@param pointer[in] Memory to free. If this parameter is NULL operator does
|
||||
nothing but asserts on checked build. Inherits IRQL restrictions
|
||||
for ExFreePool.
|
||||
*/
|
||||
__forceinline void __cdecl operator delete(void* pointer) {
|
||||
ASSERT(NULL != pointer);
|
||||
if (NULL != pointer)
|
||||
ExFreePool(pointer);
|
||||
}
|
||||
|
||||
/** \brief Operator delete for arrays.
|
||||
|
||||
Frees memory allocated by 'new' operator.
|
||||
@param pointer[in] Memory to free. If this parameter is NULL operator does
|
||||
nothing but asserts on checked build. Inherits IRQL restrictions
|
||||
for ExFreePool.
|
||||
*/
|
||||
__forceinline void __cdecl operator delete[](void* pointer) {
|
||||
ASSERT(NULL != pointer);
|
||||
if (NULL != pointer)
|
||||
ExFreePool(pointer);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
#endif // ANDROID_USB_NEW_DELETE_H__
|
||||
@@ -1,738 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 AndroidUsbPipeFileObject that
|
||||
encapsulates a common extension for pipe file objects.
|
||||
*/
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
|
||||
#include "precomp.h"
|
||||
#include "android_usb_pipe_file_object.h"
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
AndroidUsbPipeFileObject::AndroidUsbPipeFileObject(
|
||||
AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo,
|
||||
WDFUSBPIPE wdf_pipe_obj)
|
||||
: AndroidUsbFileObject(AndroidUsbFileObjectTypePipe, dev_obj, wdf_fo),
|
||||
wdf_pipe_(wdf_pipe_obj) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
ASSERT(NULL != wdf_pipe_obj);
|
||||
}
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
AndroidUsbPipeFileObject::~AndroidUsbPipeFileObject() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
}
|
||||
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
NTSTATUS AndroidUsbPipeFileObject::InitializePipe(
|
||||
const WDF_USB_PIPE_INFORMATION* pipe_info) {
|
||||
ASSERT_IRQL_LOW();
|
||||
ASSERT(IsPipeAttached());
|
||||
if (!IsPipeAttached())
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
||||
// Initialize base class
|
||||
NTSTATUS status = AndroidUsbFileObject::Initialize();
|
||||
ASSERT(NT_SUCCESS(status));
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
// Save pipe information
|
||||
pipe_information_ = *pipe_info;
|
||||
|
||||
// We will provide size check ourselves (less surprizes always better)
|
||||
WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(wdf_pipe());
|
||||
|
||||
GoogleDbgPrint("\n===== File %p for %s pipe. max_transfer_size = %X, max_packet_size = %X",
|
||||
this, is_input_pipe() ? "read" : "write",
|
||||
max_transfer_size(), max_packet_size());
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
void AndroidUsbPipeFileObject::OnEvtIoRead(WDFREQUEST request,
|
||||
size_t length) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
// Make sure that this is an input pipe
|
||||
if (is_output_pipe()) {
|
||||
GoogleDbgPrint("\n!!!! Attempt to read from output pipe %p", this);
|
||||
WdfRequestComplete(request, STATUS_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure zero length I/O doesn't go through
|
||||
if (0 == length) {
|
||||
WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get MDL for this request.
|
||||
PMDL request_mdl = NULL;
|
||||
NTSTATUS status = WdfRequestRetrieveOutputWdmMdl(request, &request_mdl);
|
||||
ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
|
||||
if (NT_SUCCESS(status)) {
|
||||
CommonBulkReadWrite(request,
|
||||
request_mdl,
|
||||
static_cast<ULONG>(length),
|
||||
true,
|
||||
0,
|
||||
false);
|
||||
} else {
|
||||
WdfRequestComplete(request, status);
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidUsbPipeFileObject::OnEvtIoWrite(WDFREQUEST request,
|
||||
size_t length) {
|
||||
|
||||
// Make sure that this is an output pipe
|
||||
if (is_input_pipe()) {
|
||||
GoogleDbgPrint("\n!!!! Attempt to write to input pipe %p", this);
|
||||
WdfRequestComplete(request, STATUS_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure zero length I/O doesn't go through
|
||||
if (0 == length) {
|
||||
WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get MDL for this request.
|
||||
PMDL request_mdl = NULL;
|
||||
NTSTATUS status = WdfRequestRetrieveInputWdmMdl(request, &request_mdl);
|
||||
ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
|
||||
if (NT_SUCCESS(status)) {
|
||||
CommonBulkReadWrite(request,
|
||||
request_mdl,
|
||||
static_cast<ULONG>(length),
|
||||
false,
|
||||
0,
|
||||
false);
|
||||
} else {
|
||||
WdfRequestComplete(request, status);
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidUsbPipeFileObject::OnEvtIoDeviceControl(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len,
|
||||
ULONG ioctl_code) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
switch (ioctl_code) {
|
||||
case ADB_IOCTL_GET_ENDPOINT_INFORMATION:
|
||||
OnCtlGetEndpointInformation(request, output_buf_len);
|
||||
break;
|
||||
|
||||
case ADB_IOCTL_BULK_READ:
|
||||
OnCtlBulkRead(request, output_buf_len, input_buf_len);
|
||||
break;
|
||||
|
||||
case ADB_IOCTL_BULK_WRITE:
|
||||
OnCtlBulkWrite(request, output_buf_len, input_buf_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
AndroidUsbFileObject::OnEvtIoDeviceControl(request,
|
||||
output_buf_len,
|
||||
input_buf_len,
|
||||
ioctl_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidUsbPipeFileObject::OnCtlGetEndpointInformation(
|
||||
WDFREQUEST request,
|
||||
size_t output_buf_len) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
// Verify output buffer
|
||||
if (output_buf_len < sizeof(AdbEndpointInformation)) {
|
||||
WdfRequestCompleteWithInformation(request,
|
||||
STATUS_BUFFER_TOO_SMALL,
|
||||
sizeof(AdbEndpointInformation));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the output buffer
|
||||
NTSTATUS status;
|
||||
AdbEndpointInformation* ret_info =
|
||||
reinterpret_cast<AdbEndpointInformation*>(OutAddress(request, &status));
|
||||
ASSERT(NT_SUCCESS(status) && (NULL != ret_info));
|
||||
if (!NT_SUCCESS(status)) {
|
||||
WdfRequestComplete(request, status);
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy endpoint info to the output
|
||||
ret_info->max_packet_size = pipe_information_.MaximumPacketSize;
|
||||
ret_info->endpoint_address = pipe_information_.EndpointAddress;
|
||||
ret_info->polling_interval = pipe_information_.Interval;
|
||||
ret_info->setting_index = pipe_information_.SettingIndex;
|
||||
ret_info->endpoint_type =
|
||||
static_cast<AdbEndpointType>(pipe_information_.PipeType);
|
||||
ret_info->max_transfer_size = pipe_information_.MaximumTransferSize;
|
||||
|
||||
WdfRequestCompleteWithInformation(request,
|
||||
STATUS_SUCCESS,
|
||||
sizeof(AdbEndpointInformation));
|
||||
}
|
||||
|
||||
void AndroidUsbPipeFileObject::OnCtlBulkRead(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
// Make sure that this is an input pipe
|
||||
if (is_output_pipe()) {
|
||||
GoogleDbgPrint("\n!!!! Attempt to IOCTL read from output pipe %p", this);
|
||||
WdfRequestComplete(request, STATUS_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure zero length I/O doesn't go through
|
||||
if (0 == output_buf_len) {
|
||||
WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify buffers
|
||||
ASSERT(input_buf_len >= sizeof(AdbBulkTransfer));
|
||||
if (input_buf_len < sizeof(AdbBulkTransfer)) {
|
||||
WdfRequestComplete(request, STATUS_INVALID_BUFFER_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the input buffer
|
||||
NTSTATUS status;
|
||||
AdbBulkTransfer* transfer_param =
|
||||
reinterpret_cast<AdbBulkTransfer*>(InAddress(request, &status));
|
||||
ASSERT(NT_SUCCESS(status) && (NULL != transfer_param));
|
||||
if (!NT_SUCCESS(status)) {
|
||||
WdfRequestComplete(request, status);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get MDL for this request.
|
||||
PMDL request_mdl = NULL;
|
||||
status = WdfRequestRetrieveOutputWdmMdl(request, &request_mdl);
|
||||
ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
|
||||
if (NT_SUCCESS(status)) {
|
||||
// Perform the read
|
||||
CommonBulkReadWrite(request,
|
||||
request_mdl,
|
||||
static_cast<ULONG>(output_buf_len),
|
||||
true,
|
||||
transfer_param->time_out,
|
||||
true);
|
||||
} else {
|
||||
WdfRequestComplete(request, status);
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidUsbPipeFileObject::OnCtlBulkWrite(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
// Make sure that this is an output pipe
|
||||
if (is_input_pipe()) {
|
||||
GoogleDbgPrint("\n!!!! Attempt to IOCTL write to input pipe %p", this);
|
||||
WdfRequestComplete(request, STATUS_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify buffers
|
||||
ASSERT(input_buf_len >= sizeof(AdbBulkTransfer));
|
||||
// Output buffer points to ULONG that receives number of transferred bytes
|
||||
ASSERT(output_buf_len >= sizeof(ULONG));
|
||||
if ((input_buf_len < sizeof(AdbBulkTransfer)) ||
|
||||
(output_buf_len < sizeof(ULONG))) {
|
||||
WdfRequestComplete(request, STATUS_INVALID_BUFFER_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the input buffer
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
AdbBulkTransfer* transfer_param =
|
||||
reinterpret_cast<AdbBulkTransfer*>(InAddress(request, &status));
|
||||
ASSERT(NT_SUCCESS(status) && (NULL != transfer_param));
|
||||
if (!NT_SUCCESS(status)) {
|
||||
WdfRequestComplete(request, status);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the output buffer
|
||||
ULONG* ret_transfer =
|
||||
reinterpret_cast<ULONG*>(OutAddress(request, &status));
|
||||
ASSERT(NT_SUCCESS(status) && (NULL != ret_transfer));
|
||||
if (!NT_SUCCESS(status)) {
|
||||
WdfRequestComplete(request, status);
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache these param to prevent us from sudden change after we've chacked it.
|
||||
// This is common practice in protecting ourselves from malicious code:
|
||||
// 1. Never trust anything that comes from the User Mode.
|
||||
// 2. Never assume that anything that User Mode buffer has will remain
|
||||
// unchanged.
|
||||
void* transfer_buffer = transfer_param->GetWriteBuffer();
|
||||
ULONG transfer_size = transfer_param->transfer_size;
|
||||
|
||||
// Make sure zero length I/O doesn't go through
|
||||
if (0 == transfer_size) {
|
||||
*ret_transfer = 0;
|
||||
WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, sizeof(ULONG));
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure that buffer is not NULL
|
||||
ASSERT(NULL != transfer_buffer);
|
||||
if (NULL == transfer_buffer) {
|
||||
WdfRequestComplete(request, STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
// At this point we are ready to build MDL for the user buffer.
|
||||
PMDL write_mdl =
|
||||
IoAllocateMdl(transfer_buffer, transfer_size, FALSE, FALSE, NULL);
|
||||
ASSERT(NULL != write_mdl);
|
||||
if (NULL == write_mdl) {
|
||||
WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
|
||||
return;
|
||||
}
|
||||
|
||||
// Now we need to probe/lock this mdl
|
||||
__try {
|
||||
MmProbeAndLockPages(write_mdl,
|
||||
WdfRequestGetRequestorMode(request),
|
||||
IoReadAccess);
|
||||
status = STATUS_SUCCESS;
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
ASSERTMSG("\n!!!!! AndroidUsbPipeFileObject::OnCtlBulkWrite exception",
|
||||
false);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
IoFreeMdl(write_mdl);
|
||||
WdfRequestComplete(request, status);
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform the write
|
||||
status = CommonBulkReadWrite(request,
|
||||
write_mdl,
|
||||
transfer_size,
|
||||
false,
|
||||
transfer_param->time_out,
|
||||
true);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
// If CommonBulkReadWrite failed we need to unlock and free MDL here
|
||||
MmUnlockPages(write_mdl);
|
||||
IoFreeMdl(write_mdl);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS AndroidUsbPipeFileObject::CommonBulkReadWrite(
|
||||
WDFREQUEST request,
|
||||
PMDL transfer_mdl,
|
||||
ULONG length,
|
||||
bool is_read,
|
||||
ULONG time_out,
|
||||
bool is_ioctl) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
ASSERT(IsPipeAttached());
|
||||
if (!IsPipeAttached()) {
|
||||
WdfRequestComplete(request, STATUS_INVALID_DEVICE_STATE);
|
||||
return STATUS_INVALID_DEVICE_STATE;
|
||||
}
|
||||
|
||||
// Quick access check. Might be redundant though...
|
||||
ASSERT((is_read && is_input_pipe()) || (!is_read && is_output_pipe()));
|
||||
if ((is_read && is_output_pipe()) || (!is_read && is_input_pipe())) {
|
||||
WdfRequestComplete(request, STATUS_ACCESS_DENIED);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
// Set URB flags
|
||||
ULONG urb_flags = USBD_SHORT_TRANSFER_OK | (is_read ?
|
||||
USBD_TRANSFER_DIRECTION_IN :
|
||||
USBD_TRANSFER_DIRECTION_OUT);
|
||||
|
||||
// Calculate transfer length for this stage.
|
||||
ULONG stage_len =
|
||||
(length > GetTransferGranularity()) ? GetTransferGranularity() : length;
|
||||
|
||||
// Get virtual address that we're gonna use in the transfer.
|
||||
// We rely here on the fact that we're in the context of the calling thread.
|
||||
void* virtual_address = MmGetMdlVirtualAddress(transfer_mdl);
|
||||
|
||||
// Allocate our private MDL for this address which we will use for the transfer
|
||||
PMDL new_mdl = IoAllocateMdl(virtual_address, length, FALSE, FALSE, NULL);
|
||||
ASSERT(NULL != new_mdl);
|
||||
if (NULL == new_mdl) {
|
||||
WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// Map the portion of user buffer that we're going to transfer at this stage
|
||||
// to our mdl.
|
||||
IoBuildPartialMdl(transfer_mdl, new_mdl, virtual_address, stage_len);
|
||||
|
||||
// Allocate memory for URB and associate it with this request
|
||||
WDF_OBJECT_ATTRIBUTES mem_attrib;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT(&mem_attrib);
|
||||
mem_attrib.ParentObject = request;
|
||||
|
||||
WDFMEMORY urb_mem = NULL;
|
||||
PURB urb = NULL;
|
||||
NTSTATUS status =
|
||||
WdfMemoryCreate(&mem_attrib,
|
||||
NonPagedPool,
|
||||
GANDR_POOL_TAG_BULKRW_URB,
|
||||
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
|
||||
&urb_mem,
|
||||
reinterpret_cast<PVOID*>(&urb));
|
||||
ASSERT(NT_SUCCESS(status) && (NULL != urb));
|
||||
if (!NT_SUCCESS(status)) {
|
||||
IoFreeMdl(new_mdl);
|
||||
WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
// Get USB pipe handle for our pipe and initialize transfer request for it
|
||||
USBD_PIPE_HANDLE usbd_pipe_hndl = usbd_pipe();
|
||||
ASSERT(NULL != usbd_pipe_hndl);
|
||||
if (NULL == usbd_pipe_hndl) {
|
||||
IoFreeMdl(new_mdl);
|
||||
WdfRequestComplete(request, STATUS_INTERNAL_ERROR);
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
// Initialize URB with request information
|
||||
UsbBuildInterruptOrBulkTransferRequest(
|
||||
urb,
|
||||
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
|
||||
usbd_pipe_hndl,
|
||||
NULL,
|
||||
new_mdl,
|
||||
stage_len,
|
||||
urb_flags,
|
||||
NULL);
|
||||
|
||||
// Build transfer request
|
||||
status = WdfUsbTargetPipeFormatRequestForUrb(wdf_pipe(),
|
||||
request,
|
||||
urb_mem,
|
||||
NULL);
|
||||
ASSERT(NT_SUCCESS(status));
|
||||
if (!NT_SUCCESS(status)) {
|
||||
IoFreeMdl(new_mdl);
|
||||
WdfRequestComplete(request, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
// Initialize our request context.
|
||||
AndroidUsbWdfRequestContext* context =
|
||||
GetAndroidUsbWdfRequestContext(request);
|
||||
ASSERT(NULL != context);
|
||||
if (NULL == context) {
|
||||
IoFreeMdl(new_mdl);
|
||||
WdfRequestComplete(request, STATUS_INTERNAL_ERROR);
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
context->object_type = AndroidUsbWdfObjectTypeRequest;
|
||||
context->urb_mem = urb_mem;
|
||||
context->transfer_mdl = transfer_mdl;
|
||||
context->mdl = new_mdl;
|
||||
context->length = length;
|
||||
context->transfer_size = stage_len;
|
||||
context->num_xfer = 0;
|
||||
context->virtual_address = virtual_address;
|
||||
context->is_read = is_read;
|
||||
context->initial_time_out = time_out;
|
||||
context->is_ioctl = is_ioctl;
|
||||
|
||||
// Set our completion routine
|
||||
WdfRequestSetCompletionRoutine(request,
|
||||
CommonReadWriteCompletionEntry,
|
||||
this);
|
||||
|
||||
// Init send options (our timeout goes here)
|
||||
WDF_REQUEST_SEND_OPTIONS send_options;
|
||||
if (0 != time_out) {
|
||||
WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_TIMEOUT);
|
||||
WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&send_options, WDF_REL_TIMEOUT_IN_MS(time_out));
|
||||
}
|
||||
|
||||
// Timestamp first WdfRequestSend
|
||||
KeQuerySystemTime(&context->sent_at);
|
||||
|
||||
// Send request asynchronously.
|
||||
if (WdfRequestSend(request, wdf_pipe_io_target(),
|
||||
(0 == time_out) ? WDF_NO_SEND_OPTIONS : &send_options)) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Something went wrong here
|
||||
status = WdfRequestGetStatus(request);
|
||||
ASSERT(!NT_SUCCESS(status));
|
||||
GoogleDbgPrint("\n!!!!! CommonBulkReadWrite: WdfRequestGetStatus (is_read = %u) failed: %08X",
|
||||
is_read, status);
|
||||
WdfRequestCompleteWithInformation(request, status, 0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void AndroidUsbPipeFileObject::OnCommonReadWriteCompletion(
|
||||
WDFREQUEST request,
|
||||
PWDF_REQUEST_COMPLETION_PARAMS completion_params,
|
||||
AndroidUsbWdfRequestContext* context) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
NTSTATUS status = completion_params->IoStatus.Status;
|
||||
if (!NT_SUCCESS(status)){
|
||||
GoogleDbgPrint("\n========== Request completed with failure: %X", status);
|
||||
IoFreeMdl(context->mdl);
|
||||
// If this was IOCTL-originated write we must unlock and free
|
||||
// our transfer MDL.
|
||||
if (context->is_ioctl && !context->is_read) {
|
||||
MmUnlockPages(context->transfer_mdl);
|
||||
IoFreeMdl(context->transfer_mdl);
|
||||
}
|
||||
WdfRequestComplete(request, status);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get our URB buffer
|
||||
PURB urb
|
||||
= reinterpret_cast<PURB>(WdfMemoryGetBuffer(context->urb_mem, NULL));
|
||||
ASSERT(NULL != urb);
|
||||
|
||||
// Lets see how much has been transfered and update our counters accordingly
|
||||
ULONG bytes_transfered =
|
||||
urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
|
||||
// We expect writes to transfer entire packet
|
||||
ASSERT((bytes_transfered == context->transfer_size) || context->is_read);
|
||||
context->num_xfer += bytes_transfered;
|
||||
context->length -= bytes_transfered;
|
||||
|
||||
// Is there anything left to transfer? Now, by the protocol we should
|
||||
// successfuly complete partial reads, instead of waiting on full set
|
||||
// of requested bytes being accumulated in the read buffer.
|
||||
if ((0 == context->length) || context->is_read) {
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
// This was the last transfer
|
||||
if (context->is_ioctl && !context->is_read) {
|
||||
// For IOCTL-originated writes we have to return transfer size through
|
||||
// the IOCTL's output buffer.
|
||||
ULONG* ret_transfer =
|
||||
reinterpret_cast<ULONG*>(OutAddress(request, NULL));
|
||||
ASSERT(NULL != ret_transfer);
|
||||
if (NULL != ret_transfer)
|
||||
*ret_transfer = context->num_xfer;
|
||||
WdfRequestSetInformation(request, sizeof(ULONG));
|
||||
|
||||
// We also must unlock / free transfer MDL
|
||||
MmUnlockPages(context->transfer_mdl);
|
||||
IoFreeMdl(context->transfer_mdl);
|
||||
} else {
|
||||
// For other requests we report transfer size through the request I/O
|
||||
// completion status.
|
||||
WdfRequestSetInformation(request, context->num_xfer);
|
||||
}
|
||||
IoFreeMdl(context->mdl);
|
||||
WdfRequestComplete(request, status);
|
||||
return;
|
||||
}
|
||||
|
||||
// There are something left for the transfer. Prepare for it.
|
||||
// Required to free any mapping made on the partial MDL and
|
||||
// reset internal MDL state.
|
||||
MmPrepareMdlForReuse(context->mdl);
|
||||
|
||||
// Update our virtual address
|
||||
context->virtual_address =
|
||||
reinterpret_cast<char*>(context->virtual_address) + bytes_transfered;
|
||||
|
||||
// Calculate size of this transfer
|
||||
ULONG stage_len =
|
||||
(context->length > GetTransferGranularity()) ? GetTransferGranularity() :
|
||||
context->length;
|
||||
|
||||
IoBuildPartialMdl(context->transfer_mdl,
|
||||
context->mdl,
|
||||
context->virtual_address,
|
||||
stage_len);
|
||||
|
||||
// Reinitialize the urb and context
|
||||
urb->UrbBulkOrInterruptTransfer.TransferBufferLength = stage_len;
|
||||
context->transfer_size = stage_len;
|
||||
|
||||
// Format the request to send a URB to a USB pipe.
|
||||
status = WdfUsbTargetPipeFormatRequestForUrb(wdf_pipe(),
|
||||
request,
|
||||
context->urb_mem,
|
||||
NULL);
|
||||
ASSERT(NT_SUCCESS(status));
|
||||
if (!NT_SUCCESS(status)) {
|
||||
if (context->is_ioctl && !context->is_read) {
|
||||
MmUnlockPages(context->transfer_mdl);
|
||||
IoFreeMdl(context->transfer_mdl);
|
||||
}
|
||||
IoFreeMdl(context->mdl);
|
||||
WdfRequestComplete(request, status);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the completion routine
|
||||
WdfRequestSetCompletionRoutine(request,
|
||||
CommonReadWriteCompletionEntry,
|
||||
this);
|
||||
|
||||
// Send the request asynchronously.
|
||||
if (!WdfRequestSend(request, wdf_pipe_io_target(), WDF_NO_SEND_OPTIONS)) {
|
||||
if (context->is_ioctl && !context->is_read) {
|
||||
MmUnlockPages(context->transfer_mdl);
|
||||
IoFreeMdl(context->transfer_mdl);
|
||||
}
|
||||
status = WdfRequestGetStatus(request);
|
||||
IoFreeMdl(context->mdl);
|
||||
WdfRequestComplete(request, status);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS AndroidUsbPipeFileObject::ResetPipe() {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
|
||||
// This routine synchronously submits a URB_FUNCTION_RESET_PIPE
|
||||
// request down the stack.
|
||||
NTSTATUS status = WdfUsbTargetPipeAbortSynchronously(wdf_pipe(),
|
||||
WDF_NO_HANDLE,
|
||||
NULL);
|
||||
if (NT_SUCCESS(status)) {
|
||||
status = WdfUsbTargetPipeResetSynchronously(wdf_pipe(),
|
||||
WDF_NO_HANDLE,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(status))
|
||||
GoogleDbgPrint("\n!!!!! AndroidUsbPipeFileObject::ResetPipe failed %X", status);
|
||||
} else {
|
||||
GoogleDbgPrint("\n!!!!! WdfUsbTargetPipeAbortSynchronously failed %X", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS AndroidUsbPipeFileObject::QueueResetPipePassiveCallback() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
// Initialize workitem
|
||||
WDF_OBJECT_ATTRIBUTES attr;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT(&attr);
|
||||
WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attr, AndroidUsbWorkitemContext);
|
||||
attr.ParentObject = wdf_device();
|
||||
|
||||
WDFWORKITEM wdf_work_item = NULL;
|
||||
WDF_WORKITEM_CONFIG workitem_config;
|
||||
WDF_WORKITEM_CONFIG_INIT(&workitem_config, ResetPipePassiveCallbackEntry);
|
||||
NTSTATUS status = WdfWorkItemCreate(&workitem_config,
|
||||
&attr,
|
||||
&wdf_work_item);
|
||||
ASSERT(NT_SUCCESS(status) && (NULL != wdf_work_item));
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
// Initialize our extension to work item
|
||||
AndroidUsbWorkitemContext* context =
|
||||
GetAndroidUsbWorkitemContext(wdf_work_item);
|
||||
ASSERT(NULL != context);
|
||||
if (NULL == context) {
|
||||
WdfObjectDelete(wdf_work_item);
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
context->object_type = AndroidUsbWdfObjectTypeWorkitem;
|
||||
context->pipe_file_ext = this;
|
||||
|
||||
// Enqueue this work item.
|
||||
WdfWorkItemEnqueue(wdf_work_item);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void AndroidUsbPipeFileObject::CommonReadWriteCompletionEntry(
|
||||
WDFREQUEST request,
|
||||
WDFIOTARGET wdf_target,
|
||||
PWDF_REQUEST_COMPLETION_PARAMS completion_params,
|
||||
WDFCONTEXT completion_context) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
AndroidUsbWdfRequestContext*
|
||||
context = GetAndroidUsbWdfRequestContext(request);
|
||||
ASSERT((NULL != context) && (AndroidUsbWdfObjectTypeRequest == context->object_type));
|
||||
|
||||
AndroidUsbPipeFileObject* pipe_file_ext =
|
||||
reinterpret_cast<AndroidUsbPipeFileObject*>(completion_context);
|
||||
ASSERT((NULL != pipe_file_ext) &&
|
||||
(pipe_file_ext->wdf_pipe() == (WDFUSBPIPE)wdf_target));
|
||||
|
||||
pipe_file_ext->OnCommonReadWriteCompletion(request,
|
||||
completion_params,
|
||||
context);
|
||||
}
|
||||
|
||||
void AndroidUsbPipeFileObject::ResetPipePassiveCallbackEntry(
|
||||
WDFWORKITEM wdf_work_item) {
|
||||
ASSERT_IRQL_PASSIVE();
|
||||
|
||||
AndroidUsbWorkitemContext* context =
|
||||
GetAndroidUsbWorkitemContext(wdf_work_item);
|
||||
ASSERT((NULL != context) &&
|
||||
(AndroidUsbWdfObjectTypeWorkitem == context->object_type));
|
||||
if ((NULL == context) ||
|
||||
(AndroidUsbWdfObjectTypeWorkitem != context->object_type)) {
|
||||
WdfObjectDelete(wdf_work_item);
|
||||
return;
|
||||
}
|
||||
|
||||
// In the sample they reset the device if pipe reset failed
|
||||
AndroidUsbDeviceObject* wdf_device_ext =
|
||||
context->pipe_file_ext->device_object();
|
||||
|
||||
NTSTATUS status = context->pipe_file_ext->ResetPipe();
|
||||
if (!NT_SUCCESS(status))
|
||||
status = wdf_device_ext->ResetDevice();
|
||||
|
||||
WdfObjectDelete(wdf_work_item);
|
||||
}
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
@@ -1,305 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_PIPE_FILE_OBJECT_H__
|
||||
#define ANDROID_USB_PIPE_FILE_OBJECT_H__
|
||||
/** \file
|
||||
This file consists of declaration of class AndroidUsbPipeFileObject that
|
||||
encapsulates a common extension for pipe file objects.
|
||||
*/
|
||||
|
||||
#include "android_usb_file_object.h"
|
||||
|
||||
/** AndroidUsbPipeFileObject class encapsulates extension for a KMDF file
|
||||
object that represents opened pipe. Instances of this class must be
|
||||
allocated from NonPagedPool.
|
||||
*/
|
||||
class AndroidUsbPipeFileObject : public AndroidUsbFileObject {
|
||||
public:
|
||||
/** \brief Constructs the object.
|
||||
|
||||
This method must be called at low IRQL.
|
||||
@param dev_obj[in] Our device object for which this file has been created
|
||||
@param wdf_fo[in] KMDF file object this extension wraps
|
||||
@param wdf_pipe_obj[in] KMDF pipe for this file
|
||||
*/
|
||||
AndroidUsbPipeFileObject(AndroidUsbDeviceObject* dev_obj,
|
||||
WDFFILEOBJECT wdf_fo,
|
||||
WDFUSBPIPE wdf_pipe_obj);
|
||||
|
||||
/** \brief Destructs the object.
|
||||
|
||||
This method can be called at any IRQL.
|
||||
*/
|
||||
virtual ~AndroidUsbPipeFileObject();
|
||||
|
||||
/** \brief Initializes the pipe file object extension
|
||||
|
||||
This method internally calls AndroidUsbFileObject::Initialize()
|
||||
This method must be called at low IRQL
|
||||
@param pipe_info[in] Pipe information
|
||||
@return STATUS_SUCCESS or an appropriate error code
|
||||
*/
|
||||
virtual NTSTATUS InitializePipe(const WDF_USB_PIPE_INFORMATION* pipe_info);
|
||||
|
||||
/** \brief Read event handler
|
||||
|
||||
This method is called when a read request comes to the file object this
|
||||
extension wraps. This method is an override.
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param length[in] The number of bytes to be read.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
virtual void OnEvtIoRead(WDFREQUEST request, size_t length);
|
||||
|
||||
/** \brief Write event handler
|
||||
|
||||
This method is called when a write request comes to the file object this
|
||||
extension wraps. This method is an override.
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param length[in] The number of bytes to be written.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
virtual void OnEvtIoWrite(WDFREQUEST request, size_t length);
|
||||
|
||||
/** \brief IOCTL event handler
|
||||
|
||||
This method is called when a device control request comes to the file
|
||||
object this extension wraps. We hanlde the following IOCTLs here:
|
||||
1. ADB_CTL_GET_ENDPOINT_INFORMATION
|
||||
2. ADB_CTL_BULK_READ
|
||||
3. ADB_CTL_BULK_WRITE
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
@param input_buf_len[in] The length, in bytes, of the request's input
|
||||
buffer, if an input buffer is available.
|
||||
@param ioctl_code[in] The driver-defined or system-defined I/O control code
|
||||
that is associated with the request.
|
||||
@return Successful status or an appropriate error code
|
||||
*/
|
||||
virtual void OnEvtIoDeviceControl(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len,
|
||||
ULONG ioctl_code);
|
||||
|
||||
protected:
|
||||
/** \brief Handler for ADB_CTL_GET_ENDPOINT_INFORMATION IOCTL request
|
||||
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
*/
|
||||
virtual void OnCtlGetEndpointInformation(WDFREQUEST request,
|
||||
size_t output_buf_len);
|
||||
|
||||
/** \brief Handler for ADB_CTL_BULK_READ IOCTL request
|
||||
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
@param input_buf_len[in] The length, in bytes, of the request's input
|
||||
buffer, if an input buffer is available.
|
||||
*/
|
||||
virtual void OnCtlBulkRead(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len);
|
||||
|
||||
/** \brief Handler for ADB_CTL_BULK_WRITE IOCTL request
|
||||
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param output_buf_len[in] The length, in bytes, of the request's output
|
||||
buffer, if an output buffer is available.
|
||||
@param input_buf_len[in] The length, in bytes, of the request's input
|
||||
buffer, if an input buffer is available.
|
||||
*/
|
||||
virtual void OnCtlBulkWrite(WDFREQUEST request,
|
||||
size_t output_buf_len,
|
||||
size_t input_buf_len);
|
||||
|
||||
/** \brief Performs common bulk read / write on the pipe
|
||||
|
||||
This method is called from bulk and interrupt pipe file extensions to
|
||||
perform read to / write from the pipe this file represents. Typicaly,
|
||||
this method is called from OnEvtIoRead / OnEvtIoWrite /
|
||||
OnEvtIoDeviceControl methods. One very special case for this method is
|
||||
IOCTL-originated write request. If this is IOCTL-originated write request
|
||||
we can't report transfer size through the request's status block. Instead,
|
||||
for IOCTL-originated writes, the output buffer must a) exist and b) point
|
||||
to an ULONG that will receive size of the transfer. Besides, for this type
|
||||
of writes we create / lock write buffer MDL ourselves so we need to unlock
|
||||
and free it in the completion routine.
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object.
|
||||
@param transfer_mdl[in] MDL for the transferring buffer. The MDL must be
|
||||
locked prior to this call.
|
||||
@param length[in] The number of bytes to be read / written. If this method
|
||||
is actually IOCTL originated write request this parameter must be
|
||||
taken from AdbBulkTransfer.transfer_size by the caller of this
|
||||
method. AdbBulkTransfer is available at the beginning of the input
|
||||
buffer for bulk read / write IOCTLs.
|
||||
@param is_read[in] If true this is a read operation, otherwise it's write
|
||||
operation.
|
||||
@param time_out[in] Number of milliseconds for this request to complete.
|
||||
If this parameter is zero there will be no timeout associated with
|
||||
the request. Otherwise, if request doesn't complete within the given
|
||||
timeframe it will be cancelled.
|
||||
@param is_ioctl[in] If 'true' this method has been called from IOCTL
|
||||
handler. Otherwise it has been called from read / write handler. If
|
||||
this is IOCTL-originated write request we need to report bytes
|
||||
transferred through the IOCTL's output buffer.
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
@return STATUS_SUCCESS or an appropriate error code
|
||||
*/
|
||||
virtual NTSTATUS CommonBulkReadWrite(WDFREQUEST request,
|
||||
PMDL transfer_mdl,
|
||||
ULONG length,
|
||||
bool is_read,
|
||||
ULONG time_out,
|
||||
bool is_ioctl);
|
||||
|
||||
/** \brief Handles request completion for CommonBulkReadWrite
|
||||
|
||||
This method is called from CommonReadWriteCompletionEntry.
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object that is being
|
||||
completed.
|
||||
@param params[in] A pointer to a WDF_REQUEST_COMPLETION_PARAMS structure
|
||||
that contains information about the completed request.
|
||||
@param context[in] Context associated with this request in
|
||||
CommonBulkReadWrite
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
*/
|
||||
virtual void OnCommonReadWriteCompletion(WDFREQUEST request,
|
||||
PWDF_REQUEST_COMPLETION_PARAMS completion_params,
|
||||
AndroidUsbWdfRequestContext* context);
|
||||
|
||||
/** \brief Resets pipe associated with this file
|
||||
|
||||
After reseting the pipe this object might be destroyed.
|
||||
This method must be called at PASSIVE IRQL.
|
||||
@param read_device_on_failure[in] If true and reset pipe has failed this
|
||||
method will attempt to reset the device.
|
||||
@return STATUS_SUCCESS on success or an appropriate error code
|
||||
*/
|
||||
virtual NTSTATUS ResetPipe();
|
||||
|
||||
/** \brief Queues a workitem to launch pipe reset at PASSIVE IRQL
|
||||
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL.
|
||||
@return STATUS_SUCCESS or an appropriate error code.
|
||||
*/
|
||||
virtual NTSTATUS QueueResetPipePassiveCallback();
|
||||
|
||||
private:
|
||||
/** \brief Request completion routine for CommonBulkReadWrite
|
||||
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL.
|
||||
@param request[in] A handle to a framework request object that is being
|
||||
completed.
|
||||
@param wdf_target[in] A handle to an I/O target object that represents the
|
||||
I/O target that completed the request. In this case this is a pipe.
|
||||
@param params[in] A pointer to a WDF_REQUEST_COMPLETION_PARAMS structure
|
||||
that contains information about the completed request.
|
||||
@param completion_context[in] A handle to driver-supplied context
|
||||
information, which the driver specified in a previous call to
|
||||
WdfRequestSetCompletionRoutine. In our case this is a pointer
|
||||
to this class instance that issued the request.
|
||||
This method can be called IRQL <= DISPATCH_LEVEL.
|
||||
*/
|
||||
static void CommonReadWriteCompletionEntry(WDFREQUEST request,
|
||||
WDFIOTARGET wdf_target,
|
||||
PWDF_REQUEST_COMPLETION_PARAMS params,
|
||||
WDFCONTEXT completion_context);
|
||||
|
||||
/** \brief Entry point for pipe reset workitem callback
|
||||
|
||||
This method is called at PASSIVE IRQL
|
||||
@param wdf_work_item[in] A handle to a framework work item object.
|
||||
*/
|
||||
static void ResetPipePassiveCallbackEntry(WDFWORKITEM wdf_work_item);
|
||||
|
||||
public:
|
||||
/// Gets KMDF pipe handle for this file
|
||||
__forceinline WDFUSBPIPE wdf_pipe() const {
|
||||
return wdf_pipe_;
|
||||
}
|
||||
|
||||
/// Gets maximum transfer size for this pipe
|
||||
__forceinline ULONG max_transfer_size() const {
|
||||
ASSERT(0 != pipe_information_.MaximumTransferSize);
|
||||
return pipe_information_.MaximumTransferSize;
|
||||
}
|
||||
|
||||
/// Gets maximum packet size this pipe is capable of
|
||||
__forceinline ULONG max_packet_size() const {
|
||||
ASSERT(0 != pipe_information_.MaximumPacketSize);
|
||||
return pipe_information_.MaximumPacketSize;
|
||||
}
|
||||
|
||||
/// Gets transfer granularity
|
||||
// TODO: It looks like device USB is capable of handling
|
||||
// packets with size greater than pipe_information_.MaximumPacketSize!
|
||||
// So, looks like we are not bound by this parameter in this driver.
|
||||
__forceinline ULONG GetTransferGranularity() const {
|
||||
return max_transfer_size();
|
||||
}
|
||||
|
||||
/// Checks if this is an input pipe
|
||||
__forceinline bool is_input_pipe() const {
|
||||
return WDF_USB_PIPE_DIRECTION_IN(pipe_information_.EndpointAddress) ?
|
||||
true : false;
|
||||
}
|
||||
|
||||
/// Checks if this is an output pipe
|
||||
__forceinline bool is_output_pipe() const {
|
||||
return WDF_USB_PIPE_DIRECTION_OUT(pipe_information_.EndpointAddress) ?
|
||||
true : false;
|
||||
}
|
||||
|
||||
/// Checks if pipe is attached to this file
|
||||
__forceinline bool IsPipeAttached() const {
|
||||
return (NULL != wdf_pipe());
|
||||
}
|
||||
|
||||
/// Gets USBD pipe handle
|
||||
// TODO: Can we cache this?
|
||||
__forceinline USBD_PIPE_HANDLE usbd_pipe() const {
|
||||
ASSERT(IsPipeAttached());
|
||||
return (IsPipeAttached()) ? WdfUsbTargetPipeWdmGetPipeHandle(wdf_pipe()) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
/// Gets I/O target handle for this pipe
|
||||
// TODO: Can we cache this?
|
||||
__forceinline WDFIOTARGET wdf_pipe_io_target() const {
|
||||
ASSERT(IsPipeAttached());
|
||||
return (IsPipeAttached()) ? WdfUsbTargetPipeGetIoTarget(wdf_pipe()) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Cached pipe information
|
||||
WDF_USB_PIPE_INFORMATION pipe_information_;
|
||||
|
||||
/// KMDF pipe handle for this file
|
||||
WDFUSBPIPE wdf_pipe_;
|
||||
};
|
||||
|
||||
#endif // ANDROID_USB_PIPE_FILE_OBJECT_H__
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_POOL_TAGS_H__
|
||||
#define ANDROID_USB_POOL_TAGS_H__
|
||||
/** \file
|
||||
This file consists definitions for pool tags used in memory allocations for
|
||||
the driver.
|
||||
*/
|
||||
|
||||
/// Default pool tag for memory allocations (GAND)
|
||||
#define GANDR_POOL_TAG_DEFAULT 'DNAG'
|
||||
|
||||
/// Pool tag for the driver object (GADR)
|
||||
#define GANDR_POOL_TAG_DRIVER_OBJECT 'RDAG'
|
||||
|
||||
/// Pool tag for KMDF device object extension (GADx)
|
||||
#define GANDR_POOL_TAG_KMDF_DEVICE 'xDAG'
|
||||
|
||||
/// Pool tag for target device configuration descriptor (GACD)
|
||||
#define GANDR_POOL_TAG_DEV_CFG_DESC 'DCAG'
|
||||
|
||||
/// Pool tag for device file object extension (GADf)
|
||||
#define GANDR_POOL_TAG_DEVICE_FO 'fDAG'
|
||||
|
||||
/// Pool tag for a bulk file object extension (GABx)
|
||||
#define GANDR_POOL_TAG_BULK_FILE 'xBAG'
|
||||
|
||||
/// Pool tag for an interrupt file object extension (GAIx)
|
||||
#define GANDR_POOL_TAG_INTERRUPT_FILE 'xIAG'
|
||||
|
||||
/// Pool tag for URB allocated in bulk read / write (GAbu)
|
||||
#define GANDR_POOL_TAG_BULKRW_URB 'ubAG'
|
||||
|
||||
/// Pool tag for interface pairs (GAip)
|
||||
#define GANDR_POOL_TAG_INTERF_PAIRS 'piAG'
|
||||
|
||||
#endif // ANDROID_USB_POOL_TAGS_H__
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 a class AndroidUsbWdfObject that
|
||||
encapsulates a basic extension to all KMDF objects. Currently, device and
|
||||
file object extensions ared derived from it.
|
||||
*/
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
|
||||
#include "precomp.h"
|
||||
#include "android_usb_wdf_object.h"
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
AndroidUsbWdfObject::AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type)
|
||||
: wdf_object_(NULL),
|
||||
object_type_(obj_type) {
|
||||
ASSERT_IRQL_LOW();
|
||||
ASSERT(obj_type < AndroidUsbWdfObjectTypeMax);
|
||||
}
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
AndroidUsbWdfObject::~AndroidUsbWdfObject() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
}
|
||||
|
||||
#pragma code_seg("PAGE")
|
||||
|
||||
NTSTATUS AndroidUsbWdfObject::InitObjectAttributes(
|
||||
PWDF_OBJECT_ATTRIBUTES wdf_obj_attr,
|
||||
WDFOBJECT parent) {
|
||||
ASSERT_IRQL_LOW();
|
||||
|
||||
// Enforce file object extension exception.
|
||||
ASSERT(!Is(AndroidUsbWdfObjectTypeFile));
|
||||
if (Is(AndroidUsbWdfObjectTypeFile))
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
||||
// Initialize attributes and set cleanup and destroy callbacks
|
||||
WDF_OBJECT_ATTRIBUTES_INIT(wdf_obj_attr);
|
||||
WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(wdf_obj_attr,
|
||||
AndroidUsbWdfObjectContext);
|
||||
wdf_obj_attr->EvtCleanupCallback = EvtCleanupCallbackEntry;
|
||||
wdf_obj_attr->EvtDestroyCallback = EvtDestroyCallbackEntry;
|
||||
wdf_obj_attr->ParentObject = parent;
|
||||
wdf_obj_attr->SynchronizationScope = GetWdfSynchronizationScope();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS AndroidUsbWdfObject::InitializeContext() {
|
||||
ASSERT_IRQL_LOW();
|
||||
ASSERT(IsAttached());
|
||||
if (!IsAttached())
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
||||
// Initialize our extension to that object
|
||||
AndroidUsbWdfObjectContext* context =
|
||||
GetAndroidUsbWdfObjectContext(wdf_object());
|
||||
ASSERT(NULL != context);
|
||||
if (NULL == context)
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
||||
// Make sure that extension has not been initialized
|
||||
ASSERT((0 == context->object_type) && (NULL == context->wdf_object_ext));
|
||||
if ((0 != context->object_type) || (NULL != context->wdf_object_ext))
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
||||
context->object_type = object_type();
|
||||
context->wdf_object_ext = this;
|
||||
ASSERT(this == GetAndroidUsbWdfObjectFromHandle(wdf_object()));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#pragma code_seg()
|
||||
|
||||
WDF_SYNCHRONIZATION_SCOPE AndroidUsbWdfObject::GetWdfSynchronizationScope() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
// By default we don't want KMDF to synchronize access to our objects
|
||||
return WdfSynchronizationScopeNone;
|
||||
}
|
||||
|
||||
void AndroidUsbWdfObject::OnEvtCleanupCallback() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
GoogleDbgPrint("\n----- Object %p of type %u is cleaned up",
|
||||
this, object_type());
|
||||
}
|
||||
|
||||
void AndroidUsbWdfObject::OnEvtDestroyCallback() {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
GoogleDbgPrint("\n----- Object %p of type %u is destroyed",
|
||||
this, object_type());
|
||||
}
|
||||
|
||||
void AndroidUsbWdfObject::EvtCleanupCallbackEntry(WDFOBJECT wdf_obj) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
AndroidUsbWdfObjectContext* context = GetAndroidUsbWdfObjectContext(wdf_obj);
|
||||
ASSERT(NULL != context);
|
||||
if (NULL != context) {
|
||||
// For file objects we will be always called here even though we didn't
|
||||
// create any extension for them. In this case the context must not be
|
||||
// initialized.
|
||||
ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) ||
|
||||
((0 != context->object_type) && (NULL != context->wdf_object_ext)));
|
||||
if (NULL != context->wdf_object_ext) {
|
||||
ASSERT(context->wdf_object_ext->Is(context->object_type));
|
||||
context->wdf_object_ext->OnEvtCleanupCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidUsbWdfObject::EvtDestroyCallbackEntry(WDFOBJECT wdf_obj) {
|
||||
ASSERT_IRQL_LOW_OR_DISPATCH();
|
||||
|
||||
AndroidUsbWdfObjectContext* context =
|
||||
GetAndroidUsbWdfObjectContext(wdf_obj);
|
||||
ASSERT(NULL != context);
|
||||
if (NULL != context) {
|
||||
// For file objects we will be always called here even though we didn't
|
||||
// create any extension for them. In this case the context must not be
|
||||
// initialized.
|
||||
ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) ||
|
||||
((0 != context->object_type) && (NULL != context->wdf_object_ext)));
|
||||
if (NULL != context->wdf_object_ext) {
|
||||
ASSERT(context->wdf_object_ext->Is(context->object_type));
|
||||
context->wdf_object_ext->OnEvtDestroyCallback();
|
||||
delete context->wdf_object_ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma data_seg()
|
||||
#pragma code_seg()
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_USB_WDF_OBJECT_H__
|
||||
#define ANDROID_USB_WDF_OBJECT_H__
|
||||
/** \file
|
||||
This file consists of declaration of a class AndroidUsbWdfObject that
|
||||
encapsulates a basic extension to all KMDF objects. Currently, device and
|
||||
file object extensions ared derived from it.
|
||||
*/
|
||||
|
||||
/** AndroidUsbWdfObject class encapsulates a basic extension to all KMDF
|
||||
objects. Currently, device and file object extensions ared derived from it.
|
||||
Instances of this and derived classes must be allocated from NonPagedPool.
|
||||
*/
|
||||
class AndroidUsbWdfObject {
|
||||
public:
|
||||
/** \brief Constructs the object.
|
||||
|
||||
@param obj_type[in] Type of the object that this wrapper represents.
|
||||
This method must be called at low IRQL.
|
||||
*/
|
||||
AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type);
|
||||
|
||||
/** \brief Destructs the object.
|
||||
|
||||
This method can be called at any IRQL.
|
||||
*/
|
||||
virtual ~AndroidUsbWdfObject();
|
||||
|
||||
/** \brief Initializes object attributes for new KMDF object.
|
||||
|
||||
Each KMDF extension object must perform attribute initializations in order
|
||||
to register an extension with KMDF framework. Since all our extensions are
|
||||
derived from the base AndroidUsbWdfObject we use a single WDF object
|
||||
extension context for all KMDF objects that we extend. So we can initialize
|
||||
and register our context extension structure here. Note that object
|
||||
attributes for file object wrappers are initialized globaly, when device
|
||||
object is created. So file object extensions must not call this method.
|
||||
This method must be called at low IRQL.
|
||||
@param wdf_obj_attr[out] Object attributes to initialize.
|
||||
@param parent[in] Parent object for this object. Can be NULL.
|
||||
@return STATUS_SUCCESS on success or an appropriate error code.
|
||||
*/
|
||||
virtual NTSTATUS InitObjectAttributes(PWDF_OBJECT_ATTRIBUTES wdf_obj_attr,
|
||||
WDFOBJECT parent);
|
||||
|
||||
/** \brief Initializes context for this extension
|
||||
|
||||
This method initializes AndroidUsbWdfObjectContext structure that KMDF
|
||||
allocated for the object that is being extended with this class.
|
||||
InitObjectAttributes method must be called prior to the call to this
|
||||
method. Besides, before calling this method, instance of this class must
|
||||
be already attached to the KMDF object it represents. Otherwise this
|
||||
method will fail with STATUS_INTERNAL_ERROR.
|
||||
This method must be called at low IRQL.
|
||||
@return STATUS_SUCCESS on success or an appropriate error code
|
||||
*/
|
||||
virtual NTSTATUS InitializeContext();
|
||||
|
||||
|
||||
protected:
|
||||
/** \brief Returns syncronisation scope for this extension type.
|
||||
|
||||
This method is called from InitObjectAttributes method to specify what
|
||||
type of synchronization is required for instances of this type. By
|
||||
default we return WdfSynchronizationScopeNone which makes KMDF not
|
||||
to synchronize access to this type of object.
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL.
|
||||
*/
|
||||
virtual WDF_SYNCHRONIZATION_SCOPE GetWdfSynchronizationScope();
|
||||
|
||||
/** \brief Handler for cleanup event fired for associated KMDF object.
|
||||
|
||||
The framework calls this callback function when either the framework or a
|
||||
driver attempts to delete the object.
|
||||
This method can be called at IRQL <= DISPATCH_LEVEL.
|
||||
*/
|
||||
virtual void OnEvtCleanupCallback();
|
||||
|
||||
/** \brief Handler for destroy callback
|
||||
|
||||
The framework calls the EvtDestroyCallback callback function after the
|
||||
object's reference count has been decremented to zero. The framework
|
||||
deletes the object immediately after the EvtDestroyCallback callback
|
||||
function returns.
|
||||
This callback can be called at IRQL <= DISPATCH_LEVEL.
|
||||
*/
|
||||
virtual void OnEvtDestroyCallback();
|
||||
|
||||
/** \brief Removes driver's references on an object so it can be deleted.
|
||||
|
||||
The framework calls the callback function when either the framework or a
|
||||
driver attempts to delete the object.
|
||||
This callback can be called at IRQL <= DISPATCH_LEVEL.
|
||||
@param wdf_obj[in] A handle to a framework object this class wraps.
|
||||
*/
|
||||
static void EvtCleanupCallbackEntry(WDFOBJECT wdf_obj);
|
||||
|
||||
/** \brief Called when framework object is being deleted
|
||||
|
||||
The framework calls the EvtDestroyCallback callback function after the
|
||||
object's reference count has been decremented to zero. The framework
|
||||
deletes the object immediately after the EvtDestroyCallback callback
|
||||
function returns.
|
||||
This callback can be called at IRQL <= DISPATCH_LEVEL.
|
||||
@param wdf_obj[in] A handle to a framework object this class wraps.
|
||||
*/
|
||||
static void EvtDestroyCallbackEntry(WDFOBJECT wdf_obj);
|
||||
|
||||
public:
|
||||
|
||||
/// Gets KMDF object extended with this instance
|
||||
__forceinline WDFOBJECT wdf_object() const {
|
||||
return wdf_object_;
|
||||
}
|
||||
|
||||
/// Sets KMDF object associated with this extension
|
||||
__forceinline void set_wdf_object(WDFOBJECT wdf_obj) {
|
||||
ASSERT(NULL == wdf_object_);
|
||||
wdf_object_ = wdf_obj;
|
||||
}
|
||||
|
||||
/// Gets KMDF object type for this extension
|
||||
__forceinline AndroidUsbWdfObjectType object_type() const {
|
||||
return object_type_;
|
||||
}
|
||||
|
||||
/** \brief Checks if this extension represends KMDF object of the given type
|
||||
|
||||
@param obj_type[in] Object type to check
|
||||
@return true if this wrapper represents object of that type and
|
||||
false otherwise.
|
||||
*/
|
||||
__forceinline Is(AndroidUsbWdfObjectType obj_type) const {
|
||||
return (obj_type == object_type());
|
||||
}
|
||||
|
||||
/// Checks if extension is attached to a KMDF object
|
||||
__forceinline bool IsAttached() const {
|
||||
return (NULL != wdf_object());
|
||||
}
|
||||
|
||||
protected:
|
||||
/// KMDF object that is extended with this instance
|
||||
WDFOBJECT wdf_object_;
|
||||
|
||||
/// KMDF object type for this extension
|
||||
AndroidUsbWdfObjectType object_type_;
|
||||
};
|
||||
|
||||
/** \brief Gets our extension for the given KMDF object
|
||||
|
||||
This method can be called at any IRQL
|
||||
@param wdf_obj[in] KMDF handle describing an object
|
||||
@return Instance of AndroidUsbWdfObject associated with this object or NULL
|
||||
if association is not found.
|
||||
*/
|
||||
__forceinline AndroidUsbWdfObject* GetAndroidUsbWdfObjectFromHandle(
|
||||
WDFOBJECT wdf_obj) {
|
||||
ASSERT(NULL != wdf_obj);
|
||||
if (NULL != wdf_obj) {
|
||||
AndroidUsbWdfObjectContext* context =
|
||||
GetAndroidUsbWdfObjectContext(wdf_obj);
|
||||
ASSERT((NULL != context) && (NULL != context->wdf_object_ext) &&
|
||||
(context->wdf_object_ext->Is(context->object_type)));
|
||||
if ((NULL != context) && (NULL != context->wdf_object_ext) &&
|
||||
context->wdf_object_ext->Is(context->object_type)) {
|
||||
return context->wdf_object_ext;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // ANDROID_USB_WDF_OBJECT_H__
|
||||
@@ -1,36 +0,0 @@
|
||||
!IF 0
|
||||
|
||||
Copyright (C) 2006 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
makefile.
|
||||
|
||||
Notes:
|
||||
|
||||
DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||
file to this component. This file merely indirects to the real make file
|
||||
that is shared by all the components of Windows NT (DDK)
|
||||
|
||||
!ENDIF
|
||||
|
||||
!if "$(DDK_TARGET_OS)"=="Win2K"
|
||||
!message This driver is not intended to target the Windows 2000 platform.
|
||||
!elseif "$(DDK_TARGET_OS)"=="WinNET"
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
!else
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
!endif
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
_LNG=$(LANGUAGE)
|
||||
_INX=.
|
||||
STAMP=stampinf -f $@ -a $(_BUILDARCH)
|
||||
|
||||
$(OBJ_PATH)\$(O)\$(INF_NAME).inf: $(_INX)\$(INF_NAME).inx
|
||||
copy $(_INX)\$(@B).inx $@
|
||||
$(STAMP)
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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
|
||||
Standard precompile file
|
||||
*/
|
||||
#pragma warning(disable:4200)
|
||||
#pragma warning(disable:4201) // nameless struct/union
|
||||
#pragma warning(disable:4214) // bit field types other than int
|
||||
extern "C" {
|
||||
#include <initguid.h>
|
||||
#include <ntddk.h>
|
||||
#include <ntintsafe.h>
|
||||
#include <ntstrsafe.h>
|
||||
#include "usbdi.h"
|
||||
#include "usbdlib.h"
|
||||
#include <wdf.h>
|
||||
#include <wdfusb.h>
|
||||
} // extern "C"
|
||||
#pragma warning(default:4200)
|
||||
#pragma warning(default:4201)
|
||||
#pragma warning(default:4214)
|
||||
|
||||
#include "adb_api_extra.h"
|
||||
#include "android_usb_common_defines.h"
|
||||
#include "android_usb_pool_tags.h"
|
||||
#include "android_usb_driver_defines.h"
|
||||
#include "android_usb_new_delete.h"
|
||||
#include "android_usb_inl.h"
|
||||
@@ -1,32 +0,0 @@
|
||||
!IF 0
|
||||
|
||||
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.
|
||||
|
||||
Module Name:
|
||||
|
||||
sources.
|
||||
|
||||
Abstract:
|
||||
|
||||
This file specifies the target component being built and the list of
|
||||
sources files needed to build that component. Also specifies optional
|
||||
compiler switches and libraries that are unique for the component being
|
||||
built.
|
||||
|
||||
!ENDIF
|
||||
|
||||
!include sources.inc
|
||||
|
||||
SOURCES= $(MOST_SOURCES) android_usb.rc
|
||||
@@ -1,84 +0,0 @@
|
||||
!IF 0
|
||||
|
||||
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.
|
||||
|
||||
Module Name:
|
||||
|
||||
sources.
|
||||
|
||||
Abstract:
|
||||
|
||||
This file specifies the target component being built and the list of
|
||||
sources files needed to build that driver. Also specifies optional
|
||||
compiler switches and libraries that are unique for the component being
|
||||
built.
|
||||
|
||||
!ENDIF
|
||||
|
||||
TARGETNAME=androidusb
|
||||
!IF "$(DDKBUILDENV)"=="chk"
|
||||
TARGETPATH=..\build\Debug
|
||||
!ELSE
|
||||
TARGETPATH=..\build\Release
|
||||
!ENDIF
|
||||
TARGETTYPE=DRIVER
|
||||
KMDF_VERSION=1
|
||||
USECXX_FLAG=/TP
|
||||
USER_C_FLAGS=$(USER_C_FLAGS) /wd4100 /wd4002 /wd4509 /wd4390 /TP
|
||||
|
||||
INCLUDES=$(INCLUDES); \
|
||||
$(IFSKIT_INC_PATH); \
|
||||
..\common; \
|
||||
..\api;
|
||||
|
||||
TARGETLIBS=$(DDK_LIB_PATH)\usbd.lib
|
||||
|
||||
MSC_WARNING_LEVEL=/W4 /WX /Wp64
|
||||
MSC_OPTIMIZATION = /Oi /Ob1
|
||||
C_DEFINES=$(C_DEFINES) -DEXPLODE_POOLTAGS -DRTL_USE_AVL_TABLES
|
||||
|
||||
RCOPTIONS=$(RCOPTIONS) /dVER_COMPANYNAME_STR="\"Google Inc\""
|
||||
RCOPTIONS=$(RCOPTIONS) /dVER_LEGALCOPYRIGHT_YEARS="\"2007\""
|
||||
RCOPTIONS=$(RCOPTIONS) /dVER_LEGALCOPYRIGHT_STR="\"\251 Google Inc. All rights reserved.\""
|
||||
RCOPTIONS=$(RCOPTIONS) /dVER_PRODUCTNAME_STR="\"Google Android USB Driver\""
|
||||
RCOPTIONS=$(RCOPTIONS) /dVER_PRODUCTVERSION="1,00,01,001"
|
||||
RCOPTIONS=$(RCOPTIONS) /dVER_PRODUCTVERSION_STR="\"1.00\""
|
||||
|
||||
!IF 0
|
||||
|
||||
By overriding .rsrc section properties (!D removes Discardable attribute)
|
||||
we make sure that all our vtables will be placed properly into non-discardable
|
||||
data segment. Because of the nature of this driver we don't need to have
|
||||
vtables in NonPaged data sections because all our objects can be paged.
|
||||
Otherwise we may want to add /SECTION:.rsrc,X option that locks section in memory
|
||||
|
||||
!ENDIF
|
||||
|
||||
LINKER_FLAGS=$(LINKER_FLAGS) /MAP /MAPINFO:LINES /SECTION:.rsrc,!D
|
||||
|
||||
MOST_SOURCES= \
|
||||
android_usb_driver_object.cpp \
|
||||
android_usb_wdf_object.cpp \
|
||||
android_usb_device_object.cpp \
|
||||
android_usb_file_object.cpp \
|
||||
android_usb_device_file_object.cpp \
|
||||
android_usb_pipe_file_object.cpp \
|
||||
android_usb_bulk_file_object.cpp \
|
||||
android_usb_interrupt_file_object.cpp
|
||||
|
||||
PRECOMPILED_INCLUDE=precomp.h
|
||||
PRECOMPILED_PCH=precomp.pch
|
||||
PRECOMPILED_OBJ=precomp.obj
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "android_usb_test", "android_usb_test.vcproj", "{9C6DBEED-9D2C-4FD8-B83D-88254035F78B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdbWinApi", "..\..\api\AdbWinApi.vcproj", "{C0A471E9-6892-4270-96DE-DB5F8D526FB1}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{9C6DBEED-9D2C-4FD8-B83D-88254035F78B}.Debug.ActiveCfg = Debug|Win32
|
||||
{9C6DBEED-9D2C-4FD8-B83D-88254035F78B}.Debug.Build.0 = Debug|Win32
|
||||
{9C6DBEED-9D2C-4FD8-B83D-88254035F78B}.Release.ActiveCfg = Release|Win32
|
||||
{9C6DBEED-9D2C-4FD8-B83D-88254035F78B}.Release.Build.0 = Release|Win32
|
||||
{C0A471E9-6892-4270-96DE-DB5F8D526FB1}.Debug.ActiveCfg = Debug|Win32
|
||||
{C0A471E9-6892-4270-96DE-DB5F8D526FB1}.Debug.Build.0 = Debug|Win32
|
||||
{C0A471E9-6892-4270-96DE-DB5F8D526FB1}.Release.ActiveCfg = Release|Win32
|
||||
{C0A471E9-6892-4270-96DE-DB5F8D526FB1}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,174 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="android_usb_test"
|
||||
ProjectGUID="{9C6DBEED-9D2C-4FD8-B83D-88254035F78B}"
|
||||
RootNamespace="android_usb_test"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
UseOfATL="1"
|
||||
CharacterSet="1">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="C:\WINDDK\6000\inc\api;..\..\common;..\..\api;..\..\..\..\..\..\..\..\google3\testing\base"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
ExceptionHandling="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
UsePrecompiledHeader="3"
|
||||
ProgramDataBaseFileName="..\..\build\$(OutDir)\i386\$(TargetName).pdb"
|
||||
WarningLevel="4"
|
||||
WarnAsError="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="AdbWinApi.lib shlwapi.lib"
|
||||
OutputFile="..\..\build\$(OutDir)\i386/android_usb_test.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""..\..\build\$(OutDir)\i386""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="..\..\build\$(OutDir)\i386\$(TargetName).pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Set DDK environment"
|
||||
CommandLine="call c:\winddk\6000\bin\setenv.bat c:\winddk\6000\ chk WXP"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
UseOfATL="1"
|
||||
CharacterSet="1">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="4"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="C:\WINDDK\6000\inc\api;..\..\common;..\..\api;..\..\..\..\..\..\..\..\google3\testing\base"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
ExceptionHandling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
UsePrecompiledHeader="3"
|
||||
ProgramDataBaseFileName="..\..\build\$(OutDir)\i386\$(TargetName).pdb"
|
||||
WarningLevel="4"
|
||||
WarnAsError="TRUE"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="AdbWinApi.lib"
|
||||
OutputFile="..\..\build\$(OutDir)\i386/android_usb_test.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""..\..\build\$(OutDir)\i386""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="..\..\build\$(OutDir)\i386\$(TargetName).pdb"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
Description="Set DKK environment"
|
||||
CommandLine="call c:\winddk\6000\bin\setenv.bat c:\winddk\6000\ fre WXP"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\android_usb_test.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\stdafx.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// android_usb_test.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <tchar.h>
|
||||
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
|
||||
|
||||
#include <atlbase.h>
|
||||
#pragma warning(disable: 4200)
|
||||
extern "C" {
|
||||
#include <usbdi.h>
|
||||
}
|
||||
#include "android_usb_common_defines.h"
|
||||
#include "adb_api.h"
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 definies entry point for the DLL.
|
||||
This project has been created from DDK's SoftUSBLoopback sample project
|
||||
that is located at $(DDK_PATH)\src\Test\DSF\USB\SoftUSBLoopback
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "resource.h"
|
||||
#include <dsfif.h>
|
||||
#include <USBProtocolDefs.h>
|
||||
#include <softusbif.h>
|
||||
#include "LoopbackDevice.h"
|
||||
#include "DeviceEmulator.h"
|
||||
|
||||
class CDeviceEmulatorModule : public CAtlDllModuleT<CDeviceEmulatorModule> {
|
||||
public:
|
||||
DECLARE_LIBID(LIBID_DeviceEmulatorLib)
|
||||
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_DEVICEEMULATOR, "{D1C80253-8DB4-4F72-BF74-270A0EDA1FA9}")
|
||||
};
|
||||
|
||||
CDeviceEmulatorModule _AtlModule;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DLL Entry Point
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {
|
||||
hInstance;
|
||||
return _AtlModule.DllMain(dwReason, lpReserved);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Used to determine whether the DLL can be unloaded by OLE
|
||||
|
||||
STDAPI DllCanUnloadNow(void) {
|
||||
return (_AtlModule.DllCanUnloadNow());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Returns a class factory to create an object of the requested type
|
||||
|
||||
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) {
|
||||
return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DllRegisterServer - Adds entries to the system registry
|
||||
|
||||
STDAPI DllRegisterServer(void) {
|
||||
// registers object, typelib and all interfaces in typelib
|
||||
HRESULT hr = _AtlModule.DllRegisterServer();
|
||||
return hr;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DllUnregisterServer - Removes entries from the system registry
|
||||
|
||||
STDAPI DllUnregisterServer(void) {
|
||||
HRESULT hr = _AtlModule.DllUnregisterServer();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
;Module Name:
|
||||
;
|
||||
; DeviceEmulator.def
|
||||
;
|
||||
;Abstract:
|
||||
; Declares the module parameters
|
||||
;
|
||||
|
||||
LIBRARY "DeviceEmulator.DLL"
|
||||
|
||||
EXPORTS
|
||||
DllCanUnloadNow PRIVATE
|
||||
DllGetClassObject PRIVATE
|
||||
DllRegisterServer PRIVATE
|
||||
DllUnregisterServer PRIVATE
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 library definition for DeviceEmulator device.
|
||||
This project has been created from DDK's SoftUSBLoopback sample project
|
||||
that is located at $(DDK_PATH)\src\Test\DSF\USB\SoftUSBLoopback
|
||||
*/
|
||||
|
||||
import "oaidl.idl";
|
||||
import "ocidl.idl";
|
||||
|
||||
[
|
||||
uuid(0C206596-5CC2-4d16-898D-4D1699BB6282),
|
||||
version(1.0),
|
||||
helpstring("DeviceEmulator 1.0 Type Library")
|
||||
]
|
||||
library DeviceEmulatorLib
|
||||
{
|
||||
importlib("stdole2.tlb");
|
||||
importlib("dsfif.tlb");
|
||||
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(0A7E88B6-E38F-4d78-ABA3-AA30DC836B7D),
|
||||
oleautomation,
|
||||
dual,
|
||||
nonextensible,
|
||||
helpstring("ILoopbackDevice Interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface ILoopbackDevice : IDispatch
|
||||
{
|
||||
[
|
||||
propget,
|
||||
id(1),
|
||||
helpstring("property DSFDevice")
|
||||
]
|
||||
HRESULT DSFDevice([out, retval] DSFDevice** ppDSFDEevice);
|
||||
|
||||
[
|
||||
id(2),
|
||||
helpstring("Demonstrates how to use the queue method to read/write data")
|
||||
]
|
||||
HRESULT _stdcall DoPolledLoopback([in] long LoopInterval);
|
||||
|
||||
[
|
||||
id(3),
|
||||
helpstring("Demonstrates how to use the eventing mechanism to read/write data")
|
||||
]
|
||||
HRESULT _stdcall StartEventProcessing();
|
||||
|
||||
[
|
||||
id(4),
|
||||
helpstring("Starts event-driven simulation and returns immediately to caller.")
|
||||
]
|
||||
HRESULT _stdcall StartAsyncEventProcessing();
|
||||
|
||||
[
|
||||
id(5),
|
||||
helpstring("Stops event-driven simulation started by a prior call to StartAsyncEventProcessing.")
|
||||
]
|
||||
HRESULT _stdcall StopAsyncEventProcessing();
|
||||
|
||||
[
|
||||
id(6),
|
||||
helpstring("Check to see if there is any key strokes to be processed")
|
||||
]
|
||||
HRESULT AreKeystrokesWaiting([out, retval] VARIANT_BOOL *pfvarKeysWaiting);
|
||||
};
|
||||
|
||||
[
|
||||
uuid(4F28A221-47B1-4f74-9ECC-CEADEDA0A287),
|
||||
nonextensible,
|
||||
helpstring("Loopback device event interface."),
|
||||
|
||||
]
|
||||
dispinterface ILoopbackDeviceEvents
|
||||
{
|
||||
properties:
|
||||
methods:
|
||||
[
|
||||
id(1),
|
||||
helpstring("Detemine if the device should stop polling the endpoint for data")
|
||||
]
|
||||
HRESULT _stdcall ContinueToPoll([out,retval] VARIANT_BOOL *pfvarConitnue);
|
||||
|
||||
[
|
||||
id(2),
|
||||
helpstring("Detemine if the device should stop the event processing")
|
||||
]
|
||||
HRESULT _stdcall ContinueEventProcessing([out,retval] VARIANT_BOOL *pfvarConitnue);
|
||||
}
|
||||
|
||||
[
|
||||
uuid(9A0BD4A6-E346-4668-A89C-ACA546212CD4),
|
||||
helpstring("LoopbackDevice Class")
|
||||
]
|
||||
coclass LoopbackDevice
|
||||
{
|
||||
[default] interface ILoopbackDevice;
|
||||
[default, source] dispinterface ILoopbackDeviceEvents;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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
|
||||
Resource file for Device USB emulator.
|
||||
*/
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"1 TYPELIB ""DeviceEmulator.tlb""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,1
|
||||
PRODUCTVERSION 1,0,0,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904e4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Google, Inc."
|
||||
VALUE "FileDescription", "Device USB Device Emulator"
|
||||
VALUE "FileVersion", "1.0.0.1"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2007 The Android Open Source Project"
|
||||
VALUE "InternalName", "DeviceEmulator.dll"
|
||||
VALUE "OriginalFilename", "DeviceEmulator.dll"
|
||||
VALUE "ProductName", "Android"
|
||||
VALUE "ProductVersion", "1.0.0.1"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// REGISTRY
|
||||
//
|
||||
|
||||
IDR_DEVICEEMULATOR REGISTRY "DeviceEmulator.rgs"
|
||||
IDR_LOOPBACKDEVICE REGISTRY "LoopbackDevice.rgs"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_PROJNAME "DeviceEmulator"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
1 TYPELIB "DeviceEmulator.tlb"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove AppID
|
||||
{
|
||||
'%APPID%' = s 'DeviceEmulator'
|
||||
'DeviceEmulator.EXE'
|
||||
{
|
||||
val AppID = s '%APPID%'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,796 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 the class CLoopbackDevice:
|
||||
Implements the interface ILoopbackDevice and
|
||||
configures the loopback device to be a valid USB device.
|
||||
The device then processes input to its endpoint in one of
|
||||
two ways.
|
||||
|
||||
1. By running in polled mode where the data is simply
|
||||
passed from the OUT Endpoint to the IN Endpoint
|
||||
|
||||
or
|
||||
2. In Event mode where the loopback device receives a
|
||||
callback to indicate that data needs to be processed,
|
||||
and then processes the data.
|
||||
This project has been created from DDK's SoftUSBLoopback sample project
|
||||
that is located at $(DDK_PATH)\src\Test\DSF\USB\SoftUSBLoopback
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <USBProtocolDefs.h>
|
||||
#include <dsfif.h>
|
||||
#include <softusbif.h>
|
||||
#include "android_usb_common_defines.h"
|
||||
#include "adb_api_extra.h"
|
||||
#include "LoopbackDevice.h"
|
||||
#include "DeviceEmulator_i.c"
|
||||
|
||||
// These are the indexes of the string descriptors. They are used both
|
||||
// as the indexes of the strings with SoftUSBDevice.Strings and as the
|
||||
// string descriptor index property values on the various objects (e.g.
|
||||
// SoftUSBDevice.Manufacturer = STRING_IDX_MANUFACTURER).
|
||||
|
||||
#define STRING_IDX_MANUFACTURER 1
|
||||
#define STRING_IDX_PRODUCT_DESC 2
|
||||
#define STRING_IDX_SERIAL_NO 3
|
||||
#define STRING_IDX_CONFIG 4
|
||||
#define STRING_IDX_INTERFACE 5
|
||||
|
||||
CLoopbackDevice::CLoopbackDevice() {
|
||||
InitMemberVariables();
|
||||
}
|
||||
|
||||
CLoopbackDevice::~CLoopbackDevice() {
|
||||
// Release the conneciton point
|
||||
ReleaseConnectionPoint();
|
||||
|
||||
// Release any interface which the device is holding
|
||||
RELEASE(m_piConnectionPoint);
|
||||
RELEASE(m_piINEndpoint);
|
||||
RELEASE(m_piOUTEndpoint);
|
||||
|
||||
if (NULL != m_piSoftUSBDevice) {
|
||||
(void)m_piSoftUSBDevice->Destroy();
|
||||
RELEASE(m_piSoftUSBDevice);
|
||||
}
|
||||
|
||||
InitMemberVariables();
|
||||
}
|
||||
|
||||
void CLoopbackDevice::InitMemberVariables() {
|
||||
m_piSoftUSBDevice = NULL;
|
||||
m_piINEndpoint = NULL;
|
||||
m_piOUTEndpoint = NULL;
|
||||
m_piConnectionPoint = NULL;
|
||||
m_iInterfaceString = 0;
|
||||
m_iConfigString = 0;
|
||||
m_dwConnectionCookie = 0;
|
||||
}
|
||||
|
||||
HRESULT CLoopbackDevice::FinalConstruct() {
|
||||
// Perform tasks which may fail when the class CLoopbackDevice
|
||||
// is finally constructed. This involves creating the USB device
|
||||
// object and initializing the device so that it is recognized
|
||||
// as a valid USB device by the controller
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
hr = CreateUSBDevice();
|
||||
IfFailHrGo(hr);
|
||||
|
||||
hr = ConfigureDevice();
|
||||
IfFailHrGo(hr);
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
void CLoopbackDevice::FinalRelease() {
|
||||
}
|
||||
|
||||
HRESULT CLoopbackDevice::CreateUSBDevice() {
|
||||
// Creates the USB device and initializes the device member variables
|
||||
// and creates and initializes the device qualifier. The device qualifier
|
||||
// is required for USB2.0 devices.
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
ISoftUSBDeviceQualifier* piDeviceQual = NULL;
|
||||
USHORT prod_id = DEVICE_EMULATOR_PROD_ID;
|
||||
|
||||
hr = ::CoCreateInstance(CLSID_SoftUSBDevice,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBDevice),
|
||||
reinterpret_cast<void**>(&m_piSoftUSBDevice));
|
||||
|
||||
IfFailHrGo(hr);
|
||||
|
||||
// Create the device qualifer
|
||||
hr = ::CoCreateInstance(CLSID_SoftUSBDeviceQualifier,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBDeviceQualifier),
|
||||
reinterpret_cast<void**>(&piDeviceQual));
|
||||
|
||||
IfFailHrGo(hr);
|
||||
|
||||
// Setup the device qualifier
|
||||
// binary coded decimal USB version 2.0
|
||||
IfFailHrGo(piDeviceQual->put_USB(0x0200));
|
||||
// FF=Vendor specfic device class
|
||||
IfFailHrGo(piDeviceQual->put_DeviceClass(0xff));
|
||||
// FF = Vendor specific device sub-class
|
||||
IfFailHrGo(piDeviceQual->put_DeviceSubClass(0xff));
|
||||
// FF = Vendor specific device protocol
|
||||
IfFailHrGo(piDeviceQual->put_DeviceProtocol(0xff));
|
||||
// Max packet size endpoint 0
|
||||
IfFailHrGo(piDeviceQual->put_MaxPacketSize0(64));
|
||||
// Number of configurations
|
||||
IfFailHrGo(piDeviceQual->put_NumConfigurations(1));
|
||||
|
||||
// Setup the device
|
||||
// binary coded decimal USB version 2.0
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_USB(0x0200));
|
||||
// FF=Vendor specfic device class
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_DeviceClass(0xff));
|
||||
// FF = Vendor specific device sub-class
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_DeviceSubClass(0xff));
|
||||
// FF = Vendor specific device protocol
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_DeviceProtocol(0xff));
|
||||
// Max packet size endpoint 0
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_MaxPacketSize0(64));
|
||||
// Vendor ID - Google
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_Vendor(DEVICE_VENDOR_ID));
|
||||
// product id - Device Emulator
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_Product(static_cast<SHORT>(prod_id)));
|
||||
// Binary decimal coded version 1.0
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_Device(0x0100));
|
||||
// Device does not suppport remote wake up
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_RemoteWakeup(VARIANT_FALSE));
|
||||
// Index of the manufacturer string
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_Manufacturer(STRING_IDX_MANUFACTURER));
|
||||
// Index of the product descripton string
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_ProductDesc(STRING_IDX_PRODUCT_DESC));
|
||||
// Index of the serial number string
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_SerialNumber(STRING_IDX_SERIAL_NO));
|
||||
// Indicate that the device is self-powered
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_SelfPowered(VARIANT_TRUE));
|
||||
// Indicate that the device has power
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_Powered(VARIANT_TRUE));
|
||||
|
||||
// Create the strings associated with the device
|
||||
IfFailHrGo(CreateStrings());
|
||||
|
||||
// Add the device qualifier
|
||||
IfFailHrGo(m_piSoftUSBDevice->put_DeviceQualifier(piDeviceQual));
|
||||
|
||||
Exit:
|
||||
RELEASE(piDeviceQual);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CLoopbackDevice::ConfigureConfig(ISoftUSBConfiguration* piConfig) {
|
||||
HRESULT hr = S_OK;
|
||||
// config number passed to SetConfig
|
||||
IfFailHrGo(piConfig->put_ConfigurationValue(1));
|
||||
// Index of string descriptor
|
||||
IfFailHrGo(piConfig->put_Configuration((BYTE)m_iConfigString));
|
||||
// Self powered
|
||||
IfFailHrGo(piConfig->put_Attributes(0x40));
|
||||
// Max power in 2mA units: 50 = 100mA
|
||||
IfFailHrGo(piConfig->put_MaxPower(50));
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CLoopbackDevice::ConfigureINEndpoint() {
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (NULL == m_piINEndpoint) {
|
||||
IfFailHrGo(E_UNEXPECTED);
|
||||
}
|
||||
|
||||
// Endpoint #1 IN
|
||||
IfFailHrGo(m_piINEndpoint->put_EndpointAddress(0x81));
|
||||
// Bulk data endpoint
|
||||
IfFailHrGo(m_piINEndpoint->put_Attributes(0x02));
|
||||
IfFailHrGo(m_piINEndpoint->put_MaxPacketSize(1024));
|
||||
IfFailHrGo(m_piINEndpoint->put_Interval(0));
|
||||
IfFailHrGo(m_piINEndpoint->put_Halted(FALSE));
|
||||
// back pointer to the device
|
||||
IfFailHrGo(m_piINEndpoint->put_USBDevice(reinterpret_cast<SoftUSBDevice*>(m_piSoftUSBDevice)));
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CLoopbackDevice::ConfigureOUTEndpoint() {
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (NULL == m_piOUTEndpoint) {
|
||||
IfFailHrGo(E_UNEXPECTED);
|
||||
}
|
||||
|
||||
// Endpoint #2 OUT
|
||||
IfFailHrGo(m_piOUTEndpoint->put_EndpointAddress(0x02));
|
||||
// Bulk data endpoint
|
||||
IfFailHrGo(m_piOUTEndpoint->put_Attributes(0x02));
|
||||
IfFailHrGo(m_piOUTEndpoint->put_MaxPacketSize(1024));
|
||||
IfFailHrGo(m_piOUTEndpoint->put_Interval(0));
|
||||
IfFailHrGo(m_piOUTEndpoint->put_Halted(FALSE));
|
||||
//back pointer to the device
|
||||
IfFailHrGo(m_piOUTEndpoint->put_USBDevice(reinterpret_cast<SoftUSBDevice*>(m_piSoftUSBDevice)));
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CLoopbackDevice::ConfigureInterface(ISoftUSBInterface* piInterface) {
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
IfFailHrGo(piInterface->put_InterfaceNumber(0));
|
||||
IfFailHrGo(piInterface->put_AlternateSetting(0));
|
||||
// Vendor specific class code
|
||||
IfFailHrGo(piInterface->put_InterfaceClass(0xFF));
|
||||
// Vendor specific sub class code
|
||||
IfFailHrGo(piInterface->put_InterfaceSubClass(0xFF));
|
||||
// Vendor specific protcol
|
||||
IfFailHrGo(piInterface->put_InterfaceProtocol(0xFF));
|
||||
//Index for string describing the interface
|
||||
IfFailHrGo(piInterface->put_Interface((BYTE)m_iInterfaceString));
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CLoopbackDevice::ConfigureDevice() {
|
||||
HRESULT hr = S_OK;
|
||||
ISoftUSBConfiguration* piConfig = NULL;
|
||||
ISoftUSBInterface* piInterface = NULL;
|
||||
ISoftUSBConfigList* piConfigList = NULL;
|
||||
ISoftUSBInterfaceList* piInterfaceList = NULL;
|
||||
ISoftUSBEndpointList* piEndpointList= NULL;
|
||||
VARIANT varIndex;
|
||||
VariantInit(&varIndex);
|
||||
|
||||
// All members of the collection will be added at the default locations
|
||||
// so set up the index appropriately
|
||||
varIndex.vt = VT_ERROR;
|
||||
varIndex.scode = DISP_E_PARAMNOTFOUND;
|
||||
|
||||
// Create the IN Endpoint
|
||||
hr = CoCreateInstance(CLSID_SoftUSBEndpoint,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBEndpoint),
|
||||
reinterpret_cast<void**>(&m_piINEndpoint));
|
||||
IfFailHrGo(hr);
|
||||
|
||||
// Setup the IN Endpoint
|
||||
IfFailHrGo(ConfigureINEndpoint());
|
||||
|
||||
// Create the OUT Endpoint
|
||||
hr = CoCreateInstance(CLSID_SoftUSBEndpoint,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBEndpoint),
|
||||
reinterpret_cast<void**>(&m_piOUTEndpoint));
|
||||
IfFailHrGo(hr);
|
||||
|
||||
// Setup the OUT Endpoint
|
||||
IfFailHrGo(ConfigureOUTEndpoint());
|
||||
|
||||
// Create the device interface
|
||||
hr = CoCreateInstance(CLSID_SoftUSBInterface,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBInterface),
|
||||
reinterpret_cast<void**>(&piInterface));
|
||||
IfFailHrGo(hr);
|
||||
|
||||
// Setup the device interface
|
||||
IfFailHrGo(ConfigureInterface(piInterface));
|
||||
|
||||
// Add the Endpoints to the endpoint list
|
||||
IfFailHrGo(piInterface->get_Endpoints(&piEndpointList));
|
||||
IfFailHrGo(piEndpointList->Add(reinterpret_cast<SoftUSBEndpoint*>(m_piINEndpoint), varIndex));
|
||||
IfFailHrGo(piEndpointList->Add(reinterpret_cast<SoftUSBEndpoint*>(m_piOUTEndpoint), varIndex));
|
||||
|
||||
// Create the configuration
|
||||
hr = CoCreateInstance(CLSID_SoftUSBConfiguration,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBConfiguration),
|
||||
reinterpret_cast<void**>(&piConfig));
|
||||
IfFailHrGo(hr);
|
||||
|
||||
// Set the configuration data up
|
||||
IfFailHrGo(ConfigureConfig(piConfig));
|
||||
|
||||
// Add the interface to the interface collection
|
||||
IfFailHrGo(piConfig->get_Interfaces(&piInterfaceList));
|
||||
IfFailHrGo(piInterfaceList->Add(reinterpret_cast<SoftUSBInterface*>(piInterface), varIndex));
|
||||
|
||||
// Add the configuration to the configuration collection
|
||||
IfFailHrGo(m_piSoftUSBDevice->get_Configurations(&piConfigList));
|
||||
IfFailHrGo(piConfigList->Add(reinterpret_cast<SoftUSBConfiguration*>(piConfig), varIndex));
|
||||
|
||||
Exit:
|
||||
RELEASE(piConfig);
|
||||
RELEASE(piInterface);
|
||||
RELEASE(piConfigList);
|
||||
RELEASE(piInterfaceList);
|
||||
RELEASE(piEndpointList);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CLoopbackDevice::CreateStrings() {
|
||||
HRESULT hr = S_OK;
|
||||
ISoftUSBStringList* piStringList = NULL;
|
||||
ISoftUSBString* piStringManufacturer = NULL;
|
||||
ISoftUSBString* piStringProductDesc = NULL;
|
||||
ISoftUSBString* piStringSerialNo = NULL;
|
||||
ISoftUSBString* piStringConfig = NULL;
|
||||
ISoftUSBString* piStringEndpoint = NULL;
|
||||
BSTR bstrManufacturer = ::SysAllocString(L"Google, Inc");
|
||||
BSTR bstrProductDesc = ::SysAllocString(L"USB Emulating Device");
|
||||
BSTR bstrSerialNo = ::SysAllocString(L"123456789ABCDEF");
|
||||
BSTR bstrConfig = ::SysAllocString(L"Configuration with a single interface");
|
||||
BSTR bstrEndpoint = ::SysAllocString(L"Interface with bulk IN endpoint and bulk OUT endpoint");
|
||||
VARIANT varIndex;
|
||||
VariantInit(&varIndex);
|
||||
|
||||
// Check that all BSTR allocations succeeded
|
||||
IfFalseHrGo(0 != ::SysStringLen(bstrManufacturer), E_OUTOFMEMORY);
|
||||
IfFalseHrGo(0 != ::SysStringLen(bstrProductDesc), E_OUTOFMEMORY);
|
||||
IfFalseHrGo(0 != ::SysStringLen(bstrSerialNo), E_OUTOFMEMORY);
|
||||
IfFalseHrGo(0 != ::SysStringLen(bstrConfig), E_OUTOFMEMORY);
|
||||
IfFalseHrGo(0 != ::SysStringLen(bstrEndpoint), E_OUTOFMEMORY);
|
||||
|
||||
//Set up the varaint used as the index
|
||||
varIndex.vt = VT_I4;
|
||||
varIndex.lVal = STRING_IDX_MANUFACTURER;
|
||||
|
||||
//Create and initialize the string descriptors. Also create a string
|
||||
//descriptor index for each. This index is used both to set the string's
|
||||
//descriptors position in the m_piSoftUSBDevice.Strings and is the index value
|
||||
//the GetDescriptors request from the host. Note that we don't use
|
||||
//string descriptor index zero because that is a reserved value for a
|
||||
//device's language ID descriptor.
|
||||
|
||||
//Get the string list from the device
|
||||
hr = m_piSoftUSBDevice->get_Strings(&piStringList);
|
||||
IfFailHrGo(hr);
|
||||
|
||||
hr = CoCreateInstance(CLSID_SoftUSBString,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBString),
|
||||
reinterpret_cast<void**>(&piStringManufacturer));
|
||||
IfFailHrGo(hr);
|
||||
|
||||
IfFailHrGo(piStringManufacturer->put_Value(bstrManufacturer));
|
||||
IfFailHrGo(piStringList->Add(reinterpret_cast<SoftUSBString*>(piStringManufacturer), varIndex));
|
||||
|
||||
hr = CoCreateInstance(CLSID_SoftUSBString,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBString),
|
||||
reinterpret_cast<void**>(&piStringProductDesc));
|
||||
|
||||
IfFailHrGo(hr);
|
||||
IfFailHrGo(piStringProductDesc->put_Value(bstrProductDesc));
|
||||
varIndex.lVal = STRING_IDX_PRODUCT_DESC;
|
||||
IfFailHrGo(piStringList->Add(reinterpret_cast<SoftUSBString*>(piStringProductDesc), varIndex));
|
||||
|
||||
hr = CoCreateInstance(CLSID_SoftUSBString,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBString),
|
||||
reinterpret_cast<void**>(&piStringSerialNo));
|
||||
IfFailHrGo(hr);
|
||||
IfFailHrGo(piStringSerialNo->put_Value(bstrSerialNo));
|
||||
varIndex.lVal = STRING_IDX_SERIAL_NO;
|
||||
IfFailHrGo(piStringList->Add(reinterpret_cast<SoftUSBString*>(piStringSerialNo), varIndex));
|
||||
|
||||
hr = CoCreateInstance(CLSID_SoftUSBString,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBString),
|
||||
reinterpret_cast<void**>(&piStringConfig));
|
||||
IfFailHrGo(hr);
|
||||
IfFailHrGo(piStringConfig->put_Value(bstrConfig));
|
||||
varIndex.lVal = STRING_IDX_CONFIG;
|
||||
m_iConfigString = varIndex.lVal;
|
||||
IfFailHrGo(piStringList->Add(reinterpret_cast<SoftUSBString*>(piStringConfig), varIndex));
|
||||
|
||||
hr = CoCreateInstance(CLSID_SoftUSBString,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISoftUSBString),
|
||||
reinterpret_cast<void**>(&piStringEndpoint));
|
||||
IfFailHrGo(hr);
|
||||
IfFailHrGo(piStringEndpoint->put_Value(bstrEndpoint));
|
||||
varIndex.lVal = STRING_IDX_INTERFACE;
|
||||
m_iInterfaceString = varIndex.lVal;
|
||||
IfFailHrGo(piStringList->Add(reinterpret_cast<SoftUSBString*>(piStringEndpoint), varIndex));
|
||||
|
||||
Exit:
|
||||
RELEASE(piStringList);
|
||||
RELEASE(piStringManufacturer);
|
||||
RELEASE(piStringProductDesc);
|
||||
RELEASE(piStringSerialNo);
|
||||
RELEASE(piStringConfig);
|
||||
RELEASE(piStringEndpoint);
|
||||
::SysFreeString(bstrManufacturer);
|
||||
::SysFreeString(bstrProductDesc);
|
||||
::SysFreeString(bstrSerialNo);
|
||||
::SysFreeString(bstrConfig);
|
||||
::SysFreeString(bstrEndpoint);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CLoopbackDevice::ReleaseConnectionPoint() {
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (NULL != m_piConnectionPoint) {
|
||||
m_piConnectionPoint->Unadvise(m_dwConnectionCookie);
|
||||
m_dwConnectionCookie = 0;
|
||||
}
|
||||
|
||||
RELEASE(m_piConnectionPoint);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CLoopbackDevice::SetupConnectionPoint(IUnknown* punkObject,
|
||||
REFIID iidConnectionPoint) {
|
||||
HRESULT hr = S_OK;
|
||||
IConnectionPointContainer* piConnectionPointContainer = NULL;
|
||||
IUnknown* punkSink = NULL;
|
||||
|
||||
//If there is already connection point enabled, disable it
|
||||
if(NULL != m_piConnectionPoint) {
|
||||
IfFailHrGo(ReleaseConnectionPoint());
|
||||
}
|
||||
|
||||
IfFailHrGo(punkObject->QueryInterface(IID_IConnectionPointContainer,
|
||||
reinterpret_cast<void **>(&piConnectionPointContainer)));
|
||||
|
||||
IfFailHrGo(piConnectionPointContainer->FindConnectionPoint(iidConnectionPoint,
|
||||
&m_piConnectionPoint));
|
||||
|
||||
// Get the IUknown of this interface as this is the event sink
|
||||
punkSink = (this)->GetUnknown();
|
||||
|
||||
if(NULL == punkSink) {
|
||||
IfFailHrGo(E_UNEXPECTED);
|
||||
}
|
||||
|
||||
IfFailHrGo(m_piConnectionPoint->Advise(punkSink, &m_dwConnectionCookie));
|
||||
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::get_DSFDevice(DSFDevice** ppDSFDevice) {
|
||||
HRESULT hr = S_OK;
|
||||
DSFDevice* pDSFDevice = NULL;
|
||||
|
||||
//Validate the the UDB device exists else this is an
|
||||
//internal error
|
||||
if (NULL == m_piSoftUSBDevice) {
|
||||
IfFailHrGo(E_UNEXPECTED);
|
||||
}
|
||||
|
||||
if (NULL == ppDSFDevice) {
|
||||
IfFailHrGo(E_POINTER);
|
||||
}
|
||||
|
||||
IfFailHrGo(m_piSoftUSBDevice->get_DSFDevice(&pDSFDevice));
|
||||
IfFailHrGo(reinterpret_cast<IDSFDevice *>(pDSFDevice)->QueryInterface(__uuidof(IDispatch), reinterpret_cast<void **>(ppDSFDevice)));
|
||||
|
||||
Exit:
|
||||
if (NULL != pDSFDevice)
|
||||
reinterpret_cast<IDSFDevice *>(pDSFDevice)->Release();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::DoPolledLoopback(long lTimeInterval) {
|
||||
/*
|
||||
Demonstrates how to use the drain OUT queue and queue IN data
|
||||
methods to communicate with the host controller.
|
||||
|
||||
The code checks to see if there is any data in the OUT, if no
|
||||
data is present an event is fired to indicate if the function
|
||||
should exit. If the function should not exit then the function
|
||||
sleeps for the time interval before re-checking the queue.
|
||||
|
||||
If there is data then the function reads the data and passes the
|
||||
data to the IN queue. This simply provides a loopback mechanism
|
||||
to the host controller.
|
||||
*/
|
||||
HRESULT hr = S_OK;
|
||||
BOOL fKeepLooping = TRUE;
|
||||
// Number of items currently in the queue
|
||||
ULONG ulNoOfQueuedItems = 0;
|
||||
// Only going to read one transfer at a time
|
||||
ULONG ulTransfers = 1;
|
||||
SOFTUSB_OUT_TRANSFER* pOUTTransfer = NULL;
|
||||
// Copied the message status
|
||||
BYTE bStatus = 0;
|
||||
// Copied the message data
|
||||
BYTE* pDataBuffer = NULL;
|
||||
// Holds the size of the data buffer
|
||||
ULONG cbDataBuffer = 0;
|
||||
VARIANT_BOOL fvarContinue = VARIANT_TRUE;
|
||||
|
||||
if (NULL == m_piINEndpoint || NULL == m_piOUTEndpoint) {
|
||||
IfFailHrGo(E_UNEXPECTED);
|
||||
}
|
||||
|
||||
while (fKeepLooping) {
|
||||
// Reset the number of queued items
|
||||
ulNoOfQueuedItems = 0;
|
||||
|
||||
// Check to see if there is any data in the out queue
|
||||
IfFailHrGo(m_piOUTEndpoint->DrainOUTQueue(0, &ulNoOfQueuedItems, NULL));
|
||||
|
||||
if (0 == ulNoOfQueuedItems) {
|
||||
// There is no data in the list so we need to check
|
||||
// If we should continue to loop
|
||||
// Fire Event to check if more processing is required
|
||||
IfFailHrGo(Fire_ContinueToPoll(&fvarContinue));
|
||||
|
||||
// Check to see if the return value is VARIANT_FALSE
|
||||
if (VARIANT_FALSE == fvarContinue)
|
||||
fKeepLooping = FALSE;
|
||||
|
||||
if (fKeepLooping)
|
||||
::Sleep(lTimeInterval);
|
||||
} else {
|
||||
// There is data to read, loop until we have moved all
|
||||
// the data from the OUT queue to the IN queue moving
|
||||
// one data item at a time
|
||||
do {
|
||||
// Get the OUT data
|
||||
IfFailHrGo(m_piOUTEndpoint->DrainOUTQueue(ulTransfers,
|
||||
&ulNoOfQueuedItems,
|
||||
&pOUTTransfer));
|
||||
|
||||
// Setup the IN data
|
||||
bStatus= pOUTTransfer->bStatus;
|
||||
cbDataBuffer = pOUTTransfer->cbData;
|
||||
pDataBuffer =&pOUTTransfer->Data[0];
|
||||
|
||||
// Send the data to the out queue
|
||||
IfFailHrGo(m_piINEndpoint->QueueINData(pDataBuffer,
|
||||
cbDataBuffer,
|
||||
bStatus,
|
||||
SOFTUSB_FOREVER));
|
||||
|
||||
// Free the memory used by pOUTTransfer
|
||||
m_piOUTEndpoint->FreeOUTQueue(pOUTTransfer);
|
||||
pOUTTransfer = NULL;
|
||||
|
||||
// Force a context switch
|
||||
::Sleep(1);
|
||||
} while (0 != ulNoOfQueuedItems);
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
// If one of the calls failed pOUTTransfer will be NON-NULL
|
||||
// And needs to be freed
|
||||
if (NULL != pOUTTransfer) {
|
||||
// Free the memory used by pOUTTransfer
|
||||
m_piOUTEndpoint->FreeOUTQueue(pOUTTransfer);
|
||||
pOUTTransfer = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::StartEventProcessing() {
|
||||
/*
|
||||
Demonstrates how to setup event sinks so that the
|
||||
event mechanism can be used to control data flow to and
|
||||
from the USB controller. In this example an event sink
|
||||
is installed on the OUT USB endpoint, when the controller
|
||||
has data to send to the device the OnWriteTransfer event
|
||||
will fire, this will occur on an arbitrary thread. The
|
||||
device then simply copies this data and passes it the
|
||||
IN queue of the IN Endpoint.
|
||||
*/
|
||||
HRESULT hr = S_OK;
|
||||
BOOL fKeepLooping = TRUE;
|
||||
VARIANT_BOOL fvarContinue = VARIANT_TRUE;
|
||||
|
||||
// Set up event sink on the OUT endpoint
|
||||
IfFailHrGo(SetupConnectionPoint(m_piOUTEndpoint, __uuidof(ISoftUSBEndpointEvents)));
|
||||
|
||||
// Loop waiting for Events to be fired
|
||||
while (TRUE == fKeepLooping) {
|
||||
// Context switch to allow other threads to process
|
||||
::Sleep(1);
|
||||
|
||||
// Fire Event to check if the caller want to continue processing
|
||||
IfFailHrGo(Fire_ContinueEventProcessing(&fvarContinue));
|
||||
|
||||
// Check to see if the return value is VARIANT_FALSE
|
||||
if (VARIANT_FALSE == fvarContinue)
|
||||
fKeepLooping = FALSE;
|
||||
}
|
||||
|
||||
// Remove the event sink from the OUT endpoint
|
||||
IfFailHrGo(ReleaseConnectionPoint());
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::StartAsyncEventProcessing() {
|
||||
/*
|
||||
Demonstrates how to setup event sinks so that the event mechanism can
|
||||
be used to control data flow to and from the USB controller. In this
|
||||
example an event sink is installed on the OUT USB endpoint, when the
|
||||
controller has data to send to the device the OnWriteTransfer event
|
||||
will fire, this will occur on an arbitrary thread. The device then
|
||||
simply copies this data and passes it the IN queue of the IN
|
||||
Endpoint. Control returns to the caller and event processing
|
||||
continues in an arbitrary thread. To terminate event processing call
|
||||
StopAsyncEventProcessing.
|
||||
*/
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Set up event sink on the OUT endpoint
|
||||
IfFailHrGo(SetupConnectionPoint(m_piOUTEndpoint, __uuidof(ISoftUSBEndpointEvents)));
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::StopAsyncEventProcessing() {
|
||||
HRESULT hr = S_OK;
|
||||
// Remove the event sink on the OUT endpoint
|
||||
IfFailHrGo(ReleaseConnectionPoint());
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::AreKeystrokesWaiting(
|
||||
VARIANT_BOOL* pfvarKeyWaiting) {
|
||||
/*
|
||||
Implements IDeviceEmulator::AreKeystrokesWaiting. It calls the low level
|
||||
IO function _kbhit to see if the keyboard has been struck. If the Keyboard
|
||||
has been hit the function return VARIANT_TRUE otherwise it returns VARIANT_FALSE
|
||||
*/
|
||||
HRESULT hr = S_OK;
|
||||
int iKeyHit = 0;
|
||||
|
||||
if (NULL == pfvarKeyWaiting) {
|
||||
IfFailHrGo(E_POINTER);
|
||||
}
|
||||
|
||||
*pfvarKeyWaiting = VARIANT_FALSE;
|
||||
|
||||
iKeyHit = _kbhit();
|
||||
|
||||
if (0 != iKeyHit)
|
||||
*pfvarKeyWaiting = VARIANT_TRUE;
|
||||
|
||||
Exit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
//ISoftUSBEndpointEvents
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::OnSetupTransfer(BYTE DataToggle,
|
||||
BYTE* pbDataBuffer,
|
||||
ULONG cbDataBuffer,
|
||||
BYTE *pbStatus) {
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
UNREFERENCED_PARAMETER(DataToggle);
|
||||
UNREFERENCED_PARAMETER(pbDataBuffer);
|
||||
UNREFERENCED_PARAMETER(cbDataBuffer);
|
||||
UNREFERENCED_PARAMETER(pbStatus);
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::OnWriteTransfer(BYTE DataToggle,
|
||||
BYTE* pbDataBuffer,
|
||||
ULONG cbDataBuffer,
|
||||
BYTE * pbStatus) {
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
BYTE bINStatus = USB_ACK;
|
||||
UNREFERENCED_PARAMETER(DataToggle);
|
||||
|
||||
// Check that the IN endpoint is valid
|
||||
if (NULL == m_piINEndpoint) {
|
||||
IfFailHrGo(E_UNEXPECTED);
|
||||
}
|
||||
|
||||
// Send the data to the IN Endpoint
|
||||
IfFailHrGo(m_piINEndpoint->QueueINData(pbDataBuffer,
|
||||
cbDataBuffer,
|
||||
bINStatus,
|
||||
SOFTUSB_FOREVER));
|
||||
|
||||
// ACK the status as the data was successfully sent to the IN endpoint
|
||||
*pbStatus = USB_ACK;
|
||||
|
||||
Exit:
|
||||
if (FAILED(hr))
|
||||
*pbStatus = USB_STALL;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::OnReadTransfer(BYTE DataToggle,
|
||||
BYTE* pbDataBuffer,
|
||||
ULONG cbDataBuffer,
|
||||
ULONG* cbDataWritten,
|
||||
BYTE* pbStatus) {
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
UNREFERENCED_PARAMETER(DataToggle);
|
||||
UNREFERENCED_PARAMETER(pbDataBuffer);
|
||||
UNREFERENCED_PARAMETER(cbDataBuffer);
|
||||
UNREFERENCED_PARAMETER(cbDataWritten);
|
||||
UNREFERENCED_PARAMETER(pbStatus);
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::OnDeviceRequest(USBSETUPREQUEST *pSetupRequest,
|
||||
ULONG_PTR* RequestHandle,
|
||||
BYTE* pbHostData,
|
||||
ULONG cbHostData,
|
||||
BYTE** ppbResponseData,
|
||||
ULONG* pcbResponseData,
|
||||
BYTE* pbSetupStatus) {
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
UNREFERENCED_PARAMETER(pSetupRequest);
|
||||
UNREFERENCED_PARAMETER(RequestHandle);
|
||||
UNREFERENCED_PARAMETER(pbHostData);
|
||||
UNREFERENCED_PARAMETER(cbHostData);
|
||||
UNREFERENCED_PARAMETER(ppbResponseData);
|
||||
UNREFERENCED_PARAMETER(pcbResponseData);
|
||||
UNREFERENCED_PARAMETER(pbSetupStatus);
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLoopbackDevice::OnDeviceRequestComplete(
|
||||
ULONG_PTR RequestHandle,
|
||||
BYTE* pbFinalRequestStatus) {
|
||||
HRESULT hr = E_NOTIMPL;
|
||||
UNREFERENCED_PARAMETER(RequestHandle);
|
||||
UNREFERENCED_PARAMETER(pbFinalRequestStatus);
|
||||
return hr;
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 definition of the class CLoopbackDevice
|
||||
This project has been created from DDK's SoftUSBLoopback sample project
|
||||
that is located at $(DDK_PATH)\src\Test\DSF\USB\SoftUSBLoopback
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "resource.h"
|
||||
|
||||
#include "DeviceEmulator.h"
|
||||
#include "LoopbackDeviceEvents.h"
|
||||
|
||||
|
||||
//Release and Add ref macros
|
||||
#define ADDREF(punk) { \
|
||||
if ((punk) != NULL) { \
|
||||
(punk)->AddRef(); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define RELEASE(punk) { \
|
||||
if ((punk) != NULL) { \
|
||||
IUnknown *_punkXxx = (punk); \
|
||||
(punk) = NULL; \
|
||||
_punkXxx->Release(); \
|
||||
} \
|
||||
}
|
||||
|
||||
//HR check
|
||||
#define IfFailHrGo(EXPR) { hr = (EXPR); if(FAILED(hr)) goto Exit; }
|
||||
#define IfFalseHrGo(EXPR, HR) { if(!(EXPR)) { hr = (HR); goto Exit; } }
|
||||
|
||||
#pragma warning(disable: 4995) //Pragma deprecated
|
||||
|
||||
class ATL_NO_VTABLE CLoopbackDevice :
|
||||
public CComObjectRootEx<CComSingleThreadModel>,
|
||||
public CComCoClass<CLoopbackDevice, &CLSID_LoopbackDevice>,
|
||||
public IConnectionPointContainerImpl<CLoopbackDevice>,
|
||||
public CProxy_ILoopbackDeviceEvents<CLoopbackDevice>,
|
||||
public ISoftUSBEndpointEvents,
|
||||
public IDispatchImpl<ILoopbackDevice, &IID_ILoopbackDevice,
|
||||
&LIBID_DeviceEmulatorLib,
|
||||
/*wMajor =*/ 1, /*wMinor =*/ 0> {
|
||||
public:
|
||||
CLoopbackDevice();
|
||||
virtual ~CLoopbackDevice();
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_LOOPBACKDEVICE)
|
||||
|
||||
|
||||
BEGIN_COM_MAP(CLoopbackDevice)
|
||||
COM_INTERFACE_ENTRY(ILoopbackDevice)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(ISoftUSBEndpointEvents)
|
||||
COM_INTERFACE_ENTRY(IConnectionPointContainer)
|
||||
END_COM_MAP()
|
||||
|
||||
BEGIN_CONNECTION_POINT_MAP(CLoopbackDevice)
|
||||
CONNECTION_POINT_ENTRY(__uuidof(ILoopbackDeviceEvents))
|
||||
END_CONNECTION_POINT_MAP()
|
||||
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
HRESULT FinalConstruct();
|
||||
|
||||
void FinalRelease();
|
||||
|
||||
private:
|
||||
void InitMemberVariables();
|
||||
|
||||
HRESULT CreateUSBDevice();
|
||||
HRESULT CreateStrings();
|
||||
HRESULT ConfigureDevice();
|
||||
HRESULT ConfigureOUTEndpoint();
|
||||
HRESULT ConfigureINEndpoint();
|
||||
HRESULT ConfigureInterface(ISoftUSBInterface* piInterface);
|
||||
HRESULT ConfigureConfig(ISoftUSBConfiguration* piConfig);
|
||||
|
||||
HRESULT SetupConnectionPoint(IUnknown* punkObject,
|
||||
REFIID iidConnectionPoint);
|
||||
HRESULT ReleaseConnectionPoint();
|
||||
|
||||
// Underlying SoftUSBDevice object
|
||||
ISoftUSBDevice *m_piSoftUSBDevice;
|
||||
// IN Endpoint
|
||||
ISoftUSBEndpoint *m_piINEndpoint;
|
||||
// OUT Endpoint
|
||||
ISoftUSBEndpoint *m_piOUTEndpoint;
|
||||
// Connection point interface
|
||||
IConnectionPoint *m_piConnectionPoint;
|
||||
// Connection point cookie.
|
||||
DWORD m_dwConnectionCookie;
|
||||
// Index of interface identifier string
|
||||
int m_iInterfaceString;
|
||||
// Index of config identifier string
|
||||
int m_iConfigString;
|
||||
|
||||
public:
|
||||
//ILoopbackDevice
|
||||
STDMETHOD(get_DSFDevice)(DSFDevice** ppDSFDevice);
|
||||
STDMETHOD(DoPolledLoopback)(long lTimeInterval);
|
||||
STDMETHOD(StartEventProcessing)();
|
||||
STDMETHOD(StartAsyncEventProcessing)();
|
||||
STDMETHOD(StopAsyncEventProcessing)();
|
||||
STDMETHOD(AreKeystrokesWaiting)(VARIANT_BOOL* pfvarKeyWaiting);
|
||||
|
||||
//ISoftUSBEndpointEvents
|
||||
STDMETHOD(OnSetupTransfer)(BYTE DataToggle, BYTE* pbDataBuffer,
|
||||
ULONG cbDataBuffer, BYTE* pbStatus);
|
||||
|
||||
STDMETHOD(OnWriteTransfer)(BYTE DataToggle, BYTE* pbDataBuffer,
|
||||
ULONG cbDataBuffer, BYTE* pbStatus);
|
||||
|
||||
STDMETHOD(OnReadTransfer)(BYTE DataToggle, BYTE* pbDataBuffer,
|
||||
ULONG cbDataBuffer,ULONG* cbDataWritten,
|
||||
BYTE* pbStatus);
|
||||
|
||||
STDMETHOD(OnDeviceRequest)(USBSETUPREQUEST* pSetupRequest,
|
||||
ULONG_PTR* RequestHandle,
|
||||
BYTE* pbHostData, ULONG cbHostData,
|
||||
BYTE** ppbResponseData,
|
||||
ULONG* pcbResponseData,BYTE* pbSetupStatus);
|
||||
|
||||
STDMETHOD(OnDeviceRequestComplete)(ULONG_PTR RequestHandle,
|
||||
BYTE* pbFinalRequestStatus);
|
||||
};
|
||||
|
||||
OBJECT_ENTRY_AUTO(__uuidof(LoopbackDevice), CLoopbackDevice)
|
||||
@@ -1,27 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
DeviceEmulator.LoopbackDevice.1 = s 'LoopbackDevice Class'
|
||||
{
|
||||
CLSID = s '{9A0BD4A6-E346-4668-A89C-ACA546212CD4}'
|
||||
}
|
||||
DeviceEmulator.LoopbackDevice = s 'LoopbackDevice Class'
|
||||
{
|
||||
CLSID = s '{9A0BD4A6-E346-4668-A89C-ACA546212CD4}'
|
||||
CurVer = s 'DeviceEmulator.LoopbackDevice.1'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {9A0BD4A6-E346-4668-A89C-ACA546212CD4} = s 'LoopbackDevice Class'
|
||||
{
|
||||
ProgID = s 'DeviceEmulator.LoopbackDevice.1'
|
||||
VersionIndependentProgID = s 'DeviceEmulator.LoopbackDevice'
|
||||
ForceRemove 'Programmable'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Apartment'
|
||||
}
|
||||
'TypeLib' = s '{0C206596-5CC2-4d16-898D-4D1699BB6282}'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 definition of the template class which implements the
|
||||
event interface ILoopbackDeviceEvents.
|
||||
This project has been created from DDK's SoftUSBLoopback sample project
|
||||
that is located at $(DDK_PATH)\src\Test\DSF\USB\SoftUSBLoopback
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
class CProxy_ILoopbackDeviceEvents :
|
||||
public IConnectionPointImpl<T, &__uuidof(ILoopbackDeviceEvents)> {
|
||||
public:
|
||||
HRESULT _stdcall Fire_ContinueToPoll(VARIANT_BOOL *pfvarContinue) {
|
||||
HRESULT hr = S_OK;
|
||||
T* pThis = static_cast<T *>(this);
|
||||
int cConnections = m_vec.GetSize();
|
||||
|
||||
for (int iConnection = 0; iConnection < cConnections; iConnection++) {
|
||||
pThis->Lock();
|
||||
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
|
||||
pThis->Unlock();
|
||||
|
||||
IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);
|
||||
|
||||
if (pConnection) {
|
||||
CComVariant varResult;
|
||||
|
||||
DISPPARAMS params = { NULL, NULL, 0, 0 };
|
||||
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT,
|
||||
DISPATCH_METHOD, ¶ms, &varResult,
|
||||
NULL, NULL);
|
||||
|
||||
//Set the return parameter
|
||||
*pfvarContinue = varResult.boolVal;
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT _stdcall Fire_ContinueEventProcessing(VARIANT_BOOL *pfvarContinue) {
|
||||
HRESULT hr = S_OK;
|
||||
T * pThis = static_cast<T *>(this);
|
||||
int cConnections = m_vec.GetSize();
|
||||
|
||||
for (int iConnection = 0; iConnection < cConnections; iConnection++) {
|
||||
pThis->Lock();
|
||||
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
|
||||
pThis->Unlock();
|
||||
|
||||
IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);
|
||||
|
||||
if (pConnection) {
|
||||
CComVariant varResult;
|
||||
|
||||
DISPPARAMS params = { NULL, NULL, 0, 0 };
|
||||
hr = pConnection->Invoke(2, IID_NULL, LOCALE_USER_DEFAULT,
|
||||
DISPATCH_METHOD, ¶ms, &varResult,
|
||||
NULL, NULL);
|
||||
|
||||
//Set the return parameter
|
||||
*pfvarContinue = varResult.boolVal;
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "device_emulator", "device_emulator.vcproj", "{EAB61831-9DDA-40AA-A5EF-2D9E8F9A5C59}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{EAB61831-9DDA-40AA-A5EF-2D9E8F9A5C59}.Debug.ActiveCfg = Debug|Win32
|
||||
{EAB61831-9DDA-40AA-A5EF-2D9E8F9A5C59}.Debug.Build.0 = Debug|Win32
|
||||
{EAB61831-9DDA-40AA-A5EF-2D9E8F9A5C59}.Release.ActiveCfg = Release|Win32
|
||||
{EAB61831-9DDA-40AA-A5EF-2D9E8F9A5C59}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,144 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="device_emulator"
|
||||
ProjectGUID="{EAB61831-9DDA-40AA-A5EF-2D9E8F9A5C59}"
|
||||
Keyword="MakeFileProj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="0">
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="call c:\winddk\6000\bin\setenv.bat c:\winddk\6000\ chk WXP
|
||||
set PROJECTDIR=$(ProjectDir)
|
||||
set DRIVE=%PROJECTDIR:~0,2%
|
||||
%DRIVE%
|
||||
cd %PROJECTDIR%
|
||||
build -beEIFZ
|
||||
"
|
||||
ReBuildCommandLine="call c:\winddk\6000\bin\setenv.bat c:\winddk\6000\ chk WXP
|
||||
set PROJECTDIR=$(ProjectDir)
|
||||
set DRIVE=%PROJECTDIR:~0,2%
|
||||
%DRIVE%
|
||||
cd %PROJECTDIR%
|
||||
build -cbeEIFZ
|
||||
"
|
||||
CleanCommandLine="call c:\winddk\6000\bin\setenv.bat c:\winddk\6000\ chk WXP
|
||||
set PROJECTDIR=$(ProjectDir)
|
||||
set DRIVE=%PROJECTDIR:~0,2%
|
||||
%DRIVE%
|
||||
cd %PROJECTDIR%
|
||||
build -c0
|
||||
"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="0">
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="call c:\winddk\6000\bin\setenv.bat c:\winddk\6000\ free WXP
|
||||
set PROJECTDIR=$(ProjectDir)
|
||||
set DRIVE=%PROJECTDIR:~0,2%
|
||||
%DRIVE%
|
||||
cd %PROJECTDIR%
|
||||
build -beEIFZ"
|
||||
ReBuildCommandLine="call c:\winddk\6000\bin\setenv.bat c:\winddk\6000\ free WXP
|
||||
set PROJECTDIR=$(ProjectDir)
|
||||
set DRIVE=%PROJECTDIR:~0,2%
|
||||
%DRIVE%
|
||||
cd %PROJECTDIR%
|
||||
build -cbeEIFZ"
|
||||
CleanCommandLine="call c:\winddk\6000\bin\setenv.bat c:\winddk\6000\ free WXP
|
||||
set PROJECTDIR=$(ProjectDir)
|
||||
set DRIVE=%PROJECTDIR:~0,2%
|
||||
%DRIVE%
|
||||
cd %PROJECTDIR%
|
||||
build -c0
|
||||
"
|
||||
Output="device_emulator.dll"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\LoopbackDevice.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DeviceEmulator.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DeviceEmulator.idl">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\LoopbackDevice.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LoopbackDeviceEvents.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h">
|
||||
</File>
|
||||
<Filter
|
||||
Name="common"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\common\android_usb_common_defines.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
<File
|
||||
RelativePath=".\LoopbackDevice.rgs">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DeviceEmulator.rc">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DeviceEmulator.rgs">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\makefile">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\RunDeviceLoopbackSample.wsf">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DeviceEmulator.def">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sources">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,8 +0,0 @@
|
||||
#
|
||||
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||
# file to this component. This file merely indirects to the real make file
|
||||
# that is shared by all the driver components of the Windows NT DDK
|
||||
#
|
||||
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 defines resources used by Emulator.rc
|
||||
This project has been created from DDK's SoftUSBLoopback sample project
|
||||
that is located at $(DDK_PATH)\src\Test\DSF\USB\SoftUSBLoopback
|
||||
*/
|
||||
|
||||
#define IDS_PROJNAME 100
|
||||
#define IDR_DEVICEEMULATOR 101
|
||||
#define IDR_LOOPBACKDEVICE 102
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 201
|
||||
#define _APS_NEXT_COMMAND_VALUE 32768
|
||||
#define _APS_NEXT_CONTROL_VALUE 201
|
||||
#define _APS_NEXT_SYMED_VALUE 103
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
TARGETNAME= DeviceEmulator
|
||||
TARGETTYPE=DYNLINK
|
||||
|
||||
DLLENTRY=_DllMainCRTStartup
|
||||
|
||||
DLLDEF=DeviceEmulator.def
|
||||
|
||||
USE_NATIVE_EH=ASYNC
|
||||
|
||||
MUI = 0
|
||||
MUI_COMMENT=TEST_TOOL, Device Simulation Framework
|
||||
|
||||
PRECOMPILED_CXX = 1
|
||||
|
||||
MSC_WARNING_LEVEL=/W4 /WX
|
||||
|
||||
USE_ATL = 1
|
||||
ATL_VER = 70
|
||||
|
||||
USE_MSVCRT = 1
|
||||
USE_OBJECT_ROOT=1
|
||||
|
||||
!IF "$(DDKBUILDENV)"=="chk"
|
||||
TARGETPATH=..\..\build\Debug
|
||||
!ELSE
|
||||
TARGETPATH=..\..\build\Release
|
||||
!ENDIF
|
||||
|
||||
|
||||
C_DEFINES = $(C_DEFINES) -DDSF_USER_MODE -DUNICODE
|
||||
|
||||
PRECOMPILED_CXX=1
|
||||
|
||||
TARGETLIBS= \
|
||||
$(SDK_LIB_PATH)\kernel32.lib \
|
||||
$(SDK_LIB_PATH)\user32.lib \
|
||||
$(SDK_LIB_PATH)\advapi32.lib \
|
||||
$(SDK_LIB_PATH)\ole32.lib \
|
||||
$(SDK_LIB_PATH)\oleaut32.lib \
|
||||
$(SDK_LIB_PATH)\uuid.lib \
|
||||
$(SDK_LIB_PATH)\shlwapi.lib \
|
||||
$(DDK_LIB_PATH)\SoftUSBIf.lib \
|
||||
|
||||
|
||||
INCLUDES=\
|
||||
..\..\api; \
|
||||
..\..\common; \
|
||||
$(DDK_LIB_DEST)\$(TARGET_DIRECTORY); \
|
||||
$(DDK_INC_PATH); \
|
||||
|
||||
SOURCES= \
|
||||
DeviceEmulator.idl \
|
||||
LoopbackDevice.cpp \
|
||||
DeviceEmulator.cpp \
|
||||
DeviceEmulator.rc \
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef STRICT
|
||||
#define STRICT
|
||||
#endif
|
||||
|
||||
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
||||
// Refer to MSDN for the latest info on corresponding values for different platforms.
|
||||
#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
|
||||
#define WINVER 0x0500 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
|
||||
#define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target Windows 2000 or later.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
|
||||
#define _WIN32_WINDOWS 0x0500 // Change this to the appropriate value to target Windows Me or later.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
|
||||
#define _WIN32_IE 0x0501 // Change this to the appropriate value to target IE 5.0 or later.
|
||||
#endif
|
||||
|
||||
#define _ATL_APARTMENT_THREADED
|
||||
#define _ATL_NO_AUTOMATIC_NAMESPACE
|
||||
|
||||
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
|
||||
|
||||
// turns off ATL's hiding of some common and often safely ignored warning messages
|
||||
#define _ATL_ALL_WARNINGS
|
||||
|
||||
|
||||
#include "resource.h"
|
||||
#include <atlbase.h>
|
||||
#include <atlcom.h>
|
||||
|
||||
using namespace ATL;
|
||||
|
||||
Reference in New Issue
Block a user