⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bot.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 3 页
字号:

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