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

📄 ufnbus.cpp

📁 It permits simultaneous use of multiple USB Serial protocols.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                if (IsClientPresent()) {
                    if (IsClientActive()) {
                        DeactivateChild(m_szClientBusName);
                    }

                    RemoveChildByFolder(GetDeviceList());
                }
            }
            else {
                // Load new child
                CUfnBusDevice *pDevice;
                dwRet = CreateChild(ClientName.szName, &pDevice);
                if (dwRet != ERROR_SUCCESS) {
                    DEBUGMSG(ZONE_ERROR, (_T("%s CreateChild failed.\r\n"), 
                        pszFname));
                    break;
                }

                if (pDevice && pDevice->Init()) {
                    // Remove the current client if there is one
                    if (IsClientPresent()) {
                        if (IsClientActive()) {
                            DeactivateChild(m_szClientBusName);
                        }

                        RemoveChildByFolder(GetDeviceList());
                    }

                    // Activate new client
                    fRet = InsertChild(pDevice);
                    if (fRet == FALSE) {
                        dwRet = ERROR_GEN_FAILURE;
                        DEBUGMSG(ZONE_ERROR, (_T("%s InsertChild failed.\r\n"), 
                            pszFname));
                        delete pDevice;
                        break;
                    }
                    
                    fRet = ActivateChild(m_szClientBusName);
                    if (fRet == FALSE) {
                        dwRet = ERROR_GEN_FAILURE;
                        DEBUGMSG(ZONE_ERROR, (_T("%s ActivateChild failed.\r\n"), 
                            pszFname));
                        RemoveChildByFolder(pDevice);
                        break;
                    }
                }
            }
     
            break;
        }

        case IOCTL_UFN_GET_DEFAULT_CLIENT: {
            if ( !pbOutBuf || (cbOutBuf != sizeof(UFN_CLIENT_INFO)) ) {
                dwRet = ERROR_INVALID_PARAMETER;
                break;
            }

            PUFN_CLIENT_INFO pClientInfo = (PUFN_CLIENT_INFO) pbOutBuf;
            pClientInfo->szDescription[0] = 0;
            pClientInfo->szName[0] = 0;

            dwRet = GetDefaultClientName(pClientInfo->szName,
                dim(pClientInfo->szName));
            if (dwRet == ERROR_SUCCESS) {
                HKEY hkDefaultClient;
                if ( ERROR_SUCCESS == RegOpenKeyEx(pBusContext->hkClients,
                        pClientInfo->szName, 0, 0, &hkDefaultClient) ) {
                    GetUfnDescription(hkDefaultClient, pClientInfo->szDescription, 
                        dim(pClientInfo->szDescription));
                    RegCloseKey(hkDefaultClient);
                }
            }
            else {
                // No default is not an error.
                dwRet = ERROR_SUCCESS;
                pClientInfo->szName[0] = 0;
            }

            if (pcbActualOutBuf) {
                *pcbActualOutBuf = sizeof(UFN_CLIENT_INFO);
            }

            break;
        }

        case IOCTL_UFN_CHANGE_DEFAULT_CLIENT: {
            if ( !pbInBuf || (cbInBuf != sizeof(UFN_CLIENT_NAME)) ) {
                dwRet = ERROR_INVALID_PARAMETER;
                break;
            }

            PUFN_CLIENT_NAME pClientName = (PUFN_CLIENT_NAME) pbInBuf;
            UFN_CLIENT_NAME ClientName;
            HRESULT hr = StringCchCopy(ClientName.szName, dim(ClientName.szName),
                pClientName->szName);
            
            TCHAR szDefaultClientKey[MAX_PATH];
            
            GetDefaultClientKey(szDefaultClientKey, dim(szDefaultClientKey));

            // Make sure that the requested default client exists.
            HKEY hkNewDefaultClient;
            dwRet = RegOpenKeyEx(pBusContext->hkClients, 
                ClientName.szName, 0, 0, &hkNewDefaultClient);
            if (dwRet == ERROR_SUCCESS) {
                RegCloseKey(hkNewDefaultClient);
            
                dwRet = RegSetValueEx(pBusContext->hkClients,
                    szDefaultClientKey, NULL, REG_SZ, (PBYTE) ClientName.szName, 
                    (_tcslen(ClientName.szName) + 1) * sizeof(TCHAR));
                if (dwRet == ERROR_SUCCESS) {
                    DEBUGMSG(ZONE_FUNCTION, (_T("%s Changed default client to \"%s\"\r\n"),
                        pszFname, ClientName.szName));
                }
                else {
                    DEBUGMSG(ZONE_FUNCTION, (_T("%s Failure changing default client to \"%s\". Error = %u\r\n"),
                        pszFname, ClientName.szName, dwRet));
                }
            }
            else {
                DEBUGMSG(ZONE_ERROR, (_T("%s \"%s\" is not an available client\r\n"),
                    pszFname, ClientName.szName));
            }

            break;
        }        
        case IOCTL_UFN_GET_CLIENT_DATA_EX:
        case IOCTL_UFN_GET_CLIENT_DATA: {
            PUFN_CLIENT_DATA pucd = (PUFN_CLIENT_DATA) pbOutBuf;
            
            if ( !pucd || (cbOutBuf != sizeof(UFN_CLIENT_DATA) ) || 
                 (pucd->dwVersion != UFN_CLIENT_INTERFACE_VERSION) ) {
                dwRet = ERROR_INVALID_PARAMETER;
                break;
            }
            
            if (GetCurrentThread() != m_hInitThread) {
                dwRet = ERROR_ACCESS_DENIED;
                break;
            }
            
            DEBUGCHK(m_pContext->fClientIsBeingAddedOrRemoved);
            PREFAST_DEBUGCHK(m_pContext->hKey);

            TCHAR szDll[MAX_PATH];
            DWORD cbDll = sizeof(szDll);
            dwRet = RegQueryValueEx(m_pContext->hKey, DEVLOAD_DLLNAME_VALNAME, 
                NULL, NULL, (PBYTE) szDll, &cbDll);
            if (dwRet != ERROR_SUCCESS) {
                break;
            }
            NULL_TERMINATE(szDll);

            dwRet = GetClientFunctions(&pucd->ufnFunctions);
            if (dwRet != ERROR_SUCCESS) {
                break;
            }

            pucd->hiParent = LoadLibrary(szDll);
            if (!pucd->hiParent) {
                dwRet = GetLastError();
                break;
            }

            pucd->hDevice = (UFN_HANDLE) m_pContext;
            if (pcbActualOutBuf) {
                *pcbActualOutBuf = sizeof(*pucd);
            }

            break;
        }


        case IOCTL_BUS_SET_POWER_STATE:
            m_fIsChildPowerManaged = TRUE;        
            // Fall through to let the default bus driver process it.
        
        default:
            dwRet = ERROR_NOT_SUPPORTED;
            break;
    }

    if (dwRet == ERROR_NOT_SUPPORTED) {
        dwRet = m_pContext->PddInfo.pfnIOControl(
            m_pContext->PddInfo.pvPddContext, BUS_IOCTL, dwCode,
            pbInBuf, cbInBuf, pbOutBuf, cbOutBuf, pcbActualOutBuf);
        if (dwRet != ERROR_SUCCESS) {
            if (dwRet == ERROR_INVALID_PARAMETER) {
                fCallDefaultBusDriver = TRUE;
            }
        }
    }

    if (fCallDefaultBusDriver) {
        DEBUGCHK(dwRet != ERROR_SUCCESS);
        SetLastError(dwRet);
        fRet = DefaultBusDriver::IOControl(dwCode,
            pbInBuf, cbInBuf, pbOutBuf, cbOutBuf, pcbActualOutBuf);
    }
    else if (dwRet != ERROR_SUCCESS) {
        SetLastError(dwRet);
        fRet = FALSE;
    }
    else {
        fRet = TRUE;
    }

    return fRet;
}


DWORD CUfnBus::GetBusNamePrefix(
    LPTSTR pszBusName, 
    DWORD cchBusName
    )
{
    HRESULT hr = StringCchCopy(pszBusName, cchBusName, UFN_BUS_PREFIX);
    return _tcslen(pszBusName) + 1;
}


DWORD
CUfnBus::CleanUpAfterClient(
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PREFAST_DEBUGCHK(m_pContext);
    
    BOOL fClientActive = IsClientActive();

    DWORD dwRet = ERROR_SUCCESS;

    DEBUGCHK(m_pContext->fClientIsBeingAddedOrRemoved == FALSE);
    m_pContext->fClientIsBeingAddedOrRemoved = TRUE;

    if (m_pContext->fRunning) {
        if (fClientActive) {
            if (m_pContext->deviceState != DS_DETACHED) {
                ChangeDeviceState(m_pContext, DS_DETACHED);
                BOOL fRet = SendDeviceNotification(m_pContext->lpDeviceNotify, 
                    m_pContext->pvDeviceNotifyParameter, UFN_MSG_BUS_EVENTS, UFN_DETACH);
            }
        }

        DoStop(m_pContext);
    }
    
    if (m_pContext->fRegistered) {
        DoDeregisterDevice(m_pContext);
    }

    if (fClientActive) {
        CUfnBusDevice *pDevice = (CUfnBusDevice *) GetDeviceList();
        DEBUGCHK(pDevice);
        
        if (!DefaultBusDriver::DeactivateChild(m_szClientBusName)) {
            // We got an error for some reason. We'll return it but keep going.
            dwRet = GetLastError();
            DEBUGMSG(ZONE_WARNING, (_T("%s DeactivateDevice on \"%s\" failed\r\n"), 
                pszFname, pDevice->GetUfnName()));
        }
        else {
            DEBUGMSG(ZONE_INIT, (_T("%s Deactivated client driver \"%s\"\r\n"), 
                pszFname, pDevice->GetUfnName()));
        }
    }

    m_pContext->fClientIsBeingAddedOrRemoved = FALSE;

    FreePipes(m_pContext);

    DEBUGCHK(m_pContext->pFreeTransferList);
    delete m_pContext->pFreeTransferList;
    m_pContext->pFreeTransferList = NULL;

    m_pContext->deviceStatePriorToSuspend = DS_DETACHED;
    m_pContext->Speed = BS_FULL_SPEED;

    FUNCTION_LEAVE_MSG();

    return dwRet;
}


VOID
CUfnBus::GetDefaultClientKey(
    LPTSTR pszDefaultClientKey,
    DWORD cchDefaultClientKey
    )
{
    DEBUGCHK(pszDefaultClientKey);
    
    DWORD cbData = cchDefaultClientKey * sizeof(TCHAR);
    DWORD dwType;
    DWORD dwRet = RegQueryValueEx(m_pContext->hKey,
        PSZ_REG_DEFAULT_CLIENT_KEY, NULL, 
        &dwType, (PBYTE) pszDefaultClientKey, &cbData);
    pszDefaultClientKey[cchDefaultClientKey - 1] = 0;
    if ( (dwRet != ERROR_SUCCESS) || (dwType != REG_SZ) ) {
        // Use the default
        StringCchCopy(pszDefaultClientKey,cchDefaultClientKey,
            PSZ_REG_DEFAULT_DEFAULT_CLIENT_DRIVER);
    }
}


DWORD
CUfnBus::GetDefaultClientName(
    LPTSTR pszClientName,
    DWORD cchClientName
    )
{
    SETFNAME();
    DEBUGCHK(pszClientName);
    
    TCHAR szDefaultClientKey[MAX_PATH];
    HKEY hkFunctions = NULL;
    
    DWORD dwRet = OpenFunctionKey(&hkFunctions);
    if (dwRet != ERROR_SUCCESS) {
        goto EXIT;
    }
    
    GetDefaultClientKey(szDefaultClientKey, dim(szDefaultClientKey));

    DEBUGMSG(ZONE_FUNCTION, (_T("%s Using default client key named \"%s\"\r\n"),
        pszFname, szDefaultClientKey));    

    DWORD cbData = cchClientName * sizeof(TCHAR);
    DWORD dwType;
    dwRet = RegQueryValueEx(hkFunctions, szDefaultClientKey, NULL, 
        &dwType, (PBYTE) pszClientName, &cbData);
    pszClientName[cchClientName - 1] = 0;
    if ( (dwRet != ERROR_SUCCESS) || (dwType != REG_SZ) ) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Failed to read the client driver key name. Error: %d\r\n"),
            pszFname, dwRet));
        goto EXIT;
    }
    else if (pszClientName[0] == 0) {
        // No client selected. This is not an error state--we do not require
        // a client since the user can tell us to activate one later.
        DEBUGMSG(ZONE_WARNING, (_T("%s No default client driver listed in \"%s\".\r\n"), 
            pszFname, szDefaultClientKey));
        dwRet = ERROR_SUCCESS;
        goto EXIT;
    }

EXIT:
    if (hkFunctions) RegCloseKey(hkFunctions);

    return dwRet;       
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -