📄 bot.cpp
字号:
return fResult;
}
// Close the store
DWORD
BOT_Close(
)
{
SETFNAME(_T("BOT_Close"));
FUNCTION_ENTER_MSG();
if (g_fStoreOpened) {
STORE_Close();
g_fStoreOpened = FALSE;
}
if (g_pbDataBuffer) LocalFree(g_pbDataBuffer);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
// Process a device event.
static
BOOL
WINAPI
BOT_DeviceNotify(
PVOID pvNotifyParameter,
DWORD dwMsg,
DWORD dwParam
)
{
EnterCriticalSection(&g_cs);
SETFNAME(_T("BOT_DeviceNotify"));
FUNCTION_ENTER_MSG();
CONTROL_RESPONSE response = CR_SUCCESS;
switch(dwMsg) {
case UFN_MSG_BUS_EVENTS: {
// Ensure device is in running state
DEBUGCHK(g_hDefaultPipe);
switch(dwParam) {
case UFN_DETACH:
if (g_fStoreOpened) {
STORE_Close();
g_fStoreOpened = FALSE;
}
// Reset device
BOT_ResetPipeState(&g_psDefaultPipeState);
BOT_ResetPipeState(&g_psBOPipeState);
BOT_ResetPipeState(&g_psBIPipeState);
if (g_hBOPipe) {
g_pUfnFuncs->lpClosePipe(g_hDevice, g_hBOPipe);
g_hBOPipe = NULL;
}
if (g_hBIPipe) {
g_pUfnFuncs->lpClosePipe(g_hDevice, g_hBIPipe);
g_hBIPipe = NULL;
}
g_fCBWArrived = FALSE;
ChangeMscState(MSC_STATE_IDLE);
break;
case UFN_ATTACH: {
// Open store if not already open
if (!g_fStoreOpened) {
RETAILMSG(1, (TEXT("UFN_ATTACH with key = %s\r\n"), g_szActiveKey));
DWORD dwRet = STORE_Init(g_szActiveKey);
if (dwRet != ERROR_SUCCESS) {
ERRORMSG(1, (_T("%s Failed to open store\r\n"),
pszFname));
}
else {
g_fStoreOpened = TRUE;
}
}
// Reset device
BOT_ResetPipeState(&g_psDefaultPipeState);
BOT_ResetPipeState(&g_psBOPipeState);
BOT_ResetPipeState(&g_psBIPipeState);
if (g_hBOPipe) {
g_pUfnFuncs->lpClosePipe(g_hDevice, g_hBOPipe);
g_hBOPipe = NULL;
}
if (g_hBIPipe) {
g_pUfnFuncs->lpClosePipe(g_hDevice, g_hBIPipe);
g_hBIPipe = NULL;
}
g_fCBWArrived = FALSE;
ChangeMscState(MSC_STATE_IDLE);
break;
}
case UFN_RESET:
// Reset device
BOT_ResetPipeState(&g_psDefaultPipeState);
BOT_ResetPipeState(&g_psBOPipeState);
BOT_ResetPipeState(&g_psBIPipeState);
if (g_hBOPipe) {
g_pUfnFuncs->lpClosePipe(g_hDevice, g_hBOPipe);
g_hBOPipe = NULL;
}
if (g_hBIPipe) {
g_pUfnFuncs->lpClosePipe(g_hDevice, g_hBIPipe);
g_hBIPipe = NULL;
}
g_fCBWArrived = FALSE;
ChangeMscState(MSC_STATE_IDLE);
break;
default:
break;
}
break;
}
case UFN_MSG_BUS_SPEED:
g_SpeedSupported = (UFN_BUS_SPEED) dwParam;
break;
case UFN_MSG_SETUP_PACKET:
case UFN_MSG_PREPROCESSED_SETUP_PACKET: {
PUSB_DEVICE_REQUEST pudr = (PUSB_DEVICE_REQUEST) dwParam;
BOT_HandleRequest(dwMsg, *pudr);
break;
}
case UFN_MSG_CONFIGURED:
if (dwParam == 0) {
// Reset device
BOT_ResetPipeState(&g_psDefaultPipeState);
BOT_ResetPipeState(&g_psBOPipeState);
BOT_ResetPipeState(&g_psBIPipeState);
if (g_hBOPipe) {
g_pUfnFuncs->lpClosePipe(g_hDevice, g_hBOPipe);
g_hBOPipe = NULL;
}
if (g_hBIPipe) {
g_pUfnFuncs->lpClosePipe(g_hDevice, g_hBIPipe);
g_hBIPipe = NULL;
}
g_fCBWArrived = FALSE;
ChangeMscState(MSC_STATE_IDLE);
}
else {
RETAILMSG(1,(TEXT("UFN_CONFIGURED: BOT_OpenInterface again\r\n")));
DEBUGCHK(g_hBIPipe == NULL);
BOT_OpenInterface();
}
break;
default:
break;
}
FUNCTION_LEAVE_MSG();
LeaveCriticalSection(&g_cs);
return TRUE;
}
DWORD
WINAPI
BOT_TransferThread(
LPVOID lpParameter
)
{
SETFNAME(_T("BOT_TransferThread"));
FUNCTION_ENTER_MSG();
HANDLE rghevWaits[dim(g_rgPipeTransfers)];
for (DWORD dwIdx = 0; dwIdx < dim(g_rgPipeTransfers); ++dwIdx) {
DEBUGCHK(g_rgPipeTransfers[dwIdx].hev);
rghevWaits[dwIdx] = g_rgPipeTransfers[dwIdx].hev;
}
while (TRUE) {
// How to exit?
DWORD dwWait = WaitForMultipleObjects(dim(rghevWaits), rghevWaits,
FALSE, INFINITE);
DEBUGMSG(ZONE_COMMENT, (_T("%s Transfer %u\r\n"), pszFname, dwWait));
DWORD dwIdx = dwWait - WAIT_OBJECT_0;
if (dwIdx >= dim(rghevWaits)) {
break;
}
EnterCriticalSection(&g_cs);
PPIPE_TRANSFER pPipeTransfer;
pPipeTransfer = &g_rgPipeTransfers[dwIdx];
DEBUGCHK(pPipeTransfer->hev);
DEBUGCHK(pPipeTransfer->hTransfer);
DWORD dwUsbError;
DWORD cbTransferred;
DWORD dwErr;
dwErr = g_pUfnFuncs->lpGetTransferStatus(g_hDevice, pPipeTransfer->hTransfer,
&cbTransferred, &dwUsbError);
DEBUGCHK(dwErr == ERROR_SUCCESS);
DEBUGMSG(ZONE_COMMENT, (_T("%s %u bytes transferred\r\n"), pszFname,
cbTransferred));
dwErr = g_pUfnFuncs->lpCloseTransfer(g_hDevice, pPipeTransfer->hTransfer);
DEBUGCHK(dwErr == ERROR_SUCCESS);
pPipeTransfer->hTransfer = NULL;
if (dwUsbError != UFN_NO_ERROR) {
DEBUGCHK(dwUsbError == UFN_CANCELED_ERROR);
goto CONTINUE;
}
// Don't process if detached
if (g_MscState == MSC_STATE_IDLE) {
goto CONTINUE;
}
// TODO: Don't do these if transfer error
if (dwIdx == CONTROL_TRANSFER) {
g_pUfnFuncs->lpSendControlStatusHandshake(g_hDevice);
}
else if (dwIdx == OUT_TRANSFER) {
ProcessBOPipeTransfer(cbTransferred);
}
else {
DEBUGCHK(dwIdx == IN_TRANSFER);
ProcessBIPipeTransfer();
}
CONTINUE:
LeaveCriticalSection(&g_cs);
}
FUNCTION_LEAVE_MSG();
return 0;
}
// Initialize the Bulk-Only Transport layer.
DWORD
BOT_InternalInit(
LPCTSTR pszActiveKey
)
{
SETFNAME(_T("BOT_InternalInit"));
FUNCTION_ENTER_MSG();
HKEY hClientDriverKey = NULL;
DWORD dwRet;
HRESULT hr = 0;
PREFAST_DEBUGCHK(pszActiveKey);
RETAILMSG(1, (TEXT("BOT_InternalInit with %s\r\n"), pszActiveKey));
InitializeCriticalSection(&g_cs);
hr = StringCchCopy(g_szActiveKey, dim(g_szActiveKey), pszActiveKey);
if (FAILED(hr)) {
dwRet = GetLastError();
ERRORMSG(1, (_T("%s Failed to copy device key. Error = %d\r\n"),
pszFname, dwRet));
goto EXIT;
}
hClientDriverKey = OpenDeviceKey(g_szActiveKey);
if (hClientDriverKey == NULL) {
dwRet = GetLastError();
ERRORMSG(1, (_T("%s Failed to open device key. Error = %d\r\n"),
pszFname, dwRet));
goto EXIT;
}
// Configure function controller
dwRet = BOT_Configure(pszActiveKey, hClientDriverKey);
if (dwRet != ERROR_SUCCESS) {
ERRORMSG(1,
(_T("%s Failed to configure function controller from registry\r\n"),
pszFname));
goto EXIT;
}
// g_pUfnFuncs = pUfnFuncs;
// Allocate data buffer
g_pbDataBuffer = (PBYTE) LocalAlloc(0, g_cbDataBuffer);
if (g_pbDataBuffer == NULL) {
dwRet = GetLastError();
ERRORMSG(1, (_T("%s LocalAlloc failed. Error: %d\r\n"),
pszFname, dwRet));
goto EXIT;
}
// Register descriptor tree with device controller
dwRet = g_pUfnFuncs->lpRegisterDevice(g_hDevice,
&g_HighSpeedDeviceDesc, &g_HighSpeedConfig,
&g_FullSpeedDeviceDesc, &g_FullSpeedConfig,
g_rgStringSets, dim(g_rgStringSets));
if (dwRet != ERROR_SUCCESS) {
ERRORMSG(1, (_T("%s Descriptor registration failed\r\n"),
pszFname));
goto EXIT;
}
// Mark registration
g_fDeviceRegistered = TRUE;
// Create pipe events
DWORD dwTransfer;
for (dwTransfer = 0; dwTransfer < dim(g_rgPipeTransfers); ++dwTransfer) {
g_rgPipeTransfers[dwTransfer].hev = CreateEvent(0, FALSE, FALSE, NULL);
if (g_rgPipeTransfers[dwTransfer].hev == NULL) {
dwRet = GetLastError();
ERRORMSG(1, (_T("%s Error creating event. Error = %d\r\n"),
pszFname, dwRet));
goto EXIT;
}
}
// Create transfer thread
g_htTransfers = CreateThread(NULL, 0, BOT_TransferThread, NULL, 0, NULL);
if (g_htTransfers == NULL) {
ERRORMSG(1, (_T("%s Transfer thread creation failed\r\n"), pszFname));
dwRet = GetLastError();
goto EXIT;
}
// Read transfer thread priority from registry
DWORD dwTransferThreadPriority;
if (BOT_ReadConfigurationValue(hClientDriverKey,
UMS_REG_TRANSFER_THREAD_PRIORITY_VAL, &dwTransferThreadPriority, FALSE))
{
DEBUGMSG(1,
(_T("%s BOT transfer thread priority = %u (from registry)\r\n"),
pszFname, dwTransferThreadPriority));
}
else {
dwTransferThreadPriority = DEFAULT_TRANSFER_THREAD_PRIORITY;
DEBUGMSG(1, (_T("%s BOT transfer thread priority = %u\r\n"),
pszFname, dwTransferThreadPriority));
}
// Set transfer thread priority
if (!CeSetThreadPriority(g_htTransfers, dwTransferThreadPriority)) {
dwRet = GetLastError();
DEBUGMSG(1,
(_T("%s Failed to set thread priority, last error = %u; exiting\r\n"),
pszFname, dwRet));
goto EXIT;
}
// Start the device controller
dwRet = g_pUfnFuncs->lpStart(g_hDevice, BOT_DeviceNotify, NULL,
&g_hDefaultPipe);
if (dwRet != ERROR_SUCCESS) {
ERRORMSG(1, (_T("%s Device controller failed to start\r\n"),
pszFname));
goto EXIT;
}
dwRet = ERROR_SUCCESS;
EXIT:
if (hClientDriverKey) {
RegCloseKey(hClientDriverKey);
}
if (dwRet != ERROR_SUCCESS) {
if (g_htTransfers) {
CloseHandle(g_htTransfers);
}
if (g_pbDataBuffer) {
LocalFree(g_pbDataBuffer);
}
if (g_fDeviceRegistered) {
g_pUfnFuncs->lpDeregisterDevice(g_hDevice);
}
}
FUNCTION_LEAVE_MSG();
return dwRet;
}
static PVOID g_pvInterface = NULL;
extern "C"
DWORD
Init(
LPCTSTR pszActiveKey
)
{
DWORD dwErr = UfnInitializeInterface(pszActiveKey, &g_hDevice,
&g_ufnFuncs, &g_pvInterface);
if (dwErr == ERROR_SUCCESS) {
dwErr = BOT_InternalInit(pszActiveKey);
if (dwErr != ERROR_SUCCESS) {
UfnDeinitializeInterface(g_pvInterface);
}
}
return (dwErr == ERROR_SUCCESS);
}
extern "C"
BOOL
Deinit(
DWORD dwContext
)
{
BOT_Close();
DEBUGCHK(g_pvInterface);
UfnDeinitializeInterface(g_pvInterface);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -