📄 ufnbus.cpp
字号:
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 + -