| 
 //--------------------------------------------------------------------------------------------------------- // PUCHAR pRxBuffer          临时数据缓存区的空闲空间的起始地址 // ULONG *pBufflen            临时数据缓存区的空闲空间的剩余长度的指针          //---------------------------------------------------------------------------------------------------------  BOOL SerialDataIn::ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen) 
{ 
    Lock(); 
    BOOL bReturn = FALSE; 
    if (pRxBuffer && pBufflen && *pBufflen) { 
        DWORD dwBufferSize = *pBufflen ; 
        *pBufflen = 0 ; 
        if ( IsFrontArmedTransferComplete () ) {             // 上一次数据处理完成的判断 
            if (m_dwSegDataDataLen[m_dwCurIndex] == 0) { // Have't update the Transfer Status yet. 
                DWORD dwClientInfo = GetClientInfo(); 
                ASSERT((dwClientInfo & SERIAL_DATAIN_COOKIE_MASK)== SERIAL_DATAIN_COOKIE);                 // 检验数据包传输的连续性 
                ASSERT(m_dwCurIndex == (dwClientInfo & (~SERIAL_DATAIN_COOKIE_MASK))); 
                m_dwCurIndex =(dwClientInfo & (~SERIAL_DATAIN_COOKIE_MASK));                  
                DWORD dwError = USB_NO_ERROR; 
                DWORD dwLength;                 // 检测这次数据传输是否正确 
                if (GetFrontArmedTransferStatus(&dwLength, &dwError) && dwError == USB_NO_ERROR) { // Complete with no error. 
                    m_dwSegDataOffset[m_dwCurIndex] = 0;                     // 获取这一次数据传输的长度,保存在m_dwSegDataDataLen[m_dwCurIndex]。‘                     // 个人感觉应该不会出现 dwLength > m_dwSegmentSize 的情况吧? 
                    m_dwSegDataDataLen[m_dwCurIndex] = min(dwLength,m_dwSegmentSize);                     // 这一次循环需要拷贝的数据的长度 
                    DWORD dwCopyLength = min(m_dwSegDataDataLen[m_dwCurIndex],dwBufferSize); 
                    memcpy(pRxBuffer,m_VirtualAddress + m_dwSegmentSize*m_dwCurIndex ,dwCopyLength);                     // 保存当前已经拷贝数据的长度 m_dwSegDataOffset[m_dwCurIndex]。 
                    m_dwSegDataOffset[m_dwCurIndex] = dwCopyLength;                     // 返回这一数据拷贝的长度。这就是为什么这个数据要以指针传入的原因。 
                    *pBufflen = dwCopyLength; 
                    bReturn = TRUE; 
                    DEBUGMSG(ZONE_READ,(TEXT("ReceiveInterruptHandler:%d Copied  ,Transfer Size=%d"),dwCopyLength,dwLength)); 
                } 
                else { 
                    DEBUGMSG(ZONE_ERROR,(TEXT("ReceiveInterruptHandler:Transfer Error %d ,dwLength=%d"),dwError,dwLength)); 
                     
                } 
            }  
            // 进入这个if的情况是 m_dwSegDataDataLen[m_dwCurIndex] > dwBufferSize             // 但是我觉得进入这种情况下,数据处理就出错了啊!             // 首先, dwBufferSize 在上面的情况中没有做相应的处理,这个时候已经没有代表正确的值了。             // 其次, *pBufflen = dwCopyLen 这个语句也不对了,应该是*pBufflen += dwCopyLen; 
            if (m_dwSegDataOffset[m_dwCurIndex] < m_dwSegDataDataLen[m_dwCurIndex] ){ // We have Extra. 
                DWORD dwCopyLen = min (dwBufferSize, m_dwSegDataDataLen[m_dwCurIndex] - m_dwSegDataOffset[m_dwCurIndex]) ; 
                memcpy(pRxBuffer,m_VirtualAddress + (m_dwSegmentSize*m_dwCurIndex + m_dwSegDataOffset[m_dwCurIndex]) ,dwCopyLen); 
                *pBufflen = dwCopyLen; 
                m_dwSegDataOffset[m_dwCurIndex] += m_dwSegDataOffset[m_dwCurIndex]; 
                bReturn = TRUE; 
            } 
            if (m_dwSegDataOffset[m_dwCurIndex]>= m_dwSegDataDataLen[m_dwCurIndex] ){ 
                CloseFrontArmedTransfer(); 
                m_dwSegDataOffset[m_dwCurIndex]= m_dwSegDataDataLen[m_dwCurIndex] =  0 ; 
                BOOL bResult = BulkOrIntrTransfer(USB_NO_WAIT|USB_SHORT_TRANSFER_OK, 
                    m_dwSegmentSize, 
                    m_VirtualAddress+ (m_dwCurIndex * m_dwSegmentSize), 
                    m_PhysicalAddress.LowPart+(m_dwCurIndex*m_dwSegmentSize), 
                    SERIAL_DATAIN_COOKIE+m_dwCurIndex); 
                ASSERT(bResult==TRUE); 
                m_dwCurIndex ++; 
                if (m_dwCurIndex>=NUM_OF_IN_TRANSFER) 
                    m_dwCurIndex = 0; 
            } 
        } 
    } 
    Unlock(); 
    return bReturn; 
}  
 |