Delete files irrelevant for the new driver model

:x
This commit is contained in:
vchtchetkine
2009-07-23 10:41:24 -07:00
parent 3b1edb4d39
commit d79c237203
51 changed files with 0 additions and 9882 deletions

View File

@@ -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__

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

View File

@@ -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()

View File

@@ -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__

View File

@@ -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()

View File

@@ -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

View File

@@ -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__

View File

@@ -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__

View File

@@ -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()

View File

@@ -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__

View File

@@ -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()

View File

@@ -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__

View File

@@ -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__

View File

@@ -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()

View File

@@ -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__

View File

@@ -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__

View File

@@ -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()

View File

@@ -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__

View File

@@ -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__

View File

@@ -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()

View File

@@ -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__

View File

@@ -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

View File

@@ -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)

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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="&quot;..\..\build\$(OutDir)\i386&quot;"
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="&quot;..\..\build\$(OutDir)\i386&quot;"
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>

View File

@@ -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

View 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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
};
};

View File

@@ -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

View File

@@ -1,12 +0,0 @@
HKCR
{
NoRemove AppID
{
'%APPID%' = s 'DeviceEmulator'
'DeviceEmulator.EXE'
{
val AppID = s '%APPID%'
}
}
}

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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}'
}
}
}

View File

@@ -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, &params, &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, &params, &varResult,
NULL, NULL);
//Set the return parameter
*pfvarContinue = varResult.boolVal;
}
}
return hr;
}
};

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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 \

View File

@@ -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"

View File

@@ -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;