📄 ufnmdd.cpp
字号:
// Open a pipe.
DWORD
WINAPI
UfnMdd_OpenPipe(
UFN_HANDLE hDevice,
DWORD dwEndpointAddress,
PUFN_PIPE phPipe
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
PCPipe pPipe = NULL;
BOOL fTookCS = FALSE;
VERIFY_PCONTEXT();
EnterCriticalSection(&pContext->csMddAccess);
fTookCS = TRUE;
VERIFY_RUNNING();
if (phPipe == NULL) {
DEBUGMSG(ZONE_ERROR, (_T("%s Invalid parameter\r\n"), pszFname));
dwRet = ERROR_INVALID_PARAMETER;
goto EXIT;
}
if (!pContext->fRegistered) {
DEBUGMSG(ZONE_ERROR, (_T("%s Device not registered\r\n"), pszFname));
dwRet = ERROR_INVALID_STATE;
goto EXIT;
}
if (dwEndpointAddress > 0xFF) {
DEBUGMSG(ZONE_ERROR, (_T("%s Invalid endpoint address = 0x%x\r\n"),
pszFname, dwEndpointAddress));
dwRet = ERROR_INVALID_PARAMETER;
goto EXIT;
}
// Search for the target endpoint address. The endpoint address is
// stored in the endpoint descriptor.
pPipe = FindPipe(pContext, dwEndpointAddress);
if (pPipe == NULL) {
DEBUGMSG(ZONE_ERROR, (_T("%s Invalid endpoint address = 0x%x\r\n"),
pszFname, dwEndpointAddress));
dwRet = ERROR_INVALID_PARAMETER;
goto EXIT;
}
// Open the endpoint
dwRet = pPipe->Open(pContext->Speed, NULL);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR, (_T("%s Error opening endpoint 0x%x\r\n"),
pszFname, pPipe->GetEndpointAddress()));
goto EXIT;
}
DEBUGMSG(ZONE_INIT || ZONE_PIPE, (_T("%s Opened endpoint 0x%x\r\n"),
pszFname, pPipe->GetEndpointAddress()));
__try {
*phPipe = pPipe;
dwRet = ERROR_SUCCESS;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR, (_T("%s Exception!\r\n"), pszFname));
dwRet = ERROR_INVALID_PARAMETER;
}
EXIT:
FUNCTION_LEAVE_MSG();
if (fTookCS) {
LeaveCriticalSection(&pContext->csMddAccess);
}
return dwRet;
}
// Close a pipe.
DWORD
WINAPI
UfnMdd_ClosePipe(
UFN_HANDLE hDevice,
UFN_PIPE hPipe
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet = ERROR_INVALID_PARAMETER;;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
PCPipe pPipe = (PCPipe) hPipe;
BOOL fTookCS = FALSE;
VERIFY_PCONTEXT();
VERIFY_RUNNING();
dwRet = CPipe::ValidatePipeHandle(pPipe);
if (dwRet != ERROR_SUCCESS) {
goto EXIT;
}
if (pPipe->GetPhysicalEndpoint() == 0) {
DEBUGMSG(ZONE_ERROR, (_T("%s Cannot close endpoint 0 pipe (0x%08x)\r\n"),
pszFname, pPipe));
dwRet = ERROR_INVALID_HANDLE;
goto EXIT;
}
EnterCriticalSection(&pContext->csMddAccess);
fTookCS = TRUE;
dwRet = pPipe->Close();
EXIT:
FUNCTION_LEAVE_MSG();
if (fTookCS) {
LeaveCriticalSection(&pContext->csMddAccess);
}
return dwRet;
}
DWORD
WINAPI
UfnMdd_GetTransferStatus(
UFN_HANDLE hDevice,
UFN_TRANSFER hTransfer,
PDWORD pcbTransferred,
PDWORD pdwUsbError
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
PCUfnMddTransfer pTransfer = (PCUfnMddTransfer) hTransfer;
VERIFY_PCONTEXT();
if ( (pcbTransferred == NULL) || (pdwUsbError == NULL) ) {
DEBUGMSG(ZONE_ERROR, (_T("%s Bad parameter\r\n"), pszFname));
dwRet = ERROR_INVALID_PARAMETER;
goto EXIT;
}
dwRet = CUfnMddTransfer::ReferenceTransferHandle(pTransfer);
if (dwRet == ERROR_SUCCESS) {
dwRet = CPipe::GetTransferStatus(pTransfer, pcbTransferred, pdwUsbError);
pTransfer->Release();
}
EXIT:
FUNCTION_LEAVE_MSG();
return dwRet;
}
DWORD
WINAPI
UfnMdd_AbortTransfer(
UFN_HANDLE hDevice,
UFN_TRANSFER hTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
PCUfnMddTransfer pTransfer = (PCUfnMddTransfer) hTransfer;
VERIFY_PCONTEXT();
VERIFY_RUNNING();
dwRet = CUfnMddTransfer::ReferenceTransferHandle(pTransfer);
if (dwRet == ERROR_SUCCESS) {
PCPipe pPipe = pTransfer->GetPipe();
dwRet = pPipe->AbortTransfer(pTransfer);
pTransfer->Release();
}
EXIT:
FUNCTION_LEAVE_MSG();
return dwRet;
}
DWORD
WINAPI
UfnMdd_CloseTransfer(
UFN_HANDLE hDevice,
UFN_TRANSFER hTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
PCUfnMddTransfer pTransfer = (PCUfnMddTransfer) hTransfer;
VERIFY_PCONTEXT();
dwRet = CUfnMddTransfer::ReferenceTransferHandle(pTransfer);
if (dwRet == ERROR_SUCCESS) {
PCPipe pPipe = pTransfer->GetPipe();
dwRet = pPipe->CloseTransfer(pTransfer);
pTransfer->Release();
}
EXIT:
FUNCTION_LEAVE_MSG();
return dwRet;
}
DWORD
WINAPI
UfnMdd_IssueTransfer(
UFN_HANDLE hDevice,
UFN_PIPE hPipe,
LPTRANSFER_NOTIFY_ROUTINE lpNotifyRoutine,
PVOID pvNotifyContext,
DWORD dwFlags,
DWORD cbBuffer,
PVOID pvBuffer,
DWORD dwBufferPhysicalAddress,
PVOID pvPddTransferInfo,
PUFN_TRANSFER phTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
PCPipe pPipe = (PCPipe) hPipe;
VERIFY_PCONTEXT();
VERIFY_RUNNING();
dwRet = CPipe::ValidatePipeHandle(pPipe);
if (dwRet != ERROR_SUCCESS) {
goto EXIT;
}
if ( (cbBuffer && (pvBuffer == NULL)) || (phTransfer == NULL) ||
( (dwFlags != USB_IN_TRANSFER) && (dwFlags != USB_OUT_TRANSFER) ) ) {
DEBUGMSG(ZONE_ERROR, (_T("%s Bad parameter\r\n"), pszFname));
dwRet = ERROR_INVALID_PARAMETER;
goto EXIT;
}
PCUfnMddTransfer *ppTransfer;
ppTransfer = (PCUfnMddTransfer*) phTransfer;
dwRet = pPipe->IssueTransfer(lpNotifyRoutine,
pvNotifyContext, dwFlags, cbBuffer, pvBuffer,
dwBufferPhysicalAddress, ppTransfer, pvPddTransferInfo);
#if 0
// Verify that the transfer was assigned properly
__try {
if (dwRet == ERROR_SUCCESS) {
DEBUGCHK(*phTransfer != NULL);
}
else {
DEBUGCHK(*phTransfer == NULL);
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGCHK(dwRet != ERROR_SUCCESS);
}
#endif
EXIT:
FUNCTION_LEAVE_MSG();
return dwRet;
}
// Stall a pipe.
DWORD
WINAPI
UfnMdd_StallPipe(
UFN_HANDLE hDevice,
UFN_PIPE hPipe
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
PCPipe pPipe = (PCPipe) hPipe;
VERIFY_PCONTEXT();
VERIFY_RUNNING();
dwRet = CPipe::ValidatePipeHandle(pPipe);
if (dwRet != ERROR_SUCCESS) {
goto EXIT;
}
dwRet = pPipe->Stall();
EXIT:
FUNCTION_LEAVE_MSG();
return dwRet;
}
// Clear a pipe stall.
DWORD
WINAPI
UfnMdd_ClearPipeStall(
UFN_HANDLE hDevice,
UFN_PIPE hPipe
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
PCPipe pPipe = (PCPipe) hPipe;
VERIFY_PCONTEXT();
VERIFY_RUNNING();
dwRet = CPipe::ValidatePipeHandle(pPipe);
if (dwRet != ERROR_SUCCESS) {
goto EXIT;
}
dwRet = pPipe->ClearStall();
EXIT:
FUNCTION_LEAVE_MSG();
return dwRet;
}
DWORD
WINAPI
UfnMdd_InitiateRemoteWakeup(
UFN_HANDLE hDevice
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
VERIFY_PCONTEXT();
VERIFY_RUNNING();
if (!pContext->fRemoteWakeupEnabled) {
DEBUGMSG(ZONE_ERROR, (_T("%s Remote wakeup has not been enabled by the host\r\n"),
pszFname));
dwRet = ERROR_GEN_FAILURE;
goto EXIT;
}
dwRet = pContext->PddInfo.pfnInitiateRemoteWakeup(pContext->PddInfo.pvPddContext);
EXIT:
FUNCTION_LEAVE_MSG();
return dwRet;
}
// Send the control status handshake. Called after sending or receiving the
// entire data transfer for a control transfer.
DWORD
WINAPI
UfnMdd_SendControlStatusHandshake(
UFN_HANDLE hDevice
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
PCPipe pPipe;
VERIFY_PCONTEXT();
VERIFY_RUNNING();
ValidateContext(pContext);
DEBUGCHK(pContext->pPipes);
pPipe = &pContext->pPipes[0];
dwRet = pPipe->SendControlStatusHandshake();
EXIT:
FUNCTION_LEAVE_MSG();
return dwRet;
}
// Free all the context resources.
static
VOID
FreeContext(
PUFN_MDD_CONTEXT pContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PREFAST_DEBUGCHK(pContext);
// Deinitialize the client.
if (pContext->pUfnBus) {
delete pContext->pUfnBus;
}
if (pContext->fPddInitialized) {
// Deinitialize the PDD
pContext->PddInfo.pfnDeinit(pContext->PddInfo.pvPddContext);
}
if (pContext->hKey) RegCloseKey(pContext->hKey);
DEBUGCHK(pContext->hEnumTransfer == NULL);
if (pContext->hevReadyForNotifications) CloseHandle(pContext->hevReadyForNotifications);
DeleteCriticalSection(&pContext->csMddAccess);
DeleteCriticalSection(&pContext->csBusIoctlAccess);
pContext->dwSig = GARBAGE_DWORD;
LocalFree(pContext);
FUNCTION_LEAVE_MSG();
}
static
BOOL
IsPddInterfaceInfoValid(
PUFN_PDD_INTERFACE_INFO pPddInterfaceInfo
)
{
BOOL fRet = TRUE;
if ( !pPddInterfaceInfo ||
pPddInterfaceInfo->dwVersion != UFN_PDD_INTERFACE_VERSION ||
pPddInterfaceInfo->dwEndpointCount == 0 ||
(pPddInterfaceInfo->dwCapabilities & UFN_PDD_CAPS_SUPPORTS_FULL_SPEED) == 0 ||
!pPddInterfaceInfo->pfnDeinit ||
!pPddInterfaceInfo->pfnIsConfigurationSupportable ||
!pPddInterfaceInfo->pfnIsEndpointSupportable ||
!pPddInterfaceInfo->pfnInitEndpoint ||
!pPddInterfaceInfo->pfnRegisterDevice ||
!pPddInterfaceInfo->pfnDeregisterDevice ||
!pPddInterfaceInfo->pfnStart ||
!pPddInterfaceInfo->pfnStop ||
!pPddInterfaceInfo->pfnIssueTransfer ||
!pPddInterfaceInfo->pfnAbortTransfer ||
!pPddInterfaceInfo->pfnDeinitEndpoint ||
!pPddInterfaceInfo->pfnStallEndpoint ||
!pPddInterfaceInfo->pfnClearEndpointStall ||
!pPddInterfaceInfo->pfnSendControlStatusHandshake ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -