📄 usbcomm.cpp
字号:
//---------------------------------------------------------------------------
// TUsbDevice Implementation
#include <windows.h>
#include <winbase.h>
#include <winioctl.h>
#include <initguid.h>
#include "usbioctl.h" // From the Win DDK
#include <dbt.h>
#include <mem.h>
#include <vcl\sysutils.hpp>
#include "WinRTUsbStatus.h"
#include "WinRTUsbCtl.h"
#include "USBComm.h"
//---------------------------------------------------------------------------
// CONSTANT DECLARATIONS
//
#define LINKNAME "ZeevoBT"
#define INTERRUPT_ENDPOINT0 0
#define BULK_ENDPOINT0 1
#define BULK_ENDPOINT1 2
#define ISO_ENDPOINT0 3
#define ISO_ENDPOINT1 4
//---------------------------------------------------------------------------
// DATA Declarations
// This array is used to track which device numbers have been used. A unique
// number must be used for each instantiation of this class.
bool TUsbDevice::deviceTracker[MAX_USB_DEVICES] = {false, false, false, false};
// GUID for ZeevoBT is EC287A61-FB9D-11D4-B459-0050DA91F28C
DEFINE_GUID(GUID_ZeevoBT, 0xEC287A61, 0xFB9D, 0x11D4, 0xB4, 0x59, 0x0, 0x50,
0xDA, 0x91, 0xF2, 0x8C);
// GUID for WinRT, our device class 1BBF12A7-1329-41E0-9230-2935E5BE558F
DEFINE_GUID(GUID_WinRT, 0x1BBF12A7, 0x1329, 0x41E0, 0x92, 0x30, 0x29,0x35,0xE5,
0xBE,0x55,0x8F);
static char pidVidStr[] = "vid_0b7a&pid_07d0";
BOOL isWin98; // Windows version flag
//---------------------------------------------------------------------------
// CONSTRUCTOR default
TUsbDevice::TUsbDevice()
: deviceHandle(INVALID_HANDLE_VALUE)
{
// Initialize all the class pointers so that the cleanup routine can tell
// when there is no pointer to delete.
OnClose = NULL; // Added By Melvin
savedError = ERROR_SUCCESS; // Start out with no error
intEpOverlapStruct.hEvent = NULL;
bulkEpOverlapStruct.hEvent = NULL;
// Search deviceTracker array to find an unused device number
// Yeah, we can fall off the end of the array
for (deviceNum = 0; deviceNum < MAX_USB_DEVICES; deviceNum++)
{
if (deviceTracker[deviceNum] == false)
break;
}
// Open a handle to our USB device
deviceHandle = WinRTOpenHandle(LINKNAME, deviceNum, true);
if (deviceHandle == INVALID_HANDLE_VALUE)
{
// Open failed
savedError = GetLastError();
return;
}
else
{
// Mark the device number as used.
deviceTracker[deviceNum] = true;
}
// Create an event for the overlapped structure for interrupt transfers
intEpOverlapStruct.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (intEpOverlapStruct.hEvent == NULL)
{
savedError = GetLastError();
cleanup();
}
// Create an event for the overlapped structure for bulk transfers
bulkEpOverlapStruct.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (bulkEpOverlapStruct.hEvent == NULL)
{
savedError = GetLastError();
cleanup();
}
return;
}
//---------------------------------------------------------------------------
// DESTRUCTOR default
TUsbDevice::~TUsbDevice()
{
cleanup();
return;
}
//---------------------------------------------------------------------------
// Destructor Helper
void TUsbDevice::cleanup(void)
{
// Get rid of USB device
if (deviceHandle != INVALID_HANDLE_VALUE)
{
deviceTracker[deviceNum] = false;
CancelIo(deviceHandle); // Kill any async I/O running
WinRTCloseHandle(deviceHandle);
if(OnClose)
OnClose();
}
// Get rid of structures used for the windows events
if (intEpOverlapStruct.hEvent != NULL)
CloseHandle(intEpOverlapStruct.hEvent);
if (bulkEpOverlapStruct.hEvent != NULL)
CloseHandle(bulkEpOverlapStruct.hEvent);
return;
}
//---------------------------------------------------------------------------
// Register for Device Notification
//
// Calling this function will register the caller for notifications when
// a device change is detected by Windows. This would include unplugging or
// plugging in the device.
//
// A device handle must be created first.
// This function is not a member of the TUsbDevice class. It may be called
// before any TUsbDevice devices are created.
//
HDEVNOTIFY registerForDevNotify(HWND m_hWnd)
{
// device notification struct
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
HDEVNOTIFY hDevnotify;
// Clear out the filter structure
setmem(&NotificationFilter, sizeof(NotificationFilter), 0);
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
// User our device ID. Only want messages for our Zeevo BT device.
NotificationFilter.dbcc_classguid = GUID_ZeevoBT;
hDevnotify = WinRTRegisterDeviceNotification(
m_hWnd,
&NotificationFilter,
DEVICE_NOTIFY_WINDOW_HANDLE);
return hDevnotify;
}
//---------------------------------------------------------------------------
void unregisterForDevNotify(HDEVNOTIFY notifyHandle)
{
WinRTUnregisterDeviceNotification(notifyHandle);
return;
}
//---------------------------------------------------------------------------
bool validateZeevoIDs(char* vendorPidString)
{
if (AnsiStrIComp(vendorPidString, pidVidStr) == 0)
return true;
else
return false;
}
//---------------------------------------------------------------------------
void getGUID(LPGUID pGUID)
{
*pGUID = GUID_ZeevoBT;
return;
}
//---------------------------------------------------------------------------
LONG TUsbDevice::clearStall(UCHAR endpoint)
{
return WinRTClearStall(deviceHandle, endpoint);
}
//---------------------------------------------------------------------------
// Detect the Windows Version
//
// Set a boolean flag if we are running on Win98
void detectWinVer(void)
{
OSVERSIONINFO verInfo;
verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&verInfo); // Get the info from the OS
if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
isWin98 = true;
return;
}
//---------------------------------------------------------------------------
LONG TUsbDevice::getDeviceStatus(void)
{
// Check the result of the CreateFile call for the USB device
if (deviceHandle == INVALID_HANDLE_VALUE)
{
// Invalid handle, return the error code
return GetLastError();
}
else
{
return savedError;
}
}
//---------------------------------------------------------------------------
bool TUsbDevice::setFeature(int feature)
{
return false;
}
//---------------------------------------------------------------------------
bool TUsbDevice::clearFeature(int feature)
{
return false;
}
//---------------------------------------------------------------------------
bool TUsbDevice::enableRemoteWakeup(void)
{
#if 0
VENDOR_OR_CLASS_REQUEST_CONTROL classReqStruct;
BOOLEAN success;
ULONG nBytes; // For holding the returned byte count
ULONG urbStatus = 0;
classReqStruct.direction = 0; // Host to device
classReqStruct.requestType = 0; // Standard request
classReqStruct.recepient = 0; // Set Device feature
classReqStruct.requestTypeReservedBits = 0; // not used
classReqStruct.request = USB_REQUEST_SET_FEATURE; // Feature request code
classReqStruct.value = USB_FEATURE_REMOTE_WAKEUP; // Feature selector
classReqStruct.index = 0; // Not used
#endif
return false;
}
//---------------------------------------------------------------------------
bool TUsbDevice::disableRemoteWakeup(void)
{
#if 0
VENDOR_OR_CLASS_REQUEST_CONTROL classReqStruct;
BOOLEAN success;
ULONG nBytes; // For holding the returned byte count
classReqStruct.direction = 0; // Host to device
classReqStruct.requestType = 0; // Standard request
classReqStruct.recepient = 0; // Set Device feature
classReqStruct.requestTypeReservedBits = 0; // not used
classReqStruct.request = USB_REQUEST_CLEAR_FEATURE; // Feature request code
classReqStruct.value = USB_FEATURE_REMOTE_WAKEUP; // Feature selector
classReqStruct.index = 0; // Not used
#endif
return false;
}
//---------------------------------------------------------------------------
bool TUsbDevice::enableScoChannel(tScoCapacity scoCapacity)
{
WORD altInterface;
LONG result;
switch (scoCapacity)
{
case TWOVOICE8_ONEVOICE16:
altInterface = 1;
break;
case ONEVOICE8:
case THREEVOICE8:
case TWOVOICE16:
case THREEVOICE16:
default:
// Illegal capacity selection
return false;
}
result = WinRTControlTransfer(deviceHandle,
REQUEST_TYPE_INTERFACE | REQUEST_TYPE_DEVICE,
11, // Set Interface request code
altInterface, // Alternate setting
1, // Interface number
true, // HostToDevice transfer
0,
NULL,
NULL);
if (result == ERROR_SUCCESS)
return true;
else
{
savedError = result; // Save error code for debugging
return false;
}
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -