📄 pipe.cpp
字号:
m_TransferQueue.PopBack();
pTransfer->Release();
}
}
if (dwRet != ERROR_SUCCESS) {
// Free the transfer
pTransfer->Release();
}
}
FUNCTION_LEAVE_MSG();
Unlock();
return dwRet;
}
DWORD
CPipe::AbortTransfer(
PCUfnMddTransfer pTransfer
)
{
SETFNAME();
DWORD dwRet = ERROR_SUCCESS;
pTransfer->AddRef();
Lock();
DEBUGMSG(ZONE_TRANSFER, (_T("%s Aborting transfer 0x%08x on pipe at address %u (0x%08x)\r\n"),
pszFname, pTransfer, GetPhysicalEndpoint(), this));
pTransfer->Validate();
if (!pTransfer->IsComplete()) {
#ifdef DEBUG
DEBUGCHK(pTransfer == m_TransferQueue.Front() ||
pTransfer == m_TransferQueue.Back()); // TODO: Perform a search for correct transfer
#endif
if (pTransfer->IsInPdd()) {
DWORD dwErr = m_pPddInfo->pfnAbortTransfer(
m_pPddInfo->pvPddContext, GetPhysicalEndpoint(),
pTransfer->GetPddTransfer());
DEBUGCHK(dwErr == ERROR_SUCCESS);
}
else {
pTransfer->SetDwUsbError(UFN_CANCELED_ERROR);
DWORD dwErr = TransferComplete(pTransfer, FALSE);
DEBUGCHK(dwErr == ERROR_SUCCESS);
}
}
Unlock();
pTransfer->Release();
return dwRet;
}
DWORD CPipe::GetTransferStatus(
const CUfnMddTransfer *pTransfer,
PDWORD pcbTransferred,
PDWORD pdwUsbError
)
{
SETFNAME();
DEBUGCHK(pTransfer);
DEBUGCHK(pcbTransferred);
DEBUGCHK(pdwUsbError);
DWORD dwRet = ERROR_SUCCESS;
__try {
// Get the USB error value first. If it is a completed value,
// then cbTransferred will be accurrate. If we got cbTransferred
// first, it may not be correct according to the error value.
*pdwUsbError = pTransfer->GetDwUsbError();
*pcbTransferred = pTransfer->GetCbTransferred();
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR, (_T("%s Exception!\r\n"), pszFname));
dwRet = ERROR_INVALID_PARAMETER;
}
return dwRet;
}
DWORD
CPipe::CloseTransfer(
PCUfnMddTransfer pTransfer
)
{
SETFNAME();
DWORD dwRet = ERROR_SUCCESS;
Lock();
DEBUGMSG(ZONE_TRANSFER, (_T("%s Closing transfer 0x%08x on pipe at address %u (0x%08x)\r\n"),
pszFname, pTransfer, GetPhysicalEndpoint(), this));
pTransfer->Validate();
if (!pTransfer->IsComplete()) {
DWORD dwErr = AbortTransfer(pTransfer);
DEBUGCHK(dwErr == ERROR_SUCCESS); // Why would this fail?
}
pTransfer->Release();
Unlock();
return dwRet;
}
VOID CPipe::FreeTransfer(
PCUfnMddTransfer pTransfer
)
{
SETFNAME();
DEBUGCHK(pTransfer);
DEBUGMSG(ZONE_TRANSFER, (_T("%s Placing transfer 0x%08x on free list\r\n"),
pszFname, pTransfer));
m_pFreeTransferList->FreeTransfer(pTransfer);
}
DWORD
CPipe::TransferComplete(
PCUfnMddTransfer pTransfer,
BOOL fTransferWasInPdd
)
{
SETFNAME();
DWORD dwRet = ERROR_SUCCESS;
PREFAST_DEBUGCHK(pTransfer);
Lock();
DEBUGMSG(ZONE_TRANSFER, (_T("%s Completing transfer 0x%08x on pipe at address %u (0x%08x)\r\n"),
pszFname, pTransfer, GetPhysicalEndpoint(), this));
pTransfer->Validate();
DEBUGCHK(pTransfer->IsInPdd() == FALSE);
DEBUGCHK(pTransfer->IsComplete() == TRUE);
DEBUGCHK(m_TransferQueue.IsEmpty() == FALSE);
if (pTransfer == m_TransferQueue.Front()) {
m_TransferQueue.PopFront();
}
else {
DEBUGCHK(pTransfer == m_TransferQueue.Back());
DEBUGCHK(fTransferWasInPdd == FALSE);
m_TransferQueue.PopBack();
}
pTransfer->Release();
pTransfer->CallCompletionRoutine();
PCUfnMddTransfer pNewTransfer = NULL;
if (fTransferWasInPdd) {
if (m_TransferQueue.IsEmpty() == FALSE) {
// Start the next transfer
pNewTransfer = m_TransferQueue.Front();
}
}
if (pNewTransfer) {
pNewTransfer->EnteringPdd();
DWORD dwErr = m_pPddInfo->pfnIssueTransfer(m_pPddInfo->pvPddContext,
GetPhysicalEndpoint(), pNewTransfer->GetPddTransfer());
if (dwErr != ERROR_SUCCESS) {
RETAILMSG(1, (_T("%s Could not start next transfer 0x%08x\r\n"),
pszFname, pTransfer));
pNewTransfer->LeavingPdd();
pNewTransfer->SetDwUsbError(UFN_DEVICE_NOT_RESPONDING_ERROR);
TransferComplete(pNewTransfer, FALSE);
}
}
Unlock();
return dwRet;
}
DWORD
CPipe::Stall(
)
{
SETFNAME();
DWORD dwRet;
Lock();
if (IsOpen() == FALSE) {
DEBUGMSG(ZONE_ERROR, (_T("%s Pipe is not open\r\n"), pszFname));
dwRet = ERROR_INVALID_PARAMETER;
}
else {
DEBUGMSG(ZONE_PIPE, (_T("%s Stalling endpoint %u pipe (0x%08x)\r\n"),
pszFname, GetEndpointAddress(), this));
dwRet = m_pPddInfo->pfnStallEndpoint(m_pPddInfo->pvPddContext,
GetPhysicalEndpoint());
}
Unlock();
return dwRet;
}
DWORD
CPipe::ClearStall(
)
{
SETFNAME();
DWORD dwRet;
Lock();
if (IsOpen() == FALSE) {
DEBUGMSG(ZONE_ERROR, (_T("%s Pipe is not open\r\n"), pszFname));
dwRet = ERROR_INVALID_PARAMETER;
}
else {
DEBUGMSG(ZONE_PIPE, (_T("%s Clearing stall on endpoint %u pipe (0x%08x)\r\n"),
pszFname, GetEndpointAddress(), this));
dwRet = m_pPddInfo->pfnClearEndpointStall(m_pPddInfo->pvPddContext, GetPhysicalEndpoint());
}
Unlock();
return dwRet;
}
DWORD
CPipe::SendControlStatusHandshake(
)
{
SETFNAME();
Lock();
DEBUGCHK(GetPhysicalEndpoint() == 0);
DEBUGCHK(IsOpen());
DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Sending Control Status Handshake\r\n"),
pszFname, GetEndpointAddress(), this));
DWORD dwRet = m_pPddInfo->pfnSendControlStatusHandshake(
m_pPddInfo->pvPddContext, 0);
Unlock();
return dwRet;
}
// Check a pipe handle from the caller for correctness.
DWORD CPipe::ValidatePipeHandle(
const CPipe *pPipe
)
{
SETFNAME();
DWORD dwRet = ERROR_SUCCESS;
__try {
if (!pPipe) {
DEBUGMSG(ZONE_WARNING, (_T("%s Invalid Pipe handle 0x%08x\r\n"),
pszFname, pPipe));
dwRet = ERROR_INVALID_HANDLE;
}
else if ( (pPipe->m_dwSig != UFN_PIPE_SIG) || !pPipe->IsOpen() ) {
DEBUGMSG(ZONE_WARNING, (_T("%s Invalid Pipe handle 0x%08x (sig 0x%X)\r\n"),
pszFname, pPipe, pPipe->m_dwSig));
dwRet = ERROR_INVALID_HANDLE;
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_ERROR, (_T("%s Exception checking Pipe handle 0x%08x\r\n"),
pszFname, pPipe));
dwRet = ERROR_INVALID_HANDLE;
}
return dwRet;
}
#ifdef DEBUG
VOID
CPipe::Validate(
)
{
Lock();
DEBUGCHK(m_dwSig == UFN_PIPE_SIG);
DEBUGCHK(m_pPddInfo != NULL);
DEBUGCHK(m_pFreeTransferList != NULL);
if (m_TransferQueue.IsEmpty() == FALSE) {
PCUfnMddTransfer pTransfer = m_TransferQueue.Front();
pTransfer->Validate();
DEBUGCHK(pTransfer->GetPipe() == this);
}
Unlock();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -